|
|
1.1 root 1: /* X Communication module for terminals which understand the X protocol.
2: Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc.
3:
4: This file is part of GNU Emacs.
5:
6: GNU Emacs is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 1, or (at your option)
9: any later version.
10:
11: GNU Emacs is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GNU Emacs; see the file COPYING. If not, write to
18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19:
20: /* Written by Yakim Martillo, mods and things by Robert Krawitz */
21:
22: /*
23: * $Source: /u2/third_party/gnuemacs.chow/src/RCS/xterm.c,v $
24: * $Author: rlk $
25: * $Locker: $
26: * $Header: xterm.c,v 1.28 86/08/27 13:30:57 rlk Exp $
27: */
28:
29: #ifndef lint
30: static char *rcsid_TrmXTERM_c = "$Header: xterm.c,v 1.28 86/08/27 13:30:57 rlk Exp $";
31: #endif lint
32:
33: /* On 4.3 this loses if it comes after xterm.h. */
34: #include <signal.h>
35: #include "config.h"
36:
37: #ifdef HAVE_X_WINDOWS
38:
39: #include "lisp.h"
40: #undef NULL
41:
42: /* This may include sys/types.h, and that somehow loses
43: if this is not done before the other system files. */
44: #include "xterm.h"
45:
46: /* Load sys/types.h if not already loaded.
47: In some systems loading it twice is suicidal. */
48: #ifndef makedev
49: #include <sys/types.h>
50: #endif
51:
52: #if !defined(USG) || defined(IBMRTAIX)
53: #include <sys/time.h>
54: #else
55: #include <time.h>
56: #endif /* USG and not IBMRTAIX */
57:
58: #include <sys/ioctl.h>
59: #include <fcntl.h>
60: #include <stdio.h>
61: #include <ctype.h>
62: #include <errno.h>
63: #ifdef BSD
64: #include <strings.h>
65: #endif
66: #include <sys/stat.h>
67:
68: #include "dispextern.h"
69: #include "termhooks.h"
70: #include "termopts.h"
71: #include "termchar.h"
72: #include "sink.h"
73: #include "sinkmask.h"
74: #include <X/Xkeyboard.h>
75: /*#include <X/Xproto.h> */
76:
77: /* Allow m- file to inhibit use of FIONREAD. */
78: #ifdef BROKEN_FIONREAD
79: #undef FIONREAD
80: #endif
81:
82: /* We are unable to use interrupts if FIONREAD is not available,
83: so flush SIGIO so we won't try. */
84: #ifndef FIONREAD
85: #ifdef SIGIO
86: #undef SIGIO
87: #endif
88: #endif
89:
90: /* Allow config to specify default font. */
91: #ifndef X_DEFAULT_FONT
92: #define X_DEFAULT_FONT "vtsingle"
93: #endif
94:
95: #define min(a,b) ((a)<(b) ? (a) : (b))
96: #define max(a,b) ((a)>(b) ? (a) : (b))
97: #define sigunblockx(sig) sigblock (0)
98: #define sigblockx(sig) sigblock (1 << ((sig) - 1))
99: XREPBUFFER Xxrepbuffer;
100: int pixelwidth;
101: int pixelheight;
102: int PendingExposure;
103: int PendingIconExposure;
104: #define MAXICID 80
105: char iconidentity[MAXICID];
106: #define ICONTAG "emacs@"
107: #define METABIT 0x80
108: Window XXIconWindow;
109: Bitmap XXIconMask;
110:
111: char *XXcurrentfont;
112: char *default_window;
113: int informflag;
114: extern int initialized;
115:
116: extern char *alternate_display;
117:
118: int XXdebug;
119: int XXpid;
120: extern int screen_garbaged;
121: int XXxoffset, XXyoffset;
122: int IconWindow;
123:
124: int WindowMapped;
125: int CurHL;
126:
127: static int flexlines; /* last line affect by dellines or */
128: /* inslines functions */
129: extern int errno;
130: int VisibleX, VisibleY; /* genuine location of cursor on screen */
131: /* if it is there */
132: static int SavedX, SavedY; /* Where the cursor was before update */
133: /* started */
134:
135: int bitblt; /* Used to track bit blt events */
136: int CursorExists; /* during updates cursor is turned off */
137: static int InUpdate; /* many of functions here may be invoked */
138: /* even if no update in progress, when */
139: /* no update is in progress the action */
140: /* can be slightly different */
141:
142: short MouseCursor[] = {
143: 0x0000, 0x0008, 0x0018, 0x0038,
144: 0x0078, 0x00f8, 0x01f8, 0x03f8,
145: 0x07f8, 0x00f8, 0x00d8, 0x0188,
146: 0x0180, 0x0300, 0x0300, 0x0000};
147:
148: short MouseMask[] = {
149: 0x000c, 0x001c, 0x003c, 0x007c,
150: 0x00fc, 0x01fc, 0x03fc, 0x07fc,
151: 0x0ffc, 0x0ffc, 0x01fc, 0x03dc,
152: 0x03cc, 0x0780, 0x0780, 0x0300};
153:
154: Display *XXdisplay;
155: FontInfo *fontinfo;
156: Window XXwindow;
157: Cursor EmacsCursor;
158:
159: char *fore_color; /* Variables to store colors */
160: char *back_color;
161: char *brdr_color;
162: char *curs_color;
163: char *mous_color;
164:
165: int fore;
166: int back;
167: int brdr;
168: int curs;
169: int mous;
170:
171: static WindowInfo windowinfo;
172: WindowInfo rootwindowinfo;
173:
174:
175:
176: static XKeyPressedEvent XXEvent; /* as X messages are read in they are */
177: /* stored here */
178: static XREPBUFFER XXqueue;/* Used for storing up ExposeRegion */
179: /* replies, so that the SIGIO inter- */
180: /* rupt serving routines do almost */
181: /* no writes to the X socket */
182: /*int CurHL; /* Current Highlighting actually being */
183: /* being used for bold font right now*/
184:
185: int XXborder;
186: int XXInternalBorder;
187:
188: int (*handler)();
189:
190: extern Display *XOpenDisplay ();
191: extern Window XCreateWindow ();
192: extern Cursor XDefineCursor ();
193: extern Cursor XCreateCursor ();
194: extern FontInfo *XOpenFont ();
195:
196: static int flashback ();
197:
198:
199: /* HLmode -- Changes the GX function for output strings. Could be used to
200: * change font. Check an XText library function call.
201: */
202:
203: static
204: HLmode (new)
205: int new;
206: {
207: CurHL = new;
208: }
209:
210:
211: /* External interface to control of standout mode.
212: Call this when about to modify line at position VPOS
213: and not change whether it is highlighted. */
214:
215: XTreassert_line_highlight (highlight, vpos)
216: int highlight, vpos;
217: {
218: HLmode (highlight);
219: }
220:
221: /* Call this when about to modify line at position VPOS
222: and change whether it is highlighted. */
223:
224: static
225: XTchange_line_highlight (new_highlight, vpos, first_unused_hpos)
226: int new_highlight, vpos, first_unused_hpos;
227: {
228: HLmode (new_highlight);
229: XTmove_cursor (vpos, 0);
230: x_clear_end_of_line (0);
231: }
232:
233:
234: /* Used for starting or restarting (after suspension) the X window. Puts the
235: * cursor in a known place, update does not begin with this routine but only
236: * with a call to redisplay. The mouse cursor is warped into the window and
237: * then the cursor is turned on.
238: */
239:
240:
241:
242: static
243: XTset_terminal_modes ()
244: {
245: int stuffpending;
246: #ifdef XDEBUG
247: fprintf (stderr, "XTset_terminal_modes\n");
248: #endif
249: InUpdate = 0;
250: stuffpending = 0;
251: if (!initialized)
252: {
253: CursorExists = 0;
254: VisibleX = 0;
255: VisibleY = 0;
256: }
257: XTclear_screen ();
258: #ifdef FIONREAD
259: ioctl (0, FIONREAD, &stuffpending);
260: if (stuffpending)
261: SIGNAL_INPUT ();
262: #endif
263: }
264:
265: /* XTmove_cursor moves the cursor to the correct location and checks whether an update
266: * is in progress in order to toggle it on.
267: */
268:
269: static
270: XTmove_cursor (row, col)
271: register int row, col;
272: {
273: BLOCK_INPUT_DECLARE ()
274:
275: BLOCK_INPUT ();
276: #ifdef XDEBUG
277: fprintf (stderr, "XTmove_cursor\n");
278: #endif
279: cursor_hpos = col;
280: cursor_vpos = row;
281: if (InUpdate)
282: {
283: if (CursorExists)
284: {
285: CursorToggle ();
286: }
287: UNBLOCK_INPUT ();
288: return; /* Generally, XTmove_cursor will be invoked */
289: /* when InUpdate with !CursorExists */
290: /* so that wasteful XFlush is not called */
291: }
292: if ((row == VisibleY) && (col == VisibleX))
293: {
294: if (!CursorExists)
295: {
296: CursorToggle ();
297: }
298: XFlush ();
299: UNBLOCK_INPUT ();
300: return;
301: }
302: if (CursorExists) CursorToggle ();
303: VisibleX = col;
304: VisibleY = row;
305: if (!CursorExists) CursorToggle ();
306: XFlush ();
307: UNBLOCK_INPUT ();
308: }
309:
310: /* Used to get the terminal back to a known state after resets. Usually
311: * used when restarting suspended or waiting emacs
312: */
313:
314: static
315: cleanup ()
316: {
317: inverse_video = 0;
318: HLmode (0);
319: }
320:
321: /* Erase current line from column cursor_hpos to column END.
322: Leave cursor at END. */
323:
324: static
325: XTclear_end_of_line (end)
326: register int end;
327: {
328: register int numcols;
329:
330: #ifdef XDEBUG
331: fprintf (stderr, "XTclear_end_of_line\n");
332:
333: #endif
334: if (cursor_vpos < 0 || cursor_vpos >= screen_height)
335: {
336: return;
337: }
338:
339: if (end >= screen_width)
340: end = screen_width;
341: if (end <= cursor_hpos)
342: return;
343:
344: numcols = end - cursor_hpos;
345: {
346: BLOCK_INPUT_DECLARE ()
347:
348: BLOCK_INPUT ();
349: if (cursor_vpos == VisibleY && VisibleX >= cursor_hpos && VisibleX < end)
350: {
351: if (CursorExists) CursorToggle ();
352: }
353: XPixSet (XXwindow,
354: cursor_hpos * fontinfo->width + XXInternalBorder,
355: cursor_vpos * fontinfo->height+XXInternalBorder,
356: fontinfo->width * numcols,
357: fontinfo->height,
358: back);
359: XTmove_cursor (cursor_vpos, end);
360: UNBLOCK_INPUT ();
361: }
362: }
363:
364: /* Erase current line from column START to right margin.
365: Leave cursor at START. */
366:
367: static
368: x_clear_end_of_line (start)
369: register int start;
370: {
371: register int numcols;
372:
373: #ifdef XDEBUG
374: fprintf (stderr, "x_clear_end_of_line\n");
375:
376: #endif
377: if (cursor_vpos < 0 || cursor_vpos >= screen_height)
378: {
379: return;
380: }
381:
382: if (start < 0)
383: start = 0;
384: if (start >= screen_width)
385: return;
386:
387: numcols = screen_width - start;
388: {
389: BLOCK_INPUT_DECLARE ()
390:
391: BLOCK_INPUT ();
392: if (cursor_vpos == VisibleY && VisibleX >= start)
393: {
394: if (CursorExists) CursorToggle ();
395: }
396: XPixSet (XXwindow,
397: start * fontinfo->width + XXInternalBorder,
398: cursor_vpos * fontinfo->height+XXInternalBorder,
399: fontinfo->width * numcols,
400: fontinfo->height,
401: back);
402: XTmove_cursor (cursor_vpos, start);
403: UNBLOCK_INPUT ();
404: }
405: }
406:
407: static
408: XTreset_terminal_modes ()
409: {
410: #ifdef XDEBUG
411: fprintf (stderr, "XTreset_terminal_modes\n");
412: #endif
413: XTclear_screen ();
414: }
415:
416: static
417: XTclear_screen ()
418: {
419: #ifdef XDEBUG
420: fprintf (stderr, "XTclear_screen\n");
421: #endif
422: HLmode (0);
423: CursorExists = 0;
424:
425: cursor_hpos = 0;
426: cursor_vpos = 0;
427: SavedX = 0;
428: SavedY = 0;
429: VisibleX = 0;
430: VisibleY = 0;
431: {
432: BLOCK_INPUT_DECLARE ()
433:
434: BLOCK_INPUT ();
435: XClear (XXwindow);
436: CursorToggle ();
437: if (!InUpdate)
438: XFlush ();
439: UNBLOCK_INPUT ();
440: }
441: }
442:
443: /* used by dumprectangle which is usually invoked upon ExposeRegion
444: * events which come from bit blt's or moving an obscuring opaque window
445: */
446:
447: static
448: dumpchars (current_screen, numcols, tempX, tempY, tempHL)
449: register struct matrix *current_screen;
450: register int numcols;
451: register int tempX, tempY, tempHL;
452: {
453: if (numcols <= 0) return;
454: if (((numcols - 1) + tempX) > screen_width)
455: {
456: numcols = (screen_width - tempX) + 1;
457: }
458: if ((tempX < 0) || (tempX >= screen_width) ||
459: (tempY < 0) || (tempY >= screen_height))
460: {
461: return;
462: }
463: XText (XXwindow,
464: (tempX * fontinfo->width+XXInternalBorder),
465: (tempY * fontinfo->height+XXInternalBorder),
466: ¤t_screen->contents[tempY][tempX],
467: numcols,
468: fontinfo->id,
469: (tempHL ? back : fore),
470: (tempHL ? fore : back));
471: }
472:
473: /* When a line has been changed this function is called. X is so fast
474: * that the actual sequence is ignore. Rather, the new version of the
475: * line is simply output if this function is invoked while in UpDate.
476: * Sometimes writechars can be invoked when not in update if text is to
477: * be output at the end of the line. In this case the whole line is not
478: * output. Simply the new text at the current cursor position given
479: * by VisibleX,Y. The cursor is moved to the end of the new text.
480: */
481: static
482: writechars (start, end)
483: register char *start, *end;
484: {
485: register int temp_length;
486: BLOCK_INPUT_DECLARE ()
487:
488: BLOCK_INPUT ();
489:
490: if ((cursor_vpos < 0) || (cursor_vpos >= screen_height))
491: {
492: UNBLOCK_INPUT ();
493: return;
494: }
495: if (CursorExists)
496: {
497: CursorToggle ();
498: }
499: if (InUpdate)
500: {
501: if (end != start - 1)
502: {
503: XText (XXwindow,
504: (cursor_hpos * fontinfo->width+XXInternalBorder),
505: (cursor_vpos * fontinfo->height+XXInternalBorder),
506: start,
507: end + 1 - start,
508: fontinfo->id,
509: (CurHL ? back : fore),
510: (CurHL ? fore : back));
511: XTmove_cursor (cursor_vpos, cursor_hpos + end - start + 1);
512: }
513: }
514: else
515: {
516: if ((VisibleX < 0) || (VisibleX >= screen_width))
517: {
518: UNBLOCK_INPUT ();
519: return;
520: }
521: if ((VisibleY < 0) || (VisibleY >= screen_height))
522: {
523: UNBLOCK_INPUT ();
524: return;
525: }
526: if (((end - start) + VisibleX) >= screen_width)
527: {
528: end = start + (screen_width - (VisibleX + 1));
529: }
530: if (end >= start)
531: {
532: XText (XXwindow,
533: (VisibleX * fontinfo->width+XXInternalBorder),
534: (VisibleY * fontinfo->height+XXInternalBorder),
535: start,
536: ((end - start) + 1),
537: fontinfo->id,
538: (CurHL ? back : fore),
539: (CurHL ? fore : back));
540: VisibleX = VisibleX + (end - start) + 1;
541: }
542: if (!CursorExists) CursorToggle ();
543: }
544: UNBLOCK_INPUT ();
545: }
546:
547:
548: static
549: XToutput_chars (start, len)
550: register char *start;
551: register int len;
552: {
553: #ifdef XDEBUG
554: fprintf (stderr, "XToutput_chars\n");
555: #endif
556: writechars (start, start + len - 1);
557: }
558:
559: /* The following routine is for the deaf or for the pervert who prefers
560: * that his terminal flash at him rather than beep at him.
561: */
562:
563: static int flashedback;
564:
565: static
566: XTflash ()
567: {
568: #ifdef ITIMER_REAL
569: struct itimerval itimer;
570:
571: #ifdef XDEBUG
572: fprintf (stderr, "XTflash\n");
573: #endif
574:
575: stop_polling ();
576: signal (SIGALRM, flashback);
577: getitimer (ITIMER_REAL, &itimer);
578: itimer.it_value.tv_usec += 250000;
579: itimer.it_interval.tv_sec = 0;
580: itimer.it_interval.tv_usec = 0;
581: flashedback = 0;
582: setitimer (ITIMER_REAL, &itimer, 0);
583: {
584: BLOCK_INPUT_DECLARE ()
585:
586: BLOCK_INPUT ();
587: XPixFill (XXwindow, 0, 0, screen_width*fontinfo->width+2*XXInternalBorder,
588: screen_height * fontinfo->height+2*XXInternalBorder, WhitePixel,
589: ClipModeClipped, GXinvert, AllPlanes);
590: XFlush ();
591: UNBLOCK_INPUT ();
592: }
593: while (!flashedback) pause ();
594: #endif /* have ITIMER_REAL */
595: }
596:
597: static
598: flashback ()
599: {
600: #ifdef ITIMER_REAL
601: #ifdef SIGIO
602: int mask = sigblock (sigmask (SIGIO) | sigmask (SIGALRM));
603: #else
604: int mask = sigblock (sigmask (SIGALRM));
605: #endif
606: XPixFill (XXwindow, 0, 0, screen_width * fontinfo->width+2*XXInternalBorder,
607: screen_height * fontinfo->height+2*XXInternalBorder, WhitePixel,
608: ClipModeClipped, GXinvert, AllPlanes);
609: XFlush ();
610: flashedback = 1;
611: sigsetmask (mask);
612: start_polling ();
613: #endif /* have ITIMER_REAL */
614: }
615:
616: /* A kludge to get a bell */
617:
618: static
619: XTfeep ()
620: {
621: BLOCK_INPUT_DECLARE ()
622:
623: BLOCK_INPUT ();
624: #ifdef XDEBUG
625: fprintf (stderr, "XTfeep\n");
626: #endif
627: XFeep (0);
628: UNBLOCK_INPUT ();
629: }
630:
631: /* Artificially creating a cursor is hard, the actual position on the
632: * screen (either where it is or last was) is tracked with VisibleX,Y.
633: * Gnu Emacs code tends to assume a cursor exists in hardward at cursor_hpos,Y
634: * and that output text will appear there. During updates, the cursor is
635: * supposed to be blinked out and will only reappear after the update
636: * finishes.
637: */
638:
639: CursorToggle ()
640: {
641: if (!WindowMapped)
642: {
643: CursorExists = 0;
644: return 0;
645: }
646: if ((VisibleX < 0) || (VisibleX >= screen_width) ||
647: (VisibleY < 0) || (VisibleY >= screen_height))
648: { /* Current Cursor position trash */
649: /* Not much can be done */
650: XFlush ();
651: CursorExists = 0;
652: return 0;
653: /* Currently the return values are not */
654: /* used, but I could anticipate using */
655: /* them in the future. */
656: }
657:
658: if (current_screen->enable[VisibleY] &&
659: (VisibleX < current_screen->used[VisibleY]))
660: {
661: if (CursorExists)
662: {
663: XText (XXwindow,
664: VisibleX * fontinfo->width+XXInternalBorder,
665: VisibleY * fontinfo->height+XXInternalBorder,
666: ¤t_screen->contents[VisibleY][VisibleX], 1,
667: fontinfo->id,
668: fore, back);
669: }
670: else
671: {
672: XText (XXwindow,
673: VisibleX * fontinfo->width+XXInternalBorder,
674: VisibleY * fontinfo->height+XXInternalBorder,
675: ¤t_screen->contents[VisibleY][VisibleX], 1,
676: fontinfo->id,
677: back, curs);
678: }
679: }
680: else if (CursorExists)
681: {
682: XPixSet (XXwindow,
683: VisibleX * fontinfo->width+XXInternalBorder,
684: VisibleY * fontinfo->height+XXInternalBorder,
685: fontinfo->width, fontinfo->height, back);
686: }
687: else
688: {
689: XPixSet (XXwindow,
690: VisibleX * fontinfo->width+XXInternalBorder,
691: VisibleY * fontinfo->height+XXInternalBorder,
692: fontinfo->width, fontinfo->height, curs);
693: }
694: CursorExists = !CursorExists;
695: /* Cursor has either been blinked in */
696: /* or out */
697: if (!InUpdate)
698: {
699: XFlush ();
700: }
701: return 1;
702: }
703:
704: /* This routine is used by routines which are called to paint regions */
705: /* designated by ExposeRegion events. If the cursor may be in the exposed */
706: /* region, this routine makes sure it is gone so that dumprectangle can */
707: /* toggle it back into existance if dumprectangle is invoked when not in */
708: /* the midst of a screen update. */
709: static
710: ClearCursor ()
711: {
712: BLOCK_INPUT_DECLARE ()
713:
714: BLOCK_INPUT ();
715: if (!WindowMapped)
716: {
717: CursorExists = 0;
718: UNBLOCK_INPUT ();
719: return;
720: }
721: if ((VisibleX < 0) || (VisibleX >= screen_width)
722: || (VisibleY < 0) || (VisibleY >= screen_height))
723: { /* Current Cursor position trash */
724: /* Not much can be done */
725: CursorExists = 0;
726: UNBLOCK_INPUT ();
727: return;
728: }
729: XPixSet (XXwindow,
730: VisibleX * fontinfo->width+XXInternalBorder,
731: VisibleY * fontinfo->height+XXInternalBorder,
732: fontinfo->width, fontinfo->height,
733: back);
734: CursorExists = 0;
735: UNBLOCK_INPUT ();
736: }
737:
738: static
739: XTupdate_begin ()
740: {
741: BLOCK_INPUT_DECLARE ()
742:
743: BLOCK_INPUT ();
744: #ifdef XDEBUG
745: fprintf (stderr, "XTupdate_begin\n");
746: #endif
747:
748: InUpdate = 1;
749: if (CursorExists)
750: {
751: CursorToggle ();
752: }
753: SavedX = cursor_hpos; /* The initial"hardware" cursor position is */
754: /* saved because that is where gnu emacs */
755: /* expects the cursor to be at the end of*/
756: /* the update */
757: SavedY = cursor_vpos;
758: dumpqueue ();
759: UNBLOCK_INPUT ();
760: }
761:
762:
763: static
764: XTupdate_end ()
765: {
766: BLOCK_INPUT_DECLARE ()
767:
768: BLOCK_INPUT ();
769: #ifdef XDEBUG
770: fprintf (stderr, "XTupdate_end\n");
771: #endif
772: if (CursorExists)
773: CursorToggle ();
774: InUpdate = 0;
775: dumpqueue ();
776: XTmove_cursor (SavedY, SavedX); /* XTmove_cursor invokes cursor toggle */
777: UNBLOCK_INPUT ();
778: }
779:
780: /* Used for expose region and expose copy events. Have to get the text
781: * back into the newly blank areas.
782: */
783:
784: dumprectangle (top, left, rows, cols)
785: register int top, left, rows, cols;
786: {
787: register int index;
788: int localX, localY, localHL;
789: rows += top;
790: cols += left;
791: top /= fontinfo->height;
792: /* Get row and col containing up and */
793: /* left borders of exposed region -- */
794: /* round down here*/
795: left /= fontinfo->width;
796: rows += (fontinfo->height - 1);
797: cols += (fontinfo->width - 1);
798: rows /= fontinfo->height;
799: /* Get row and col containing bottom and */
800: /* right borders -- round up here */
801: rows -= top;
802: cols /= fontinfo->width;
803: cols -= left;
804: if (rows < 0) return;
805: if (cols < 0) return;
806: if (top > (screen_height - 1)) return;
807: if (left > (screen_width - 1)) return;
808: if ((VisibleX >= left) && (VisibleX < (left + cols)) &&
809: (VisibleY >= top) && (VisibleY < (top + rows)))
810: {
811: ClearCursor ();
812: }
813:
814: /* should perhaps be DesiredScreen */
815: /* but PhysScreen is guaranteed to contain*/
816: /* date which was good for every line on */
817: /* screen. For desired screen only for */
818: /* lines which are changing. Emacs does */
819: /* not consider a line within a newly */
820: /* exposed region necessarily to have */
821: /* been changed. Emacs knows nothing */
822: /* about ExposeRegion events.*/
823: for (localY = top, index = 0;
824: (index < rows) && (localY < screen_height);
825: ++index, ++localY)
826: {
827: if ((localY < 0) || (localY >= screen_height)) continue;
828: if (!current_screen->enable[localY]) continue;
829: if ((left + 1) > current_screen->used[localY]) continue;
830: localX = left;
831: localHL = current_screen->highlight[localY];
832: dumpchars (current_screen,
833: min (cols,
834: current_screen->used[localY]
835: - localX),
836: localX, localY, localHL);
837: }
838: if (!InUpdate && !CursorExists) CursorToggle ();
839: /* Routine usually called */
840: /* when not in update */
841: }
842:
843: /* What sections of the window will be modified from the UpdateDisplay
844: * routine is totally under software control. Any line with Y coordinate
845: * greater than flexlines will not change during an update. This is really
846: * used only during dellines and inslines routines (scraplines and stufflines)
847: */
848: static
849: XTset_terminal_window (n)
850: register int n;
851: {
852: #ifdef XDEBUG
853: fprintf (stderr, "XTset_terminal_window\n");
854: #endif
855: if ((n <= 0) || (n > screen_height))
856: flexlines = screen_height;
857: else
858: flexlines = n;
859: }
860:
861: XTins_del_lines (vpos, n)
862: int vpos, n;
863: {
864: #ifdef XDEBUG
865: fprintf (stderr, "XTins_del_lines\n");
866: #endif
867: XTmove_cursor (vpos, 0);
868: if (n >= 0) stufflines (n);
869: else scraplines (-n);
870: }
871:
872: static
873: XTinsert_chars (start, len)
874: register char *start;
875: register int len;
876: {
877: #ifdef XDEBUG
878: fprintf (stderr, "XTinsert_chars\n");
879: #endif
880: writechars (start, start + len - 1);
881: }
882:
883: static
884: XTdelete_chars (n)
885: register int n;
886: {
887: char *msg = "***Delete Chars Called Outside of Update!!!***";
888: #ifdef XDEBUG
889: fprintf (stderr, "XTdelete_chars\n");
890: #endif
891: writechars (msg, msg + strlen (msg) - 1);
892: }
893:
894: static
895: stufflines (n)
896: register int n;
897: {
898: register int topregion, bottomregion;
899: register int length, newtop;
900: BLOCK_INPUT_DECLARE ()
901:
902: if (cursor_vpos >= flexlines)
903: return;
904:
905: if (!WindowMapped)
906: {
907: bitblt = 0;
908: return;
909: }
910: BLOCK_INPUT ();
911: if (CursorExists) CursorToggle ();
912: dumpqueue ();
913: UNBLOCK_INPUT ();
914: topregion = cursor_vpos;
915: bottomregion = flexlines - (n + 1);
916: newtop = cursor_vpos + n;
917: length = (bottomregion - topregion) + 1;
918: if ((length > 0) && (newtop <= flexlines))
919: {
920: BLOCK_INPUT ();
921: /* Should already have cleared */
922: /* queue of events associated */
923: /* with old bitblts */
924: XMoveArea (XXwindow, XXInternalBorder,
925: topregion * fontinfo->height+XXInternalBorder,
926: XXInternalBorder, newtop * fontinfo->height+XXInternalBorder,
927: screen_width * fontinfo->width,
928: length * fontinfo->height);
929: if (WindowMapped)
930: bitblt = 1;
931: XFlush ();
932: UNBLOCK_INPUT ();
933: SIGNAL_INPUT_WHILE (bitblt);
934: XFlush ();
935: }
936: newtop = min (newtop, (flexlines - 1));
937: length = newtop - topregion;
938: if (length > 0)
939: {
940: XPixSet (XXwindow,
941: XXInternalBorder,
942: topregion * fontinfo->height+XXInternalBorder,
943: screen_width * fontinfo->width,
944: n * fontinfo->height,
945: back);
946: }
947: /* if (!InUpdate) CursorToggle (); */
948: }
949:
950: static
951: scraplines (n)
952: register int n;
953: {
954: BLOCK_INPUT_DECLARE ()
955: if (!WindowMapped)
956: {
957: bitblt = 0;
958: return;
959: }
960:
961: if (cursor_vpos >= flexlines)
962: return;
963: BLOCK_INPUT ();
964: if (CursorExists) CursorToggle ();
965: dumpqueue ();
966: if ((cursor_vpos + n) >= flexlines)
967: {
968: if (flexlines >= (cursor_vpos + 1))
969: {
970: XPixSet (XXwindow,
971: XXInternalBorder, cursor_vpos * fontinfo->height+XXInternalBorder,
972: screen_width * fontinfo->width,
973: (flexlines - cursor_vpos) * fontinfo->height,
974: back);
975: }
976: UNBLOCK_INPUT ();
977: }
978: else
979: {
980: XMoveArea (XXwindow,
981: XXInternalBorder,
982: (cursor_vpos + n) * fontinfo->height+XXInternalBorder,
983: XXInternalBorder, cursor_vpos * fontinfo->height+XXInternalBorder,
984: screen_width * fontinfo->width,
985: (flexlines - (cursor_vpos + n)) * fontinfo->height);
986: if (WindowMapped)
987: bitblt = 1;
988: XFlush ();
989: UNBLOCK_INPUT ();
990: SIGNAL_INPUT_WHILE (bitblt);
991: BLOCK_INPUT ();
992: XFlush ();
993: XPixSet (XXwindow, XXInternalBorder,
994: (flexlines - n) * fontinfo->height+XXInternalBorder,
995: screen_width * fontinfo->width,
996: n * fontinfo->height, back);
997: UNBLOCK_INPUT ();
998: }
999: /* if (!InUpdate) CursorToggle (); */
1000: }
1001:
1002: /* Substitutes for standard read routine. Under X not interested in individual
1003: * bytes but rather individual packets.
1004: */
1005:
1006: XTread_socket (sd, bufp, numchars)
1007: register int sd;
1008: register char *bufp;
1009: register int numchars;
1010: {
1011:
1012: int count;
1013: char *where_mapping;
1014: int nbytes;
1015: int stuffpending;
1016: int temp_width, temp_height;
1017: BLOCK_INPUT_DECLARE ()
1018: /* XKeyPressedEvent event; */
1019: /* typedef struct reply {XEvent event; struct reply *next} Reply;
1020: Reply *replies = NULL;*/
1021:
1022: BLOCK_INPUT ();
1023: count = 0;
1024: if (numchars <= 0)
1025: { /* To keep from overflowing read buffer */
1026: numchars = 1;
1027: --bufp;
1028: }
1029: #ifdef SIGIO
1030: while (bitblt || XPending () != 0)
1031: #else
1032: #ifndef HAVE_SELECT
1033: if (! (fcntl (fileno (stdin), F_GETFL, 0) & O_NDELAY))
1034: {
1035: extern int read_alarm_should_throw;
1036: if (CursorExists)
1037: xfixscreen ();
1038: read_alarm_should_throw = 1;
1039: XPeekEvent (&XXEvent);
1040: read_alarm_should_throw = 0;
1041: }
1042: #endif
1043: while (XPending () != 0)
1044: #endif
1045: {
1046: /* while there are more events*/
1047: XNextEvent (&XXEvent);
1048: switch (XXEvent.type)
1049: {
1050: /* case X_Reply:
1051: {
1052: extern char *malloc ();
1053: Reply *reply = (Reply *) malloc (sizeof (Reply));
1054: reply->next = replies;
1055: reply->event = XXEvent;
1056: replies = reply;
1057: break;
1058: }*/
1059: default:
1060: break;
1061: case ExposeWindow:
1062: if (((XExposeEvent *)&XXEvent)->window == XXIconWindow)
1063: {
1064: PendingIconExposure = 1;
1065: }
1066: else
1067: PendingExposure = 1;/* No reason to repeat */
1068: /* this if several */
1069: /* ExposeWindow events */
1070: /* come in quick succes-*/
1071: /* ion */
1072: break;
1073: case ExposeRegion:
1074: if (PendingExposure)
1075: { /* Don't bother with */
1076: /* region events when */
1077: /* full window event */
1078: /* is pending */
1079: break;
1080: }
1081: loadxrepbuffer (&XXEvent, &XXqueue);
1082: if (XXqueue.rindex == XXqueue.windex)
1083: {
1084: PendingExposure = 1;
1085: }
1086: if ((XXqueue.rindex > XXqueue.mindex) ||
1087: (XXqueue.windex > XXqueue.mindex) ||
1088: (XXqueue.rindex < 0) ||
1089: (XXqueue.windex < 0))
1090: {
1091: PendingExposure = 1;
1092: }
1093: break;
1094: case ExposeCopy: /* For ExposeCopy sync */
1095: /* will block all outgoing */
1096: /* requests until this is */
1097: /* decremented */
1098: if (WindowMapped) bitblt = 0;
1099: break;
1100: case KeyPressed:
1101: /* bcopy (XXEvent, event, sizeof (XKeyPressedEvent)); */
1102: where_mapping = XLookupMapping (&XXEvent, &nbytes);
1103: /* Nasty fix for arrow keys */
1104: if (!nbytes && IsCursorKey (XXEvent.detail & 0xff))
1105: {
1106: switch (XXEvent.detail & 0xff)
1107: {
1108: case KC_CURSOR_LEFT:
1109: where_mapping = "\002";
1110: break;
1111: case KC_CURSOR_RIGHT:
1112: where_mapping = "\006";
1113: break;
1114: case KC_CURSOR_UP:
1115: where_mapping = "\020";
1116: break;
1117: case KC_CURSOR_DOWN:
1118: where_mapping = "\016";
1119: break;
1120: }
1121: nbytes = 1;
1122: }
1123: if (numchars - nbytes > 0)
1124: {
1125: bcopy (where_mapping, bufp, nbytes);
1126: bufp += nbytes;
1127: count += nbytes;
1128: numchars -= nbytes;
1129: }
1130: /* else
1131: {
1132: bcopy (where_mapping, bufp, numchars);
1133: bufp += numchars;
1134: count += numchars;
1135: numchars = 0;
1136: *(bufp-1) = *(where_mapping + nbytes - 1);
1137: }*/
1138: break;
1139: case ButtonPressed:
1140: case ButtonReleased:
1141: switch (spacecheck (Xxrepbuffer.mindex,
1142: Xxrepbuffer.rindex,
1143: Xxrepbuffer.windex, 0))
1144: {
1145: case 0:
1146: loadxrepbuffer (&XXEvent,
1147: &Xxrepbuffer);
1148: if (informflag && (numchars > 1))
1149: {
1150: *bufp++ = (char) 'X' & 037; /* C-x */
1151: ++count;
1152: --numchars;
1153: *bufp++ = (char) 0; /* C-@ */
1154: ++count;
1155: --numchars;
1156: }
1157: break;
1158: case -1:
1159: break;
1160: case -2:
1161: default:
1162: fixxrepbuffer ();
1163: break;
1164: }
1165: break;
1166: }
1167: }
1168: /* while (replies) {
1169: Reply *reply = replies;
1170: XPutBackEvent (&reply->event);
1171: replies = reply->next;
1172: free (reply);
1173: }*/
1174: if (count < 0)
1175: count = 0;
1176: #ifdef HAVE_SELECT
1177: if (CursorExists
1178: #ifdef O_NDELAY
1179: #ifdef F_GETFL
1180: && (! (fcntl (fileno (stdin), F_GETFL, 0) & O_NDELAY))
1181: #endif
1182: #endif
1183: )
1184: xfixscreen ();
1185: #endif
1186: UNBLOCK_INPUT ();
1187: return count;
1188: }
1189:
1190: /* refresh bitmap kitchen sink icon */
1191: refreshicon ()
1192: {
1193: BLOCK_INPUT_DECLARE ()
1194:
1195: BLOCK_INPUT ();
1196: if (XXIconWindow)
1197: XBitmapBitsPut (XXIconWindow, 0, 0, sink_width, sink_height,
1198: sink_bits, BlackPixel, WhitePixel,
1199: XXIconMask, GXcopy, AllPlanes);
1200: XFlush ();
1201: UNBLOCK_INPUT ();
1202: }
1203:
1204: XBitmapIcon ()
1205: {
1206: BLOCK_INPUT_DECLARE ()
1207:
1208: BLOCK_INPUT ();
1209: if (!IconWindow)
1210: {
1211: XSetIconWindow (XXwindow,XXIconWindow);
1212: XSelectInput (XXIconWindow, ExposeWindow);
1213: IconWindow = !IconWindow;
1214: }
1215: UNBLOCK_INPUT ();
1216: }
1217:
1218: XTextIcon ()
1219: {
1220: BLOCK_INPUT_DECLARE ()
1221:
1222: BLOCK_INPUT ();
1223: if (IconWindow)
1224: {
1225: XClearIconWindow (XXwindow);
1226: XSelectInput (XXIconWindow, NoEvent);
1227: IconWindow = !IconWindow;
1228: }
1229: UNBLOCK_INPUT ();
1230: }
1231:
1232: /* Interpreting incoming keycodes. Should have table modifiable as needed
1233: * from elisp.
1234: */
1235:
1236: /* Exit gracefully from gnuemacs, doing an autosave and giving a status.
1237: */
1238:
1239: XExitGracefully (disp, event)
1240: Display *disp;
1241: XErrorEvent *event;
1242: {
1243: XCleanUp ();
1244: exit (70);
1245: }
1246:
1247: x_io_error (disp)
1248: Display *disp;
1249: {
1250: XCleanUp ();
1251: exit (71);
1252: }
1253:
1254: #if 0
1255: /* This kludge overcomes the failure to handle EAGAIN and EINTR
1256: in a certain version of X for 386 running system V. */
1257:
1258: x_io_error (disp, a, b, c, nwrite)
1259: Display *disp;
1260: {
1261: extern _XSend ();
1262: unsigned int pc = ((unsigned int *)&disp)[-1];
1263: if (pc - (unsigned int)&_XSend - 100 < 100
1264: && (errno == EAGAIN || errno == EINTR))
1265: {
1266: /* We were called by `writedata' erroneously.
1267: Modify a local variable which `writedata'
1268: will subtract from the number of bytes to be written. */
1269: nwrite = 0;
1270: return;
1271: }
1272: abort ();
1273: }
1274: #endif
1275:
1276: xfixscreen ()
1277: {
1278: register int temp_width, temp_height;
1279: BLOCK_INPUT_DECLARE ()
1280: /* register int temp_x, temp_y; */
1281:
1282: BLOCK_INPUT ();
1283: dumpqueue ();
1284: /* Check that the connection is in fact open. This works by doing a nop */
1285: /* (well, almost) write operation. If there is an XIOerror or a */
1286: /* SIGPIPE, exit gracefully. This fixes the loop-on-logout bug.*/
1287: /* XIOErrorHandler (XExitGracefully); */
1288: XPixFill (XXwindow, 0, 0, 1, 1, back, ClipModeClipped, GXnoop, AllPlanes);
1289: XFlush ();
1290: /* XIOErrorHandler (0); */
1291: if (PendingIconExposure)
1292: {
1293: refreshicon ();
1294: PendingIconExposure = 0;
1295: }
1296: if (PendingExposure)
1297: {
1298: PendingExposure = 0;
1299: ClearCursor ();
1300: XXqueue.rindex = 0;
1301: XXqueue.windex = 0;
1302: XQueryWindow (XXwindow, &windowinfo); /* Dangerous to do */
1303: /* writes here but */
1304: /* otherwise would */
1305: /* have to alter */
1306: /* gnu emacs display */
1307: /* routines to query */
1308: /* when screen garbaged */
1309: temp_width = (windowinfo.width - 2 * XXInternalBorder) / fontinfo->width;
1310: temp_height = (windowinfo.height- 2*XXInternalBorder) / fontinfo->height;
1311: if (temp_width != screen_width || temp_height != screen_height)
1312: change_screen_size (max (5, temp_height), max (10, temp_width),
1313: 0, 0, 0);
1314: XXxoffset= windowinfo.x;
1315: XXyoffset = windowinfo.y;
1316: /*if (temp_x != XXxoffset || temp_y != XXyoffset)
1317: XSetOffset (temp_x, temp_y);*/
1318: dumprectangle (0, 0,
1319: screen_height * fontinfo->height + 2 * XXInternalBorder,
1320: screen_width * fontinfo->width + 2 * XXInternalBorder);
1321: }
1322: if (!InUpdate)
1323: if (!CursorExists)
1324: CursorToggle ();
1325: XFlush ();
1326: UNBLOCK_INPUT ();
1327: SIGNAL_INPUT ();
1328: }
1329:
1330: x_term_init ()
1331: {
1332: char *vardisplay;
1333: char *temp_font;
1334: register char *option;
1335: extern XTinterrupt_signal ();
1336: int reversevideo;
1337: Color cdef;
1338: char *progname;
1339:
1340: Fset (intern ("window-system-version"), make_number (10));
1341:
1342: vardisplay = (alternate_display ? alternate_display
1343: : (char *) egetenv ("DISPLAY"));
1344: if (!vardisplay || *vardisplay == '\0')
1345: {
1346: fprintf (stderr, "DISPLAY environment variable must be set\n");
1347: exit (-200);
1348: }
1349:
1350: XXdisplay = XOpenDisplay (vardisplay);
1351: if (XXdisplay == (Display *) 0)
1352: {
1353: fprintf (stderr, "X server not responding. Check your DISPLAY environment variable.\n");
1354: exit (-200);
1355: }
1356: x_init_1 (1);
1357: Xxrepbuffer.mindex = XREPBUFSIZE - 1;
1358: Xxrepbuffer.windex = 0;
1359: Xxrepbuffer.rindex = 0;
1360: XXqueue.mindex = XREPBUFSIZE - 1;
1361: XXqueue.windex = 0;
1362: XXqueue.rindex = 0;
1363: WindowMapped = 0;
1364: baud_rate = 9600;
1365: min_padding_speed = 10000;
1366: must_write_spaces = 1;
1367: informflag = 1;
1368: meta_key = 1;
1369: visible_bell = 1;
1370: #ifdef SIGIO
1371: interrupt_input = 1;
1372: #endif
1373: inverse_video = 1;
1374: bitblt = 0;
1375: PendingExposure = 0;
1376:
1377: fix_screen_hook = xfixscreen;
1378: clear_screen_hook = XTclear_screen;
1379: clear_end_of_line_hook = XTclear_end_of_line;
1380: ins_del_lines_hook = XTins_del_lines;
1381: change_line_highlight_hook = XTchange_line_highlight;
1382: insert_chars_hook = XTinsert_chars;
1383: output_chars_hook = XToutput_chars;
1384: delete_chars_hook = XTdelete_chars;
1385: ring_bell_hook = XTfeep;
1386: reset_terminal_modes_hook = XTreset_terminal_modes;
1387: set_terminal_modes_hook = XTset_terminal_modes;
1388: update_begin_hook = XTupdate_begin;
1389: update_end_hook = XTupdate_end;
1390: set_terminal_window_hook = XTset_terminal_window;
1391: read_socket_hook = XTread_socket;
1392: move_cursor_hook = XTmove_cursor;
1393: /* raw_move_cursor_hook = XTraw_move_cursor; */
1394: reassert_line_highlight_hook = XTreassert_line_highlight;
1395: scroll_region_ok = 1; /* we'll scroll partial screens */
1396: char_ins_del_ok = 0; /* just as fast to write the line */
1397: line_ins_del_ok = 1; /* we'll just blt 'em */
1398: fast_clear_end_of_line = 1; /* X does this well */
1399: memory_below_screen = 0; /* we don't remember what scrolls
1400: off the bottom */
1401: dont_calculate_costs = 1;
1402:
1403: /* New options section */
1404: IconWindow = 0;
1405: XXborder = 1;
1406: XXInternalBorder = 1;
1407: screen_width = 80;
1408: screen_height = 66;
1409: reversevideo = 0;
1410: XXxoffset = 0;
1411: XXyoffset = 0;
1412: XXdebug = 0;
1413:
1414: XErrorHandler (XExitGracefully);
1415: XIOErrorHandler (x_io_error);
1416:
1417: progname = "emacs";
1418: if (option = XGetDefault (progname,"ReverseVideo"))
1419: if (strcmp (option,"on") == 0) reversevideo = 1;
1420: if (option = XGetDefault (progname, "BitmapIcon"))
1421: if (strcmp (option, "on") == 0) IconWindow = 1;
1422:
1423: if (option = XGetDefault (progname,"BorderWidth"))
1424: XXborder = atoi (option);
1425: if (option = XGetDefault (progname,"InternalBorder"))
1426: XXInternalBorder = atoi (option);
1427:
1428: brdr_color = XGetDefault (progname,"Border");
1429: if (!brdr_color) brdr_color = XGetDefault (progname, "BorderColor");
1430: back_color = XGetDefault (progname,"Background");
1431: fore_color = XGetDefault (progname,"Foreground");
1432: mous_color = XGetDefault (progname,"Mouse");
1433: curs_color = XGetDefault (progname,"Cursor");
1434:
1435: temp_font = XGetDefault (progname,"BodyFont");
1436: if (temp_font == 0) temp_font = X_DEFAULT_FONT;
1437: XXcurrentfont = (char *) xmalloc (strlen (temp_font) + 1);
1438: strcpy (XXcurrentfont, temp_font);
1439:
1440: /* If user has specified a special keymap for use with Emacs, use it. */
1441: {
1442: char *temp = XGetDefault (progname, "KeyMap");
1443: if (temp) XUseKeymap (temp);
1444: }
1445:
1446: if (DisplayCells () > 2)
1447: {
1448:
1449: if (fore_color && XParseColor (fore_color, &cdef) &&
1450: XGetHardwareColor (&cdef))
1451: fore = cdef.pixel;
1452: else
1453: {
1454: fore_color = "black";
1455: fore = BlackPixel;
1456: }
1457:
1458: if (back_color && XParseColor (back_color, &cdef) &&
1459: XGetHardwareColor (&cdef))
1460: back = cdef.pixel;
1461: else
1462: {
1463: back_color = "white";
1464: back = WhitePixel;
1465: }
1466:
1467: if (curs_color && XParseColor (curs_color, &cdef) &&
1468: XGetHardwareColor (&cdef))
1469: curs = cdef.pixel;
1470: else
1471: {
1472: curs_color = "black";
1473: curs = BlackPixel;
1474: }
1475:
1476: if (mous_color && XParseColor (mous_color, &cdef) &&
1477: XGetHardwareColor (&cdef))
1478: mous = cdef.pixel;
1479: else
1480: {
1481: mous_color = "black";
1482: mous = BlackPixel;
1483: }
1484:
1485: if (brdr_color && XParseColor (brdr_color, &cdef) &&
1486: XGetHardwareColor (&cdef))
1487: brdr = cdef.pixel;
1488: else
1489: {
1490: brdr_color = "black";
1491: brdr = BlackPixel;
1492: }
1493: }
1494: else
1495: {
1496: fore_color = curs_color = mous_color = brdr_color = "black";
1497: fore = curs = mous = brdr = BlackPixel;
1498: back_color = "white";
1499: back = WhitePixel;
1500: }
1501:
1502: /*
1503: if (fore_color && DisplayCells () > 2 &&
1504: XParseColor (fore_color, &cdef) && XGetHardwareColor (&cdef))
1505: fore = cdef.pixel;
1506: else if (fore_color && strcmp (fore_color, "black") == 0)
1507: fore = BlackPixel;
1508: else if (fore_color && strcmp (fore_color, "white") == 0)
1509: fore = WhitePixel;
1510: else
1511: {
1512: fore_color = "black";
1513: fore = BlackPixel;
1514: }
1515:
1516: if (back_color && DisplayCells () > 2 &&
1517: XParseColor (back_color, &cdef) && XGetHardwareColor (&cdef))
1518: back = cdef.pixel;
1519: else if (back_color && strcmp (back_color, "white") == 0)
1520: back = WhitePixel;
1521: else if (back_color && strcmp (back_color, "black") == 0)
1522: back = BlackPixel;
1523: else
1524: {
1525: back_color = "white";
1526: back = WhitePixel;
1527: }
1528:
1529: if (brdr_color && DisplayCells () > 2 &&
1530: XParseColor (brdr_color, &cdef) && XGetHardwareColor (&cdef))
1531: brdr = cdef.pixel;
1532: else if (brdr_color && (!strcmp (brdr_color, "gray") ||
1533: !strcmp (brdr_color, "grey") ||
1534: !strcmp (brdr_color, "Gray") ||
1535: !strcmp (brdr_color, "Grey")))
1536: brdr = BlackPixel;
1537: else if (brdr_color && strcmp (brdr_color, "white") == 0)
1538: brdr = WhitePixel;
1539: else
1540: {
1541: brdr_color = "black";
1542: brdr = BlackPixel;
1543: }
1544:
1545: if (curs_color && DisplayCells () > 2 &&
1546: XParseColor (curs_color, &cdef) && XGetHardwareColor (&cdef))
1547: curs = cdef.pixel;
1548: else if (curs_color && strcmp (curs_color, "black") == 0)
1549: curs = BlackPixel;
1550: else if (curs_color && strcmp (curs_color, "white") == 0)
1551: curs = WhitePixel;
1552: else
1553: {
1554: curs_color = "black";
1555: curs = BlackPixel;
1556: }
1557:
1558: if (mous_color && DisplayCells () > 2 &&
1559: XParseColor (mous_color, &cdef) && XGetHardwareColor (&cdef))
1560: mous = cdef.pixel;
1561: else if (mous_color && strcmp (mous_color, "black") == 0)
1562: mous = BlackPixel;
1563: else if (mous_color && strcmp (mous_color, "white") == 0)
1564: mous = WhitePixel;
1565: else
1566: {
1567: mous_color = "black";
1568: mous = BlackPixel;
1569: }
1570: */
1571:
1572: XXpid = getpid ();
1573: if (XXcurrentfont == (char *) 0)
1574: {
1575: fprintf (stderr, "Memory allocation failure.\n");
1576: exit (-150);
1577: }
1578: default_window = "=80x24+0+0";
1579: /* RMS: XTread_socket does not have an interface suitable
1580: for being a signal handler. In any case, the SIGIO handler is
1581: set up in init_keyboard and X uses the same one as usual. */
1582: /* signal (SIGIO, XTread_socket); */
1583: signal (SIGPIPE, XExitGracefully);
1584: XQueryWindow (RootWindow, &rootwindowinfo);
1585: strncpy (iconidentity, ICONTAG, MAXICID);
1586: fontinfo = XOpenFont (XXcurrentfont);
1587: if (fontinfo == (FontInfo *) 0)
1588: {
1589: fprintf (stderr, "No font\n");
1590: exit (-98);
1591: }
1592: pixelwidth = screen_width * fontinfo->width + 2 * XXInternalBorder;
1593: pixelheight = screen_height * fontinfo->height + 2 * XXInternalBorder;
1594: XXwindow = XCreateWindow (RootWindow,
1595: XXxoffset /* Absolute horizontal offset */,
1596: XXyoffset /* Absolute Vertical offset */,
1597: pixelwidth, pixelheight,
1598: XXborder, BlackPixmap, WhitePixmap);
1599: if (!XXwindow)
1600: {
1601: fprintf (stderr, "Unable to create window.\n");
1602: exit (-97);
1603: }
1604:
1605: XXIconWindow = XCreateWindow (RootWindow, 0, 0, sink_width, sink_height,
1606: 2, WhitePixmap, (Pixmap) NULL);
1607:
1608: if (!XXIconWindow)
1609: {
1610: fprintf (stderr, "Unable to create icon window.\n");
1611: fflush (stderr);
1612: exit (-97);
1613: }
1614: XSelectInput (XXIconWindow, NoEvent);
1615: XXIconMask = XStoreBitmap (sink_mask_width, sink_mask_height, sink_mask_bits);
1616:
1617: XSelectInput (XXwindow, NoEvent);
1618: XSetResizeHint (XXwindow, 2 * XXInternalBorder, 2 * XXInternalBorder,
1619: /* fontinfo->width * 1, fontinfo->height * 1, */
1620: fontinfo->width, fontinfo->height);
1621:
1622: #if defined (BSD) || defined (HPUX) || defined (IBMRTAIX)
1623: if (gethostname (&iconidentity[sizeof (ICONTAG) - 1],
1624: (MAXICID - 1) - sizeof (ICONTAG)))
1625: #endif
1626: {
1627: iconidentity[sizeof (ICONTAG) - 2] = '\0';
1628: }
1629: XStoreName (XXwindow, &iconidentity[0]);
1630:
1631: EmacsCursor = XCreateCursor (16, 16, MouseCursor, MouseMask,
1632: 0, 0, mous, back, GXcopy);
1633: XDefineCursor (XXwindow, EmacsCursor);
1634: flexlines = screen_height;
1635: #if 0
1636: /* Do not call XPopUpWindow here! This is too early.
1637: It is supposed ot be called via the term-setup-hook
1638: and not until after lisp/term/x-win.el has had a chance
1639: to process the user's switches.
1640: I am not sure that there are any circumstances under which
1641: this should be done here -- RMS. */
1642: XPopUpWindow (); /* This looks at Vxterm */
1643: #endif /* 0 */
1644: if (reversevideo) XFlipColor ();
1645: }
1646:
1647: x_init_1 (unrequest)
1648: {
1649: #ifdef F_SETOWN
1650: extern int old_fcntl_owner;
1651: #endif
1652: #ifndef USG
1653: extern void init_sigio (), request_sigio (), unrequest_sigio ();
1654: #endif
1655:
1656: dup2 (dpyno (), 0);
1657: close (dpyno ());
1658: dpyno () = 0; /* Looks a little strange?
1659: check the def of the macro;
1660: it is a genuine lvalue */
1661: #ifndef USG
1662: init_sigio ();
1663: request_sigio ();
1664: #endif /* USG */
1665: #ifdef F_SETOWN
1666: old_fcntl_owner = fcntl (0, F_GETOWN, 0);
1667: #ifdef F_SETOWN_SOCK_NEG
1668: fcntl (0, F_SETOWN, -getpid ()); /* stdin is a socket here */
1669: #else
1670: fcntl (0, F_SETOWN, getpid ());
1671: #endif /* F_SETOWN_SOCK_NEG */
1672: #endif /* F_SETOWN */
1673: #ifndef USG
1674: if (unrequest) unrequest_sigio ();
1675: #endif
1676: }
1677:
1678: /* Process all queued ExposeRegion events. */
1679: static
1680: dumpqueue ()
1681: {
1682: register int i;
1683: XExposeRegionEvent r;
1684: if ((XXqueue.rindex > XXqueue.mindex) ||
1685: (XXqueue.windex > XXqueue.mindex) ||
1686: (XXqueue.rindex < 0) ||
1687: (XXqueue.windex < 0))
1688: {
1689: PendingExposure = 1;
1690: }
1691: else
1692: while (XXqueue.rindex != XXqueue.windex)
1693: {
1694: if (CursorExists)
1695: CursorToggle ();
1696: unloadxrepbuffer (&r, &XXqueue);
1697: dumprectangle (r.y - XXInternalBorder, r.x - XXInternalBorder,
1698: r.height, r.width);
1699: }
1700: }
1701:
1702: XSetFlash ()
1703: {
1704: ring_bell_hook = XTflash;
1705: }
1706:
1707: XSetFeep ()
1708: {
1709: ring_bell_hook = XTfeep;
1710: }
1711:
1712: XNewFont (newname)
1713: register char *newname;
1714: {
1715: FontInfo *temp;
1716: BLOCK_INPUT_DECLARE ()
1717:
1718: BLOCK_INPUT ();
1719: XFlush ();
1720: if (XXdebug)
1721: fprintf (stderr, "Request id is %d\n", XXdisplay->request);
1722: temp = XOpenFont (newname);
1723: if (temp == (FontInfo *) 0)
1724: {
1725: UNBLOCK_INPUT_RESIGNAL ();
1726: return -1;
1727: }
1728: XCloseFont (fontinfo);
1729: fontinfo = temp;
1730: XSetResizeHint (XXwindow, 2*XXInternalBorder, 2*XXInternalBorder,
1731: /* fontinfo->width * 1, fontinfo->height * 1, */
1732: fontinfo->width, fontinfo->height);
1733: XSetWindowSize (screen_height, screen_width);
1734: UNBLOCK_INPUT_RESIGNAL ();
1735: return 0;
1736: }
1737:
1738: XFlipColor ()
1739: {
1740: Pixmap temp;
1741: int tempcolor;
1742: char *tempname;
1743: Cursor temp_curs;
1744: BLOCK_INPUT_DECLARE ()
1745:
1746: BLOCK_INPUT ();
1747: CursorToggle ();
1748: temp = XMakeTile (fore);
1749: XChangeBackground (XXwindow, temp);
1750: XFreePixmap (temp);
1751: temp = XMakeTile (back);
1752: if (XXborder)
1753: XChangeBorder (XXwindow, temp);
1754: XFreePixmap (temp);
1755: brdr = back;
1756: brdr_color = back_color;
1757: tempcolor = fore;
1758: fore = back;
1759: back = tempcolor;
1760: tempname = fore_color ;
1761: fore_color = back_color;
1762: back_color = tempname;
1763: /* XPixFill (XXwindow, 0, 0, screen_width * fontinfo->width,
1764: screen_height * fontinfo->height, back, ClipModeClipped,
1765: GXcopy, AllPlanes);
1766: dumprectangle (0, 0, screen_height * fontinfo->height + 2 * XXInternalBorder,
1767: screen_width * fontinfo -> width + 2 * XXInternalBorder);*/
1768: XRedrawDisplay ();
1769: if (curs == WhitePixel)
1770: {
1771: curs = BlackPixel;
1772: curs_color = "black";
1773: }
1774: else if (curs == BlackPixel)
1775: {
1776: curs = WhitePixel;
1777: curs_color = "white";
1778: }
1779: if (mous == WhitePixel)
1780: {
1781: mous = BlackPixel;
1782: mous_color = "black";
1783: }
1784: else if (mous == BlackPixel)
1785: {
1786: mous = WhitePixel;
1787: mous_color = "white";
1788: }
1789: temp_curs = XCreateCursor (16, 16, MouseCursor, MouseMask, 0, 0,
1790: mous, back, GXcopy);
1791: XUndefineCursor (XXwindow);
1792: XDefineCursor (XXwindow, temp_curs);
1793: XFreeCursor (EmacsCursor);
1794: bcopy (&temp_curs, &EmacsCursor, sizeof (Cursor));
1795: CursorToggle ();
1796: XFlush ();
1797: UNBLOCK_INPUT ();
1798: }
1799:
1800: XSetOffset (xoff, yoff)
1801: register int xoff, yoff;
1802: {
1803: BLOCK_INPUT_DECLARE ()
1804:
1805: BLOCK_INPUT ();
1806: if (xoff < 0)
1807: {
1808: XXxoffset = rootwindowinfo.width + (++xoff) - pixelwidth - 4;
1809: }
1810: else
1811: {
1812: XXxoffset = xoff;
1813: }
1814: if (yoff < 0)
1815: {
1816: XXyoffset
1817: = rootwindowinfo.height + (++yoff) - pixelheight - 4;
1818: }
1819: else
1820: {
1821: XXyoffset = yoff;
1822: }
1823: XMoveWindow (XXwindow, XXxoffset, XXyoffset);
1824: UNBLOCK_INPUT ();
1825: /* XWarpMouse (XXwindow, pixelwidth >> 1, pixelheight >> 1); */
1826: }
1827:
1828: XSetWindowSize (rows, cols)
1829: register int rows, cols;
1830: {
1831: /* if (rows < 3) rows = 24;
1832: if (cols < 1) cols = 80; */
1833: pixelwidth = cols * fontinfo->width + 2 * XXInternalBorder;
1834: pixelheight = rows * fontinfo->height + 2 * XXInternalBorder;
1835: XChangeWindow (XXwindow, pixelwidth, pixelheight);
1836: XFlush ();
1837: change_screen_size (rows, cols, 0, 0, 0);
1838: PendingExposure = 0;
1839: }
1840:
1841: XPopUpWindow ()
1842: {
1843: BLOCK_INPUT_DECLARE ()
1844: if (WindowMapped)
1845: return;
1846: BLOCK_INPUT ();
1847: if (!x_edges_specified)
1848: Fx_rubber_band ();
1849: bitblt = 0;
1850: CursorExists = 0;
1851: VisibleX = 0;
1852: VisibleY = 0;
1853: WindowMapped = 1;
1854: XMapWindow (XXwindow);
1855: dumprectangle (0, 0,
1856: screen_height * fontinfo->height + 2 * XXInternalBorder,
1857: screen_width * fontinfo->width + 2 * XXInternalBorder);
1858: XSelectInput (XXwindow, KeyPressed | ExposeWindow | ButtonPressed
1859: | ButtonReleased
1860: | ExposeRegion | ExposeCopy);
1861: /* XWarpMouse (XXwindow, pixelwidth >> 1, pixelheight >> 1);*/
1862: XTmove_cursor (0, 0);
1863: if (IconWindow)
1864: {
1865: XSetIconWindow (XXwindow,XXIconWindow);
1866: XSelectInput (XXIconWindow, ExposeWindow);
1867: }
1868: else
1869: {
1870: XClearIconWindow (XXwindow);
1871: XSelectInput (XXIconWindow, NoEvent);
1872: }
1873: /* XRedrawDisplay ();*/
1874: XFlush ();
1875: UNBLOCK_INPUT ();
1876: }
1877:
1878: spacecheck (mindex, rindex, windex, minfreespace)
1879: register int mindex, rindex, windex, minfreespace;
1880: {
1881: if ((rindex > mindex) || (windex > mindex))
1882: {
1883: /* fprintf (stderr, "Fatal Mouse Buffer Error.\n");
1884: fprintf (stderr, "%d = mindex, %d = rindex, %d = windex\n",
1885: mindex, rindex, windex); */
1886: return -2;
1887: }
1888: if (windex >= rindex)
1889: {
1890: if ((mindex - (windex - rindex)) > minfreespace)
1891: return 0;
1892: }
1893: else
1894: {
1895: if (((rindex - windex) - 1) > minfreespace)
1896: return 0;
1897: }
1898: return -1;
1899: }
1900:
1901: loadxrepbuffer (p_xrep, p_buffer)
1902: register XEvent *p_xrep;
1903: register XREPBUFFER *p_buffer;
1904: {
1905: p_buffer->xrep[p_buffer->windex] = *p_xrep;
1906: if (p_buffer->windex == p_buffer->mindex)
1907: p_buffer->windex = 0;
1908: else
1909: p_buffer->windex++;
1910: }
1911:
1912: unloadxrepbuffer (p_xrep, p_buffer)
1913: register XEvent *p_xrep;
1914: register XREPBUFFER *p_buffer;
1915: {
1916: if (p_buffer->windex == p_buffer->rindex)
1917: return -1;
1918: *p_xrep = p_buffer->xrep[p_buffer->rindex];
1919: if (p_buffer->rindex == p_buffer->mindex)
1920: p_buffer->rindex = 0;
1921: else
1922: p_buffer->rindex++;
1923: return 0;
1924: }
1925:
1926: fixxrepbuffer ()
1927: {
1928: Xxrepbuffer.mindex = XREPBUFSIZE - 1;
1929: Xxrepbuffer.windex = 0;
1930: Xxrepbuffer.rindex = 0;
1931: }
1932:
1933: #endif /* HAVE_X_WINDOWS */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.