|
|
1.1 root 1: /* X Communication module for terminals which understand the X protocol.
2: Copyright (C) 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: /* Redone for X11 by Robert French */
23: /* Thanks to Mark Biggers for all of the Window Manager support */
24:
25: /*
26: * $Source: /mit/emacs/src/RCS/11xterm.c,v $
27: * $Author: rfrench $
28: * $Locker: $
29: * $Header: x11term.c,v 1.12 88/02/29 14:11:07 rfrench Exp $
30: */
31:
32: #ifndef lint
33: static char *rcsid_xterm_c = "$Header: x11term.c,v 1.12 88/02/29 14:11:07 rfrench Exp $";
34: #endif lint
35:
36: /* On 4.3 this loses if it comes after x11term.h.
37: On hp-ux it loses if it comes after config.h. */
38: #include <signal.h>
39: #include <sys/ioctl.h>
40:
41: /* Load sys/types.h if not already loaded.
42: In some systems loading it twice is suicidal. */
43: #ifndef makedev
44: #include <sys/types.h>
45: #endif
46:
47: #include "config.h"
48:
49: #ifdef HAVE_X_WINDOWS
50: /*#define LK201 */ /* DecStation Keyboards (EVM) */
51:
52: #include "lisp.h"
53: #undef NULL
54:
55: /* Allow m- file to inhibit use of interrupt-driven input. */
56: #ifdef BROKEN_FIONREAD
57: #undef FIONREAD
58: #endif
59:
60: /* We are unable to use interrupts if FIONREAD is not available,
61: so flush SIGIO so we won't try. */
62: #ifndef FIONREAD
63: #ifdef SIGIO
64: #undef SIGIO
65: #endif
66: #endif
67:
68: /* This may include sys/types.h, and that somehow loses
69: if this is not done before the other system files.
70: However, perhaps the problem has been avoided by loading types.h above. */
71:
72: #include "x11term.h"
73:
74: #ifdef USG
75: #ifdef IRIS_4D
76: #include <sys/time.h>
77: #else
78: #include <time.h>
79: #endif
80: #else
81: #include <sys/time.h>
82: #endif
83:
84: #ifdef AIX
85: #include <sys/time.h> /* In addition to time.h. */
86: #endif
87:
88: #include <fcntl.h>
89: #include <stdio.h>
90: #include <ctype.h>
91: #include <errno.h>
92: #ifdef BSD
93: #include <strings.h>
94: #endif
95: #include <sys/stat.h>
96:
97: #include "dispextern.h"
98: #include "termhooks.h"
99: #include "termopts.h"
100: #include "termchar.h"
101:
102: #include "sink11.h"
103: #include "sink11mask.h"
104:
105: #define min(a,b) ((a)<(b) ? (a) : (b))
106: #define max(a,b) ((a)>(b) ? (a) : (b))
107:
108: extern int errno;
109:
110: #define sigunblockx(sig) sigblock (0)
111: #define sigblockx(sig) sigblock (1 << ((sig) - 1))
112:
113: #define METABIT 0200
114: #define MINWIDTH 12 /* In pixels */
115: #define MINHEIGHT 5 /* In pixels */
116: #define MAXHEIGHT 300 /* In lines */
117:
118: int pixelwidth,pixelheight;
119: char *progname;
120:
121: XEvent *XXm_queue[XMOUSEBUFSIZE];
122: int XXm_queue_num, XXm_queue_in, XXm_queue_out;
123:
124: char *XXcurrentfont;
125: XFontStruct *fontinfo;
126: Font XXfid;
127: int XXfontw, XXfonth, XXbase, XXisColor;
128:
129: Colormap XXColorMap;
130: char *default_window;
131: int configure_pending;
132: extern struct display_line *DesiredScreen[], *PhysScreen[];
133: extern int initialized;
134: extern int screen_width, screen_height;
135:
136: /* Function for init_keyboard to call with no args (if nonzero). */
137: extern void (*keyboard_init_hook) ();
138:
139: extern char *alternate_display;
140: extern int xargc;
141: extern char **xargv;
142:
143: int XXdebug;
144: int XXpid;
145:
146: int WindowMapped;
147:
148: char *XXidentity; /* Resource name of this invocation of Emacs */
149: static char *XXicon_name; /* user-supplied icon info */
150: static int XXicon_usebitmap; /* Use bitmap or not */
151: static char *XXheader; /* user-supplied window header info */
152:
153: static int flexlines; /* last line affected by dellines or
154: * inslines functions */
155: int VisibleX, VisibleY; /* genuine location of cursor on screen
156: * if it is there */
157:
158: static int SavedX, SavedY; /* Where the cursor was before update
159: * started */
160:
161:
162: int CursorExists; /* during updates cursor is turned off */
163: int CursorOutline; /* when the pointer is not in the Emacs
164: * widow the cursor should be drawn in
165: * outline form a la xterm */
166: static int InUpdate; /* many of functions here may be invoked
167: * even if no update in progress; when
168: * no update is in progress the action
169: * can be slightly different */
170:
171: Display *XXdisplay;
172: int XXscreen;
173: Window XXwindow;
174: GC XXgc_norm,XXgc_rev,XXgc_curs,XXgc_temp;
175: XGCValues XXgcv;
176: Cursor EmacsCursor;
177: Pixmap SinkPixmap, SinkMaskPixmap;
178:
179: char *fore_color; /* Variables to store color names */
180: char *back_color;
181: char *brdr_color;
182: char *curs_color;
183: char *mous_color;
184:
185: unsigned long fore; /* Variables to store pixel values */
186: unsigned long back;
187: unsigned long brdr;
188: unsigned long curs;
189:
190: char *desiredwindow;
191:
192: int CurHL; /* Current Highlighting (ala mode line) */
193:
194: int XXborder; /* Window border width */
195: int XXInternalBorder; /* Internal border width */
196: int updated[MAXHEIGHT];
197:
198: static char *temp_font; /* needed because of loading hacks */
199: static char *temp_reverseVideo;
200: static char *temp_borderWidth;
201: static char *temp_internalBorder;
202:
203: struct _xdeftab
204: {
205: char *iname; /* instance name */
206: char *cname; /* class name (fake it) */
207: char **varp; /* variable to set */
208: };
209:
210: static struct _xdeftab xDefaultsValueTable[]
211: = {
212: { "reverseVideo", "ReverseVideo", &temp_reverseVideo },
213: { "borderWidth", "BorderWidth", &temp_borderWidth },
214: { "internalBorder","BorderWidth", &temp_internalBorder },
215: { "borderColor", "BorderColor", &brdr_color },
216: { "background", "Background", &back_color },
217: { "foreground", "Foreground", &fore_color },
218: { "pointerColor", "Foreground", &mous_color },
219: { "cursorColor", "Foreground", &curs_color },
220: { "font", "Font", &temp_font },
221: { "geometry", "Geometry", &desiredwindow },
222: { "title", "Title", &XXheader },
223: { "iconName", "Title", &XXicon_name },
224: { NULL, NULL, NULL }
225: };
226:
227:
228: int (*handler)();
229:
230: static void x_init_1 ();
231:
232: char *rindex();
233:
234: /* HLmode -- Changes the GX function for output strings. Could be used to
235: * change font. Check an XText library function call.
236: */
237:
238: HLmode (new)
239: int new;
240: {
241: extern Lisp_Object inverse_video;
242:
243: CurHL = new;
244: }
245:
246: /* External interface to control of standout mode.
247: Call this when about to modify line at position VPOS
248: and not change whether it is highlighted. */
249:
250: XTreassert_line_highlight (highlight, vpos)
251: int highlight, vpos;
252: {
253: HLmode (highlight);
254: }
255:
256: /* Call this when about to modify line at position VPOS
257: and change whether it is highlighted. */
258:
259: XTchange_line_highlight (new_highlight, vpos, first_unused_hpos)
260: int new_highlight, vpos, first_unused_hpos;
261: {
262: HLmode (new_highlight);
263: XTtopos (vpos, 0);
264: x_clear_end_of_line (0);
265: }
266:
267:
268: /* Used for starting or restarting (after suspension) the X window. Puts the
269: * cursor in a known place, update does not begin with this routine but only
270: * with a call to DoDsp.
271: */
272:
273: XTset_terminal_modes ()
274: {
275: int stuffpending;
276: #ifdef XDEBUG
277: fprintf (stderr, "XTset_terminal_modes\n");
278: #endif
279:
280: InUpdate = 0;
281: stuffpending = 0;
282: if (!initialized) {
283: CursorExists = 0;
284: CursorOutline = 1;
285: VisibleX = 0;
286: VisibleY = 0;
287: }
288: XTclear_screen ();
289: }
290:
291: /* XTtopos moves the cursor to the correct location and checks whether an
292: * update is in progress in order to toggle it on.
293: */
294:
295: XTtopos (row, col)
296: register int row, col;
297: {
298: BLOCK_INPUT_DECLARE ();
299: #ifdef XDEBUG
300: fprintf (stderr, "XTtopos (X %d, Y %d)\n",col,row);
301: #endif
302:
303: BLOCK_INPUT ();
304: cursX = col;
305: cursY = row;
306:
307: if (InUpdate) {
308: if (CursorExists)
309: CursorToggle ();
310: UNBLOCK_INPUT ();
311: return;
312: /* Generally, XTtopos will be invoked */
313: /* when InUpdate with !CursorExists */
314: /* so that wasteful XFlush is not called */
315: }
316: if ((row == VisibleY) && (col == VisibleX)) {
317: if (!CursorExists)
318: CursorToggle ();
319: XFlush (XXdisplay);
320: UNBLOCK_INPUT ();
321: return;
322: }
323: if (CursorExists)
324: CursorToggle ();
325: VisibleX = col;
326: VisibleY = row;
327: if (!CursorExists)
328: CursorToggle ();
329: XFlush (XXdisplay);
330: UNBLOCK_INPUT ();
331: }
332:
333: /* Used to get the terminal back to a known state after resets. Usually
334: * used when restarting suspended or waiting emacs
335: */
336:
337: cleanup ()
338: {
339: inverse_video = 0;
340: HLmode (0);
341: }
342:
343: /* Erase current line from current column to column END.
344: Leave cursor at END. */
345:
346: XTclear_end_of_line (end)
347: register int end;
348: {
349: register int numcols;
350: BLOCK_INPUT_DECLARE ();
351:
352: #ifdef XDEBUG
353: fprintf (stderr, "XTclear_end_of_line (to %d)\n",end);
354: #endif
355:
356: if (cursY < 0 || cursY >= screen_height)
357: return;
358:
359: if (end <= cursX)
360: return;
361: if (end >= screen_width)
362: end = screen_width;
363:
364: numcols = end - cursX;
365: BLOCK_INPUT ();
366: if (cursY == VisibleY && VisibleX >= cursX && VisibleX < end)
367: if (CursorExists) CursorToggle ();
368: if (CurHL)
369: XFillRectangle (XXdisplay, XXwindow, XXgc_norm,
370: cursX*XXfontw+XXInternalBorder,
371: cursY*XXfonth+XXInternalBorder,
372: XXfontw*numcols,
373: XXfonth);
374: else
375: XClearArea (XXdisplay, XXwindow,
376: cursX*XXfontw+XXInternalBorder,
377: cursY*XXfonth+XXInternalBorder,
378: XXfontw*numcols,
379: XXfonth,
380: 0);
381: XTtopos (cursY, end);
382: UNBLOCK_INPUT ();
383: }
384:
385: /* Erase current line from column START to right margin.
386: Leave cursor at START. */
387:
388: x_clear_end_of_line (start)
389: register int start;
390: {
391: register int numcols;
392: BLOCK_INPUT_DECLARE ();
393:
394: #ifdef XDEBUG
395: fprintf (stderr, "x_clear_end_of_line (start %d)\n",first_blank);
396: #endif
397:
398: if (cursY < 0 || cursY >= screen_height)
399: return;
400:
401: if (start >= screen_width)
402: return;
403: if (start < 0)
404: start = 0;
405:
406: numcols = screen_width - start;
407: BLOCK_INPUT ();
408: if (cursY == VisibleY && VisibleX >= start)
409: if (CursorExists) CursorToggle ();
410: if (CurHL)
411: XFillRectangle (XXdisplay, XXwindow, XXgc_norm,
412: start*XXfontw+XXInternalBorder,
413: cursY*XXfonth+XXInternalBorder,
414: XXfontw*numcols,
415: XXfonth);
416: else
417: XClearArea (XXdisplay, XXwindow,
418: start*XXfontw+XXInternalBorder,
419: cursY*XXfonth+XXInternalBorder,
420: XXfontw*numcols,
421: XXfonth,
422: 0);
423: XTtopos (cursY, start);
424: UNBLOCK_INPUT ();
425: }
426:
427: XTreset_terminal_modes ()
428: {
429: #ifdef XDEBUG
430: fprintf (stderr, "XTreset_terminal_modes\n");
431: #endif
432:
433: XTclear_screen ();
434: }
435:
436: XTclear_screen ()
437: {
438: BLOCK_INPUT_DECLARE ();
439:
440: #ifdef XDEBUG
441: fprintf (stderr, "XTclear_screen\n");
442: #endif
443:
444: BLOCK_INPUT ();
445: HLmode (0);
446: CursorExists = 0;
447:
448: cursX = 0;
449: cursY = 0;
450: SavedX = 0;
451: SavedY = 0;
452: VisibleX = 0;
453: VisibleY = 0;
454: XClearWindow(XXdisplay, XXwindow);
455: CursorToggle ();
456: if (!InUpdate)
457: XFlush (XXdisplay);
458: UNBLOCK_INPUT ();
459: }
460:
461: /* used by dumprectangle which is usually invoked upon Expose
462: * events which come from bit blt's or moving an obscuring opaque window
463: */
464:
465: dumpchars (ActiveScreen, numcols, tempX, tempY, tempHL)
466: register struct display_line **ActiveScreen;
467: register int numcols;
468: register int tempX, tempY, tempHL;
469: {
470: if (numcols <= 0)
471: return;
472:
473: if (numcols-1+tempX > screen_width)
474: numcols = screen_width-tempX+1;
475:
476: if (tempX < 0 || tempX >= screen_width ||
477: tempY < 0 || tempY >= screen_height)
478: return;
479:
480: XDrawImageString(XXdisplay, XXwindow, tempHL ? XXgc_rev : XXgc_norm,
481: tempX*XXfontw+XXInternalBorder,
482: tempY*XXfonth+XXInternalBorder+XXbase,
483: &ActiveScreen[tempY+1]->body[tempX],
484: numcols);
485: }
486:
487: /* When a line has been changed this function is called. Due to various
488: * bits of braindamage on the parts of both X11 and Emacs, the new
489: * version of the line is simply output if this function is invoked while
490: * in UpDate. Sometimes writechars can be invoked when not in update if
491: * text is to be output at the end of the line. In this case the whole
492: * line is not output. Simply the new text at the current cursor
493: * position given by VisibleX,Y. The cursor is moved to the end of the
494: * new text.
495: */
496:
497: updateline (first)
498: int first;
499: {
500: register int temp_length;
501: BLOCK_INPUT_DECLARE ();
502:
503: #ifdef XDEBUG
504: fprintf(stderr, "updateline\n");
505: #endif XDEBUG
506:
507: BLOCK_INPUT ();
508: if ((cursY < 0) || (cursY >= screen_height)
509: || updated[cursY]) {
510: UNBLOCK_INPUT ();
511: return;
512: }
513: if (!first)
514: updated[cursY] = 1;
515: if (CursorExists)
516: CursorToggle ();
517: if (DesiredScreen && DesiredScreen[cursY + 1])
518: temp_length = DesiredScreen[cursY + 1]->length-first;
519: else
520: temp_length = 0;
521: if (temp_length > 0) {
522: XDrawImageString (XXdisplay, XXwindow,
523: CurHL ? XXgc_rev : XXgc_norm,
524: first*XXfontw+XXInternalBorder,
525: cursY*XXfonth+XXInternalBorder+XXbase,
526: &DesiredScreen[cursY + 1]->body[first],
527: temp_length);
528: if (temp_length < screen_width)
529: x_clear_end_of_line (temp_length);
530: XTtopos (cursY, temp_length);
531: }
532: else {
533: x_clear_end_of_line (0);
534: XTtopos (cursY, 0);
535: }
536: UNBLOCK_INPUT ();
537: }
538:
539: writechars (start, end)
540: register char *start, *end;
541: {
542: BLOCK_INPUT_DECLARE ();
543:
544: #ifdef XDEBUG
545: fprintf(stderr, "writechars (cursX %d temp_len %d InUpd %d)\n",
546: cursX, end-start+1, InUpdate);
547: #endif XDEBUG
548:
549: BLOCK_INPUT ();
550:
551: if ((cursY < 0) || (cursY >= screen_height))
552: {
553: UNBLOCK_INPUT ();
554: return;
555: }
556:
557: if (CursorExists)
558: CursorToggle ();
559:
560:
561: if (InUpdate)
562: {
563: XDrawImageString (XXdisplay, XXwindow,
564: CurHL ? XXgc_rev : XXgc_norm,
565: cursX*XXfontw+XXInternalBorder,
566: cursY*XXfonth+XXInternalBorder+XXbase,
567: start,
568: (end - start) + 1);
569: XTtopos (cursY, (end - start) + 1);
570:
571: UNBLOCK_INPUT ();
572: return;
573: }
574:
575: if ((VisibleX < 0) || (VisibleX >= screen_width)) {
576: UNBLOCK_INPUT ();
577: return;
578: }
579: if ((VisibleY < 0) || (VisibleY >= screen_height)) {
580: UNBLOCK_INPUT ();
581: return;
582: }
583: if (((end - start) + VisibleX) >= screen_width)
584: end = start + (screen_width - (VisibleX + 1));
585: if (end >= start) {
586: XDrawImageString (XXdisplay, XXwindow,
587: CurHL ? XXgc_rev : XXgc_norm,
588: (VisibleX * XXfontw+XXInternalBorder),
589: VisibleY * XXfonth+XXInternalBorder+XXbase,
590: start,
591: ((end - start) + 1));
592: VisibleX = VisibleX + (end - start) + 1;
593: }
594: if (!CursorExists)
595: CursorToggle ();
596: UNBLOCK_INPUT ();
597: }
598:
599: static
600: XTwrite_chars (start, len)
601: register char *start;
602: register int len;
603: {
604: #ifdef XDEBUG
605: fprintf (stderr, "XTwrite_chars (len %d)\n",len);
606: #endif
607:
608: writechars (start, start+len-1);
609: }
610:
611: XTflash ()
612: {
613: XGCValues gcv_temp;
614: struct timeval to;
615: BLOCK_INPUT_DECLARE ();
616:
617: #ifdef XDEBUG
618: fprintf (stderr, "XTflash\n");
619: #endif
620:
621: BLOCK_INPUT ();
622: XXgc_temp = XCreateGC(XXdisplay, XXwindow, 0, &gcv_temp);
623: XSetState(XXdisplay, XXgc_temp, WhitePixel (XXdisplay, XXscreen),
624: BlackPixel(XXdisplay, XXscreen), GXinvert,
625: AllPlanes);
626:
627: XFillRectangle (XXdisplay, XXwindow, XXgc_temp, 0, 0,
628: screen_width*XXfontw+2*XXInternalBorder,
629: screen_height*XXfonth+2*XXInternalBorder);
630: XFlush (XXdisplay);
631:
632: UNBLOCK_INPUT ();
633:
634: to.tv_sec = 0;
635: to.tv_usec = 250000;
636:
637: select(0, 0, 0, 0, &to);
638:
639: BLOCK_INPUT ();
640:
641: XFillRectangle (XXdisplay, XXwindow, XXgc_temp, 0, 0,
642: screen_width*XXfontw+2*XXInternalBorder,
643: screen_height*XXfonth+2*XXInternalBorder);
644:
645: XFreeGC(XXdisplay, XXgc_temp);
646: XFlush (XXdisplay);
647:
648: UNBLOCK_INPUT ();
649: }
650:
651: XTfeep ()
652: {
653: BLOCK_INPUT_DECLARE ();
654: #ifdef XDEBUG
655: fprintf (stderr, "XTfeep\n");
656: #endif
657: BLOCK_INPUT ();
658: XBell (XXdisplay,50);
659: UNBLOCK_INPUT ();
660: }
661:
662: /* Artificially creating a cursor is hard, the actual position on the
663: * screen (either where it is or last was) is tracked with VisibleX,Y.
664: * Gnu Emacs code tends to assume a cursor exists in hardward at cursX,Y
665: * and that output text will appear there. During updates, the cursor is
666: * supposed to be blinked out and will only reappear after the update
667: * finishes.
668: */
669:
670: CursorToggle ()
671: {
672: register struct display_line **ActiveScreen;
673:
674: if (!WindowMapped) {
675: CursorExists = 0;
676: CursorOutline = 1;
677: return 0;
678: /* Currently the return values are not */
679: /* used, but I could anticipate using */
680: /* them in the future. */
681: }
682:
683: if (VisibleX < 0 || VisibleX >= screen_width ||
684: VisibleY < 0 || VisibleY >= screen_height) {
685: /* Not much can be done */
686: XFlush (XXdisplay);
687: CursorExists = 0;
688: return 0;
689: }
690:
691: ActiveScreen = PhysScreen;
692:
693: if (ActiveScreen && ActiveScreen[VisibleY+1] &&
694: VisibleX < ActiveScreen[VisibleY+1]->length) {
695: if (CursorExists)
696: XDrawImageString(XXdisplay, XXwindow, XXgc_norm,
697: VisibleX*XXfontw+XXInternalBorder,
698: VisibleY*XXfonth+XXInternalBorder+XXbase,
699: &ActiveScreen[VisibleY+1]->body[VisibleX],
700: 1);
701: else if (CursorOutline) {
702: XDrawImageString(XXdisplay, XXwindow, XXgc_norm,
703: VisibleX*XXfontw+XXInternalBorder,
704: VisibleY*XXfonth+XXInternalBorder+XXbase,
705: &ActiveScreen[VisibleY+1]->body[VisibleX],
706: 1);
707: XDrawRectangle (XXdisplay, XXwindow, XXgc_norm,
708: VisibleX*XXfontw+XXInternalBorder,
709: VisibleY*XXfonth+XXInternalBorder,
710: XXfontw - 1, XXfonth - 1);
711: } else
712: XDrawImageString(XXdisplay, XXwindow, XXgc_curs,
713: VisibleX*XXfontw+XXInternalBorder,
714: VisibleY*XXfonth+XXInternalBorder+XXbase,
715: &ActiveScreen[VisibleY+1]->body[VisibleX],
716: 1);
717: }
718: else {
719: if (CursorExists)
720: XClearArea (XXdisplay, XXwindow,
721: VisibleX*XXfontw+XXInternalBorder,
722: VisibleY*XXfonth+XXInternalBorder,
723: XXfontw, XXfonth, 0);
724: else if (CursorOutline)
725: XDrawRectangle (XXdisplay, XXwindow, XXgc_norm,
726: VisibleX*XXfontw+XXInternalBorder,
727: VisibleY*XXfonth+XXInternalBorder,
728: XXfontw - 1, XXfonth - 1);
729: else
730: XDrawImageString(XXdisplay, XXwindow, XXgc_curs,
731: VisibleX*XXfontw+XXInternalBorder,
732: VisibleY*XXfonth+XXInternalBorder+XXbase,
733: " ", 1);
734: }
735:
736: CursorExists = !CursorExists;
737:
738: if (!InUpdate)
739: XFlush (XXdisplay);
740:
741: return 1;
742: }
743:
744: /* This routine is used by routines which are called to paint regions */
745: /* designated by Expose events. If the cursor may be in the exposed */
746: /* region, this routine makes sure it is gone so that dumprectangle can */
747: /* toggle it back into existance if dumprectangle is invoked when not in */
748: /* the midst of a screen update. */
749:
750: static
751: ClearCursor ()
752: {
753: BLOCK_INPUT_DECLARE ();
754:
755: BLOCK_INPUT ();
756: if (!WindowMapped) {
757: CursorExists = 0;
758: CursorOutline = 1;
759: UNBLOCK_INPUT ();
760: return;
761: }
762:
763: if (VisibleX < 0 || VisibleX >= screen_width ||
764: VisibleY < 0 || VisibleY >= screen_height) {
765: /* Not much can be done */
766: CursorExists = 0;
767: UNBLOCK_INPUT ();
768: return;
769: }
770:
771: XClearArea (XXdisplay, XXwindow,
772: VisibleX*XXfontw+XXInternalBorder,
773: VisibleY*XXfonth+XXInternalBorder,
774: XXfontw, XXfonth, 0);
775:
776: CursorExists = 0;
777: UNBLOCK_INPUT ();
778: }
779:
780: XTupdate_begin ()
781: {
782: BLOCK_INPUT_DECLARE ();
783: register int i;
784:
785: #ifdef XDEBUG
786: fprintf (stderr, "XTupdate_begin\n");
787: #endif
788:
789: BLOCK_INPUT ();
790: InUpdate = 1;
791: if (CursorExists)
792: CursorToggle ();
793:
794: for (i=0;i<MAXHEIGHT;i++)
795: updated[i] = 0;
796:
797: SavedX = cursX;
798: SavedY = cursY;
799: /* Thw initial "hardware" cursor position is */
800: /* saved because that is where gnu emacs */
801: /* expects the cursor to be at the end of */
802: /* the update */
803:
804: UNBLOCK_INPUT ();
805: }
806:
807: XTupdate_end ()
808: {
809: BLOCK_INPUT_DECLARE ();
810:
811: #ifdef XDEBUG
812: fprintf (stderr, "XTupdate_end\n");
813: #endif
814:
815: BLOCK_INPUT ();
816: if (CursorExists)
817: CursorToggle ();
818:
819: InUpdate = 0;
820: XTtopos (SavedY, SavedX); /* XTtopos invokes cursor toggle */
821: XFlush (XXdisplay);
822: UNBLOCK_INPUT ();
823: }
824:
825: /* Used for Expose events. Have to get the text
826: * back into the newly blank areas.
827: */
828:
829: dumprectangle (top, left, rows, cols)
830: register int top, left, rows, cols;
831: {
832: register struct display_line **ActiveScreen;
833: register int ourindex;
834: int localX, localY, localHL;
835:
836: if (top < 0)
837: top = 0;
838: if (left < 0)
839: left = 0;
840: rows += top;
841: cols += left;
842: top /= XXfonth;
843: /* Get row and col containing up and */
844: /* left borders of exposed region -- */
845: /* round down here*/
846: left /= XXfontw;
847: rows += XXfonth-1;
848: cols += XXfontw-1;
849: rows /= XXfonth;
850: /* Get row and col containing bottom and */
851: /* right borders -- round up here */
852: rows -= top;
853: cols /= XXfontw;
854: cols -= left;
855:
856: if (rows < 0)
857: return;
858: if (cols < 0)
859: return;
860: if (top > screen_height - 1)
861: return;
862: if (left > screen_width - 1)
863: return;
864: if (VisibleX >= left && VisibleX < left + cols &&
865: VisibleY >= top && VisibleY < top + rows)
866: ClearCursor ();
867:
868: if (InUpdate && DesiredScreen)
869: ActiveScreen = DesiredScreen;
870: else
871: if (PhysScreen)
872: /* When queue is dumped in update this */
873: ActiveScreen = PhysScreen;
874: else
875: return;
876:
877: /* should perhaps be DesiredScreen */
878: /* but PhysScreen is guaranteed to contain */
879: /* data which was good for every line on */
880: /* screen. For desired screen only for */
881: /* lines which are changing. Emacs does */
882: /* not consider a line within a newly */
883: /* exposed region necessarily to have */
884: /* been changed. Emacs knows nothing */
885: /* about Expose events. */
886:
887: for (localY = top, ourindex = 0;
888: ourindex < rows && localY < screen_height;
889: ++ourindex, ++localY) {
890: if (localY < 0 || localY >= screen_height ||
891: !ActiveScreen[localY+1] ||
892: left+1 > ActiveScreen[localY+1]->length)
893: continue;
894: localX = left;
895: localHL = ActiveScreen[localY+1]->highlighted;
896: dumpchars (ActiveScreen,
897: min (cols,
898: ActiveScreen[localY+1]->length-localX),
899: localX, localY, localHL);
900: }
901: if (!InUpdate && !CursorExists)
902: CursorToggle ();
903: /* Routine usually called */
904: /* when not in update */
905: }
906:
907: /* What sections of the window will be modified from the UpdateDisplay
908: * routine is totally under software control. Any line with Y coordinate
909: * greater than flexlines will not change during an update. This is really
910: * used only during dellines and inslines routines (scraplines and stufflines)
911: */
912:
913: XTset_terminal_window (n)
914: register int n;
915: {
916: #ifdef XDEBUG
917: fprintf (stderr, "XTset_terminal_window\n");
918: #endif
919:
920: if (n <= 0 || n > screen_height)
921: flexlines = screen_height;
922: else
923: flexlines = n;
924: }
925:
926: XTins_del_lines (vpos, n)
927: int vpos, n;
928: {
929: #ifdef XDEBUG
930: fprintf (stderr, "XTins_del_lines\n");
931: #endif
932:
933: XTtopos (vpos, 0);
934: if (n >= 0)
935: stufflines (n);
936: else
937: scraplines (-n);
938: }
939:
940: static
941: XTinsert_chars (start, len)
942: register char *start;
943: register int len;
944: {
945: #ifdef XDEBUG
946: fprintf (stderr, "XTinsert_chars\n");
947: #endif
948:
949: updateline (0);
950: }
951:
952: static
953: XTdelete_chars (n)
954: register int n;
955: {
956: char *msg = "Major foobars! This shouldn't show up!";
957:
958: #ifdef XDEBUG
959: fprintf (stderr, "XTdelete_chars (num %d cursX %d)\n",n,cursX);
960: #endif
961:
962: updateline (0);
963: }
964:
965: stufflines (n)
966: register int n;
967: {
968: register int topregion, bottomregion;
969: register int length, newtop;
970: BLOCK_INPUT_DECLARE ();
971:
972: if (cursY >= flexlines)
973: return;
974:
975: BLOCK_INPUT ();
976:
977: if (CursorExists)
978: CursorToggle ();
979:
980: topregion = cursY;
981: bottomregion = flexlines-(n+1);
982: newtop = cursY+n;
983: length = bottomregion-topregion+1;
984:
985: if (length > 0 && newtop <= flexlines) {
986: XCopyArea (XXdisplay, XXwindow, XXwindow, XXgc_norm,
987: XXInternalBorder,
988: topregion*XXfonth+XXInternalBorder,
989: screen_width*XXfontw,
990: length*XXfonth,
991: XXInternalBorder, newtop*XXfonth+XXInternalBorder);
992: }
993:
994: newtop = min (newtop, flexlines-1);
995: length = newtop-topregion;
996: if (length > 0)
997: XClearArea (XXdisplay, XXwindow,
998: XXInternalBorder,
999: topregion*XXfonth+XXInternalBorder,
1000: screen_width*XXfontw,
1001: n*XXfonth, 0);
1002: UNBLOCK_INPUT ();
1003: }
1004:
1005: scraplines (n)
1006: register int n;
1007: {
1008: BLOCK_INPUT_DECLARE ();
1009:
1010: if (cursY >= flexlines)
1011: return;
1012:
1013: BLOCK_INPUT ();
1014:
1015: if (CursorExists)
1016: CursorToggle ();
1017:
1018: if (cursY+n >= flexlines) {
1019: if (flexlines >= (cursY + 1))
1020: XClearArea (XXdisplay, XXwindow,
1021: XXInternalBorder,
1022: cursY*XXfonth+XXInternalBorder,
1023: screen_width*XXfontw,
1024: (flexlines-cursY) * XXfonth,
1025: 0);
1026: UNBLOCK_INPUT ();
1027: }
1028: else {
1029: XCopyArea (XXdisplay, XXwindow, XXwindow, XXgc_norm,
1030: XXInternalBorder,
1031: (cursY+n)*XXfonth+XXInternalBorder,
1032: screen_width*XXfontw,
1033: (flexlines-cursY-n)*XXfonth,
1034: XXInternalBorder, cursY*XXfonth+XXInternalBorder);
1035:
1036: XClearArea (XXdisplay, XXwindow, XXInternalBorder,
1037: (flexlines-n)*XXfonth+XXInternalBorder,
1038: screen_width*XXfontw,
1039: n*XXfonth, 0);
1040: UNBLOCK_INPUT ();
1041: }
1042: }
1043:
1044: /* Substitutes for standard read routine. Under X not interested in individual
1045: * bytes but rather individual packets.
1046: */
1047:
1048: XTread_socket (sd, bufp, numchars)
1049: register int sd;
1050: register char *bufp;
1051: register int numchars;
1052: {
1053: #ifdef XDEBUG
1054: fprintf(stderr,"XTread_socket\n");
1055: #endif
1056:
1057: return (internal_socket_read (bufp, numchars));
1058: }
1059:
1060: /*
1061: * Interpreting incoming keycodes. Should have table modifiable as needed
1062: * from elisp.
1063: */
1064:
1065: #ifdef sun
1066: char *stringFuncVal(keycode)
1067: KeySym keycode;
1068: {
1069: switch (keycode) {
1070: case XK_L1:
1071: return("192");
1072: case XK_L2:
1073: return("193");
1074: case XK_L3:
1075: return("194");
1076: case XK_L4:
1077: return("195");
1078: case XK_L5:
1079: return("196");
1080: case XK_L6:
1081: return("197");
1082: case XK_L7:
1083: return("198");
1084: case XK_L8:
1085: return("199");
1086: case XK_L9:
1087: return("200");
1088: case XK_L10:
1089: return("201");
1090:
1091: case XK_R1:
1092: return("208");
1093: case XK_R2:
1094: return("209");
1095: case XK_R3:
1096: return("210");
1097: case XK_R4:
1098: return("211");
1099: case XK_R5:
1100: return("212");
1101: case XK_R6:
1102: return("213");
1103: case XK_R7:
1104: return("214");
1105: case XK_R8:
1106: return("215");
1107: case XK_R9:
1108: return("216");
1109: case XK_R10:
1110: return("217");
1111: case XK_R11:
1112: return("218");
1113: case XK_R12:
1114: return("219");
1115: case XK_R13:
1116: return("220");
1117: case XK_R14:
1118: return("221");
1119: case XK_R15:
1120: return("222");
1121:
1122: case XK_Break: /* Sun3 "Alternate" key */
1123: return("223");
1124:
1125: case XK_F1:
1126: return("224");
1127: case XK_F2:
1128: return("225");
1129: case XK_F3:
1130: return("226");
1131: case XK_F4:
1132: return("227");
1133: case XK_F5:
1134: return("228");
1135: case XK_F6:
1136: return("229");
1137: case XK_F7:
1138: return("230");
1139: case XK_F8:
1140: return("231");
1141: case XK_F9:
1142: return("232");
1143:
1144: default:
1145: return("-1");
1146: }
1147: }
1148: #else
1149: char *stringFuncVal(keycode)
1150: KeySym keycode;
1151: {
1152: switch (keycode) {
1153: case XK_F1:
1154: return("11");
1155: case XK_F2:
1156: return("12");
1157: case XK_F3:
1158: return("13");
1159: case XK_F4:
1160: return("14");
1161: case XK_F5:
1162: return("15");
1163: case XK_F6:
1164: return("17");
1165: case XK_F7:
1166: return("18");
1167: case XK_F8:
1168: return("19");
1169: case XK_F9:
1170: return("20");
1171: case XK_F10:
1172: return("21");
1173: case XK_F11:
1174: return("23");
1175: case XK_F12:
1176: return("24");
1177: case XK_F13:
1178: return("25");
1179: case XK_F14:
1180: return("26");
1181: case XK_F15:
1182: return("28");
1183: case XK_Help:
1184: return("28");
1185: case XK_F16:
1186: return("29");
1187: case XK_Menu:
1188: return("29");
1189: case XK_F17:
1190: return("31");
1191: case XK_F18:
1192: return("32");
1193: case XK_F19:
1194: return("33");
1195: case XK_F20:
1196: return("34");
1197:
1198: case XK_Find :
1199: return("1");
1200: case XK_Insert:
1201: return("2");
1202: case XK_Delete:
1203: return("3");
1204: case XK_Select:
1205: return("4");
1206: case XK_Prior:
1207: return("5");
1208: case XK_Next:
1209: return("6");
1210: default:
1211: return("-1");
1212: }
1213: }
1214:
1215: #ifdef LK201
1216: char *stringFuncVal_Shifted(keycode) /* LK201 Function keys - shifted */
1217: KeySym keycode;
1218: {
1219: switch (keycode) {
1220: case XK_F1:
1221: return("41");
1222: case XK_F2:
1223: return("42");
1224: case XK_F3:
1225: return("43");
1226: case XK_F4:
1227: return("44");
1228: case XK_F5:
1229: return("45");
1230: case XK_F6:
1231: return("47");
1232: case XK_F7:
1233: return("48");
1234: case XK_F8:
1235: return("49");
1236: case XK_F9:
1237: return("50");
1238: case XK_F10:
1239: return("51");
1240: case XK_F11:
1241: return("53");
1242: case XK_F12:
1243: return("54");
1244: case XK_F13:
1245: return("55");
1246: case XK_F14:
1247: return("56");
1248: case XK_F15:
1249: return("58");
1250: case XK_Help:
1251: return("58");
1252: case XK_F16:
1253: return("59");
1254: case XK_Menu:
1255: return("59");
1256: case XK_F17:
1257: return("61");
1258: case XK_F18:
1259: return("62");
1260: case XK_F19:
1261: return("63");
1262: case XK_F20:
1263: return("64");
1264: default:
1265: return("-1");
1266: }
1267: }
1268:
1269: char *stringFuncVal_KP(keycode) /* LK201 keypad keys */
1270: KeySym keycode;
1271: {
1272: switch (keycode) {
1273: case XK_KP_F1:
1274: return("\033OP");
1275: case XK_KP_F2:
1276: return("\033OQ");
1277: case XK_KP_F3:
1278: return("\033OR");
1279: case XK_KP_F4:
1280: return("\033OS");
1281:
1282: case XK_KP_Subtract: /* Minus */
1283: return("\033Om");
1284: case XK_KP_Separator: /* Comma */
1285: return("\033Ol");
1286: case XK_KP_Decimal: /* Period */
1287: return("\033On");
1288: case XK_KP_Enter:
1289: return("\033OM");
1290:
1291: case XK_KP_0:
1292: return("\033Op");
1293: case XK_KP_1:
1294: return("\033Oq");
1295: case XK_KP_2:
1296: return("\033Or");
1297: case XK_KP_3:
1298: return("\033Os");
1299: case XK_KP_4:
1300: return("\033Ot");
1301: case XK_KP_5:
1302: return("\033Ou");
1303: case XK_KP_6:
1304: return("\033Ov");
1305: case XK_KP_7:
1306: return("\033Ow");
1307: case XK_KP_8:
1308: return("\033Ox");
1309: case XK_KP_9:
1310: return("\033Oy");
1311:
1312: default:
1313: return("-1");
1314: }
1315: }
1316: #endif /* LK201 */
1317: #endif /* not sun */
1318:
1319: internal_socket_read(bufp, numchars)
1320: register unsigned char *bufp;
1321: register int numchars;
1322: {
1323: /* Number of keyboard chars we have produced so far. */
1324: int count = 0;
1325: int nbytes,rows,cols;
1326: char mapping_buf[20];
1327: BLOCK_INPUT_DECLARE ();
1328: XEvent event;
1329: XComposeStatus status;
1330: KeySym keysym;
1331:
1332: BLOCK_INPUT ();
1333: #ifndef HAVE_SELECT
1334: if (! (fcntl (fileno (stdin), F_GETFL, 0) & O_NDELAY))
1335: {
1336: extern int read_alarm_should_throw;
1337: read_alarm_should_throw = 1;
1338: XPeekEvent (XXdisplay,&event);
1339: read_alarm_should_throw = 0;
1340: }
1341: #endif
1342: while (XPending (XXdisplay)) {
1343: XNextEvent (XXdisplay,&event);
1344: event.type &= 0177; /* Mask out XSendEvent indication */
1345:
1346: switch (event.type) {
1347:
1348: default:
1349: break;
1350:
1351: case MappingNotify:
1352: XRefreshKeyboardMapping(&event);
1353: break;
1354:
1355: case MapNotify:
1356: WindowMapped = 1;
1357: break;
1358:
1359: case UnmapNotify:
1360: WindowMapped = 0;
1361: break;
1362:
1363: case ConfigureNotify:
1364: if (abs(pixelheight-event.xconfigure.height) <
1365: XXfonth &&
1366: abs(pixelwidth-event.xconfigure.width) <
1367: XXfontw)
1368: break;
1369:
1370: configure_pending = 1;
1371:
1372: rows = (event.xconfigure.height-2*XXInternalBorder)/
1373: XXfonth;
1374: cols = (event.xconfigure.width-2*XXInternalBorder)/
1375: XXfontw;
1376: pixelwidth = cols*XXfontw+2*XXInternalBorder;
1377: pixelheight = rows*XXfonth+2*XXInternalBorder;
1378:
1379: break;
1380:
1381: case Expose:
1382: if (configure_pending) {
1383: int width, height;
1384: if (event.xexpose.count)
1385: break;
1386: /* This is absolutely, amazingly gross.
1387: * However, without it, emacs will core
1388: * dump if the window gets too small. And
1389: * uwm is too brain-damaged to handle
1390: * large minimum size windows. */
1391: width = (pixelwidth-2*XXInternalBorder)/XXfontw;
1392: height = (pixelheight-2*XXInternalBorder)/XXfonth;
1393: if (width > 11 && height > 4)
1394: change_screen_size (height, width, 0);
1395: dumprectangle (0,0,pixelheight,pixelwidth);
1396: configure_pending = 0;
1397: break;
1398: }
1399: dumprectangle (event.xexpose.y-XXInternalBorder,
1400: event.xexpose.x-XXInternalBorder,
1401: event.xexpose.height,
1402: event.xexpose.width);
1403: break;
1404:
1405: case GraphicsExpose:
1406: dumprectangle (event.xgraphicsexpose.y-XXInternalBorder,
1407: event.xgraphicsexpose.x-XXInternalBorder,
1408: event.xgraphicsexpose.height,
1409: event.xgraphicsexpose.width);
1410: break;
1411:
1412: case NoExpose:
1413: break;
1414:
1415: /*
1416: * NOTE: No 'Focus' management is being done yet. If
1417: * some other window has grabbed the focus, emacs will
1418: * still show a filled cursor whenever the pointer
1419: * enters the emacs window.
1420: */
1421: case EnterNotify:
1422: CursorToggle ();
1423: CursorOutline = 0;
1424: CursorToggle ();
1425: break;
1426:
1427: case LeaveNotify:
1428: CursorToggle ();
1429: CursorOutline = 1;
1430: CursorToggle ();
1431: break;
1432:
1433: case KeyPress:
1434: nbytes = XLookupString (&event,
1435: mapping_buf, 20, &keysym,
1436: 0);
1437: /* Someday this will be unnecessary as we will
1438: be able to use XRebindKeysym so XLookupString
1439: will have already given us the string we want. */
1440: if (IsFunctionKey(keysym) ||
1441: IsMiscFunctionKey(keysym)) {
1442: strcpy(mapping_buf,"[");
1443: #ifdef LK201
1444: if (event.xkey.state & ShiftMask)
1445: strcat(mapping_buf,stringFuncVal_Shifted(keysym));
1446: else
1447: #endif
1448:
1449: strcat(mapping_buf,stringFuncVal(keysym));
1450: #ifdef sun
1451: strcat(mapping_buf,"z");
1452: #else
1453: strcat(mapping_buf,"~");
1454: #endif /* sun */
1455: nbytes = strlen(mapping_buf);
1456: }
1457: #ifdef LK201
1458: else if (IsKeypadKey(keysym) || IsPFKey(keysym)) {
1459: strcpy(mapping_buf,stringFuncVal_KP(keysym));
1460: nbytes = strlen(mapping_buf);
1461: }
1462: #endif
1463:
1464: else {
1465: switch (keysym) {
1466: case XK_Left:
1467: strcpy(mapping_buf,"\002");
1468: nbytes = 1;
1469: break;
1470: case XK_Right:
1471: strcpy(mapping_buf,"\006");
1472: nbytes = 1;
1473: break;
1474: case XK_Up:
1475: strcpy(mapping_buf,"\020");
1476: nbytes = 1;
1477: break;
1478: case XK_Down:
1479: strcpy(mapping_buf,"\016");
1480: nbytes = 1;
1481: break;
1482: #ifdef LK201
1483: case XK_Next:
1484: strcpy(mapping_buf,"\033[6~");
1485: nbytes = 4;
1486: break;
1487: case XK_Prior:
1488: strcpy(mapping_buf,"\033[5~");
1489: nbytes = 4;
1490: break;
1491: case DXK_Remove:
1492: strcpy(mapping_buf,"\033[3~");
1493: #endif /* LK201 */
1494:
1495: }
1496: }
1497: if (nbytes) {
1498: if (event.xkey.state & Mod1Mask)
1499: *mapping_buf |= METABIT;
1500: if (numchars-nbytes > 0) {
1501: bcopy (mapping_buf, bufp, nbytes);
1502: bufp += nbytes;
1503: count += nbytes;
1504: numchars -= nbytes;
1505: }
1506: }
1507: break;
1508:
1509: case ButtonPress:
1510: case ButtonRelease:
1511: *bufp++ = (char) 'X' & 037;
1512: ++count;
1513: --numchars;
1514: *bufp++ = (char) '@' & 037;
1515: ++count;
1516: --numchars;
1517: if (XXm_queue_num == XMOUSEBUFSIZE)
1518: break;
1519: XXm_queue[XXm_queue_in] = (XEvent *) malloc (sizeof(XEvent));
1520: *XXm_queue[XXm_queue_in] = event;
1521: XXm_queue_num++;
1522: XXm_queue_in = (XXm_queue_in + 1) % XMOUSEBUFSIZE;
1523: break;
1524: }
1525: }
1526:
1527: if (CursorExists)
1528: xfixscreen ();
1529:
1530: UNBLOCK_INPUT ();
1531: return count;
1532: }
1533:
1534: /* Exit gracefully from gnuemacs, doing an autosave and giving a status.
1535: */
1536:
1537: XExitGracefully ()
1538: {
1539: XCleanUp();
1540: exit (70);
1541: }
1542:
1543: XIgnoreError ()
1544: {
1545: return 0;
1546: }
1547:
1548: xfixscreen ()
1549: {
1550: static int server_ping_timer;
1551: BLOCK_INPUT_DECLARE ();
1552:
1553: if (server_ping_timer > 0)
1554: server_ping_timer--;
1555: else
1556: {
1557: server_ping_timer = 100;
1558:
1559: /* Yes, this is really what I mean -- Check to see if we've
1560: * lost our connection */
1561:
1562: BLOCK_INPUT ();
1563: XSetErrorHandler(0);
1564: XSetIOErrorHandler(0);
1565: XNoOp (XXdisplay);
1566: XFlush (XXdisplay);
1567: XSetErrorHandler(handler);
1568: XSetIOErrorHandler(handler);
1569: if (!InUpdate && !CursorExists)
1570: CursorToggle ();
1571:
1572: UNBLOCK_INPUT ();
1573: }
1574: }
1575:
1576:
1577: /* ------------------------------------------------------------
1578: */
1579: static int reversevideo;
1580:
1581: static int
1582: XT_GetDefaults (class)
1583: char *class;
1584: {
1585: register char *option;
1586: register struct _xdeftab *entry;
1587:
1588: /*
1589: * Walk the table reading in the resources. Instance names supersede
1590: * class names.
1591: */
1592:
1593: for (entry = xDefaultsValueTable; entry->iname; entry++)
1594: {
1595: if (!(option = XGetDefault (XXdisplay, class, entry->iname)))
1596: option = XGetDefault (XXdisplay, class, entry->cname);
1597: if (option && entry->varp)
1598: *entry->varp = option;
1599: }
1600:
1601: /*
1602: * Now set global variables that aren't character strings; yes it would
1603: * be nice to do this automatically as part of the scanning step, but this
1604: * is less likely to screw up. The real answer is to use the resource
1605: * manager.
1606: */
1607:
1608: if (temp_reverseVideo)
1609: {
1610: if (strcmp (temp_reverseVideo, "on") == 0)
1611: reversevideo = 1;
1612: else if (strcmp (temp_reverseVideo, "off") == 0)
1613: reversevideo = 0;
1614: }
1615:
1616: if (temp_borderWidth)
1617: XXborder = atoi (temp_borderWidth);
1618:
1619: if (temp_internalBorder)
1620: XXInternalBorder = atoi (temp_internalBorder);
1621:
1622: return 0;
1623: }
1624:
1625: x_error_handler (disp, event)
1626: Display *disp;
1627: XErrorEvent *event;
1628: {
1629: char msg[200];
1630: XGetErrorText (disp, event->error_code, msg, 200);
1631: fprintf (stderr, "Fatal X-windows error: %s\n", msg);
1632: Fkill_emacs (make_number (70));
1633: }
1634:
1635: x_io_error_handler ()
1636: {
1637: Fdo_auto_save ();
1638: perror ("Fatal X-windows I/O error");
1639: Fkill_emacs (make_number (70));
1640: }
1641:
1642: x_term_init ()
1643: {
1644: register char *vardisplay;
1645: register int xxargc;
1646: register char **xxargv;
1647: char *ptr;
1648: XColor cdef;
1649:
1650: extern char *getenv ();
1651: extern XTinterrupt_signal ();
1652: extern char *malloc ();
1653: extern Lisp_Object Vxterm, Vxterm1, Qt;
1654: extern int XIgnoreError();
1655: int ix;
1656:
1657:
1658: vardisplay = (alternate_display ? alternate_display : "");
1659: if (!vardisplay) {
1660: fprintf (stderr, "DISPLAY environment variable must be set\n");
1661: exit (-200);
1662: }
1663:
1664: XXdisplay = XOpenDisplay (vardisplay);
1665: if (XXdisplay == (Display *) 0) {
1666: fprintf (stderr, "X server not responding. Check your DISPLAY environment variable.\n");
1667: exit (-99);
1668: }
1669:
1670: XXscreen = DefaultScreen (XXdisplay);
1671: XXisColor = DisplayCells (XXdisplay, XXscreen) > 2;
1672: XXColorMap = DefaultColormap (XXdisplay, XXscreen);
1673:
1674: XSetErrorHandler (x_error_handler);
1675: XSetIOErrorHandler (x_io_error_handler);
1676: signal (SIGPIPE, x_io_error_handler);
1677:
1678: WindowMapped = 0;
1679: baud_rate = 9600;
1680: min_padding_speed = 10000;
1681: must_write_spaces = 1;
1682: MetaFlag = 1;
1683: visible_bell = 1;
1684: inverse_video = 0;
1685: configure_pending = 0;
1686:
1687: fix_screen_hook = xfixscreen;
1688: clear_screen_hook = XTclear_screen;
1689: clear_end_of_line_hook = XTclear_end_of_line;
1690: ins_del_lines_hook = XTins_del_lines;
1691: change_line_highlight_hook = XTchange_line_highlight;
1692: insert_chars_hook = XTinsert_chars;
1693: write_chars_hook = XTwrite_chars;
1694: delete_chars_hook = XTdelete_chars;
1695: ring_bell_hook = XTfeep;
1696: reset_terminal_modes_hook = XTreset_terminal_modes;
1697: set_terminal_modes_hook = XTset_terminal_modes;
1698: update_begin_hook = XTupdate_begin;
1699: update_end_hook = XTupdate_end;
1700: set_terminal_window_hook = XTset_terminal_window;
1701: read_socket_hook = XTread_socket;
1702: topos_hook = XTtopos;
1703: reassert_line_highlight_hook = XTreassert_line_highlight;
1704: scroll_region_ok = 1; /* we'll scroll partial screens */
1705: char_ins_del_ok = 0;
1706: line_ins_del_ok = 1; /* we'll just blt 'em */
1707: fast_clear_end_of_line = 1; /* X does this well */
1708: memory_below_screen = 0; /* we don't remember what scrolls
1709: * off the bottom */
1710: dont_calculate_costs = 1;
1711:
1712: /* New options section */
1713: XXborder = 1;
1714: XXInternalBorder = 1;
1715: screen_width = 80;
1716: screen_height = 66;
1717:
1718: reversevideo = 0;
1719:
1720: XXdebug = 0;
1721: XXm_queue_num = 0;
1722: XXm_queue_in = 0;
1723: XXm_queue_out = 0;
1724:
1725: handler = XIgnoreError;
1726: XSetErrorHandler (handler);
1727: XSetIOErrorHandler (handler);
1728:
1729: desiredwindow =
1730: XXcurrentfont =
1731: XXidentity =
1732: XXicon_name =
1733: XXheader = (char *) NULL;
1734:
1735: XXicon_usebitmap = 0;
1736:
1737: temp_font = "fixed";
1738: progname = xargv[0];
1739: if (ptr = rindex(progname, '/'))
1740: progname = ptr+1;
1741: XXpid = getpid ();
1742: default_window = "=80x24+0+0";
1743:
1744: handler = XIgnoreError;
1745: XSetErrorHandler (handler);
1746: XSetIOErrorHandler (handler);
1747:
1748:
1749: /* Get resource name and its defaults, it it exists...
1750: */
1751: for (ix = 1; ix < xargc && xargv[ix][0] == '-'; ix++)
1752: {
1753: int valx;
1754:
1755: if (strcmp(xargv[ix], "-rn") == 0 &&
1756: (valx = ix + 1) < xargc)
1757: {
1758: XXidentity = (char *) xmalloc( strlen(xargv[valx]) + 1 );
1759: (void) strcpy(XXidentity, xargv[valx]);
1760:
1761: break;
1762: }
1763: }
1764:
1765: if (!XXidentity)
1766: {
1767: char *t;
1768:
1769: if ( (t = getenv("WM_RES_NAME")) != (char *) NULL )
1770: XXidentity = t;
1771:
1772: if (!XXidentity && strcmp(CLASS, progname) != 0)
1773: {
1774: XXidentity = progname;
1775: }
1776: }
1777:
1778: if (XXidentity)
1779: XT_GetDefaults(XXidentity);
1780: else
1781: XT_GetDefaults(CLASS);
1782:
1783: XXpid = getpid ();
1784: default_window = "=80x24+0+0";
1785:
1786: /* Process X command line args...*/
1787: xxargc = xargc;
1788: xxargv = xargv;
1789: xxargv++;
1790: xxargc--;
1791: while (xxargc) {
1792: int sargc;
1793: sargc = xxargc;
1794: if (xxargc && !strcmp (*xxargv, "-r")) {
1795: reversevideo = !reversevideo;
1796: xxargc--;
1797: xxargv++;
1798: }
1799: if ((xxargc > 1) && (!strcmp (*xxargv, "-font") ||
1800: !strcmp (*xxargv, "-fn"))) {
1801: xxargc--;
1802: xxargv++;
1803: if (XXcurrentfont != NULL)
1804: free(XXcurrentfont);
1805: XXcurrentfont = (char *) xmalloc (strlen (*xxargv)+1);
1806: strcpy (XXcurrentfont, *xxargv);
1807: xxargc--;
1808: xxargv++;
1809: }
1810: if ((xxargc > 1) && !strcmp (*xxargv, "-wn")) {
1811: xxargc--;
1812: xxargv++;
1813: XXheader = (char *) xmalloc (strlen (*xxargv)+1);
1814: strcpy (XXheader, *xxargv);
1815: xxargc--;
1816: xxargv++;
1817: }
1818: if ((xxargc > 1) && !strcmp (*xxargv, "-in")) {
1819: xxargc--;
1820: xxargv++;
1821: XXicon_name = (char *) xmalloc (strlen (*xxargv)+1);
1822: strcpy (XXicon_name, *xxargv);
1823: xxargc--;
1824: xxargv++;
1825: }
1826: if (xxargc && !strcmp (*xxargv, "-i")) {
1827: xxargc--;
1828: xxargv++;
1829: XXicon_usebitmap = 1;
1830: }
1831: if ((xxargc > 1) && !strcmp (*xxargv, "-b")) {
1832: xxargc--;
1833: xxargv++;
1834: XXborder = atoi (*xxargv);
1835: xxargc--;
1836: xxargv++;
1837: }
1838: if ((xxargc > 1) && !strcmp (*xxargv, "-ib")) {
1839: xxargc--;
1840: xxargv++;
1841: XXInternalBorder = atoi (*xxargv);
1842: xxargc--;
1843: xxargv++;
1844: }
1845: if ((xxargc > 1) && (!strcmp (*xxargv, "-w") ||
1846: !strcmp (*xxargv, "-geometry"))) {
1847: xxargc--;
1848: xxargv++;
1849: desiredwindow = (char *) xmalloc (strlen (*xxargv)+1);
1850: strcpy (desiredwindow, *xxargv);
1851: xxargc--;
1852: xxargv++;
1853: }
1854: if (XXisColor) {
1855: if ((xxargc > 1 && !strcmp (*xxargv, "-fg"))) {
1856: xxargc--;
1857: xxargv++;
1858:
1859: fore_color =
1860: (char *) xmalloc (strlen (*xxargv)+1);
1861: strcpy (fore_color, *xxargv);
1862:
1863: xxargc--;
1864: xxargv++;
1865: }
1866: if ((xxargc > 1 && !strcmp (*xxargv, "-bg"))) {
1867: xxargc--;
1868: xxargv++;
1869:
1870: back_color =
1871: (char *) xmalloc (strlen (*xxargv)+1);
1872: strcpy (back_color, *xxargv);
1873:
1874: xxargc--;
1875: xxargv++;
1876: }
1877: if ((xxargc > 1 && !strcmp (*xxargv, "-bd"))) {
1878: xxargc--;
1879: xxargv++;
1880:
1881: brdr_color =
1882: (char *) xmalloc (strlen (*xxargv)+1);
1883: strcpy (brdr_color, *xxargv);
1884:
1885: xxargc--;
1886: xxargv++;
1887: }
1888: if ((xxargc > 1 && !strcmp (*xxargv, "-cr"))) {
1889: xxargc--;
1890: xxargv++;
1891:
1892: curs_color =
1893: (char *) xmalloc (strlen (*xxargv)+1);
1894: strcpy (curs_color, *xxargv);
1895:
1896: xxargc--;
1897: xxargv++;
1898: }
1899: if ((xxargc > 1 && !strcmp (*xxargv, "-ms"))) {
1900: xxargc--;
1901: xxargv++;
1902:
1903: mous_color =
1904: (char *) xmalloc (strlen (*xxargv)+1);
1905: strcpy (mous_color, *xxargv);
1906:
1907: xxargc--;
1908: xxargv++;
1909: }
1910: }
1911: if (sargc == xxargc) {
1912: xxargc--;
1913: xxargv++;
1914: }
1915: }
1916:
1917: /* Now, actually Parse and Set colors...
1918: */
1919: if (XXisColor) {
1920: if (fore_color || back_color)
1921: reversevideo = 0;
1922: if (fore_color &&
1923: XParseColor (XXdisplay, XXColorMap, fore_color, &cdef) &&
1924: XAllocColor (XXdisplay, XXColorMap, &cdef))
1925: fore = cdef.pixel;
1926: else {
1927: fore_color = "black";
1928: fore = BlackPixel (XXdisplay, XXscreen);
1929: }
1930:
1931: if (back_color &&
1932: XParseColor (XXdisplay, XXColorMap, back_color, &cdef) &&
1933: XAllocColor (XXdisplay, XXColorMap, &cdef))
1934: back = cdef.pixel;
1935: else {
1936: back_color = "white";
1937: back = WhitePixel (XXdisplay, XXscreen);
1938: }
1939:
1940: if (curs_color &&
1941: XParseColor (XXdisplay, XXColorMap, curs_color, &cdef) &&
1942: XAllocColor (XXdisplay, XXColorMap, &cdef))
1943: curs = cdef.pixel;
1944: else {
1945: curs_color = "black";
1946: curs = BlackPixel (XXdisplay, XXscreen);
1947: }
1948:
1949: if (mous_color &&
1950: XParseColor (XXdisplay, XXColorMap, mous_color, &cdef) &&
1951: XAllocColor (XXdisplay, XXColorMap, &cdef))
1952: ;
1953: else mous_color = "black";
1954:
1955: if (brdr_color &&
1956: XParseColor (XXdisplay, XXColorMap, brdr_color, &cdef) &&
1957: XAllocColor (XXdisplay, XXColorMap, &cdef))
1958: brdr = cdef.pixel;
1959: else {
1960: brdr_color = "black";
1961: brdr = BlackPixel (XXdisplay, XXscreen);
1962: }
1963: }
1964: else {
1965: fore_color = curs_color = mous_color = brdr_color = "black";
1966: fore = curs = brdr = BlackPixel (XXdisplay, XXscreen);
1967: back_color = "white";
1968: back = WhitePixel (XXdisplay, XXscreen);
1969: }
1970:
1971:
1972: if (reversevideo) {
1973: int tempcolor;
1974: char *tempname;
1975: brdr = back;
1976: brdr_color = back_color;
1977: tempcolor = fore;
1978: fore = back;
1979: back = tempcolor;
1980: tempname = fore_color;
1981: fore_color = back_color;
1982: back_color = tempname;
1983: if (curs == WhitePixel (XXdisplay, XXscreen)) {
1984: curs = BlackPixel (XXdisplay, XXscreen);
1985: curs_color = "black";
1986: }
1987: else if (curs == BlackPixel (XXdisplay, XXscreen)) {
1988: curs = WhitePixel (XXdisplay, XXscreen);
1989: curs_color = "white";
1990: }
1991: if (!strcmp (mous_color, "white"))
1992: mous_color = "black";
1993: else if (!strcmp (mous_color, "black"))
1994: mous_color = "white";
1995: }
1996:
1997:
1998: if (!XXcurrentfont)
1999: {
2000: XXcurrentfont = (char *) xmalloc (strlen (temp_font) + 1);
2001:
2002: if (!XXcurrentfont) {
2003: fprintf (stderr, "Memory allocation failure.\n");
2004: exit (-150);
2005: }
2006:
2007: strcpy (XXcurrentfont, temp_font);
2008: }
2009:
2010:
2011:
2012: signal (SIGPIPE, XExitGracefully);
2013:
2014: #ifndef CANNOT_DUMP
2015: if (initialized)
2016: #endif /* CANNOT_DUMP */
2017: Vxterm = Qt;
2018:
2019: Fset (intern ("window-system-version"), make_number (11));
2020:
2021: XInitWindow ();
2022:
2023: keyboard_init_hook = x_init_1;
2024: }
2025:
2026: /* Initialize for keyboard input using X.
2027: This is called by init_keyboard via keyboard_init_hook. */
2028:
2029: static void
2030: x_init_1 ()
2031: {
2032: #ifdef F_SETOWN
2033: extern int old_fcntl_owner;
2034: #endif
2035:
2036: dup2 (ConnectionNumber(XXdisplay), 0);
2037: close (ConnectionNumber(XXdisplay));
2038: ConnectionNumber(XXdisplay) = 0; /* Looks a little strange?
2039: * check the def of the macro;
2040: * it is a genuine lvalue */
2041: setpgrp (0,getpid());
2042:
2043: #ifdef F_SETOWN
2044: old_fcntl_owner = fcntl (0, F_GETOWN, 0);
2045: fcntl (0, F_SETOWN, getpid ());
2046: #endif
2047:
2048: /* Enable interrupt_input because otherwise we cannot asynchronously
2049: detect C-g sent as a keystroke event from the X server. */
2050: Fset_input_mode (Qt, Qnil);
2051: }
2052:
2053: XSetFlash ()
2054: {
2055: ring_bell_hook = XTflash;
2056: }
2057:
2058: XSetFeep ()
2059: {
2060: ring_bell_hook = XTfeep;
2061: }
2062:
2063:
2064: /* ------------------------------------------------------------
2065: * Load a font by name. Return the font pointer, or NULL if
2066: * it can't be loaded. Do all appropriate calculations.
2067: */
2068: static XFontStruct *
2069: XT_CalcForFont(fontname)
2070: char *fontname;
2071: {
2072: XFontStruct *fontp;
2073:
2074:
2075: if ( (fontp = XLoadQueryFont(XXdisplay, fontname)) == (XFontStruct *) 0 )
2076: {
2077: return (XFontStruct *) NULL;
2078: }
2079:
2080: XXfid = fontp->fid;
2081: XXfonth = fontp->ascent + fontp->descent;
2082: XXfontw = fontp->max_bounds.width;
2083: XXbase = fontp->ascent;
2084:
2085: return fontp;
2086: }
2087:
2088:
2089: /* ------------------------------------------------------------
2090: */
2091: XNewFont (newname)
2092: register char *newname;
2093: {
2094: XFontStruct *temp;
2095: BLOCK_INPUT_DECLARE ();
2096:
2097: BLOCK_INPUT ();
2098: XFlush (XXdisplay);
2099:
2100:
2101: temp = XT_CalcForFont(newname);
2102:
2103: if (temp == (XFontStruct *) NULL)
2104: {
2105: UNBLOCK_INPUT ();
2106: return -1;
2107: }
2108:
2109: XSetFont (XXdisplay, XXgc_norm, XXfid);
2110: XSetFont (XXdisplay, XXgc_rev, XXfid);
2111: XSetFont (XXdisplay, XXgc_curs, XXfid);
2112:
2113: XFreeFont (XXdisplay, fontinfo);
2114: fontinfo = temp;
2115:
2116:
2117: XSetWindowSize(screen_height, screen_width);
2118:
2119:
2120: UNBLOCK_INPUT ();
2121: return 0;
2122: }
2123:
2124: /* Flip foreground/background colors */
2125:
2126: XFlipColor ()
2127: {
2128: int tempcolor;
2129: char *tempname;
2130: XColor forec, backc;
2131: BLOCK_INPUT_DECLARE ();
2132:
2133: BLOCK_INPUT ();
2134: CursorToggle ();
2135: XSetWindowBackground(XXdisplay, XXwindow, fore);
2136: if (XXborder)
2137: XSetWindowBorder(XXdisplay, XXwindow, back);
2138:
2139: brdr = back;
2140: brdr_color = back_color;
2141: tempcolor = fore;
2142: fore = back;
2143: back = tempcolor;
2144: tempname = fore_color ;
2145: fore_color = back_color;
2146: back_color = tempname;
2147: XClearArea (XXdisplay, XXwindow, 0, 0,
2148: screen_width*XXfontw+2*XXInternalBorder,
2149: screen_height*XXfonth+2*XXInternalBorder, 0);
2150:
2151: XXgc_temp = XXgc_norm;
2152: XXgc_norm = XXgc_rev;
2153: XXgc_rev = XXgc_temp;
2154:
2155: if (!strcmp (mous_color, "white"))
2156: mous_color = "black";
2157: else if (!strcmp (mous_color, "black"))
2158: mous_color = "white";
2159:
2160: x_set_cursor_colors ();
2161:
2162: XRedrawDisplay ();
2163: if (curs == WhitePixel (XXdisplay, XXscreen)) {
2164: curs = BlackPixel (XXdisplay, XXscreen);
2165: curs_color = "black";
2166: }
2167: else
2168: if (curs == BlackPixel (XXdisplay, XXscreen)) {
2169: curs = WhitePixel (XXdisplay, XXscreen);
2170: curs_color = "white";
2171: }
2172: XSetState (XXdisplay, XXgc_curs, back, curs, GXinvert, AllPlanes);
2173:
2174: CursorToggle ();
2175: XFlush (XXdisplay);
2176: UNBLOCK_INPUT ();
2177: }
2178:
2179: /* ------------------------------------------------------------
2180: */
2181:
2182: #define NO_MANAGER 1
2183:
2184:
2185: /* ------------------------------------------------------------
2186: */
2187: static XClassHint class_hint;
2188:
2189:
2190: static int
2191: XT_Set_Class_Hints(w)
2192: Window w;
2193: {
2194: extern char *getenv();
2195:
2196:
2197: if (XXidentity == (char *) NULL)
2198: XXidentity = ""; /* XSCH() doesn't like NULL pointers! */
2199:
2200: class_hint.res_name = XXidentity;
2201: class_hint.res_class = CLASS;
2202:
2203:
2204: XSetClassHint(XXdisplay, w, &class_hint);
2205: }
2206:
2207:
2208: /* ------------------------------------------------------------
2209: */
2210: static int
2211: XT_Set_Command_Line(w)
2212: Window w;
2213: {
2214:
2215: XSetCommand(XXdisplay, w, xargv, xargc);
2216: }
2217:
2218:
2219: /* ------------------------------------------------------------
2220: */
2221: static char hostname[100];
2222:
2223: static int
2224: XT_Set_Host(w)
2225: Window w;
2226: {
2227:
2228: gethostname(hostname, 100);
2229: hostname[99] = '\0';
2230:
2231: XChangeProperty(XXdisplay, w, XA_WM_CLIENT_MACHINE, XA_STRING, 8,
2232: PropModeReplace, hostname, strlen(hostname));
2233: }
2234:
2235:
2236: /* ------------------------------------------------------------
2237: * Set header title to window-name (from '-wn'), or if none,
2238: * "optional-id: class-of-appl @ host"
2239: */
2240: static int
2241: XT_Set_Title(w)
2242: Window w;
2243: {
2244: char header_info[200];
2245:
2246:
2247: if (XXheader != (char *) NULL)
2248: {
2249: strcpy(header_info, XXheader);
2250: }
2251: else
2252: {
2253: char *next;
2254:
2255: next = header_info;
2256:
2257: if (strlen(class_hint.res_name) != 0)
2258: {
2259: sprintf(header_info, "%s: ",
2260: class_hint.res_name);
2261:
2262: next += strlen(header_info);
2263: }
2264:
2265: sprintf(next, "%s @ %s",
2266: class_hint.res_class,
2267: hostname);
2268: }
2269:
2270:
2271: XStoreName(XXdisplay, w, header_info);
2272: }
2273:
2274:
2275: /* ------------------------------------------------------------
2276: * Set icon title to icon-name (from '-in'),
2277: * or if none, to "invocation-or-class @ host".
2278: *
2279: */
2280: static int
2281: XT_Set_Icon_Title(w)
2282: Window w;
2283: {
2284: char title_info[100];
2285:
2286: if (XXicon_name != (char *) NULL)
2287: {
2288: strcpy(title_info, XXicon_name);
2289: }
2290: else
2291: {
2292: if (strlen(class_hint.res_name) != 0)
2293: {
2294: sprintf(title_info, "%s@", class_hint.res_name);
2295: }
2296: else
2297: {
2298: sprintf(title_info, "%s@", class_hint.res_class);
2299: }
2300:
2301: strcat(title_info, hostname);
2302: }
2303:
2304:
2305: XChangeProperty(XXdisplay, w, XA_WM_ICON_NAME, XA_STRING, 8,
2306: PropModeReplace, title_info, strlen(title_info));
2307: }
2308:
2309:
2310: /* Arg PR carries value returned by XGeometry at startup, or 0. */
2311:
2312: static int
2313: XT_Set_Size_Hints(w, x, y, width, height, do_resize, pr)
2314: int x, y; /* only used at Startup: do_resize == FALSE */
2315: int width, height;
2316: Window w;
2317: Bool do_resize;
2318: int pr;
2319: {
2320: XSizeHints sizehints;
2321:
2322: sizehints.flags = (pr & (WidthValue | HeightValue)) ? USSize : PSize;
2323:
2324: if (!do_resize)
2325: sizehints.flags |= (pr & (XValue | YValue)) ? USPosition : PPosition;
2326:
2327: sizehints.flags |= PResizeInc|PMinSize;
2328:
2329:
2330: sizehints.x = x;
2331: sizehints.y = y;
2332: sizehints.width = width*XXfontw+2*XXInternalBorder;
2333: sizehints.height = height*XXfonth+2*XXInternalBorder;
2334:
2335: pixelwidth = sizehints.width;
2336: pixelheight = sizehints.height;
2337: flexlines = height;
2338:
2339:
2340: change_screen_size (height, width, 0 - (do_resize == False));
2341:
2342: if (do_resize)
2343: {
2344: XResizeWindow(XXdisplay, XXwindow, pixelwidth, pixelheight);
2345: XFlush(XXdisplay);
2346: }
2347:
2348:
2349: sizehints.width_inc = XXfontw;
2350: sizehints.height_inc = XXfonth;
2351:
2352: sizehints.min_width = XXfontw*MINWIDTH+2*XXInternalBorder;
2353: sizehints.min_height = XXfonth*MINHEIGHT+2*XXInternalBorder;
2354:
2355: /*
2356: * Until the new X Inter-Client Communications Conventions are adopted,
2357: * the minimum sizes are really the base sizes.
2358: */
2359: #ifdef XICCC
2360: sizehints.base_width = 2 * XXInternalBorder;
2361: sizehints.base_height = 2 * XXInternalBorder;
2362: sizehints.min_width = XXfontw * MINWIDTH + sizehints.base_width;
2363: sizehints.min_height = XXfonth * MINHEIGHT + sizehints.base_height;
2364: sizehints.flags |= PBaseSize;
2365: #else
2366: /* old, broken versions */
2367: sizehints.min_width = 2 * XXInternalBorder;
2368: sizehints.min_height = 2 * XXInternalBorder;
2369: #endif
2370:
2371: XSetNormalHints(XXdisplay, w, &sizehints);
2372: }
2373:
2374:
2375: /* ------------------------------------------------------------
2376: */
2377: /*ARGSUSED*/
2378: static int
2379: XT_Set_Zoom_Sizes(w)
2380: Window w;
2381: {
2382: }
2383:
2384:
2385: /* ------------------------------------------------------------
2386: * Set our state and icon parameters.
2387: */
2388: static int
2389: XT_Set_WM_Hints(w)
2390: Window w;
2391: {
2392: XWMHints wmhints;
2393:
2394: wmhints.flags = InputHint | StateHint;
2395: if (XXicon_usebitmap)
2396: wmhints.flags |= IconPixmapHint | IconMaskHint;
2397:
2398: wmhints.input = True;
2399: wmhints.initial_state = NormalState;
2400:
2401: SinkPixmap = XCreateBitmapFromData (XXdisplay, w,
2402: sink_bits, sink_width,
2403: sink_height);
2404:
2405: SinkMaskPixmap = XCreateBitmapFromData (XXdisplay, w,
2406: sink_mask_bits,
2407: sink_mask_width,
2408: sink_mask_height);
2409:
2410: if (XXicon_usebitmap) {
2411: wmhints.icon_pixmap = SinkPixmap;
2412: wmhints.icon_mask = SinkMaskPixmap;
2413: }
2414: else {
2415: wmhints.icon_pixmap = 0;
2416: wmhints.icon_mask = 0;
2417: }
2418:
2419: XSetWMHints(XXdisplay, w, &wmhints);
2420: }
2421:
2422:
2423: /* ------------------------------------------------------------
2424: * Change just the size of the window.
2425: */
2426: XSetWindowSize(rows, cols)
2427: int rows, cols;
2428: {
2429: XT_Set_Size_Hints(XXwindow, 0, 0, cols, rows, NO_MANAGER, 0);
2430: }
2431:
2432:
2433: /* ------------------------------------------------------------
2434: */
2435: static int
2436: XInitWindow ()
2437: {
2438: extern int xargc;
2439: extern char **xargv;
2440: int x, y, width, height, pr;
2441: char *dp;
2442: Window desktop;
2443: XColor forec, backc;
2444:
2445:
2446: if ( (fontinfo = XT_CalcForFont(XXcurrentfont))
2447: == (XFontStruct *) NULL)
2448: fatal ("X server unable to find requested font `%s'.\n",
2449: (XXcurrentfont == NULL) ? "(null)" : XXcurrentfont);
2450:
2451: pr = XGeometry (XXdisplay, 0, desiredwindow, default_window,
2452: XXborder, XXfontw, XXfonth,
2453: XXInternalBorder*2, XXInternalBorder*2,
2454: &x, &y, &width, &height);
2455:
2456: /* Which desktop do we start up on?
2457: */
2458: if ( (dp = getenv("WM_DESKTOP")) != (char *) NULL )
2459: {
2460: desktop = atoi(dp);
2461: }
2462: else
2463: {
2464: desktop = RootWindow(XXdisplay, DefaultScreen(XXdisplay));
2465: }
2466:
2467: XXwindow = XCreateSimpleWindow(XXdisplay, desktop,
2468: x, y,
2469: width*XXfontw + 2*XXInternalBorder,
2470: height*XXfonth + 2*XXInternalBorder,
2471: XXborder, brdr, back);
2472: if (!XXwindow)
2473: {
2474: fprintf (stderr, "Could not create X window!\n");
2475: fflush (stderr);
2476: exit (-97);
2477: }
2478:
2479: XXgcv.font = XXfid;
2480: XXgcv.foreground = fore;
2481: XXgcv.background = back;
2482: XXgc_norm = XCreateGC(XXdisplay, XXwindow,
2483: GCFont|GCForeground|GCBackground,
2484: &XXgcv);
2485: XXgcv.foreground = back;
2486: XXgcv.background = fore;
2487: XXgc_rev = XCreateGC(XXdisplay, XXwindow,
2488: GCFont|GCForeground|GCBackground,
2489: &XXgcv);
2490: XXgcv.foreground = back;
2491: XXgcv.background = curs;
2492: XXgc_curs = XCreateGC(XXdisplay, XXwindow,
2493: GCFont|GCForeground|GCBackground,
2494: &XXgcv);
2495:
2496: EmacsCursor = XCreateFontCursor(XXdisplay, XC_left_ptr);
2497:
2498: x_set_cursor_colors ();
2499:
2500: XDefineCursor (XXdisplay, XXwindow, EmacsCursor);
2501:
2502: CursorExists = 0;
2503: CursorOutline = 1;
2504: VisibleX = 0;
2505: VisibleY = 0;
2506:
2507:
2508: XT_Set_Class_Hints(XXwindow);
2509: XT_Set_Command_Line(XXwindow);
2510: XT_Set_Host(XXwindow);
2511: XT_Set_Title(XXwindow);
2512: XT_Set_Icon_Title(XXwindow);
2513: XT_Set_Size_Hints(XXwindow, x, y, width, height, False, pr);
2514: XT_Set_Zoom_Sizes(XXwindow);
2515: XT_Set_WM_Hints(XXwindow);
2516:
2517: XSelectInput(XXdisplay, XXwindow, KeyPressMask |
2518: ExposureMask | ButtonPressMask | ButtonReleaseMask |
2519: EnterWindowMask | LeaveWindowMask |
2520: StructureNotifyMask);
2521:
2522: XMapWindow (XXdisplay, XXwindow);
2523: XFlush (XXdisplay);
2524: }
2525:
2526: #endif /* HAVE_X_WINDOWS */
2527:
2528: /*#include "xundebug.h"*/
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.