⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 x11term.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
/* X Communication module for terminals which understand the X protocol.   Copyright (C) 1988, 1990 Free Software Foundation, Inc.This file is part of GNU Emacs.GNU Emacs is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GNU Emacs is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Emacs; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  *//* Written by Yakim Martillo, mods and things by Robert Krawitz  *//* Redone for X11 by Robert French *//* Thanks to Mark Biggers for all of the Window Manager support *//* *	$Source: /mit/emacs/src/RCS/11xterm.c,v $ *	$Author: rfrench $ *	$Locker:  $ *	$Header: x11term.c,v 1.12 88/02/29 14:11:07 rfrench Exp $ */#ifndef lintstatic char *rcsid_xterm_c = "$Header: x11term.c,v 1.12 88/02/29 14:11:07 rfrench Exp $";#endif	lint/* On 4.3 this loses if it comes after x11term.h.   On hp-ux it loses if it comes after config.h.  */#include <signal.h>#include <sys/ioctl.h>/* Load sys/types.h if not already loaded.   In some systems loading it twice is suicidal.  */#ifndef makedev#include <sys/types.h>#endif#include "config.h"#ifdef HAVE_X_WINDOWS/* Get FIONREAD, if it is available.   It would be logical to include <sys/ioctl.h> here,   but it was moved up above to avoid problems.  */#ifdef USG#include <termio.h>#include <fcntl.h>#endif /* USG */#include "lisp.h"#undef NULL/* Allow m- file to inhibit use of interrupt-driven input.  */#ifdef BROKEN_FIONREAD#undef FIONREAD#endif/* We are unable to use interrupts if FIONREAD is not available,   so flush SIGIO so we won't try.  */#ifndef FIONREAD#ifdef SIGIO#undef SIGIO#endif#endif/* This may include sys/types.h, and that somehow loses   if this is not done before the other system files.   However, perhaps the problem has been avoided by loading types.h above.  */#include "x11term.h"#ifdef IRIS#include <sys/sysmacros.h>	/* for "minor" */#include <sys/time.h>#else#ifdef UNIPLUS#include <sys/time.h>#else /* not IRIS, not UNIPLUS *//* Use socket.h just to control whether to use time.h or sys/time.h.   This works like the code in process.c.  */#ifdef HAVE_SOCKETS#include <sys/socket.h>#endif#ifdef HAVE_TIMEVAL/* _h_BSDTYPES is checked because on ISC unix, socket.h includes   both time.h and sys/time.h, and the latter file is protected   from repeated inclusion.  */#if defined(USG) && !defined(_h_BSDTYPES)#include <time.h>#else /* _h_BSDTYPES or not USG */#include <sys/time.h>#endif /* _h_BSDTYPES or not USG */#endif /* HAVE_TIMEVAL */#endif /* not UNIPLUS */#endif /* not IRIS */#ifdef BAT68K#include <sys/time.h>   /* In addition to time.h.  */#endif#ifdef AIX#include <sys/time.h>   /* In addition to time.h.  */static KeySym XMOD_Alt[] = { XK_Alt_L };static KeySym XMOD_Shift[] = { XK_Shift_L };static KeySym XMOD_ShiftAlt[] = { XK_Alt_L, XK_Shift_L };static KeySym XMOD_CtrlAlt[] = { XK_Control_L, XK_Alt_L };static KeySym XMOD_Ctrl[] = { XK_Control_L };static KeySym XMOD_CtrlShift[] = { XK_Control_L, XK_Shift_L };static KeySym XMOD_ShiftCtrlAlt[] = { XK_Control_L, XK_Alt_L, XK_Shift_L };#endif#include <fcntl.h>#include <stdio.h>#include <ctype.h>#include <errno.h>#ifdef BSD#include <strings.h>#endif#include <sys/stat.h>#include "dispextern.h"#include "termhooks.h"#include "termopts.h"#include "termchar.h"#include "sink11.h"#include "sink11mask.h"#define min(a,b) ((a)<(b) ? (a) : (b))#define max(a,b) ((a)>(b) ? (a) : (b))extern int errno;#define sigunblockx(sig) sigblock (0)#define sigblockx(sig) sigblock (1 << ((sig) - 1))#define METABIT 0200#define MINWIDTH 12	/* In pixels */#define MINHEIGHT 5	/* In pixels */#define MAXHEIGHT 300	/* In lines */int pixelwidth,pixelheight;char *progname;XEvent *XXm_queue[XMOUSEBUFSIZE];int XXm_queue_num, XXm_queue_in, XXm_queue_out;char *XXcurrentfont;XFontStruct *fontinfo;Font XXfid;int XXfontw, XXfonth, XXbase, XXisColor;/* Nonzero means Emacs has explicit keyboard focus.  */int x_focus_flag;Colormap XXColorMap;char *default_window;int configure_pending;extern int initialized;extern int screen_width, screen_height;/* Function for init_keyboard to call with no args (if nonzero).  */extern void (*keyboard_init_hook) ();extern char *alternate_display;extern int xargc;extern char **xargv;int XXdebug;int XXpid;int WindowMapped;char  *XXidentity;	/* Resource name of this invocation of Emacs */static char  *XXicon_name;	/* user-supplied icon info */static int   XXicon_usebitmap;	/* Use bitmap or not */static char  *XXheader;		/* user-supplied window header info */static int flexlines;  		/* last line affected by dellines or				 * inslines functions */int VisibleX, VisibleY;		/* genuine location of cursor on screen				 * if it is there *//* Last cursor position specified by move_cursor.   During an update, this does not display a cursor on the screen;   But it controls the position that is output.  */static int local_cursor_hpos;static int local_cursor_vpos;static int SavedX, SavedY;	/* Where the cursor was before update				 * started */int CursorExists;		/* during updates cursor is turned off */int CursorOutline; 	    	/* when the pointer is not in the Emacs    	    	    	    	 * widow the cursor should be drawn in    	    	    	         * outline form a la xterm */static int InUpdate;		/* many of functions here may be invoked				 * even if no update in progress; when				 * no update is in progress the action				 * can be slightly different */Display *XXdisplay;int XXscreen;Window XXwindow;GC XXgc_norm,XXgc_rev,XXgc_curs,XXgc_temp;XGCValues XXgcv;Cursor EmacsCursor;Pixmap SinkPixmap, SinkMaskPixmap;char *fore_color;	/* Variables to store color names */char *back_color;char *brdr_color;char *curs_color;char *mous_color;unsigned long fore;	/* Variables to store pixel values */unsigned long back;unsigned long brdr;unsigned long curs;char *desiredwindow;int CurHL;			/* Current Highlighting (ala mode line) */int XXborder;			/* Window border width */int XXInternalBorder;		/* Internal border width */int updated[MAXHEIGHT];static char  *temp_font;                /* needed because of loading hacks */static char  *temp_reverseVideo;static char  *temp_borderWidth;static char  *temp_internalBorder;static char  *temp_useBitmap;struct _xdeftab {  char *iname;			/* instance name */  char *cname;			/* class name (fake it) */  char **varp;			/* variable to set */};static struct _xdeftab xDefaultsValueTable[] = {     { "reverseVideo",	"ReverseVideo",		&temp_reverseVideo },     { "borderWidth",	"BorderWidth",		&temp_borderWidth },     { "internalBorder","BorderWidth",		&temp_internalBorder },     { "bitmapIcon",	"BitmapIcon",		&temp_useBitmap },     { "borderColor",	"BorderColor",		&brdr_color },     { "background",	"Background",		&back_color },     { "foreground",	"Foreground",		&fore_color },     { "pointerColor",	"Foreground",		&mous_color },     { "cursorColor",	"Foreground",		&curs_color },     { "font",		"Font",			&temp_font },     { "geometry",	"Geometry",		&desiredwindow },     { "title",		"Title",		&XXheader },     { "iconName",	"Title",		&XXicon_name },     { NULL,		NULL,			NULL }   };int (*handler)();static void x_init_1 ();char *rindex();/* HLmode -- Changes the GX function for output strings.  Could be used to * change font.  Check an XText library function call. */HLmode (new)     int new;{	extern Lisp_Object inverse_video;		CurHL = new;}/* External interface to control of standout mode.   Call this when about to modify line at position VPOS   and not change whether it is highlighted.  */XTreassert_line_highlight (highlight, vpos)     int highlight, vpos;{	HLmode (highlight);}/* Call this when about to modify line at position VPOS   and change whether it is highlighted.  */XTchange_line_highlight (new_highlight, vpos, first_unused_hpos)     int new_highlight, vpos, first_unused_hpos;{	HLmode (new_highlight);	XTmove_cursor (vpos, 0);	x_clear_end_of_line (0);}/* Used for starting or restarting (after suspension) the X window.  Puts the * cursor in a known place, update does not begin with this routine but only * with a call to redisplay. */XTset_terminal_modes (){	int stuffpending;#ifdef XDEBUG	fprintf (stderr, "XTset_terminal_modes\n");#endif	InUpdate = 0;	stuffpending = 0;	if (!initialized) {		CursorExists = 0;		CursorOutline = 1;		VisibleX = 0;		VisibleY = 0;	}	XTclear_screen ();}/* XTmove_cursor moves the cursor to the correct location and checks whether an * update is in progress in order to toggle it on. */XTmove_cursor (row, col)     register int row, col;{	BLOCK_INPUT_DECLARE ();#ifdef XDEBUG	fprintf (stderr, "XTmove_cursor (X %d, Y %d)\n",col,row);#endif	BLOCK_INPUT ();	local_cursor_hpos = col;	local_cursor_vpos = row;	if (InUpdate) {		if (CursorExists)			CursorToggle ();		UNBLOCK_INPUT ();		return;		/* Generally, XTmove_cursor will be invoked */		/* when InUpdate with !CursorExists */		/* so that wasteful XFlush is not called */	}	if ((row == VisibleY) && (col == VisibleX)) {		if (!CursorExists)			CursorToggle ();		XFlush (XXdisplay);		UNBLOCK_INPUT ();		return;	}	if (CursorExists)		CursorToggle ();	VisibleX = col;	VisibleY = row;	if (!CursorExists)		CursorToggle ();	XFlush (XXdisplay);	UNBLOCK_INPUT ();}/* Used to get the terminal back to a known state after resets.  Usually * used when restarting suspended or waiting emacs */cleanup (){	inverse_video = 0;	HLmode (0);}/* Erase current line from current column to column END.   Leave cursor at END.  */XTclear_end_of_line (end)     register int end;{  register int numcols;  BLOCK_INPUT_DECLARE ();#ifdef XDEBUG  fprintf (stderr, "XTclear_end_of_line (to %d)\n",end);#endif  if (local_cursor_vpos < 0 || local_cursor_vpos >= screen_height)    return;  if (end <= local_cursor_hpos)    return;  if (end >= screen_width)    end = screen_width;  numcols = end - local_cursor_hpos;  BLOCK_INPUT ();  if (local_cursor_vpos == VisibleY && VisibleX >= local_cursor_hpos && VisibleX < end)    if (CursorExists) CursorToggle ();  if (CurHL)    XFillRectangle (XXdisplay, XXwindow, XXgc_norm,		    local_cursor_hpos*XXfontw+XXInternalBorder,		    local_cursor_vpos*XXfonth+XXInternalBorder,		    XXfontw*numcols,		    XXfonth);  else    XClearArea (XXdisplay, XXwindow,		local_cursor_hpos*XXfontw+XXInternalBorder,		local_cursor_vpos*XXfonth+XXInternalBorder,		XXfontw*numcols,		XXfonth,		0);  XTmove_cursor (local_cursor_vpos, end);  UNBLOCK_INPUT ();}/* Erase current line from column START to right margin.   Leave cursor at START.  */x_clear_end_of_line (start)     register int start;{  register int numcols;  BLOCK_INPUT_DECLARE ();#ifdef XDEBUG  fprintf (stderr, "x_clear_end_of_line (start %d)\n", start);#endif  if (local_cursor_vpos < 0 || local_cursor_vpos >= screen_height)    return;  if (start >= screen_width)    return;  if (start < 0)    start = 0;  numcols = screen_width - start;  BLOCK_INPUT ();  if (local_cursor_vpos == VisibleY && VisibleX >= start)    if (CursorExists) CursorToggle ();  if (CurHL)    XFillRectangle (XXdisplay, XXwindow, XXgc_norm,		    start*XXfontw+XXInternalBorder,		    local_cursor_vpos*XXfonth+XXInternalBorder,		    XXfontw*numcols,		    XXfonth);  else    XClearArea (XXdisplay, XXwindow,		start*XXfontw+XXInternalBorder,		local_cursor_vpos*XXfonth+XXInternalBorder,		XXfontw*numcols,		XXfonth,		0);  XTmove_cursor (local_cursor_vpos, start);  UNBLOCK_INPUT ();}XTreset_terminal_modes (){#ifdef XDEBUG	fprintf (stderr, "XTreset_terminal_modes\n");#endif	XTclear_screen ();}XTclear_screen (){	BLOCK_INPUT_DECLARE ();#ifdef XDEBUG	fprintf (stderr, "XTclear_screen\n");#endif	BLOCK_INPUT ();	HLmode (0);	CursorExists = 0;	local_cursor_hpos = 0;	local_cursor_vpos = 0;	SavedX = 0;	SavedY = 0;	VisibleX = 0;	VisibleY = 0;	XClearWindow(XXdisplay, XXwindow);	CursorToggle ();	if (!InUpdate)		XFlush (XXdisplay);	UNBLOCK_INPUT ();}/* used by dumprectangle which is usually invoked upon Expose * events which come from bit blt's or moving an obscuring opaque window */dumpchars (active_screen, numcols, tempX, tempY, tempHL)     register struct matrix *active_screen;     register int numcols;     register int tempX, tempY, tempHL;{	if (numcols <= 0)		return;	if (numcols-1+tempX > screen_width)		numcols = screen_width-tempX+1;	if (tempX < 0 || tempX >= screen_width ||	    tempY < 0 || tempY >= screen_height)		return;	XDrawImageString(XXdisplay, XXwindow, tempHL ? XXgc_rev : XXgc_norm,			 tempX*XXfontw+XXInternalBorder,			 tempY*XXfonth+XXInternalBorder+XXbase,			 &active_screen->contents[tempY][tempX],			 numcols);}/* When a line has been changed this function is called.  Due to various * bits of braindamage on the parts of both X11 and Emacs, the new * version of the line is simply output if this function is invoked while * in UpDate.  Sometimes writechars can be invoked when not in update if * text is to be output at the end of the line.  In this case the whole * line is not output.  Simply the new text at the current cursor * position given by VisibleX,Y.  The cursor is moved to the end of the * new text. */updateline (first)	int first;{	register int temp_length;	BLOCK_INPUT_DECLARE ();#ifdef XDEBUG	fprintf(stderr, "updateline\n");#endif XDEBUG	BLOCK_INPUT ();	if ((local_cursor_vpos < 0) || (local_cursor_vpos >= screen_height)	    || updated[local_cursor_vpos]) {		UNBLOCK_INPUT ();		return;	}	if (!first)		updated[local_cursor_vpos] = 1;	if (CursorExists)		CursorToggle ();	if (new_screen->enable[local_cursor_vpos])		temp_length = new_screen->used[local_cursor_vpos]-first;	else		temp_length = 0;	if (temp_length > 0) {		XDrawImageString (XXdisplay, XXwindow,				  CurHL ? XXgc_rev : XXgc_norm,				  first*XXfontw+XXInternalBorder,				  local_cursor_vpos*XXfonth+XXInternalBorder+XXbase,				  &new_screen->contents[local_cursor_vpos][first],				  temp_length);		if (temp_length < screen_width)			x_clear_end_of_line (temp_length);		XTmove_cursor (local_cursor_vpos, temp_length);	}	else {		x_clear_end_of_line (0);		XTmove_cursor (local_cursor_vpos, 0);	}	UNBLOCK_INPUT ();}writechars (start, end)	register char *start, *end;{  BLOCK_INPUT_DECLARE ();#ifdef XDEBUG  fprintf(stderr, "writechars (local_cursor_hpos %d temp_len %d InUpd %d)\n",	  local_cursor_hpos, end-start+1, InUpdate);#endif XDEBUG  BLOCK_INPUT ();  if ((local_cursor_vpos < 0) || (local_cursor_vpos >= screen_height))    {      UNBLOCK_INPUT ();      return;    }  if (CursorExists)    CursorToggle ();  if (InUpdate)    {      XDrawImageString (XXdisplay, XXwindow,			CurHL ? XXgc_rev : XXgc_norm,			local_cursor_hpos*XXfontw+XXInternalBorder,			local_cursor_vpos*XXfonth+XXInternalBorder+XXbase,			start,			(end - start) + 1);      XTmove_cursor (local_cursor_vpos, (end - start) + 1);      UNBLOCK_INPUT ();      return;    }  if ((VisibleX < 0) || (VisibleX >= screen_width)) {    UNBLOCK_INPUT ();    return;  }  if ((VisibleY < 0) || (VisibleY >= screen_height)) {    UNBLOCK_INPUT ();    return;  }  if (((end - start) + VisibleX) >= screen_width)    end = start + (screen_width - (VisibleX + 1));  if (end >= start) {    XDrawImageString (XXdisplay, XXwindow,		      CurHL ? XXgc_rev : XXgc_norm,		      (VisibleX * XXfontw+XXInternalBorder),		      VisibleY * XXfonth+XXInternalBorder+XXbase,		      start,		      ((end - start) + 1));    VisibleX = VisibleX + (end - start) + 1;  }  if (!CursorExists)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -