|
|
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.