|
|
1.1 ! root 1: /* X Communication module for terminals which understand the X protocol. ! 2: Copyright (C) 1985 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. */ ! 22: ! 23: /* ! 24: * $Source: /u1/third_party/gnuemacs.v17/src/RCS/xterm.c,v $ ! 25: * $Author: rlk $ ! 26: * $Locker: $ ! 27: * $Header: xterm.c,v 1.13 86/02/17 12:24:48 rlk Exp $ ! 28: */ ! 29: ! 30: #ifndef lint ! 31: static char *rcsid_TrmXTERM_c = "$Header: xterm.c,v 1.13 86/02/17 12:24:48 rlk Exp $"; ! 32: #endif lint ! 33: ! 34: #include "config.h" ! 35: ! 36: /* This includes sys/types.h, and that somehow loses ! 37: if this is not done before the other system files. */ ! 38: #include "xterm.h" ! 39: ! 40: #include <sys/time.h> ! 41: #include <sys/ioctl.h> ! 42: #include <stdio.h> ! 43: #include <ctype.h> ! 44: #include <errno.h> ! 45: #include <signal.h> ! 46: #include <strings.h> ! 47: #include <sys/stat.h> ! 48: ! 49: #include "dispextern.h" ! 50: #include "termhooks.h" ! 51: #include "termopts.h" ! 52: #include "termchar.h" ! 53: #include "sink.h" ! 54: #include "sinkmask.h" ! 55: /*#include <X/Xproto.h> */ ! 56: ! 57: #define min(a,b) ((a)<(b) ? (a) : (b)) ! 58: #define sigunblockx(sig) sigblock (0) ! 59: #define sigblockx(sig) sigblock (1 << ((sig) - 1)) ! 60: XREPBUFFER Xxrepbuffer; ! 61: int pixelwidth; ! 62: int pixelheight; ! 63: int PendingExposure; ! 64: int PendingIconExposure; ! 65: #define MAXICID 80 ! 66: char iconidentity[MAXICID]; ! 67: #define ICONTAG "emacs@" ! 68: #define METABIT 0x80 ! 69: Window XXIconWindow; ! 70: Bitmap XXIconMask; ! 71: ! 72: char *XXcurrentfont; ! 73: char *default_window; ! 74: int informflag; ! 75: extern struct display_line *DesiredScreen[], *PhysScreen[]; ! 76: extern int initialized; ! 77: int XXdebug; ! 78: int XXpid; ! 79: extern int screen_garbaged; ! 80: int XXxoffset, XXyoffset; ! 81: int IconWindow; ! 82: ! 83: int WindowMapped; ! 84: int CurHL; ! 85: ! 86: static int flexlines; /* last line affect by dellines or */ ! 87: /* inslines functions */ ! 88: extern int errno; ! 89: int VisibleX, VisibleY; /* genuine location of cursor on screen */ ! 90: /* if it is there */ ! 91: static int SavedX, SavedY; /* Where the cursor was before update */ ! 92: /* started */ ! 93: ! 94: int bitblt; /* Used to track bit blt events */ ! 95: int CursorExists; /* during updates cursor is turned off */ ! 96: static int InUpdate; /* many of functions here may be invoked */ ! 97: /* even if no update in progress, when */ ! 98: /* no update is in progress the action */ ! 99: /* can be slightly different */ ! 100: char MouseCursor[33] ="\000\000\002\000\006\000\016\000\036\000\076\000\ ! 101: \176\000\376\000\376\001\076\000\066\000\142\000\140\000\300\000\300\000\000\ ! 102: \000"; ! 103: ! 104: char MouseMask[33] = "\003\000\007\000\017\000\037\000\077\000\177\000\ ! 105: \377\000\377\001\377\003\377\003\177\000\367\000\363\000\340\001\340\001\ ! 106: \300\000"; ! 107: ! 108: Display *XXdisplay; ! 109: FontInfo *fontinfo; ! 110: Window XXwindow; ! 111: Cursor EmacsCursor; ! 112: ! 113: char *fore_color; /* Variables to store colors */ ! 114: char *back_color; ! 115: char *brdr_color; ! 116: char *curs_color; ! 117: char *mous_color; ! 118: ! 119: int fore; ! 120: int back; ! 121: int brdr; ! 122: int curs; ! 123: int mous; ! 124: ! 125: static WindowInfo windowinfo; ! 126: WindowInfo rootwindowinfo; ! 127: ! 128: ! 129: ! 130: static XEvent XXEvent; /* as X messages are read in they are */ ! 131: /* stored here */ ! 132: static XREPBUFFER XXqueue;/* Used for storing up ExposeRegion */ ! 133: /* replies, so that the SIGIO inter- */ ! 134: /* rupt serving routines do almost */ ! 135: /* no writes to the X socket */ ! 136: /*int CurHL; /* Current Highlighting actually being */ ! 137: /* being used for bold font right now*/ ! 138: ! 139: int XXborder; ! 140: ! 141: ! 142: extern Display *XOpenDisplay (); ! 143: extern Window XCreateWindow (); ! 144: extern Cursor XDefineCursor (); ! 145: extern Cursor XCreateCursor (); ! 146: extern FontInfo *XOpenFont (); ! 147: ! 148: ! 149: /* HLmode -- Changes the GX function for output strings. Could be used to ! 150: * change font. Check an XText library function call. ! 151: */ ! 152: ! 153: static ! 154: HLmode (new) ! 155: int new; ! 156: { ! 157: CurHL = new; ! 158: } ! 159: ! 160: ! 161: /* External interface to control of standout mode. ! 162: Call this when about to modify line at position VPOS ! 163: and not change whether it is highlighted. */ ! 164: ! 165: XTreassert_line_highlight (highlight, vpos) ! 166: int highlight, vpos; ! 167: { ! 168: HLmode (highlight); ! 169: } ! 170: ! 171: /* Call this when about to modify line at position VPOS ! 172: and change whether it is highlighted. */ ! 173: ! 174: static ! 175: XTchange_line_highlight (new_highlight, vpos, first_unused_hpos) ! 176: int new_highlight, vpos, first_unused_hpos; ! 177: { ! 178: HLmode (new_highlight); ! 179: XTtopos (vpos, 0); ! 180: XTclear_end_of_line (0); ! 181: } ! 182: ! 183: ! 184: /* Used for starting or restarting (after suspension) the X window. Puts the ! 185: * cursor in a known place, update does not begin with this routine but only ! 186: * with a call to DoDsp. The mouse cursor is warped into the window and then ! 187: * the cursor is turned on. ! 188: */ ! 189: ! 190: ! 191: ! 192: static ! 193: XTset_terminal_modes () ! 194: { ! 195: int stuffpending; ! 196: #ifdef XDEBUG ! 197: fprintf (stderr, "XTset_terminal_modes\n"); ! 198: #endif ! 199: InUpdate = 0; ! 200: stuffpending = 0; ! 201: if (!initialized) ! 202: { ! 203: CursorExists = 0; ! 204: VisibleX = 0; ! 205: VisibleY = 0; ! 206: } ! 207: XTclear_screen (); ! 208: ioctl (0, FIONREAD, &stuffpending); ! 209: if (stuffpending) ! 210: kill (XXpid, SIGIO); ! 211: } ! 212: ! 213: /* XTtopos moves the cursor to the correct location and checks whether an update ! 214: * is in progress in order to toggle it on. ! 215: */ ! 216: ! 217: static ! 218: XTtopos (row, col) ! 219: register int row, col; ! 220: { ! 221: #ifdef XDEBUG ! 222: fprintf (stderr, "XTtopos\n"); ! 223: #endif ! 224: cursX = col; ! 225: cursY = row; ! 226: if (InUpdate) ! 227: { ! 228: if (CursorExists) ! 229: { ! 230: CursorToggle (); ! 231: } ! 232: return; /* Generally, XTtopos will be invoked */ ! 233: /* when InUpdate with !CursorExists */ ! 234: /* so that wasteful XFlush is not called */ ! 235: } ! 236: if ((row == VisibleY) && (col == VisibleX)) ! 237: { ! 238: if (!CursorExists) ! 239: { ! 240: CursorToggle (); ! 241: } ! 242: XFlush (); ! 243: return; ! 244: } ! 245: if (CursorExists) CursorToggle (); ! 246: VisibleX = col; ! 247: VisibleY = row; ! 248: if (!CursorExists) CursorToggle (); ! 249: XFlush (); ! 250: } ! 251: ! 252: /* Used to get the terminal back to a known state after resets. Usually ! 253: * used when restarting suspended or waiting emacs ! 254: */ ! 255: ! 256: static ! 257: cleanup () ! 258: { ! 259: inverse_video = 0; ! 260: HLmode (0); ! 261: } ! 262: ! 263: /* wipes out numcols columns starting a current column on the current line */ ! 264: ! 265: static ! 266: XTclear_end_of_line (first_blank) ! 267: register int first_blank; ! 268: { ! 269: register int numcols; ! 270: ! 271: #ifdef XDEBUG ! 272: fprintf (stderr, "XTclear_end_of_line\n"); ! 273: ! 274: #endif ! 275: if (cursY < 0 || cursY >= screen_height) ! 276: return; ! 277: if (first_blank >= screen_width) ! 278: return; ! 279: ! 280: if (first_blank < 0) ! 281: first_blank = 0; ! 282: numcols = screen_width - first_blank; ! 283: if (cursY == VisibleY && VisibleX >= first_blank) ! 284: { ! 285: if (CursorExists) CursorToggle (); ! 286: } ! 287: XPixSet (XXwindow, ! 288: first_blank * fontinfo->width, ! 289: cursY * fontinfo->height, ! 290: fontinfo->width * numcols, ! 291: fontinfo->height, ! 292: back); ! 293: XTtopos (cursY, first_blank); ! 294: } ! 295: ! 296: static ! 297: XTreset_terminal_modes () ! 298: { ! 299: #ifdef XDEBUG ! 300: fprintf (stderr, "XTreset_terminal_modes\n"); ! 301: #endif ! 302: XTclear_screen (); ! 303: } ! 304: ! 305: static ! 306: XTclear_screen () ! 307: { ! 308: #ifdef XDEBUG ! 309: fprintf (stderr, "XTclear_screen\n"); ! 310: #endif ! 311: HLmode (0); ! 312: CursorExists = 0; ! 313: ! 314: cursX = 0; ! 315: cursY = 0; ! 316: SavedX = 0; ! 317: SavedY = 0; ! 318: VisibleX = 0; ! 319: VisibleY = 0; ! 320: XClear (XXwindow); ! 321: CursorToggle (); ! 322: if (!InUpdate) ! 323: XFlush (); ! 324: } ! 325: ! 326: /* used by dumprectangle which is usually invoked upon ExposeRegion ! 327: * events which come from bit blt's or moving an obscuring opaque window ! 328: */ ! 329: ! 330: static ! 331: dumpchars (ActiveScreen, numcols, tempX, tempY, tempHL) ! 332: register struct display_line **ActiveScreen; ! 333: register int numcols; ! 334: register int tempX, tempY, tempHL; ! 335: { ! 336: if (numcols <= 0) return; ! 337: if (((numcols - 1) + tempX) > screen_width) ! 338: { ! 339: numcols = (screen_width - tempX) + 1; ! 340: } ! 341: if ((tempX < 0) || (tempX >= screen_width) || ! 342: (tempY < 0) || (tempY >= screen_height)) ! 343: { ! 344: return; ! 345: } ! 346: XText (XXwindow, ! 347: (tempX * fontinfo->width), ! 348: (tempY * fontinfo->height), ! 349: &ActiveScreen[tempY + 1]->body[tempX], ! 350: numcols, ! 351: fontinfo->id, ! 352: (tempHL ? back : fore), ! 353: (tempHL ? fore : back)); ! 354: } ! 355: ! 356: /* When a line has been changed this function is called. X is so fast ! 357: * that the actual sequence is ignore. Rather, the new version of the ! 358: * line is simply output if this function is invoked while in UpDate. ! 359: * Sometimes writechars can be invoked when not in update if text is to ! 360: * be output at the end of the line. In this case the whole line is not ! 361: * output. Simply the new text at the current cursor position given ! 362: * by VisibleX,Y. The cursor is moved to the end of the new text. ! 363: */ ! 364: static ! 365: writechars (start, end) ! 366: register char *start, *end; ! 367: { ! 368: register int temp_length; ! 369: ! 370: if ((cursY < 0) || (cursY >= screen_height)) ! 371: { ! 372: return; ! 373: } ! 374: if (CursorExists) ! 375: { ! 376: CursorToggle (); ! 377: } ! 378: if (InUpdate) ! 379: { ! 380: if (DesiredScreen && DesiredScreen[cursY + 1]) ! 381: { ! 382: temp_length = DesiredScreen[cursY + 1]->length; ! 383: } ! 384: else ! 385: temp_length = 0; ! 386: if (temp_length > 0) ! 387: { ! 388: XText (XXwindow, ! 389: 0, ! 390: (cursY * fontinfo->height), ! 391: &DesiredScreen[cursY + 1]->body[0], ! 392: temp_length, ! 393: fontinfo->id, ! 394: (CurHL ? back : fore), ! 395: (CurHL ? fore : back)); ! 396: if (temp_length < screen_width) ! 397: { ! 398: XTclear_end_of_line (temp_length); ! 399: } ! 400: XTtopos (cursY, temp_length); ! 401: } ! 402: else ! 403: { ! 404: XTclear_end_of_line (0); ! 405: XTtopos (cursY, 0); ! 406: } ! 407: } ! 408: else ! 409: { ! 410: if ((VisibleX < 0) || (VisibleX >= screen_width)) ! 411: { ! 412: return; ! 413: } ! 414: if ((VisibleY < 0) || (VisibleY >= screen_height)) ! 415: { ! 416: return; ! 417: } ! 418: if (((end - start) + VisibleX) >= screen_width) ! 419: { ! 420: end = start + (screen_width - (VisibleX + 1)); ! 421: } ! 422: if(end >= start) ! 423: { ! 424: XText (XXwindow, ! 425: (VisibleX * fontinfo->width), ! 426: (VisibleY * fontinfo->height), ! 427: start, ! 428: ((end - start) + 1), ! 429: fontinfo->id, ! 430: (CurHL ? back : fore), ! 431: (CurHL ? fore : back)); ! 432: VisibleX = VisibleX + (end - start) + 1; ! 433: } ! 434: if (!CursorExists) CursorToggle (); ! 435: } ! 436: } ! 437: ! 438: ! 439: static ! 440: XTwrite_chars (start, len) ! 441: register char *start; ! 442: register int len; ! 443: { ! 444: #ifdef XDEBUG ! 445: fprintf (stderr, "XTwrite_chars\n"); ! 446: #endif ! 447: writechars (start, start + len - 1); ! 448: } ! 449: ! 450: /* The following routine is for the deaf or for the pervert who prefers ! 451: * that his terminal flashes at him rather than beep at him. ! 452: */ ! 453: ! 454: static int flashedback; ! 455: ! 456: static ! 457: XTflash () ! 458: { ! 459: struct itimerval itimer; ! 460: extern int flashback (); ! 461: ! 462: #ifdef XDEBUG ! 463: fprintf (stderr, "XTflash\n"); ! 464: #endif ! 465: ! 466: signal (SIGALRM, flashback); ! 467: getitimer (ITIMER_REAL, &itimer); ! 468: itimer.it_value.tv_usec += 250000; ! 469: itimer.it_interval.tv_sec = 0; ! 470: itimer.it_interval.tv_usec = 0; ! 471: flashedback = 0; ! 472: setitimer (ITIMER_REAL, &itimer, 0); ! 473: XPixFill (XXwindow, 0, 0, screen_width * fontinfo->width, ! 474: screen_height * fontinfo->height, WhitePixel, ClipModeClipped, ! 475: GXinvert, AllPlanes); ! 476: XFlush (); ! 477: while (!flashedback) pause (); ! 478: } ! 479: ! 480: static ! 481: flashback () ! 482: { ! 483: signal (SIGALRM, SIG_IGN); ! 484: XPixFill (XXwindow, 0, 0, screen_width * fontinfo->width, ! 485: screen_height * fontinfo->height, WhitePixel, ClipModeClipped, ! 486: GXinvert, AllPlanes); ! 487: XFlush (); ! 488: flashedback = 1; ! 489: } ! 490: ! 491: /* A kludge to get a bell */ ! 492: ! 493: static ! 494: XTfeep () ! 495: { ! 496: #ifdef XDEBUG ! 497: fprintf (stderr, "XTfeep\n"); ! 498: #endif ! 499: XFeep (0); ! 500: } ! 501: ! 502: /* Artificially creating a cursor is hard, the actual position on the ! 503: * screen (either where it is or last was) is tracked with VisibleX,Y. ! 504: * Gnu Emacs code tends to assume a cursor exists in hardward at cursX,Y ! 505: * and that output text will appear there. During updates, the cursor is ! 506: * supposed to be blinked out and will only reappear after the update ! 507: * finishes. ! 508: */ ! 509: ! 510: CursorToggle () ! 511: { ! 512: register struct display_line **ActiveScreen; ! 513: if (!WindowMapped) ! 514: { ! 515: CursorExists = 0; ! 516: return 0; ! 517: } ! 518: if ((VisibleX < 0) || (VisibleX >= screen_width) || ! 519: (VisibleY < 0) || (VisibleY >= screen_height)) ! 520: { /* Current Cursor position trash */ ! 521: /* Not much can be done */ ! 522: XFlush (); ! 523: CursorExists = 0; ! 524: return 0; /* Currently the return values are not */ ! 525: /* used, but I could anticipate using */ ! 526: /* them in the future. */ ! 527: } ! 528: /* if(InUpdate && DesiredScreen) ! 529: ActiveScreen = DesiredScreen; ! 530: else*/ ! 531: ActiveScreen = PhysScreen; ! 532: if (ActiveScreen && ActiveScreen[VisibleY + 1] && ! 533: (VisibleX < ActiveScreen[VisibleY + 1]->length)) ! 534: { ! 535: if (CursorExists) ! 536: { ! 537: XText (XXwindow, ! 538: VisibleX * fontinfo->width, ! 539: VisibleY * fontinfo->height, ! 540: &ActiveScreen[VisibleY + 1]->body[VisibleX], 1, ! 541: fontinfo->id, ! 542: fore, back); ! 543: } ! 544: else ! 545: { ! 546: XText (XXwindow, ! 547: VisibleX * fontinfo->width, ! 548: VisibleY * fontinfo->height, ! 549: &ActiveScreen[VisibleY + 1]->body[VisibleX], 1, ! 550: fontinfo->id, ! 551: back, curs); ! 552: } ! 553: } ! 554: else if (CursorExists) ! 555: { ! 556: XPixSet (XXwindow, ! 557: VisibleX * fontinfo->width, ! 558: VisibleY * fontinfo->height, ! 559: fontinfo->width, fontinfo->height, back); ! 560: } ! 561: else ! 562: { ! 563: XPixSet (XXwindow, ! 564: VisibleX * fontinfo->width, ! 565: VisibleY * fontinfo->height, ! 566: fontinfo->width, fontinfo->height, curs); ! 567: } ! 568: CursorExists = !CursorExists;/* Cursor has either been blinked in */ ! 569: /* or out */ ! 570: if (!InUpdate) ! 571: { ! 572: XFlush (); ! 573: } ! 574: return 1; ! 575: } ! 576: ! 577: /* This routine is used by routines which are called to paint regions */ ! 578: /* designated by ExposeRegion events. If the cursor may be in the exposed */ ! 579: /* region, this routine makes sure it is gone so that dumprectangle can */ ! 580: /* toggle it back into existance if dumprectangle is invoked when not in */ ! 581: /* the midst of a screen update. */ ! 582: static ! 583: ClearCursor () ! 584: { ! 585: if (!WindowMapped) ! 586: { ! 587: CursorExists = 0; ! 588: return; ! 589: } ! 590: if ((VisibleX < 0) || (VisibleX >= screen_width) ! 591: || (VisibleY < 0) || (VisibleY >= screen_height)) ! 592: { /* Current Cursor position trash */ ! 593: /* Not much can be done */ ! 594: CursorExists = 0; ! 595: return; ! 596: } ! 597: XPixSet (XXwindow, ! 598: VisibleX * fontinfo->width, ! 599: VisibleY * fontinfo->height, ! 600: fontinfo->width, fontinfo->height, ! 601: back); ! 602: CursorExists = 0; ! 603: } ! 604: ! 605: static ! 606: XTupdate_begin () ! 607: { ! 608: #ifdef XDEBUG ! 609: fprintf (stderr, "XTupdate_begin\n"); ! 610: #endif ! 611: ! 612: InUpdate = 1; ! 613: if (CursorExists) ! 614: { ! 615: CursorToggle (); ! 616: } ! 617: SavedX = cursX; /* The initial"hardware" cursor position is */ ! 618: /* saved because that is where gnu emacs */ ! 619: /* expects the cursor to be at the end of*/ ! 620: /* the update */ ! 621: SavedY = cursY; ! 622: dumpqueue(); ! 623: } ! 624: ! 625: ! 626: static ! 627: XTupdate_end () ! 628: { ! 629: #ifdef XDEBUG ! 630: fprintf (stderr, "XTupdate_end\n"); ! 631: #endif ! 632: if (CursorExists) ! 633: CursorToggle (); ! 634: InUpdate = 0; ! 635: dumpqueue (); ! 636: XTtopos (SavedY, SavedX); /* XTtopos invokes cursor toggle */ ! 637: } ! 638: ! 639: /* Used for expose region and expose copy events. Have to get the text ! 640: * back into the newly blank areas. ! 641: */ ! 642: ! 643: dumprectangle (top, left, rows, cols) ! 644: register int top, left, rows, cols; ! 645: { ! 646: register struct display_line **ActiveScreen; ! 647: register int index; ! 648: int localX, localY, localHL; ! 649: rows += top; ! 650: cols += left; ! 651: top /= fontinfo->height; /* Get row and col containing up and */ ! 652: /* left borders of exposed region -- */ ! 653: /* round down here*/ ! 654: left /= fontinfo->width; ! 655: rows += (fontinfo->height - 1); ! 656: cols += (fontinfo->width - 1); ! 657: rows /= fontinfo->height;/* Get row and col containing bottom and */ ! 658: /* right borders -- round up here */ ! 659: rows -= top; ! 660: cols /= fontinfo->width; ! 661: cols -= left; ! 662: if (rows < 0) return; ! 663: if (cols < 0) return; ! 664: if (top > (screen_height - 1)) return; ! 665: if (left > (screen_width - 1)) return; ! 666: if ((VisibleX >= left) && (VisibleX < (left + cols)) && ! 667: (VisibleY >= top) && (VisibleY < (top + rows))) ! 668: { ! 669: ClearCursor (); ! 670: } ! 671: if (InUpdate && DesiredScreen) ! 672: ActiveScreen = PhysScreen; ! 673: else if (PhysScreen) ! 674: ActiveScreen = PhysScreen;/* When cue is dumped in update this */ ! 675: else ! 676: return; ! 677: /* should perhaps be DesiredScreen */ ! 678: /* but PhysScreen is guaranteed to contain*/ ! 679: /* date which was good for every line on */ ! 680: /* screen. For desired screen only for */ ! 681: /* lines which are changing. Emacs does */ ! 682: /* not consider a line within a newly */ ! 683: /* exposed region necessarily to have */ ! 684: /* been changed. Emacs knows nothing */ ! 685: /* about ExposeRegion events.*/ ! 686: for (localY = top, index = 0; ! 687: (index < rows) && (localY < screen_height); ! 688: ++index, ++localY) ! 689: { ! 690: if ((localY < 0) || (localY >= screen_height)) continue; ! 691: if (!ActiveScreen[localY + 1]) continue; ! 692: if ((left + 1) > ActiveScreen[localY + 1]->length) continue; ! 693: localX = left; ! 694: localHL = ActiveScreen[localY + 1]->highlighted; ! 695: dumpchars (ActiveScreen, ! 696: min (cols, ! 697: ActiveScreen[localY + 1]->length ! 698: - localX), ! 699: localX, localY, localHL); ! 700: } ! 701: if (!InUpdate && !CursorExists) CursorToggle (); ! 702: /* Routine usually called */ ! 703: /* when not in update */ ! 704: } ! 705: ! 706: /* What sections of the window will be modified from the UpdateDisplay ! 707: * routine is totally under software control. Any line with Y coordinate ! 708: * greater than flexlines will not change during an update. This is really ! 709: * used only during dellines and inslines routines (scraplines and stufflines) ! 710: */ ! 711: static ! 712: XTset_terminal_window (n) ! 713: register int n; ! 714: { ! 715: #ifdef XDEBUG ! 716: fprintf (stderr, "XTset_terminal_window\n"); ! 717: #endif ! 718: if ((n <= 0) || (n > screen_height)) ! 719: flexlines = screen_height; ! 720: else ! 721: flexlines = n; ! 722: } ! 723: ! 724: XTins_del_lines (vpos, n) ! 725: int vpos, n; ! 726: { ! 727: #ifdef XDEBUG ! 728: fprintf (stderr, "XTins_del_lines\n"); ! 729: #endif ! 730: XTtopos (vpos, 0); ! 731: if (n >= 0) stufflines (n); ! 732: else scraplines (-n); ! 733: ! 734: } ! 735: ! 736: static ! 737: XTinsert_chars (start, len) ! 738: register char *start; ! 739: register int len; ! 740: { ! 741: #ifdef XDEBUG ! 742: fprintf (stderr, "XTinsert_chars\n"); ! 743: #endif ! 744: writechars (start, start + len - 1); ! 745: } ! 746: ! 747: static ! 748: XTdelete_chars (n) ! 749: register int n; ! 750: { ! 751: char *msg = "***Delete Chars Called Outside of Update!!!***"; ! 752: #ifdef XDEBUG ! 753: fprintf (stderr, "XTdelete_chars\n"); ! 754: #endif ! 755: writechars (msg, msg + strlen (msg) - 1); ! 756: } ! 757: ! 758: static ! 759: stufflines (n) ! 760: register int n; ! 761: { ! 762: register int topregion, bottomregion; ! 763: register int length, newtop; ! 764: ! 765: if (cursY >= flexlines) ! 766: return; ! 767: ! 768: if (!WindowMapped) ! 769: { ! 770: bitblt = 0; ! 771: return; ! 772: } ! 773: if (CursorExists) CursorToggle (); ! 774: dumpqueue (); ! 775: topregion = cursY; ! 776: bottomregion = flexlines - (n + 1); ! 777: newtop = cursY + n; ! 778: length = (bottomregion - topregion) + 1; ! 779: if ((length > 0) && (newtop <= flexlines)) ! 780: { ! 781: /* Should already have cleared */ ! 782: /* queue of events associated */ ! 783: /* with old bitblts */ ! 784: XMoveArea (XXwindow, 0, ! 785: topregion * fontinfo->height, ! 786: 0, newtop * fontinfo->height, ! 787: screen_width * fontinfo->width, ! 788: length * fontinfo->height); ! 789: if (WindowMapped) ! 790: bitblt = 1; ! 791: request_sigio (); ! 792: XFlush (); ! 793: while (bitblt) ! 794: { ! 795: kill (XXpid, SIGIO); ! 796: } ! 797: unrequest_sigio (); ! 798: XFlush (); ! 799: } ! 800: newtop = min (newtop, (flexlines - 1)); ! 801: length = newtop - topregion; ! 802: if (length > 0) ! 803: { ! 804: XPixSet (XXwindow, ! 805: 0, ! 806: topregion * fontinfo->height, ! 807: screen_width * fontinfo->width, ! 808: n * fontinfo->height, ! 809: back); ! 810: } ! 811: /* if (!InUpdate) CursorToggle (); */ ! 812: } ! 813: ! 814: static ! 815: scraplines (n) ! 816: register int n; ! 817: { ! 818: if (!WindowMapped) ! 819: { ! 820: bitblt = 0; ! 821: return; ! 822: } ! 823: ! 824: if (cursY >= flexlines) ! 825: return; ! 826: if (CursorExists) CursorToggle (); ! 827: dumpqueue (); ! 828: if ((cursY + n) >= flexlines) ! 829: { ! 830: if (flexlines >= (cursY + 1)) ! 831: { ! 832: XPixSet (XXwindow, ! 833: 0, cursY * fontinfo->height, ! 834: screen_width * fontinfo->width, ! 835: (flexlines - cursY) * fontinfo->height, ! 836: back); ! 837: } ! 838: } ! 839: else ! 840: { ! 841: XMoveArea (XXwindow, ! 842: 0, (cursY + n) * fontinfo->height, ! 843: 0, cursY * fontinfo->height, ! 844: screen_width * fontinfo->width, ! 845: (flexlines - (cursY + n)) * fontinfo->height); ! 846: if (WindowMapped) ! 847: bitblt = 1; ! 848: request_sigio (); ! 849: XFlush (); ! 850: while (bitblt) ! 851: { ! 852: kill (XXpid, SIGIO); ! 853: } ! 854: unrequest_sigio (); ! 855: XFlush (); ! 856: XPixSet (XXwindow, 0, (flexlines - n) * fontinfo->height, ! 857: screen_width * fontinfo->width, ! 858: n * fontinfo->height, back); ! 859: } ! 860: /* if (!InUpdate) CursorToggle (); */ ! 861: } ! 862: ! 863: /* Substitutes for standard read routine. Under X not interested in individual ! 864: * bytes but rather individual packets. ! 865: */ ! 866: ! 867: XTread_socket (sd, bufp, numchars) ! 868: register int sd; ! 869: register char *bufp; ! 870: register int numchars; ! 871: { ! 872: ! 873: int count; ! 874: int stuffpending; ! 875: int temp_width, temp_height; ! 876: /* typedef struct reply {XEvent event; struct reply *next} Reply; ! 877: Reply *replies = NULL;*/ ! 878: ! 879: count = 0; ! 880: if (numchars <= 0) ! 881: { /* To keep from overflowing read buffer */ ! 882: numchars = 1; ! 883: --bufp; ! 884: } ! 885: while (bitblt || XPending () != 0) ! 886: { ! 887: /* while there are more events*/ ! 888: XNextEvent (&XXEvent); ! 889: switch (XXEvent.type) ! 890: { ! 891: /* case X_Reply: ! 892: { ! 893: extern char *malloc(); ! 894: Reply *reply = (Reply *) malloc (sizeof (Reply)); ! 895: reply->next = replies; ! 896: reply->event = XXEvent; ! 897: replies = reply; ! 898: break; ! 899: }*/ ! 900: default: ! 901: break; ! 902: case ExposeWindow: ! 903: if (((XExposeEvent *)&XXEvent)->window == XXIconWindow) ! 904: { ! 905: PendingIconExposure = 1; ! 906: } ! 907: else ! 908: PendingExposure = 1;/* No reason to repeat */ ! 909: /* this if several */ ! 910: /* ExposeWindow events */ ! 911: /* come in quick succes-*/ ! 912: /* ion */ ! 913: break; ! 914: case ExposeRegion: ! 915: if (PendingExposure) ! 916: { /* Don't bother with */ ! 917: /* region events when */ ! 918: /* full window event */ ! 919: /* is pending */ ! 920: break; ! 921: } ! 922: loadxrepbuffer (&XXEvent, &XXqueue); ! 923: if (XXqueue.rindex == XXqueue.windex) ! 924: { ! 925: PendingExposure = 1; ! 926: } ! 927: if ((XXqueue.rindex > XXqueue.mindex) || ! 928: (XXqueue.windex > XXqueue.mindex) || ! 929: (XXqueue.rindex < 0) || ! 930: (XXqueue.windex < 0)) ! 931: { ! 932: PendingExposure = 1; ! 933: } ! 934: break; ! 935: case ExposeCopy: /* For ExposeCopy sync */ ! 936: /* will block all outgoing */ ! 937: /* requests until this is */ ! 938: /* decremented */ ! 939: if (WindowMapped) bitblt = 0; ! 940: break; ! 941: case KeyPressed: ! 942: if (Input (((XKeyPressedEvent *) &XXEvent)->detail, bufp)) ! 943: { ! 944: ++bufp; ! 945: ++count; ! 946: --numchars; ! 947: } ! 948: break; ! 949: case ButtonPressed: ! 950: switch (spacecheck (Xxrepbuffer.mindex, ! 951: Xxrepbuffer.rindex, ! 952: Xxrepbuffer.windex, 0)) ! 953: { ! 954: case 0: ! 955: loadxrepbuffer (&XXEvent, ! 956: &Xxrepbuffer); ! 957: if (informflag) ! 958: { ! 959: *bufp++ = (char) 003; /* C-c */ ! 960: ++count; ! 961: --numchars; ! 962: *bufp++ = (char) '\r'; /* C-m */ ! 963: ++count; ! 964: --numchars; ! 965: } ! 966: break; ! 967: case -1: ! 968: break; ! 969: case -2: ! 970: default: ! 971: fixxrepbuffer (); ! 972: break; ! 973: } ! 974: break; ! 975: } ! 976: } ! 977: /* while (replies) { ! 978: Reply *reply = replies; ! 979: XPutBackEvent (&reply->event); ! 980: replies = reply->next; ! 981: free (reply); ! 982: }*/ ! 983: if (count < 0) ! 984: count = 0; ! 985: if (CursorExists) ! 986: xfixscreen (); ! 987: return count; ! 988: } ! 989: ! 990: /* refresh bitmap kitchen sink icon */ ! 991: refreshicon () ! 992: { ! 993: if (XXIconWindow) ! 994: XBitmapBitsPut (XXIconWindow, 0, 0, sink_width, sink_height, ! 995: sink_bits, BlackPixel, WhitePixel, ! 996: XXIconMask, GXcopy, AllPlanes); ! 997: XFlush (); ! 998: } ! 999: ! 1000: XBitmapIcon () ! 1001: { ! 1002: if (!IconWindow) ! 1003: { ! 1004: XSetIconWindow (XXwindow,XXIconWindow); ! 1005: XSelectInput (XXIconWindow, ExposeWindow); ! 1006: IconWindow = !IconWindow; ! 1007: } ! 1008: } ! 1009: ! 1010: XTextIcon () ! 1011: { ! 1012: if (IconWindow) ! 1013: { ! 1014: XClearIconWindow (XXwindow); ! 1015: XSelectInput (XXIconWindow, NoEvent); ! 1016: IconWindow = !IconWindow; ! 1017: } ! 1018: } ! 1019: ! 1020: /* Interpreting incoming keycodes. Should have table modifiable as needed ! 1021: * from elisp. ! 1022: */ ! 1023: ! 1024: /* Exit gracefully from gnuemacs, doing an autosave and giving a status. ! 1025: */ ! 1026: ! 1027: XExitGracefully () ! 1028: { ! 1029: XAutoSave(); ! 1030: exit(70); ! 1031: } ! 1032: ! 1033: xfixscreen () ! 1034: { ! 1035: register int temp_width, temp_height; ! 1036: register int (*func) (); ! 1037: register int temp_x, temp_y; ! 1038: dumpqueue (); ! 1039: func = signal (SIGIO, SIG_IGN); ! 1040: /* Check that the connection is in fact open. This works by doing a nop */ ! 1041: /* (well, almost) write operation. If there is an XIOerror or a */ ! 1042: /* SIGPIPE, exit gracefully. This fixes the loop-on-logout bug.*/ ! 1043: XIOErrorHandler (XExitGracefully); ! 1044: CursorToggle(); ! 1045: CursorToggle(); ! 1046: XFlush (); ! 1047: XIOErrorHandler (0); ! 1048: if (PendingIconExposure) ! 1049: { ! 1050: refreshicon (); ! 1051: PendingIconExposure = 0; ! 1052: } ! 1053: if (PendingExposure) ! 1054: { ! 1055: PendingExposure = 0; ! 1056: ClearCursor (); ! 1057: XXqueue.rindex = 0; ! 1058: XXqueue.windex = 0; ! 1059: XQueryWindow (XXwindow, &windowinfo); /* Dangerous to do */ ! 1060: /* writes here but */ ! 1061: /* otherwise would */ ! 1062: /* have to alter */ ! 1063: /* gnu emacs display */ ! 1064: /* routines to query */ ! 1065: /* when screen garbaged */ ! 1066: temp_width = (windowinfo.width / fontinfo->width); ! 1067: temp_height = (windowinfo.height / fontinfo->height); ! 1068: if (temp_width != screen_width || temp_height != screen_height) ! 1069: change_screen_size (temp_height, temp_width); ! 1070: temp_x = windowinfo.x; ! 1071: temp_y = windowinfo.y; ! 1072: if (temp_x != XXxoffset || temp_y != XXyoffset) ! 1073: XSetOffset (temp_x, temp_y); ! 1074: dumprectangle (0, 0, screen_height * fontinfo->height, ! 1075: screen_width * fontinfo->width); ! 1076: } ! 1077: if (!InUpdate) ! 1078: if (!CursorExists) ! 1079: CursorToggle (); ! 1080: (void) signal (SIGIO, func); ! 1081: kill (XXpid, SIGIO); ! 1082: } ! 1083: ! 1084: ! 1085: static ! 1086: Input (keycode, buffer) ! 1087: register int keycode; ! 1088: register char *buffer; ! 1089: { ! 1090: register short c; ! 1091: register int offset; ! 1092: extern KeyMapEntry StdMap[]; ! 1093: offset = KeyState (keycode); /* set SHIFT, CONTROL, META */ ! 1094: c = StdMap [keycode & ValueMask] [offset]; ! 1095: if ((keycode & ShiftLockMask) && (c >= 'a') && (c <= 'z')) ! 1096: { ! 1097: c += 'A' - 'a'; ! 1098: } ! 1099: keycode &= ValueMask; /* no longer need shift bits for anything */ ! 1100: if (! (c & ~377)) ! 1101: { ! 1102: *buffer = c; ! 1103: return 1; ! 1104: } ! 1105: switch (c) ! 1106: { ! 1107: /* case '\007': ! 1108: kill(XXpid, SIGINT); ! 1109: break;*/ ! 1110: case KEYPAD: ! 1111: case CURSOR: ! 1112: switch (keycode & ValueMask) ! 1113: { ! 1114: case 0247: /* left-arrow maps to C-B */ ! 1115: c = 002 | ((keycode & MetaMask) ? METABIT : 0); ! 1116: *buffer = c; ! 1117: return(1); ! 1118: case 0250: /* right-arrow maps to C-F */ ! 1119: c = 006 | ((keycode & MetaMask) ? METABIT : 0); ! 1120: *buffer = c; ! 1121: return(1); ! 1122: case 0252: /* up-arrow maps to C-P */ ! 1123: c = 020 | ((keycode & MetaMask) ? METABIT : 0); ! 1124: *buffer = c; ! 1125: return(1); ! 1126: case 0251: /* down-arrow maps to C-N */ ! 1127: c = 016 | ((keycode & MetaMask) ? METABIT : 0); ! 1128: *buffer = c; ! 1129: return(1); ! 1130: default: ! 1131: return(0); ! 1132: } ! 1133: case PFX: ! 1134: case (short) -1: ! 1135: case SHFT: ! 1136: case CNTL: ! 1137: case SYMBOL: ! 1138: case LOCK: ! 1139: case FUNC1: ! 1140: case FUNC2: ! 1141: case FUNC3: ! 1142: case FUNC4: ! 1143: case FUNC5: ! 1144: case FUNC6: ! 1145: case FUNC7: ! 1146: case FUNC8: ! 1147: case FUNC9: ! 1148: case FUNC10: ! 1149: case FUNC11: ! 1150: case FUNC12: ! 1151: case FUNC13: ! 1152: case FUNC14: ! 1153: case FUNC15: ! 1154: case FUNC16: ! 1155: case FUNC17: ! 1156: case FUNC18: ! 1157: case FUNC19: ! 1158: case FUNC20: ! 1159: case E1: ! 1160: case E2: ! 1161: case E3: ! 1162: case E4: ! 1163: case E5: ! 1164: case E6: ! 1165: return 0; ! 1166: default: ! 1167: *buffer = c; ! 1168: return 1; ! 1169: } ! 1170: } ! 1171: ! 1172: ! 1173: x_term_init () ! 1174: { ! 1175: register char *vardisplay; ! 1176: register char *colonpointer; ! 1177: register int status; ! 1178: extern char *getenv (); ! 1179: register int scratchindex; ! 1180: extern XTinterrupt_signal (); ! 1181: extern char *malloc (); ! 1182: ! 1183: vardisplay = getenv ("DISPLAY"); ! 1184: if (!vardisplay) ! 1185: { ! 1186: fprintf (stderr, "DISPLAY environment variable must be set\n"); ! 1187: exit (-200); ! 1188: } ! 1189: XXdisplay = XOpenDisplay (vardisplay); ! 1190: if (XXdisplay == (Display *) 0) ! 1191: { ! 1192: fprintf (stderr, "No X.\n"); ! 1193: exit (-99); ! 1194: } ! 1195: dup2 (dpyno (), 0); ! 1196: close (dpyno ()); ! 1197: dpyno () = 0; /* Looks a little strange? */ ! 1198: /* check the def of the */ ! 1199: /* macro, it is a genuine */ ! 1200: /* lvalue */ ! 1201: Xxrepbuffer.mindex = XREPBUFSIZE - 1; ! 1202: Xxrepbuffer.windex = 0; ! 1203: Xxrepbuffer.rindex = 0; ! 1204: XXqueue.mindex = XREPBUFSIZE - 1; ! 1205: XXqueue.windex = 0; ! 1206: XXqueue.rindex = 0; ! 1207: WindowMapped = 0; ! 1208: baud_rate = 9600; ! 1209: min_padding_speed = 10000; ! 1210: must_write_spaces = 1; ! 1211: informflag = 1; ! 1212: MetaFlag = 1; ! 1213: visible_bell = 1; ! 1214: interrupt_input = 1; ! 1215: inverse_video = 1; ! 1216: bitblt = 0; ! 1217: PendingExposure = 0; ! 1218: IconWindow = 0; ! 1219: ! 1220: fix_screen_hook = xfixscreen; ! 1221: clear_screen_hook = XTclear_screen; ! 1222: clear_end_of_line_hook = XTclear_end_of_line; ! 1223: ins_del_lines_hook = XTins_del_lines; ! 1224: change_line_highlight_hook = XTchange_line_highlight; ! 1225: insert_chars_hook = XTinsert_chars; ! 1226: write_chars_hook = XTwrite_chars; ! 1227: delete_chars_hook = XTdelete_chars; ! 1228: ring_bell_hook = XTfeep; ! 1229: reset_terminal_modes_hook = XTreset_terminal_modes; ! 1230: set_terminal_modes_hook = XTset_terminal_modes; ! 1231: update_begin_hook = XTupdate_begin; ! 1232: update_end_hook = XTupdate_end; ! 1233: set_terminal_window_hook = XTset_terminal_window; ! 1234: read_socket_hook = XTread_socket; ! 1235: topos_hook = XTtopos; ! 1236: /* raw_topos_hook = XTraw_topos; */ ! 1237: reassert_line_highlight_hook = XTreassert_line_highlight; ! 1238: scroll_region_ok = 1; /* we'll scroll partial screens */ ! 1239: char_ins_del_ok = 0; /* just as fast to write the line */ ! 1240: line_ins_del_ok = 1; /* we'll just blt 'em */ ! 1241: fast_clear_end_of_line = 1; /* X does this well */ ! 1242: memory_below_screen = 0; /* we don't remember what scrolls ! 1243: off the bottom */ ! 1244: dont_calculate_costs = 1; ! 1245: ! 1246: fore = BlackPixel; ! 1247: back = WhitePixel; ! 1248: brdr = BlackPixel; ! 1249: mous = BlackPixel; ! 1250: curs = BlackPixel; ! 1251: ! 1252: fore_color = "black"; ! 1253: back_color = "white"; ! 1254: brdr_color = "black"; ! 1255: mous_color = "black"; ! 1256: curs_color = "black"; ! 1257: ! 1258: XXpid = getpid (); ! 1259: XXcurrentfont = malloc (sizeof ("vtsingle") + 1); ! 1260: default_window = "=80x24+1+1"; ! 1261: signal (SIGIO, XTread_socket); ! 1262: signal (SIGPIPE, XExitGracefully); ! 1263: if (XXcurrentfont == (char *) 0) ! 1264: { ! 1265: fprintf (stderr, "Memory allocation failure.\n"); ! 1266: exit (-150); ! 1267: } ! 1268: strcpy (&XXcurrentfont[0], "vtsingle"); ! 1269: XQueryWindow (RootWindow, &rootwindowinfo); ! 1270: strncpy (iconidentity, ICONTAG, MAXICID); ! 1271: XXborder = 1; ! 1272: screen_width = 80; ! 1273: screen_height = 66; ! 1274: XXxoffset = 0; ! 1275: XXyoffset = 0; ! 1276: XXdebug = 0; ! 1277: fontinfo = XOpenFont (&XXcurrentfont[0]); ! 1278: if (fontinfo == (FontInfo *) 0) ! 1279: { ! 1280: fprintf (stderr, "No font\n"); ! 1281: exit (-98); ! 1282: } ! 1283: pixelwidth = screen_width * fontinfo->width + 1; ! 1284: pixelheight = screen_height * fontinfo->height + 1; ! 1285: XXwindow = XCreateWindow (RootWindow, ! 1286: XXxoffset /* Absolute horizontal offset */, ! 1287: XXyoffset /* Absolute Vertical offset */, ! 1288: pixelwidth, pixelheight, ! 1289: XXborder, BlackPixmap, WhitePixmap); ! 1290: if (!XXwindow) ! 1291: { ! 1292: fprintf (stderr, "Unable to create window.\n"); ! 1293: exit (-97); ! 1294: } ! 1295: ! 1296: XXIconWindow = XCreateWindow (RootWindow, 0, 0, sink_width, sink_height, ! 1297: 2, WhitePixmap, (Pixmap) NULL); ! 1298: ! 1299: if (!XXIconWindow) ! 1300: { ! 1301: fprintf (stderr, "Unable to create icon window.\n"); ! 1302: fflush (stderr); ! 1303: exit (-97); ! 1304: } ! 1305: XSelectInput (XXIconWindow, NoEvent); ! 1306: XXIconMask = XStoreBitmap(sink_mask_width, sink_mask_height, sink_mask_bits); ! 1307: ! 1308: XSelectInput (XXwindow, NoEvent); ! 1309: XSetResizeHint (XXwindow, fontinfo->width * 10, fontinfo->height *5, ! 1310: fontinfo->width, fontinfo->height); ! 1311: ! 1312: if (gethostname (&iconidentity[sizeof (ICONTAG) - 1], ! 1313: (MAXICID - 1) - sizeof (ICONTAG))) ! 1314: { ! 1315: iconidentity[sizeof (ICONTAG) - 2] = '\0'; ! 1316: } ! 1317: XStoreName (XXwindow, &iconidentity[0]); ! 1318: ! 1319: EmacsCursor = XCreateCursor (16, 16, MouseCursor, MouseMask, ! 1320: 0, 0, BlackPixel, WhitePixel, GXcopy); ! 1321: XDefineCursor (XXwindow, EmacsCursor); ! 1322: /* Dirty kluge so maybe things will work right */ ! 1323: XBitmapIcon(); ! 1324: XTextIcon(); ! 1325: flexlines = screen_height; ! 1326: if (!initialized) ! 1327: XPopUpWindow (); ! 1328: setxterm (); ! 1329: } ! 1330: ! 1331: ! 1332: /* Process all queued ExposeRegion events. */ ! 1333: static ! 1334: dumpqueue () ! 1335: { ! 1336: register int i; ! 1337: XExposeRegionEvent r; ! 1338: if ((XXqueue.rindex > XXqueue.mindex) || ! 1339: (XXqueue.windex > XXqueue.mindex) || ! 1340: (XXqueue.rindex < 0) || ! 1341: (XXqueue.windex < 0)) ! 1342: { ! 1343: PendingExposure = 1; ! 1344: } ! 1345: else ! 1346: while (XXqueue.rindex != XXqueue.windex) ! 1347: { ! 1348: if (CursorExists) ! 1349: CursorToggle (); ! 1350: unloadxrepbuffer (&r, &XXqueue); ! 1351: dumprectangle (r.y, r.x, r.height, r.width); ! 1352: } ! 1353: } ! 1354: ! 1355: ! 1356: ! 1357: XSetFlash () ! 1358: { ! 1359: ring_bell_hook = XTflash; ! 1360: } ! 1361: ! 1362: XSetFeep () ! 1363: { ! 1364: ring_bell_hook = XTfeep; ! 1365: } ! 1366: ! 1367: ! 1368: XNewFont (newname) ! 1369: register char *newname; ! 1370: { ! 1371: FontInfo *temp; ! 1372: int (*func) (); ! 1373: func = signal (SIGIO, SIG_IGN); ! 1374: XFlush (); ! 1375: if (XXdebug) ! 1376: fprintf (stderr, "Request id is %d\n", XXdisplay->request); ! 1377: temp = XOpenFont (newname); ! 1378: if (temp == (FontInfo *) 0) ! 1379: { ! 1380: (void) signal (SIGIO, func); ! 1381: if (QLength () > 0) ! 1382: { ! 1383: kill (XXpid, SIGIO); ! 1384: } ! 1385: return -1; ! 1386: } ! 1387: XCloseFont (fontinfo); ! 1388: fontinfo = temp; ! 1389: (void) signal (SIGIO, func); ! 1390: XSetResizeHint (XXwindow, fontinfo->width * 10, fontinfo->height *5, ! 1391: fontinfo->width, fontinfo->height); ! 1392: XSetWindowSize (screen_height, screen_width); ! 1393: if (QLength () > 0) ! 1394: { ! 1395: kill (XXpid, SIGIO); ! 1396: } ! 1397: return 0; ! 1398: } ! 1399: ! 1400: XFlipColor () ! 1401: { ! 1402: Pixmap temp; ! 1403: int tempcolor; ! 1404: char *tempname; ! 1405: int (*func) (); ! 1406: Cursor temp_curs; ! 1407: CursorToggle (); ! 1408: func = signal (SIGIO, SIG_IGN); ! 1409: temp = XMakeTile(fore); ! 1410: XChangeBackground (XXwindow, temp); ! 1411: XFreePixmap (temp); ! 1412: temp = XMakeTile (back); ! 1413: if (XXborder) ! 1414: XChangeBorder (XXwindow, temp); ! 1415: XFreePixmap(temp); ! 1416: brdr = back; ! 1417: brdr_color = back_color; ! 1418: tempcolor = fore; ! 1419: fore = back; ! 1420: back = tempcolor; ! 1421: tempname = fore_color ; ! 1422: fore_color = back_color; ! 1423: back_color = tempname; ! 1424: /* XPixFill (XXwindow, 0, 0, screen_width * fontinfo->width, ! 1425: screen_height * fontinfo->height, back, ClipModeClipped, ! 1426: GXcopy, AllPlanes); ! 1427: dumprectangle(0, 0, screen_height * fontinfo->height, ! 1428: screen_width * fontinfo -> width);*/ ! 1429: XRedrawDisplay(); ! 1430: if (curs == WhitePixel) ! 1431: { ! 1432: curs = BlackPixel; ! 1433: curs_color = "black"; ! 1434: } ! 1435: else if (curs == BlackPixel) ! 1436: { ! 1437: curs = WhitePixel; ! 1438: curs_color = "white"; ! 1439: } ! 1440: if (mous == WhitePixel) ! 1441: { ! 1442: mous = BlackPixel; ! 1443: mous_color = "black"; ! 1444: } ! 1445: else if (mous == BlackPixel) ! 1446: { ! 1447: mous = WhitePixel; ! 1448: mous_color = "white"; ! 1449: } ! 1450: temp_curs = XCreateCursor(16, 16, MouseCursor, MouseMask, 0, 0, ! 1451: mous, back, GXcopy); ! 1452: XUndefineCursor (XXwindow); ! 1453: XDefineCursor (XXwindow, temp_curs); ! 1454: XFreeCursor (EmacsCursor); ! 1455: (void) signal (SIGIO, func); ! 1456: bcopy (&temp_curs, &EmacsCursor, sizeof (Cursor)); ! 1457: CursorToggle (); ! 1458: XFlush (); ! 1459: } ! 1460: ! 1461: XSetOffset (xoff, yoff) ! 1462: register int xoff, yoff; ! 1463: { ! 1464: if (xoff < 0) ! 1465: { ! 1466: XXxoffset = rootwindowinfo.width + (++xoff) - pixelwidth - 4; ! 1467: } ! 1468: else ! 1469: { ! 1470: XXxoffset = xoff; ! 1471: } ! 1472: if (yoff < 0) ! 1473: { ! 1474: XXyoffset ! 1475: = rootwindowinfo.height + (++yoff) - pixelheight - 4; ! 1476: } ! 1477: else ! 1478: { ! 1479: XXyoffset = yoff; ! 1480: } ! 1481: XMoveWindow (XXwindow, XXxoffset, XXyoffset); ! 1482: /* XWarpMouse (XXwindow, pixelwidth >> 1, pixelheight >> 1); */ ! 1483: } ! 1484: ! 1485: XSetWindowSize (rows, cols) ! 1486: register int rows, cols; ! 1487: { ! 1488: if (rows < 5) rows = 66; ! 1489: if (cols < 5) cols = 80; ! 1490: pixelwidth = cols * fontinfo->width + 1; ! 1491: pixelheight = rows * fontinfo->height + 1; ! 1492: XChangeWindow (XXwindow, pixelwidth, pixelheight); ! 1493: XFlush (); ! 1494: change_screen_size (rows, cols); ! 1495: PendingExposure = 0; ! 1496: } ! 1497: ! 1498: XPopUpWindow () ! 1499: { ! 1500: if (WindowMapped) ! 1501: return; ! 1502: if(!x_edges_specified) ! 1503: Fx_rubber_band (); ! 1504: bitblt = 0; ! 1505: CursorExists = 0; ! 1506: VisibleX = 0; ! 1507: VisibleY = 0; ! 1508: WindowMapped = 1; ! 1509: XMapWindow (XXwindow); ! 1510: dumprectangle (0, 0, screen_height * fontinfo->height, ! 1511: screen_width * fontinfo->width); ! 1512: XSelectInput (XXwindow, KeyPressed | ExposeWindow | ! 1513: ButtonPressed | ExposeRegion | ExposeCopy); ! 1514: /* XWarpMouse(XXwindow, pixelwidth >> 1, pixelheight >> 1);*/ ! 1515: XTtopos (0, 0); ! 1516: /* XRedrawDisplay();*/ ! 1517: XFlush (); ! 1518: } ! 1519: ! 1520: spacecheck (mindex, rindex, windex, minfreespace) ! 1521: register int mindex, rindex, windex, minfreespace; ! 1522: { ! 1523: if ((rindex > mindex) || (windex > mindex)) ! 1524: { ! 1525: fprintf (stderr, "Fatal Mouse Buffer Error.\n"); ! 1526: fprintf (stderr, "%d = mindex, %d = rindex, %d = windex\n", ! 1527: mindex, rindex, windex); ! 1528: return -2; ! 1529: } ! 1530: if (windex >= rindex) ! 1531: { ! 1532: if ((mindex - (windex - rindex)) > minfreespace) ! 1533: return 0; ! 1534: } ! 1535: else ! 1536: { ! 1537: if (((rindex - windex) - 1) > minfreespace) ! 1538: return 0; ! 1539: } ! 1540: return -1; ! 1541: } ! 1542: ! 1543: loadxrepbuffer (p_xrep, p_buffer) ! 1544: register XEvent *p_xrep; ! 1545: register XREPBUFFER *p_buffer; ! 1546: { ! 1547: p_buffer->xrep[p_buffer->windex] = *p_xrep; ! 1548: if (p_buffer->windex == p_buffer->mindex) ! 1549: p_buffer->windex = 0; ! 1550: else ! 1551: p_buffer->windex++; ! 1552: } ! 1553: ! 1554: unloadxrepbuffer (p_xrep, p_buffer) ! 1555: register XEvent *p_xrep; ! 1556: register XREPBUFFER *p_buffer; ! 1557: { ! 1558: if (p_buffer->windex == p_buffer->rindex) ! 1559: return -1; ! 1560: *p_xrep = p_buffer->xrep[p_buffer->rindex]; ! 1561: if (p_buffer->rindex == p_buffer->mindex) ! 1562: p_buffer->rindex = 0; ! 1563: else ! 1564: p_buffer->rindex++; ! 1565: return 0; ! 1566: } ! 1567: ! 1568: fixxrepbuffer () ! 1569: { ! 1570: Xxrepbuffer.mindex = XREPBUFSIZE - 1; ! 1571: Xxrepbuffer.windex = 0; ! 1572: Xxrepbuffer.rindex = 0; ! 1573: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.