summaryrefslogtreecommitdiff
path: root/src/xterm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c1933
1 files changed, 1933 insertions, 0 deletions
diff --git a/src/xterm.c b/src/xterm.c
new file mode 100644
index 00000000000..7d946a76a76
--- /dev/null
+++ b/src/xterm.c
@@ -0,0 +1,1933 @@
+/* X Communication module for terminals which understand the X protocol.
+ Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the 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 of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Written by Yakim Martillo, mods and things by Robert Krawitz */
+
+/*
+ * $Source: /u2/third_party/gnuemacs.chow/src/RCS/xterm.c,v $
+ * $Author: rlk $
+ * $Locker: $
+ * $Header: xterm.c,v 1.28 86/08/27 13:30:57 rlk Exp $
+ */
+
+#ifndef lint
+static char *rcsid_TrmXTERM_c = "$Header: xterm.c,v 1.28 86/08/27 13:30:57 rlk Exp $";
+#endif lint
+
+/* On 4.3 this loses if it comes after xterm.h. */
+#include <signal.h>
+#include "config.h"
+
+#ifdef HAVE_X_WINDOWS
+
+#include "lisp.h"
+#undef NULL
+
+/* This may include sys/types.h, and that somehow loses
+ if this is not done before the other system files. */
+#include "xterm.h"
+
+/* Load sys/types.h if not already loaded.
+ In some systems loading it twice is suicidal. */
+#ifndef makedev
+#include <sys/types.h>
+#endif
+
+#if !defined(USG) || defined(IBMRTAIX)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif /* USG and not IBMRTAIX */
+
+#include <sys/ioctl.h>
+#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 "sink.h"
+#include "sinkmask.h"
+#include <X/Xkeyboard.h>
+/*#include <X/Xproto.h> */
+
+/* Allow m- file to inhibit use of FIONREAD. */
+#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
+
+/* Allow config to specify default font. */
+#ifndef X_DEFAULT_FONT
+#define X_DEFAULT_FONT "vtsingle"
+#endif
+
+#define min(a,b) ((a)<(b) ? (a) : (b))
+#define max(a,b) ((a)>(b) ? (a) : (b))
+#define sigunblockx(sig) sigblock (0)
+#define sigblockx(sig) sigblock (1 << ((sig) - 1))
+XREPBUFFER Xxrepbuffer;
+int pixelwidth;
+int pixelheight;
+int PendingExposure;
+int PendingIconExposure;
+#define MAXICID 80
+char iconidentity[MAXICID];
+#define ICONTAG "emacs@"
+#define METABIT 0x80
+Window XXIconWindow;
+Bitmap XXIconMask;
+
+char *XXcurrentfont;
+char *default_window;
+int informflag;
+extern int initialized;
+
+extern char *alternate_display;
+
+int XXdebug;
+int XXpid;
+extern int screen_garbaged;
+int XXxoffset, XXyoffset;
+int IconWindow;
+
+int WindowMapped;
+int CurHL;
+
+static int flexlines; /* last line affect by dellines or */
+ /* inslines functions */
+extern int errno;
+int VisibleX, VisibleY; /* genuine location of cursor on screen */
+ /* if it is there */
+static int SavedX, SavedY; /* Where the cursor was before update */
+ /* started */
+
+int bitblt; /* Used to track bit blt events */
+int CursorExists; /* during updates cursor is turned off */
+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 */
+
+short MouseCursor[] = {
+ 0x0000, 0x0008, 0x0018, 0x0038,
+ 0x0078, 0x00f8, 0x01f8, 0x03f8,
+ 0x07f8, 0x00f8, 0x00d8, 0x0188,
+ 0x0180, 0x0300, 0x0300, 0x0000};
+
+short MouseMask[] = {
+ 0x000c, 0x001c, 0x003c, 0x007c,
+ 0x00fc, 0x01fc, 0x03fc, 0x07fc,
+ 0x0ffc, 0x0ffc, 0x01fc, 0x03dc,
+ 0x03cc, 0x0780, 0x0780, 0x0300};
+
+Display *XXdisplay;
+FontInfo *fontinfo;
+Window XXwindow;
+Cursor EmacsCursor;
+
+char *fore_color; /* Variables to store colors */
+char *back_color;
+char *brdr_color;
+char *curs_color;
+char *mous_color;
+
+int fore;
+int back;
+int brdr;
+int curs;
+int mous;
+
+static WindowInfo windowinfo;
+WindowInfo rootwindowinfo;
+
+
+
+static XKeyPressedEvent XXEvent; /* as X messages are read in they are */
+ /* stored here */
+static XREPBUFFER XXqueue;/* Used for storing up ExposeRegion */
+ /* replies, so that the SIGIO inter- */
+ /* rupt serving routines do almost */
+ /* no writes to the X socket */
+/*int CurHL; /* Current Highlighting actually being */
+ /* being used for bold font right now*/
+
+int XXborder;
+int XXInternalBorder;
+
+int (*handler)();
+
+extern Display *XOpenDisplay ();
+extern Window XCreateWindow ();
+extern Cursor XDefineCursor ();
+extern Cursor XCreateCursor ();
+extern FontInfo *XOpenFont ();
+
+static int flashback ();
+
+
+/* HLmode -- Changes the GX function for output strings. Could be used to
+ * change font. Check an XText library function call.
+ */
+
+static
+HLmode (new)
+ int new;
+{
+ 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. */
+
+static
+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. The mouse cursor is warped into the window and
+ * then the cursor is turned on.
+ */
+
+
+
+static
+XTset_terminal_modes ()
+{
+ int stuffpending;
+#ifdef XDEBUG
+ fprintf (stderr, "XTset_terminal_modes\n");
+#endif
+ InUpdate = 0;
+ stuffpending = 0;
+ if (!initialized)
+ {
+ CursorExists = 0;
+ VisibleX = 0;
+ VisibleY = 0;
+ }
+ XTclear_screen ();
+#ifdef FIONREAD
+ ioctl (0, FIONREAD, &stuffpending);
+ if (stuffpending)
+ SIGNAL_INPUT ();
+#endif
+}
+
+/* XTmove_cursor moves the cursor to the correct location and checks whether an update
+ * is in progress in order to toggle it on.
+ */
+
+static
+XTmove_cursor (row, col)
+ register int row, col;
+{
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+#ifdef XDEBUG
+ fprintf (stderr, "XTmove_cursor\n");
+#endif
+ cursor_hpos = col;
+ 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 ();
+ UNBLOCK_INPUT ();
+ return;
+ }
+ if (CursorExists) CursorToggle ();
+ VisibleX = col;
+ VisibleY = row;
+ if (!CursorExists) CursorToggle ();
+ XFlush ();
+ UNBLOCK_INPUT ();
+}
+
+/* Used to get the terminal back to a known state after resets. Usually
+ * used when restarting suspended or waiting emacs
+ */
+
+static
+cleanup ()
+{
+ inverse_video = 0;
+ HLmode (0);
+}
+
+/* Erase current line from column cursor_hpos to column END.
+ Leave cursor at END. */
+
+static
+XTclear_end_of_line (end)
+ register int end;
+{
+ register int numcols;
+
+#ifdef XDEBUG
+ fprintf (stderr, "XTclear_end_of_line\n");
+
+#endif
+ if (cursor_vpos < 0 || cursor_vpos >= screen_height)
+ {
+ return;
+ }
+
+ if (end >= screen_width)
+ end = screen_width;
+ if (end <= cursor_hpos)
+ return;
+
+ numcols = end - cursor_hpos;
+ {
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+ if (cursor_vpos == VisibleY && VisibleX >= cursor_hpos && VisibleX < end)
+ {
+ if (CursorExists) CursorToggle ();
+ }
+ XPixSet (XXwindow,
+ cursor_hpos * fontinfo->width + XXInternalBorder,
+ cursor_vpos * fontinfo->height+XXInternalBorder,
+ fontinfo->width * numcols,
+ fontinfo->height,
+ back);
+ XTmove_cursor (cursor_vpos, end);
+ UNBLOCK_INPUT ();
+ }
+}
+
+/* Erase current line from column START to right margin.
+ Leave cursor at START. */
+
+static
+x_clear_end_of_line (start)
+ register int start;
+{
+ register int numcols;
+
+#ifdef XDEBUG
+ fprintf (stderr, "x_clear_end_of_line\n");
+
+#endif
+ if (cursor_vpos < 0 || cursor_vpos >= screen_height)
+ {
+ return;
+ }
+
+ if (start < 0)
+ start = 0;
+ if (start >= screen_width)
+ return;
+
+ numcols = screen_width - start;
+ {
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+ if (cursor_vpos == VisibleY && VisibleX >= start)
+ {
+ if (CursorExists) CursorToggle ();
+ }
+ XPixSet (XXwindow,
+ start * fontinfo->width + XXInternalBorder,
+ cursor_vpos * fontinfo->height+XXInternalBorder,
+ fontinfo->width * numcols,
+ fontinfo->height,
+ back);
+ XTmove_cursor (cursor_vpos, start);
+ UNBLOCK_INPUT ();
+ }
+}
+
+static
+XTreset_terminal_modes ()
+{
+#ifdef XDEBUG
+ fprintf (stderr, "XTreset_terminal_modes\n");
+#endif
+ XTclear_screen ();
+}
+
+static
+XTclear_screen ()
+{
+#ifdef XDEBUG
+ fprintf (stderr, "XTclear_screen\n");
+#endif
+ HLmode (0);
+ CursorExists = 0;
+
+ cursor_hpos = 0;
+ cursor_vpos = 0;
+ SavedX = 0;
+ SavedY = 0;
+ VisibleX = 0;
+ VisibleY = 0;
+ {
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+ XClear (XXwindow);
+ CursorToggle ();
+ if (!InUpdate)
+ XFlush ();
+ UNBLOCK_INPUT ();
+ }
+}
+
+/* used by dumprectangle which is usually invoked upon ExposeRegion
+ * events which come from bit blt's or moving an obscuring opaque window
+ */
+
+static
+dumpchars (current_screen, numcols, tempX, tempY, tempHL)
+ register struct matrix *current_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;
+ }
+ XText (XXwindow,
+ (tempX * fontinfo->width+XXInternalBorder),
+ (tempY * fontinfo->height+XXInternalBorder),
+ &current_screen->contents[tempY][tempX],
+ numcols,
+ fontinfo->id,
+ (tempHL ? back : fore),
+ (tempHL ? fore : back));
+}
+
+/* When a line has been changed this function is called. X is so fast
+ * that the actual sequence is ignore. Rather, 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.
+ */
+static
+writechars (start, end)
+ register char *start, *end;
+{
+ register int temp_length;
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+
+ if ((cursor_vpos < 0) || (cursor_vpos >= screen_height))
+ {
+ UNBLOCK_INPUT ();
+ return;
+ }
+ if (CursorExists)
+ {
+ CursorToggle ();
+ }
+ if (InUpdate)
+ {
+ if (end != start - 1)
+ {
+ XText (XXwindow,
+ (cursor_hpos * fontinfo->width+XXInternalBorder),
+ (cursor_vpos * fontinfo->height+XXInternalBorder),
+ start,
+ end + 1 - start,
+ fontinfo->id,
+ (CurHL ? back : fore),
+ (CurHL ? fore : back));
+ XTmove_cursor (cursor_vpos, cursor_hpos + end - start + 1);
+ }
+ }
+ else
+ {
+ 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)
+ {
+ XText (XXwindow,
+ (VisibleX * fontinfo->width+XXInternalBorder),
+ (VisibleY * fontinfo->height+XXInternalBorder),
+ start,
+ ((end - start) + 1),
+ fontinfo->id,
+ (CurHL ? back : fore),
+ (CurHL ? fore : back));
+ VisibleX = VisibleX + (end - start) + 1;
+ }
+ if (!CursorExists) CursorToggle ();
+ }
+ UNBLOCK_INPUT ();
+}
+
+
+static
+XToutput_chars (start, len)
+ register char *start;
+ register int len;
+{
+#ifdef XDEBUG
+ fprintf (stderr, "XToutput_chars\n");
+#endif
+ writechars (start, start + len - 1);
+}
+
+/* The following routine is for the deaf or for the pervert who prefers
+ * that his terminal flash at him rather than beep at him.
+ */
+
+static int flashedback;
+
+static
+XTflash ()
+{
+#ifdef ITIMER_REAL
+ struct itimerval itimer;
+
+#ifdef XDEBUG
+ fprintf (stderr, "XTflash\n");
+#endif
+
+ stop_polling ();
+ signal (SIGALRM, flashback);
+ getitimer (ITIMER_REAL, &itimer);
+ itimer.it_value.tv_usec += 250000;
+ itimer.it_interval.tv_sec = 0;
+ itimer.it_interval.tv_usec = 0;
+ flashedback = 0;
+ setitimer (ITIMER_REAL, &itimer, 0);
+ {
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+ XPixFill (XXwindow, 0, 0, screen_width*fontinfo->width+2*XXInternalBorder,
+ screen_height * fontinfo->height+2*XXInternalBorder, WhitePixel,
+ ClipModeClipped, GXinvert, AllPlanes);
+ XFlush ();
+ UNBLOCK_INPUT ();
+ }
+ while (!flashedback) pause ();
+#endif /* have ITIMER_REAL */
+}
+
+static
+flashback ()
+{
+#ifdef ITIMER_REAL
+#ifdef SIGIO
+ int mask = sigblock (sigmask (SIGIO) | sigmask (SIGALRM));
+#else
+ int mask = sigblock (sigmask (SIGALRM));
+#endif
+ XPixFill (XXwindow, 0, 0, screen_width * fontinfo->width+2*XXInternalBorder,
+ screen_height * fontinfo->height+2*XXInternalBorder, WhitePixel,
+ ClipModeClipped, GXinvert, AllPlanes);
+ XFlush ();
+ flashedback = 1;
+ sigsetmask (mask);
+ start_polling ();
+#endif /* have ITIMER_REAL */
+}
+
+/* A kludge to get a bell */
+
+static
+XTfeep ()
+{
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+#ifdef XDEBUG
+ fprintf (stderr, "XTfeep\n");
+#endif
+ XFeep (0);
+ UNBLOCK_INPUT ();
+}
+
+/* Artificially creating a cursor is hard, the actual position on the
+ * screen (either where it is or last was) is tracked with VisibleX,Y.
+ * Gnu Emacs code tends to assume a cursor exists in hardward at cursor_hpos,Y
+ * and that output text will appear there. During updates, the cursor is
+ * supposed to be blinked out and will only reappear after the update
+ * finishes.
+ */
+
+CursorToggle ()
+{
+ if (!WindowMapped)
+ {
+ CursorExists = 0;
+ return 0;
+ }
+ if ((VisibleX < 0) || (VisibleX >= screen_width) ||
+ (VisibleY < 0) || (VisibleY >= screen_height))
+ { /* Current Cursor position trash */
+ /* Not much can be done */
+ XFlush ();
+ CursorExists = 0;
+ return 0;
+ /* Currently the return values are not */
+ /* used, but I could anticipate using */
+ /* them in the future. */
+ }
+
+ if (current_screen->enable[VisibleY] &&
+ (VisibleX < current_screen->used[VisibleY]))
+ {
+ if (CursorExists)
+ {
+ XText (XXwindow,
+ VisibleX * fontinfo->width+XXInternalBorder,
+ VisibleY * fontinfo->height+XXInternalBorder,
+ &current_screen->contents[VisibleY][VisibleX], 1,
+ fontinfo->id,
+ fore, back);
+ }
+ else
+ {
+ XText (XXwindow,
+ VisibleX * fontinfo->width+XXInternalBorder,
+ VisibleY * fontinfo->height+XXInternalBorder,
+ &current_screen->contents[VisibleY][VisibleX], 1,
+ fontinfo->id,
+ back, curs);
+ }
+ }
+ else if (CursorExists)
+ {
+ XPixSet (XXwindow,
+ VisibleX * fontinfo->width+XXInternalBorder,
+ VisibleY * fontinfo->height+XXInternalBorder,
+ fontinfo->width, fontinfo->height, back);
+ }
+ else
+ {
+ XPixSet (XXwindow,
+ VisibleX * fontinfo->width+XXInternalBorder,
+ VisibleY * fontinfo->height+XXInternalBorder,
+ fontinfo->width, fontinfo->height, curs);
+ }
+ CursorExists = !CursorExists;
+ /* Cursor has either been blinked in */
+ /* or out */
+ if (!InUpdate)
+ {
+ XFlush ();
+ }
+ return 1;
+}
+
+/* This routine is used by routines which are called to paint regions */
+/* designated by ExposeRegion events. If the cursor may be in the exposed */
+/* region, this routine makes sure it is gone so that dumprectangle can */
+/* toggle it back into existance if dumprectangle is invoked when not in */
+/* the midst of a screen update. */
+static
+ClearCursor ()
+{
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+ if (!WindowMapped)
+ {
+ CursorExists = 0;
+ UNBLOCK_INPUT ();
+ return;
+ }
+ if ((VisibleX < 0) || (VisibleX >= screen_width)
+ || (VisibleY < 0) || (VisibleY >= screen_height))
+ { /* Current Cursor position trash */
+ /* Not much can be done */
+ CursorExists = 0;
+ UNBLOCK_INPUT ();
+ return;
+ }
+ XPixSet (XXwindow,
+ VisibleX * fontinfo->width+XXInternalBorder,
+ VisibleY * fontinfo->height+XXInternalBorder,
+ fontinfo->width, fontinfo->height,
+ back);
+ CursorExists = 0;
+ UNBLOCK_INPUT ();
+}
+
+static
+XTupdate_begin ()
+{
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+#ifdef XDEBUG
+ fprintf (stderr, "XTupdate_begin\n");
+#endif
+
+ InUpdate = 1;
+ if (CursorExists)
+ {
+ CursorToggle ();
+ }
+ SavedX = cursor_hpos; /* The initial"hardware" cursor position is */
+ /* saved because that is where gnu emacs */
+ /* expects the cursor to be at the end of*/
+ /* the update */
+ SavedY = cursor_vpos;
+ dumpqueue ();
+ UNBLOCK_INPUT ();
+}
+
+
+static
+XTupdate_end ()
+{
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+#ifdef XDEBUG
+ fprintf (stderr, "XTupdate_end\n");
+#endif
+ if (CursorExists)
+ CursorToggle ();
+ InUpdate = 0;
+ dumpqueue ();
+ XTmove_cursor (SavedY, SavedX); /* XTmove_cursor invokes cursor toggle */
+ UNBLOCK_INPUT ();
+}
+
+/* Used for expose region and expose copy events. Have to get the text
+ * back into the newly blank areas.
+ */
+
+dumprectangle (top, left, rows, cols)
+ register int top, left, rows, cols;
+{
+ register int index;
+ int localX, localY, localHL;
+ rows += top;
+ cols += left;
+ top /= fontinfo->height;
+ /* Get row and col containing up and */
+ /* left borders of exposed region -- */
+ /* round down here*/
+ left /= fontinfo->width;
+ rows += (fontinfo->height - 1);
+ cols += (fontinfo->width - 1);
+ rows /= fontinfo->height;
+ /* Get row and col containing bottom and */
+ /* right borders -- round up here */
+ rows -= top;
+ cols /= fontinfo->width;
+ cols -= left;
+ if (rows < 0) return;
+ if (cols < 0) return;
+ if (top > (screen_height - 1)) return;
+ if (left > (screen_width - 1)) return;
+ if ((VisibleX >= left) && (VisibleX < (left + cols)) &&
+ (VisibleY >= top) && (VisibleY < (top + rows)))
+ {
+ ClearCursor ();
+ }
+
+ /* should perhaps be DesiredScreen */
+ /* but PhysScreen is guaranteed to contain*/
+ /* date which was good for every line on */
+ /* screen. For desired screen only for */
+ /* lines which are changing. Emacs does */
+ /* not consider a line within a newly */
+ /* exposed region necessarily to have */
+ /* been changed. Emacs knows nothing */
+ /* about ExposeRegion events.*/
+ for (localY = top, index = 0;
+ (index < rows) && (localY < screen_height);
+ ++index, ++localY)
+ {
+ if ((localY < 0) || (localY >= screen_height)) continue;
+ if (!current_screen->enable[localY]) continue;
+ if ((left + 1) > current_screen->used[localY]) continue;
+ localX = left;
+ localHL = current_screen->highlight[localY];
+ dumpchars (current_screen,
+ min (cols,
+ current_screen->used[localY]
+ - localX),
+ localX, localY, localHL);
+ }
+ if (!InUpdate && !CursorExists) CursorToggle ();
+ /* Routine usually called */
+ /* when not in update */
+}
+
+/* What sections of the window will be modified from the UpdateDisplay
+ * routine is totally under software control. Any line with Y coordinate
+ * greater than flexlines will not change during an update. This is really
+ * used only during dellines and inslines routines (scraplines and stufflines)
+ */
+static
+XTset_terminal_window (n)
+ register int n;
+{
+#ifdef XDEBUG
+ fprintf (stderr, "XTset_terminal_window\n");
+#endif
+ if ((n <= 0) || (n > screen_height))
+ flexlines = screen_height;
+ else
+ flexlines = n;
+}
+
+XTins_del_lines (vpos, n)
+ int vpos, n;
+{
+#ifdef XDEBUG
+ fprintf (stderr, "XTins_del_lines\n");
+#endif
+ XTmove_cursor (vpos, 0);
+ if (n >= 0) stufflines (n);
+ else scraplines (-n);
+}
+
+static
+XTinsert_chars (start, len)
+ register char *start;
+ register int len;
+{
+#ifdef XDEBUG
+ fprintf (stderr, "XTinsert_chars\n");
+#endif
+ writechars (start, start + len - 1);
+}
+
+static
+XTdelete_chars (n)
+ register int n;
+{
+ char *msg = "***Delete Chars Called Outside of Update!!!***";
+#ifdef XDEBUG
+ fprintf (stderr, "XTdelete_chars\n");
+#endif
+ writechars (msg, msg + strlen (msg) - 1);
+}
+
+static
+stufflines (n)
+ register int n;
+{
+ register int topregion, bottomregion;
+ register int length, newtop;
+ BLOCK_INPUT_DECLARE ()
+
+ if (cursor_vpos >= flexlines)
+ return;
+
+ if (!WindowMapped)
+ {
+ bitblt = 0;
+ return;
+ }
+ BLOCK_INPUT ();
+ if (CursorExists) CursorToggle ();
+ dumpqueue ();
+ UNBLOCK_INPUT ();
+ topregion = cursor_vpos;
+ bottomregion = flexlines - (n + 1);
+ newtop = cursor_vpos + n;
+ length = (bottomregion - topregion) + 1;
+ if ((length > 0) && (newtop <= flexlines))
+ {
+ BLOCK_INPUT ();
+ /* Should already have cleared */
+ /* queue of events associated */
+ /* with old bitblts */
+ XMoveArea (XXwindow, XXInternalBorder,
+ topregion * fontinfo->height+XXInternalBorder,
+ XXInternalBorder, newtop * fontinfo->height+XXInternalBorder,
+ screen_width * fontinfo->width,
+ length * fontinfo->height);
+ if (WindowMapped)
+ bitblt = 1;
+ XFlush ();
+ UNBLOCK_INPUT ();
+ SIGNAL_INPUT_WHILE (bitblt);
+ XFlush ();
+ }
+ newtop = min (newtop, (flexlines - 1));
+ length = newtop - topregion;
+ if (length > 0)
+ {
+ XPixSet (XXwindow,
+ XXInternalBorder,
+ topregion * fontinfo->height+XXInternalBorder,
+ screen_width * fontinfo->width,
+ n * fontinfo->height,
+ back);
+ }
+ /* if (!InUpdate) CursorToggle (); */
+}
+
+static
+scraplines (n)
+ register int n;
+{
+ BLOCK_INPUT_DECLARE ()
+ if (!WindowMapped)
+ {
+ bitblt = 0;
+ return;
+ }
+
+ if (cursor_vpos >= flexlines)
+ return;
+ BLOCK_INPUT ();
+ if (CursorExists) CursorToggle ();
+ dumpqueue ();
+ if ((cursor_vpos + n) >= flexlines)
+ {
+ if (flexlines >= (cursor_vpos + 1))
+ {
+ XPixSet (XXwindow,
+ XXInternalBorder, cursor_vpos * fontinfo->height+XXInternalBorder,
+ screen_width * fontinfo->width,
+ (flexlines - cursor_vpos) * fontinfo->height,
+ back);
+ }
+ UNBLOCK_INPUT ();
+ }
+ else
+ {
+ XMoveArea (XXwindow,
+ XXInternalBorder,
+ (cursor_vpos + n) * fontinfo->height+XXInternalBorder,
+ XXInternalBorder, cursor_vpos * fontinfo->height+XXInternalBorder,
+ screen_width * fontinfo->width,
+ (flexlines - (cursor_vpos + n)) * fontinfo->height);
+ if (WindowMapped)
+ bitblt = 1;
+ XFlush ();
+ UNBLOCK_INPUT ();
+ SIGNAL_INPUT_WHILE (bitblt);
+ BLOCK_INPUT ();
+ XFlush ();
+ XPixSet (XXwindow, XXInternalBorder,
+ (flexlines - n) * fontinfo->height+XXInternalBorder,
+ screen_width * fontinfo->width,
+ n * fontinfo->height, back);
+ UNBLOCK_INPUT ();
+ }
+ /* if (!InUpdate) CursorToggle (); */
+}
+
+/* Substitutes for standard read routine. Under X not interested in individual
+ * bytes but rather individual packets.
+ */
+
+XTread_socket (sd, bufp, numchars)
+ register int sd;
+ register char *bufp;
+ register int numchars;
+{
+
+ int count;
+ char *where_mapping;
+ int nbytes;
+ int stuffpending;
+ int temp_width, temp_height;
+ BLOCK_INPUT_DECLARE ()
+ /* XKeyPressedEvent event; */
+ /* typedef struct reply {XEvent event; struct reply *next} Reply;
+ Reply *replies = NULL;*/
+
+ BLOCK_INPUT ();
+ count = 0;
+ if (numchars <= 0)
+ { /* To keep from overflowing read buffer */
+ numchars = 1;
+ --bufp;
+ }
+#ifdef SIGIO
+ while (bitblt || XPending () != 0)
+#else
+#ifndef HAVE_SELECT
+ if (! (fcntl (fileno (stdin), F_GETFL, 0) & O_NDELAY))
+ {
+ extern int read_alarm_should_throw;
+ if (CursorExists)
+ xfixscreen ();
+ read_alarm_should_throw = 1;
+ XPeekEvent (&XXEvent);
+ read_alarm_should_throw = 0;
+ }
+#endif
+ while (XPending () != 0)
+#endif
+ {
+ /* while there are more events*/
+ XNextEvent (&XXEvent);
+ switch (XXEvent.type)
+ {
+/* case X_Reply:
+ {
+ extern char *malloc ();
+ Reply *reply = (Reply *) malloc (sizeof (Reply));
+ reply->next = replies;
+ reply->event = XXEvent;
+ replies = reply;
+ break;
+ }*/
+ default:
+ break;
+ case ExposeWindow:
+ if (((XExposeEvent *)&XXEvent)->window == XXIconWindow)
+ {
+ PendingIconExposure = 1;
+ }
+ else
+ PendingExposure = 1;/* No reason to repeat */
+ /* this if several */
+ /* ExposeWindow events */
+ /* come in quick succes-*/
+ /* ion */
+ break;
+ case ExposeRegion:
+ if (PendingExposure)
+ { /* Don't bother with */
+ /* region events when */
+ /* full window event */
+ /* is pending */
+ break;
+ }
+ loadxrepbuffer (&XXEvent, &XXqueue);
+ if (XXqueue.rindex == XXqueue.windex)
+ {
+ PendingExposure = 1;
+ }
+ if ((XXqueue.rindex > XXqueue.mindex) ||
+ (XXqueue.windex > XXqueue.mindex) ||
+ (XXqueue.rindex < 0) ||
+ (XXqueue.windex < 0))
+ {
+ PendingExposure = 1;
+ }
+ break;
+ case ExposeCopy: /* For ExposeCopy sync */
+ /* will block all outgoing */
+ /* requests until this is */
+ /* decremented */
+ if (WindowMapped) bitblt = 0;
+ break;
+ case KeyPressed:
+ /* bcopy (XXEvent, event, sizeof (XKeyPressedEvent)); */
+ where_mapping = XLookupMapping (&XXEvent, &nbytes);
+ /* Nasty fix for arrow keys */
+ if (!nbytes && IsCursorKey (XXEvent.detail & 0xff))
+ {
+ switch (XXEvent.detail & 0xff)
+ {
+ case KC_CURSOR_LEFT:
+ where_mapping = "\002";
+ break;
+ case KC_CURSOR_RIGHT:
+ where_mapping = "\006";
+ break;
+ case KC_CURSOR_UP:
+ where_mapping = "\020";
+ break;
+ case KC_CURSOR_DOWN:
+ where_mapping = "\016";
+ break;
+ }
+ nbytes = 1;
+ }
+ if (numchars - nbytes > 0)
+ {
+ bcopy (where_mapping, bufp, nbytes);
+ bufp += nbytes;
+ count += nbytes;
+ numchars -= nbytes;
+ }
+/* else
+ {
+ bcopy (where_mapping, bufp, numchars);
+ bufp += numchars;
+ count += numchars;
+ numchars = 0;
+ *(bufp-1) = *(where_mapping + nbytes - 1);
+ }*/
+ break;
+ case ButtonPressed:
+ case ButtonReleased:
+ switch (spacecheck (Xxrepbuffer.mindex,
+ Xxrepbuffer.rindex,
+ Xxrepbuffer.windex, 0))
+ {
+ case 0:
+ loadxrepbuffer (&XXEvent,
+ &Xxrepbuffer);
+ if (informflag && (numchars > 1))
+ {
+ *bufp++ = (char) 'X' & 037; /* C-x */
+ ++count;
+ --numchars;
+ *bufp++ = (char) 0; /* C-@ */
+ ++count;
+ --numchars;
+ }
+ break;
+ case -1:
+ break;
+ case -2:
+ default:
+ fixxrepbuffer ();
+ break;
+ }
+ break;
+ }
+ }
+/* while (replies) {
+ Reply *reply = replies;
+ XPutBackEvent (&reply->event);
+ replies = reply->next;
+ free (reply);
+ }*/
+ if (count < 0)
+ count = 0;
+#ifdef HAVE_SELECT
+ if (CursorExists
+#ifdef O_NDELAY
+#ifdef F_GETFL
+ && (! (fcntl (fileno (stdin), F_GETFL, 0) & O_NDELAY))
+#endif
+#endif
+ )
+ xfixscreen ();
+#endif
+ UNBLOCK_INPUT ();
+ return count;
+}
+
+/* refresh bitmap kitchen sink icon */
+refreshicon ()
+{
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+ if (XXIconWindow)
+ XBitmapBitsPut (XXIconWindow, 0, 0, sink_width, sink_height,
+ sink_bits, BlackPixel, WhitePixel,
+ XXIconMask, GXcopy, AllPlanes);
+ XFlush ();
+ UNBLOCK_INPUT ();
+}
+
+XBitmapIcon ()
+{
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+ if (!IconWindow)
+ {
+ XSetIconWindow (XXwindow,XXIconWindow);
+ XSelectInput (XXIconWindow, ExposeWindow);
+ IconWindow = !IconWindow;
+ }
+ UNBLOCK_INPUT ();
+}
+
+XTextIcon ()
+{
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+ if (IconWindow)
+ {
+ XClearIconWindow (XXwindow);
+ XSelectInput (XXIconWindow, NoEvent);
+ IconWindow = !IconWindow;
+ }
+ UNBLOCK_INPUT ();
+}
+
+/* Interpreting incoming keycodes. Should have table modifiable as needed
+ * from elisp.
+ */
+
+/* Exit gracefully from gnuemacs, doing an autosave and giving a status.
+ */
+
+XExitGracefully (disp, event)
+ Display *disp;
+ XErrorEvent *event;
+{
+ XCleanUp ();
+ exit (70);
+}
+
+x_io_error (disp)
+ Display *disp;
+{
+ XCleanUp ();
+ exit (71);
+}
+
+#if 0
+/* This kludge overcomes the failure to handle EAGAIN and EINTR
+ in a certain version of X for 386 running system V. */
+
+x_io_error (disp, a, b, c, nwrite)
+ Display *disp;
+{
+ extern _XSend ();
+ unsigned int pc = ((unsigned int *)&disp)[-1];
+ if (pc - (unsigned int)&_XSend - 100 < 100
+ && (errno == EAGAIN || errno == EINTR))
+ {
+ /* We were called by `writedata' erroneously.
+ Modify a local variable which `writedata'
+ will subtract from the number of bytes to be written. */
+ nwrite = 0;
+ return;
+ }
+ abort ();
+}
+#endif
+
+xfixscreen ()
+{
+ register int temp_width, temp_height;
+ BLOCK_INPUT_DECLARE ()
+ /* register int temp_x, temp_y; */
+
+ BLOCK_INPUT ();
+ dumpqueue ();
+ /* Check that the connection is in fact open. This works by doing a nop */
+ /* (well, almost) write operation. If there is an XIOerror or a */
+ /* SIGPIPE, exit gracefully. This fixes the loop-on-logout bug.*/
+ /* XIOErrorHandler (XExitGracefully); */
+ XPixFill (XXwindow, 0, 0, 1, 1, back, ClipModeClipped, GXnoop, AllPlanes);
+ XFlush ();
+ /* XIOErrorHandler (0); */
+ if (PendingIconExposure)
+ {
+ refreshicon ();
+ PendingIconExposure = 0;
+ }
+ if (PendingExposure)
+ {
+ PendingExposure = 0;
+ ClearCursor ();
+ XXqueue.rindex = 0;
+ XXqueue.windex = 0;
+ XQueryWindow (XXwindow, &windowinfo); /* Dangerous to do */
+ /* writes here but */
+ /* otherwise would */
+ /* have to alter */
+ /* gnu emacs display */
+ /* routines to query */
+ /* when screen garbaged */
+ temp_width = (windowinfo.width - 2 * XXInternalBorder) / fontinfo->width;
+ temp_height = (windowinfo.height- 2*XXInternalBorder) / fontinfo->height;
+ if (temp_width != screen_width || temp_height != screen_height)
+ change_screen_size (max (5, temp_height), max (10, temp_width),
+ 0, 0, 0);
+ XXxoffset= windowinfo.x;
+ XXyoffset = windowinfo.y;
+ /*if (temp_x != XXxoffset || temp_y != XXyoffset)
+ XSetOffset (temp_x, temp_y);*/
+ dumprectangle (0, 0,
+ screen_height * fontinfo->height + 2 * XXInternalBorder,
+ screen_width * fontinfo->width + 2 * XXInternalBorder);
+ }
+ if (!InUpdate)
+ if (!CursorExists)
+ CursorToggle ();
+ XFlush ();
+ UNBLOCK_INPUT ();
+ SIGNAL_INPUT ();
+}
+
+x_term_init ()
+{
+ char *vardisplay;
+ char *temp_font;
+ register char *option;
+ extern XTinterrupt_signal ();
+ int reversevideo;
+ Color cdef;
+ char *progname;
+
+ Fset (intern ("window-system-version"), make_number (10));
+
+ vardisplay = (alternate_display ? alternate_display
+ : (char *) egetenv ("DISPLAY"));
+ if (!vardisplay || *vardisplay == '\0')
+ {
+ fprintf (stderr, "DISPLAY environment variable must be set\n");
+ exit (-200);
+ }
+
+ XXdisplay = XOpenDisplay (vardisplay);
+ if (XXdisplay == (Display *) 0)
+ {
+ fprintf (stderr, "X server not responding. Check your DISPLAY environment variable.\n");
+ exit (-200);
+ }
+ x_init_1 (1);
+ Xxrepbuffer.mindex = XREPBUFSIZE - 1;
+ Xxrepbuffer.windex = 0;
+ Xxrepbuffer.rindex = 0;
+ XXqueue.mindex = XREPBUFSIZE - 1;
+ XXqueue.windex = 0;
+ XXqueue.rindex = 0;
+ WindowMapped = 0;
+ baud_rate = 9600;
+ min_padding_speed = 10000;
+ must_write_spaces = 1;
+ informflag = 1;
+ meta_key = 1;
+ visible_bell = 1;
+#ifdef SIGIO
+ interrupt_input = 1;
+#endif
+ inverse_video = 1;
+ bitblt = 0;
+ PendingExposure = 0;
+
+ fix_screen_hook = xfixscreen;
+ clear_screen_hook = XTclear_screen;
+ clear_end_of_line_hook = XTclear_end_of_line;
+ ins_del_lines_hook = XTins_del_lines;
+ change_line_highlight_hook = XTchange_line_highlight;
+ insert_chars_hook = XTinsert_chars;
+ output_chars_hook = XToutput_chars;
+ delete_chars_hook = XTdelete_chars;
+ ring_bell_hook = XTfeep;
+ reset_terminal_modes_hook = XTreset_terminal_modes;
+ set_terminal_modes_hook = XTset_terminal_modes;
+ update_begin_hook = XTupdate_begin;
+ update_end_hook = XTupdate_end;
+ set_terminal_window_hook = XTset_terminal_window;
+ read_socket_hook = XTread_socket;
+ move_cursor_hook = XTmove_cursor;
+ /* raw_move_cursor_hook = XTraw_move_cursor; */
+ reassert_line_highlight_hook = XTreassert_line_highlight;
+ scroll_region_ok = 1; /* we'll scroll partial screens */
+ char_ins_del_ok = 0; /* just as fast to write the line */
+ line_ins_del_ok = 1; /* we'll just blt 'em */
+ fast_clear_end_of_line = 1; /* X does this well */
+ memory_below_screen = 0; /* we don't remember what scrolls
+ off the bottom */
+ dont_calculate_costs = 1;
+
+ /* New options section */
+ IconWindow = 0;
+ XXborder = 1;
+ XXInternalBorder = 1;
+ screen_width = 80;
+ screen_height = 66;
+ reversevideo = 0;
+ XXxoffset = 0;
+ XXyoffset = 0;
+ XXdebug = 0;
+
+ XErrorHandler (XExitGracefully);
+ XIOErrorHandler (x_io_error);
+
+ progname = "emacs";
+ if (option = XGetDefault (progname,"ReverseVideo"))
+ if (strcmp (option,"on") == 0) reversevideo = 1;
+ if (option = XGetDefault (progname, "BitmapIcon"))
+ if (strcmp (option, "on") == 0) IconWindow = 1;
+
+ if (option = XGetDefault (progname,"BorderWidth"))
+ XXborder = atoi (option);
+ if (option = XGetDefault (progname,"InternalBorder"))
+ XXInternalBorder = atoi (option);
+
+ brdr_color = XGetDefault (progname,"Border");
+ if (!brdr_color) brdr_color = XGetDefault (progname, "BorderColor");
+ back_color = XGetDefault (progname,"Background");
+ fore_color = XGetDefault (progname,"Foreground");
+ mous_color = XGetDefault (progname,"Mouse");
+ curs_color = XGetDefault (progname,"Cursor");
+
+ temp_font = XGetDefault (progname,"BodyFont");
+ if (temp_font == 0) temp_font = X_DEFAULT_FONT;
+ XXcurrentfont = (char *) xmalloc (strlen (temp_font) + 1);
+ strcpy (XXcurrentfont, temp_font);
+
+ /* If user has specified a special keymap for use with Emacs, use it. */
+ {
+ char *temp = XGetDefault (progname, "KeyMap");
+ if (temp) XUseKeymap (temp);
+ }
+
+ if (DisplayCells () > 2)
+ {
+
+ if (fore_color && XParseColor (fore_color, &cdef) &&
+ XGetHardwareColor (&cdef))
+ fore = cdef.pixel;
+ else
+ {
+ fore_color = "black";
+ fore = BlackPixel;
+ }
+
+ if (back_color && XParseColor (back_color, &cdef) &&
+ XGetHardwareColor (&cdef))
+ back = cdef.pixel;
+ else
+ {
+ back_color = "white";
+ back = WhitePixel;
+ }
+
+ if (curs_color && XParseColor (curs_color, &cdef) &&
+ XGetHardwareColor (&cdef))
+ curs = cdef.pixel;
+ else
+ {
+ curs_color = "black";
+ curs = BlackPixel;
+ }
+
+ if (mous_color && XParseColor (mous_color, &cdef) &&
+ XGetHardwareColor (&cdef))
+ mous = cdef.pixel;
+ else
+ {
+ mous_color = "black";
+ mous = BlackPixel;
+ }
+
+ if (brdr_color && XParseColor (brdr_color, &cdef) &&
+ XGetHardwareColor (&cdef))
+ brdr = cdef.pixel;
+ else
+ {
+ brdr_color = "black";
+ brdr = BlackPixel;
+ }
+ }
+ else
+ {
+ fore_color = curs_color = mous_color = brdr_color = "black";
+ fore = curs = mous = brdr = BlackPixel;
+ back_color = "white";
+ back = WhitePixel;
+ }
+
+ /*
+ if (fore_color && DisplayCells () > 2 &&
+ XParseColor (fore_color, &cdef) && XGetHardwareColor (&cdef))
+ fore = cdef.pixel;
+ else if (fore_color && strcmp (fore_color, "black") == 0)
+ fore = BlackPixel;
+ else if (fore_color && strcmp (fore_color, "white") == 0)
+ fore = WhitePixel;
+ else
+ {
+ fore_color = "black";
+ fore = BlackPixel;
+ }
+
+ if (back_color && DisplayCells () > 2 &&
+ XParseColor (back_color, &cdef) && XGetHardwareColor (&cdef))
+ back = cdef.pixel;
+ else if (back_color && strcmp (back_color, "white") == 0)
+ back = WhitePixel;
+ else if (back_color && strcmp (back_color, "black") == 0)
+ back = BlackPixel;
+ else
+ {
+ back_color = "white";
+ back = WhitePixel;
+ }
+
+ if (brdr_color && DisplayCells () > 2 &&
+ XParseColor (brdr_color, &cdef) && XGetHardwareColor (&cdef))
+ brdr = cdef.pixel;
+ else if (brdr_color && (!strcmp (brdr_color, "gray") ||
+ !strcmp (brdr_color, "grey") ||
+ !strcmp (brdr_color, "Gray") ||
+ !strcmp (brdr_color, "Grey")))
+ brdr = BlackPixel;
+ else if (brdr_color && strcmp (brdr_color, "white") == 0)
+ brdr = WhitePixel;
+ else
+ {
+ brdr_color = "black";
+ brdr = BlackPixel;
+ }
+
+ if (curs_color && DisplayCells () > 2 &&
+ XParseColor (curs_color, &cdef) && XGetHardwareColor (&cdef))
+ curs = cdef.pixel;
+ else if (curs_color && strcmp (curs_color, "black") == 0)
+ curs = BlackPixel;
+ else if (curs_color && strcmp (curs_color, "white") == 0)
+ curs = WhitePixel;
+ else
+ {
+ curs_color = "black";
+ curs = BlackPixel;
+ }
+
+ if (mous_color && DisplayCells () > 2 &&
+ XParseColor (mous_color, &cdef) && XGetHardwareColor (&cdef))
+ mous = cdef.pixel;
+ else if (mous_color && strcmp (mous_color, "black") == 0)
+ mous = BlackPixel;
+ else if (mous_color && strcmp (mous_color, "white") == 0)
+ mous = WhitePixel;
+ else
+ {
+ mous_color = "black";
+ mous = BlackPixel;
+ }
+ */
+
+ XXpid = getpid ();
+ if (XXcurrentfont == (char *) 0)
+ {
+ fprintf (stderr, "Memory allocation failure.\n");
+ exit (-150);
+ }
+ default_window = "=80x24+0+0";
+/* RMS: XTread_socket does not have an interface suitable
+ for being a signal handler. In any case, the SIGIO handler is
+ set up in init_keyboard and X uses the same one as usual. */
+/* signal (SIGIO, XTread_socket); */
+ signal (SIGPIPE, XExitGracefully);
+ XQueryWindow (RootWindow, &rootwindowinfo);
+ strncpy (iconidentity, ICONTAG, MAXICID);
+ fontinfo = XOpenFont (XXcurrentfont);
+ if (fontinfo == (FontInfo *) 0)
+ {
+ fprintf (stderr, "No font\n");
+ exit (-98);
+ }
+ pixelwidth = screen_width * fontinfo->width + 2 * XXInternalBorder;
+ pixelheight = screen_height * fontinfo->height + 2 * XXInternalBorder;
+ XXwindow = XCreateWindow (RootWindow,
+ XXxoffset /* Absolute horizontal offset */,
+ XXyoffset /* Absolute Vertical offset */,
+ pixelwidth, pixelheight,
+ XXborder, BlackPixmap, WhitePixmap);
+ if (!XXwindow)
+ {
+ fprintf (stderr, "Unable to create window.\n");
+ exit (-97);
+ }
+
+ XXIconWindow = XCreateWindow (RootWindow, 0, 0, sink_width, sink_height,
+ 2, WhitePixmap, (Pixmap) NULL);
+
+ if (!XXIconWindow)
+ {
+ fprintf (stderr, "Unable to create icon window.\n");
+ fflush (stderr);
+ exit (-97);
+ }
+ XSelectInput (XXIconWindow, NoEvent);
+ XXIconMask = XStoreBitmap (sink_mask_width, sink_mask_height, sink_mask_bits);
+
+ XSelectInput (XXwindow, NoEvent);
+ XSetResizeHint (XXwindow, 2 * XXInternalBorder, 2 * XXInternalBorder,
+ /* fontinfo->width * 1, fontinfo->height * 1, */
+ fontinfo->width, fontinfo->height);
+
+#if defined (BSD) || defined (HPUX) || defined (IBMRTAIX)
+ if (gethostname (&iconidentity[sizeof (ICONTAG) - 1],
+ (MAXICID - 1) - sizeof (ICONTAG)))
+#endif
+ {
+ iconidentity[sizeof (ICONTAG) - 2] = '\0';
+ }
+ XStoreName (XXwindow, &iconidentity[0]);
+
+ EmacsCursor = XCreateCursor (16, 16, MouseCursor, MouseMask,
+ 0, 0, mous, back, GXcopy);
+ XDefineCursor (XXwindow, EmacsCursor);
+ flexlines = screen_height;
+#if 0
+/* Do not call XPopUpWindow here! This is too early.
+ It is supposed ot be called via the term-setup-hook
+ and not until after lisp/term/x-win.el has had a chance
+ to process the user's switches.
+ I am not sure that there are any circumstances under which
+ this should be done here -- RMS. */
+ XPopUpWindow (); /* This looks at Vxterm */
+#endif /* 0 */
+ if (reversevideo) XFlipColor ();
+}
+
+x_init_1 (unrequest)
+{
+#ifdef F_SETOWN
+ extern int old_fcntl_owner;
+#endif
+#ifndef USG
+ extern void init_sigio (), request_sigio (), unrequest_sigio ();
+#endif
+
+ dup2 (dpyno (), 0);
+ close (dpyno ());
+ dpyno () = 0; /* Looks a little strange?
+ check the def of the macro;
+ it is a genuine lvalue */
+#ifndef USG
+ init_sigio ();
+ request_sigio ();
+#endif /* USG */
+#ifdef F_SETOWN
+ old_fcntl_owner = fcntl (0, F_GETOWN, 0);
+#ifdef F_SETOWN_SOCK_NEG
+ fcntl (0, F_SETOWN, -getpid ()); /* stdin is a socket here */
+#else
+ fcntl (0, F_SETOWN, getpid ());
+#endif /* F_SETOWN_SOCK_NEG */
+#endif /* F_SETOWN */
+#ifndef USG
+ if (unrequest) unrequest_sigio ();
+#endif
+}
+
+/* Process all queued ExposeRegion events. */
+static
+dumpqueue ()
+{
+ register int i;
+ XExposeRegionEvent r;
+ if ((XXqueue.rindex > XXqueue.mindex) ||
+ (XXqueue.windex > XXqueue.mindex) ||
+ (XXqueue.rindex < 0) ||
+ (XXqueue.windex < 0))
+ {
+ PendingExposure = 1;
+ }
+ else
+ while (XXqueue.rindex != XXqueue.windex)
+ {
+ if (CursorExists)
+ CursorToggle ();
+ unloadxrepbuffer (&r, &XXqueue);
+ dumprectangle (r.y - XXInternalBorder, r.x - XXInternalBorder,
+ r.height, r.width);
+ }
+}
+
+XSetFlash ()
+{
+ ring_bell_hook = XTflash;
+}
+
+XSetFeep ()
+{
+ ring_bell_hook = XTfeep;
+}
+
+XNewFont (newname)
+ register char *newname;
+{
+ FontInfo *temp;
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+ XFlush ();
+ if (XXdebug)
+ fprintf (stderr, "Request id is %d\n", XXdisplay->request);
+ temp = XOpenFont (newname);
+ if (temp == (FontInfo *) 0)
+ {
+ UNBLOCK_INPUT_RESIGNAL ();
+ return -1;
+ }
+ XCloseFont (fontinfo);
+ fontinfo = temp;
+ XSetResizeHint (XXwindow, 2*XXInternalBorder, 2*XXInternalBorder,
+ /* fontinfo->width * 1, fontinfo->height * 1, */
+ fontinfo->width, fontinfo->height);
+ XSetWindowSize (screen_height, screen_width);
+ UNBLOCK_INPUT_RESIGNAL ();
+ return 0;
+}
+
+XFlipColor ()
+{
+ Pixmap temp;
+ int tempcolor;
+ char *tempname;
+ Cursor temp_curs;
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+ CursorToggle ();
+ temp = XMakeTile (fore);
+ XChangeBackground (XXwindow, temp);
+ XFreePixmap (temp);
+ temp = XMakeTile (back);
+ if (XXborder)
+ XChangeBorder (XXwindow, temp);
+ XFreePixmap (temp);
+ brdr = back;
+ brdr_color = back_color;
+ tempcolor = fore;
+ fore = back;
+ back = tempcolor;
+ tempname = fore_color ;
+ fore_color = back_color;
+ back_color = tempname;
+/* XPixFill (XXwindow, 0, 0, screen_width * fontinfo->width,
+ screen_height * fontinfo->height, back, ClipModeClipped,
+ GXcopy, AllPlanes);
+ dumprectangle (0, 0, screen_height * fontinfo->height + 2 * XXInternalBorder,
+ screen_width * fontinfo -> width + 2 * XXInternalBorder);*/
+ XRedrawDisplay ();
+ if (curs == WhitePixel)
+ {
+ curs = BlackPixel;
+ curs_color = "black";
+ }
+ else if (curs == BlackPixel)
+ {
+ curs = WhitePixel;
+ curs_color = "white";
+ }
+ if (mous == WhitePixel)
+ {
+ mous = BlackPixel;
+ mous_color = "black";
+ }
+ else if (mous == BlackPixel)
+ {
+ mous = WhitePixel;
+ mous_color = "white";
+ }
+ temp_curs = XCreateCursor (16, 16, MouseCursor, MouseMask, 0, 0,
+ mous, back, GXcopy);
+ XUndefineCursor (XXwindow);
+ XDefineCursor (XXwindow, temp_curs);
+ XFreeCursor (EmacsCursor);
+ bcopy (&temp_curs, &EmacsCursor, sizeof (Cursor));
+ CursorToggle ();
+ XFlush ();
+ UNBLOCK_INPUT ();
+}
+
+XSetOffset (xoff, yoff)
+ register int xoff, yoff;
+{
+ BLOCK_INPUT_DECLARE ()
+
+ BLOCK_INPUT ();
+ if (xoff < 0)
+ {
+ XXxoffset = rootwindowinfo.width + (++xoff) - pixelwidth - 4;
+ }
+ else
+ {
+ XXxoffset = xoff;
+ }
+ if (yoff < 0)
+ {
+ XXyoffset
+ = rootwindowinfo.height + (++yoff) - pixelheight - 4;
+ }
+ else
+ {
+ XXyoffset = yoff;
+ }
+ XMoveWindow (XXwindow, XXxoffset, XXyoffset);
+ UNBLOCK_INPUT ();
+ /* XWarpMouse (XXwindow, pixelwidth >> 1, pixelheight >> 1); */
+}
+
+XSetWindowSize (rows, cols)
+ register int rows, cols;
+{
+ /* if (rows < 3) rows = 24;
+ if (cols < 1) cols = 80; */
+ pixelwidth = cols * fontinfo->width + 2 * XXInternalBorder;
+ pixelheight = rows * fontinfo->height + 2 * XXInternalBorder;
+ XChangeWindow (XXwindow, pixelwidth, pixelheight);
+ XFlush ();
+ change_screen_size (rows, cols, 0, 0, 0);
+ PendingExposure = 0;
+}
+
+XPopUpWindow ()
+{
+ BLOCK_INPUT_DECLARE ()
+ if (WindowMapped)
+ return;
+ BLOCK_INPUT ();
+ if (!x_edges_specified)
+ Fx_rubber_band ();
+ bitblt = 0;
+ CursorExists = 0;
+ VisibleX = 0;
+ VisibleY = 0;
+ WindowMapped = 1;
+ XMapWindow (XXwindow);
+ dumprectangle (0, 0,
+ screen_height * fontinfo->height + 2 * XXInternalBorder,
+ screen_width * fontinfo->width + 2 * XXInternalBorder);
+ XSelectInput (XXwindow, KeyPressed | ExposeWindow | ButtonPressed
+ | ButtonReleased
+ | ExposeRegion | ExposeCopy);
+ /* XWarpMouse (XXwindow, pixelwidth >> 1, pixelheight >> 1);*/
+ XTmove_cursor (0, 0);
+ if (IconWindow)
+ {
+ XSetIconWindow (XXwindow,XXIconWindow);
+ XSelectInput (XXIconWindow, ExposeWindow);
+ }
+ else
+ {
+ XClearIconWindow (XXwindow);
+ XSelectInput (XXIconWindow, NoEvent);
+ }
+ /* XRedrawDisplay ();*/
+ XFlush ();
+ UNBLOCK_INPUT ();
+}
+
+spacecheck (mindex, rindex, windex, minfreespace)
+ register int mindex, rindex, windex, minfreespace;
+{
+ if ((rindex > mindex) || (windex > mindex))
+ {
+ /* fprintf (stderr, "Fatal Mouse Buffer Error.\n");
+ fprintf (stderr, "%d = mindex, %d = rindex, %d = windex\n",
+ mindex, rindex, windex); */
+ return -2;
+ }
+ if (windex >= rindex)
+ {
+ if ((mindex - (windex - rindex)) > minfreespace)
+ return 0;
+ }
+ else
+ {
+ if (((rindex - windex) - 1) > minfreespace)
+ return 0;
+ }
+ return -1;
+}
+
+loadxrepbuffer (p_xrep, p_buffer)
+ register XEvent *p_xrep;
+ register XREPBUFFER *p_buffer;
+{
+ p_buffer->xrep[p_buffer->windex] = *p_xrep;
+ if (p_buffer->windex == p_buffer->mindex)
+ p_buffer->windex = 0;
+ else
+ p_buffer->windex++;
+}
+
+unloadxrepbuffer (p_xrep, p_buffer)
+ register XEvent *p_xrep;
+ register XREPBUFFER *p_buffer;
+{
+ if (p_buffer->windex == p_buffer->rindex)
+ return -1;
+ *p_xrep = p_buffer->xrep[p_buffer->rindex];
+ if (p_buffer->rindex == p_buffer->mindex)
+ p_buffer->rindex = 0;
+ else
+ p_buffer->rindex++;
+ return 0;
+}
+
+fixxrepbuffer ()
+{
+ Xxrepbuffer.mindex = XREPBUFSIZE - 1;
+ Xxrepbuffer.windex = 0;
+ Xxrepbuffer.rindex = 0;
+}
+
+#endif /* HAVE_X_WINDOWS */