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