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