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