xterm.c 99.9 KB
Newer Older
Jim Blandy's avatar
Jim Blandy committed
1
/* X Communication module for terminals which understand the X protocol.
Jim Blandy's avatar
Jim Blandy committed
2
   Copyright (C) 1989, 1992 Free Software Foundation, Inc.
Jim Blandy's avatar
Jim Blandy committed
3 4 5 6 7

This file is part of GNU Emacs.

GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Jim Blandy's avatar
Jim Blandy committed
8
the Free Software Foundation; either version 2, or (at your option)
Jim Blandy's avatar
Jim Blandy committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
any later version.

GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* Serious problems:

   Kludge: dup2 is used to put the X-connection socket into desc # 0
   so that wait_reading_process_input will wait for it in place of
   actual terminal input.
   
*/

#include "config.h"

#ifdef HAVE_X_WINDOWS

#include "lisp.h"

/* On 4.3 this loses if it comes after xterm.h.  */
#include <signal.h>

/* This may include sys/types.h, and that somehow loses
   if this is not done before the other system files.  */
#include "xterm.h"

41
#ifndef USG
Jim Blandy's avatar
Jim Blandy committed
42 43 44 45 46
/* Load sys/types.h if not already loaded.
   In some systems loading it twice is suicidal.  */
#ifndef makedev
#include <sys/types.h>
#endif
47
#endif
Jim Blandy's avatar
Jim Blandy committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

#ifdef BSD
#include <sys/ioctl.h>
#include <strings.h>
#else
#include <sys/termio.h>
#include <string.h>
#endif

/* Allow m- file to inhibit use of FIONREAD.  */
#ifdef BROKEN_FIONREAD
#undef FIONREAD
#endif

/* We are unable to use interrupts if FIONREAD is not available,
   so flush SIGIO so we won't try.  */
#ifndef FIONREAD
#ifdef SIGIO
#undef SIGIO
#endif
#endif

Jim Blandy's avatar
Jim Blandy committed
70
#include "systime.h"
Jim Blandy's avatar
Jim Blandy committed
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

#include <fcntl.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <setjmp.h>
#include <sys/stat.h>
#include <sys/param.h>

#include "dispextern.h"
#include "termhooks.h"
#include "termopts.h"
#include "termchar.h"
#if 0
#include "sink.h"
#include "sinkmask.h"
#endif
#include "gnu.h"
Jim Blandy's avatar
Jim Blandy committed
89
#include "frame.h"
Jim Blandy's avatar
Jim Blandy committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
#include "disptab.h"
#include "buffer.h"

#ifdef HAVE_X11
#define XMapWindow XMapRaised		/* Raise them when mapping. */
#else
#include <X/Xkeyboard.h>
/*#include <X/Xproto.h>	*/
#endif /* HAVE_X11 */

/* For sending Meta-characters.  Do we need this? */
#define METABIT 0200

#define min(a,b) ((a)<(b) ? (a) : (b))
#define max(a,b) ((a)>(b) ? (a) : (b))

/* Nonzero means we must reprint all windows
   because 1) we received an ExposeWindow event
   or 2) we received too many ExposeRegion events to record.  */

static int expose_all_windows;

/* Nonzero means we must reprint all icon windows.  */

static int expose_all_icons;

#ifndef HAVE_X11
/* ExposeRegion events, when received, are copied into this queue
   for later processing.  */

static struct event_queue x_expose_queue;

/* ButtonPressed and ButtonReleased events, when received,
   are copied into this queue for later processing.  */

struct event_queue x_mouse_queue;
#endif

/* Nonzero after BLOCK_INPUT; prevents input events from being
   processed until later.  */

int x_input_blocked;

#if defined (SIGIO) && defined (FIONREAD)
int BLOCK_INPUT_mask;
#endif

/* Nonzero if input events came in while x_input_blocked was nonzero.
   UNBLOCK_INPUT checks for this.  */

int x_pending_input;

/* The id of a bitmap used for icon windows.
   One such map is shared by all Emacs icon windows.
   This is zero if we have not yet had a need to create the bitmap.  */

static Bitmap icon_bitmap;

/* Font used for text icons.  */

static FONT_TYPE *icon_font_info;

/* Stuff for dealing with the main icon title. */

extern Lisp_Object Vcommand_line_args;
Jim Blandy's avatar
Jim Blandy committed
155
char *hostname, *x_id_name;
Jim Blandy's avatar
Jim Blandy committed
156
Lisp_Object invocation_name;
Jim Blandy's avatar
Jim Blandy committed
157 158 159 160 161

/* This is the X connection that we are using.  */

Display *x_current_display;

Jim Blandy's avatar
Jim Blandy committed
162
/* Frame being updated by update_frame.  */
Jim Blandy's avatar
Jim Blandy committed
163 164
/* This is set by XTupdate_begin and looked at by all the
   XT functions.  It is zero while not inside an update.
Jim Blandy's avatar
Jim Blandy committed
165 166
   In that case, the XT functions assume that `selected_frame'
   is the frame to apply to.  */
Jim Blandy's avatar
Jim Blandy committed
167

Jim Blandy's avatar
Jim Blandy committed
168
static struct frame *updating_frame;
Jim Blandy's avatar
Jim Blandy committed
169

Jim Blandy's avatar
Jim Blandy committed
170 171 172
/* The frame (if any) which has the X window that has keyboard focus.
   Zero if none.  This is examined by Ffocus_frame in frame.c.  */
struct frame *x_focus_frame;
Jim Blandy's avatar
Jim Blandy committed
173

Jim Blandy's avatar
Jim Blandy committed
174 175 176 177
/* The frame which currently has the visual highlight, and should get
   keyboard input (other sorts of input have the frame encoded in the
   event).  It points to the X focus frame's selected window's
   frame.  It differs from x_focus_frame when we're using a global
Jim Blandy's avatar
Jim Blandy committed
178
   minibuffer.  */
Jim Blandy's avatar
Jim Blandy committed
179
static struct frame *x_highlight_frame;
Jim Blandy's avatar
Jim Blandy committed
180

Jim Blandy's avatar
Jim Blandy committed
181
/* From .Xdefaults, the value of "emacs.WarpMouse".  If non-zero,
Jim Blandy's avatar
Jim Blandy committed
182
   mouse is moved to inside of frame when frame is de-iconified.  */
Jim Blandy's avatar
Jim Blandy committed
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258

static int warp_mouse_on_deiconify;

/* During an update, maximum vpos for ins/del line operations to affect.  */

static int flexlines;

/* During an update, nonzero if chars output now should be highlighted.  */

static int highlight;

/* Nominal cursor position -- where to draw output.
   During an update, these are different from the cursor-box position.  */

static int curs_x;
static int curs_y;

#ifdef HAVE_X11
/* `t' if a mouse button is depressed. */

extern Lisp_Object Vmouse_depressed;

/* Tells if a window manager is present or not. */

extern Lisp_Object Vx_no_window_manager;

/* Timestamp that we requested selection data was made. */
extern Time requestor_time;

/* ID of the window requesting selection data. */
extern Window requestor_window;

/* Nonzero enables some debugging for the X interface code. */
extern int _Xdebug;

#else /* X10 stuff */

/* Bit patterns for the mouse cursor.  */

short MouseCursor[] = {
  0x0000, 0x0008, 0x0018, 0x0038,
  0x0078, 0x00f8, 0x01f8, 0x03f8,
  0x07f8, 0x00f8, 0x00d8, 0x0188,
  0x0180, 0x0300, 0x0300, 0x0000};

short MouseMask[] = {
  0x000c, 0x001c, 0x003c, 0x007c,
  0x00fc, 0x01fc, 0x03fc, 0x07fc,
  0x0ffc, 0x0ffc, 0x01fc, 0x03dc,
  0x03cc, 0x0780, 0x0780, 0x0300};

static short grey_bits[] = {
  0x0005, 0x000a, 0x0005, 0x000a};

static Pixmap GreyPixmap = 0;
#endif /* X10 stuff */

/* From time to time we get info on an Emacs window, here.  */

static WINDOWINFO_TYPE windowinfo;

extern int errno;

extern Display *XOpenDisplay ();
extern Window XCreateWindow ();

extern Cursor XCreateCursor ();
extern FONT_TYPE *XOpenFont ();

static void flashback ();

#ifndef HAVE_X11
static void dumpqueue ();
#endif

void dumpborder ();
Jim Blandy's avatar
Jim Blandy committed
259 260
static int XTcursor_to ();
static int XTclear_end_of_line ();
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316

/* R3/R4 compatibility stuff.  Rah.  */


/* Set the property PROPERTY on the window displaying FRAME to VALUE.
   VALUE must be a string.
   
   We use this function instead of XSetWMName and XStoreName, since
   the former isn't present in R3, while the latter isn't likely to
   stay around.  XChangeProperty, however, is likely to be around.

   I have no idea if this is the right thing to do.  Someone who is more
   hip on how X is supposed to work should let us know if this is wrong.  */

x_set_text_property (f, property, value)
     FRAME_PTR f;
     Atom property;
     Lisp_Object value;
{
  BLOCK_INPUT;

#ifdef HAVE_X11R4
  {
    XTextProperty text;
    text.value = XSTRING (value)->data;
    text.encoding = XA_STRING;
    text.format = 8;
    text.nitems = XSTRING (value)->size;
    switch (property)
      {
      case XA_WM_NAME:
	XSetWMName (x_current_display, f->display.x->window_desc, &text);
	break;
      case XA_WM_ICON_NAME:
	XSetWMIconName (x_current_display, f->display.x->window_desc, &text);
	break;
      default:
	/* If you want to use this function, you have to make sure it supports
	   the atoms you want!  Dummy.  */
	abort ();
      }
  }
#else
  XChangeProperty (x_current_display,
		   f->display.x->window_desc,
		   prop,
		   XA_STRING,	/* type */
		   8,		/* format */
		   PropModeReplace, /* mode */
		   XSTRING (value)->data,
		   XSTRING (value)->size);
#endif

  UNBLOCK_INPUT;
}

Jim Blandy's avatar
Jim Blandy committed
317

Jim Blandy's avatar
Jim Blandy committed
318 319 320 321
/* These hooks are called by update_frame at the beginning and end
   of a frame update.  We record in `updating_frame' the identity
   of the frame being updated, so that the XT... functions do not
   need to take a frame as argument.  Most of the XT... functions
Jim Blandy's avatar
Jim Blandy committed
322 323 324 325 326 327
   should never be called except during an update, the only exceptions
   being XTcursor_to, XTwrite_char and XTreassert_line_highlight.  */

extern int mouse_track_top, mouse_track_left, mouse_track_width;

static
Jim Blandy's avatar
Jim Blandy committed
328 329
XTupdate_begin (f)
     struct frame *f;
Jim Blandy's avatar
Jim Blandy committed
330 331 332
{	
  int mask;

Jim Blandy's avatar
Jim Blandy committed
333
  if (f == 0)
Jim Blandy's avatar
Jim Blandy committed
334 335
    abort ();

Jim Blandy's avatar
Jim Blandy committed
336 337
  updating_frame = f;
  flexlines = f->height;
Jim Blandy's avatar
Jim Blandy committed
338 339 340 341 342 343 344 345 346 347 348 349
  highlight = 0;

  BLOCK_INPUT;
#ifndef HAVE_X11
  dumpqueue ();
#endif
  UNBLOCK_INPUT;
}

static void x_do_pending_expose ();

static
Jim Blandy's avatar
Jim Blandy committed
350 351
XTupdate_end (f)
     struct frame *f;
Jim Blandy's avatar
Jim Blandy committed
352 353 354
{	
  int mask;

Jim Blandy's avatar
Jim Blandy committed
355 356
  if (updating_frame == 0
      || updating_frame != f)
Jim Blandy's avatar
Jim Blandy committed
357 358 359 360 361 362
    abort ();

  BLOCK_INPUT;
#ifndef HAVE_X11
  dumpqueue ();
#endif
Jim Blandy's avatar
Jim Blandy committed
363
  adjust_scrollbars (f);
Jim Blandy's avatar
Jim Blandy committed
364 365
  x_do_pending_expose ();

Jim Blandy's avatar
Jim Blandy committed
366
  x_display_cursor (f, 1);
Jim Blandy's avatar
Jim Blandy committed
367

Jim Blandy's avatar
Jim Blandy committed
368
  updating_frame = 0;
Jim Blandy's avatar
Jim Blandy committed
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
  XFlushQueue ();
  UNBLOCK_INPUT;
}

/* External interface to control of standout mode.
   Call this when about to modify line at position VPOS
   and not change whether it is highlighted.  */

XTreassert_line_highlight (new, vpos)
     int new, vpos;
{
  highlight = new;
}

/* Call this when about to modify line at position VPOS
   and change whether it is highlighted.  */

static
XTchange_line_highlight (new_highlight, vpos, first_unused_hpos)
     int new_highlight, vpos, first_unused_hpos;
{
  highlight = new_highlight;
  XTcursor_to (vpos, 0);
Jim Blandy's avatar
Jim Blandy committed
392
  XTclear_end_of_line (updating_frame->width);
Jim Blandy's avatar
Jim Blandy committed
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
}

/* This is used when starting Emacs and when restarting after suspend.
   When starting Emacs, no X window is mapped.  And nothing must be done
   to Emacs's own window if it is suspended (though that rarely happens).  */

static
XTset_terminal_modes ()
{
}

/* This is called when exiting or suspending Emacs.
   Exiting will make the X-windows go away, and suspending
   requires no action.  */

static
XTreset_terminal_modes ()
{
Jim Blandy's avatar
Jim Blandy committed
411
/*  XTclear_frame ();  */
Jim Blandy's avatar
Jim Blandy committed
412 413
}

Jim Blandy's avatar
Jim Blandy committed
414
/* Set the nominal cursor position of the frame:
Jim Blandy's avatar
Jim Blandy committed
415 416 417
   where display update commands will take effect.
   This does not affect the place where the cursor-box is displayed.  */

Jim Blandy's avatar
Jim Blandy committed
418
static int
Jim Blandy's avatar
Jim Blandy committed
419 420 421 422 423 424 425 426 427
XTcursor_to (row, col)
     register int row, col;
{
  int mask;
  int orow = row;

  curs_x = col;
  curs_y = row;

Jim Blandy's avatar
Jim Blandy committed
428
  if (updating_frame == 0)
Jim Blandy's avatar
Jim Blandy committed
429 430
    {
      BLOCK_INPUT;
Jim Blandy's avatar
Jim Blandy committed
431
      x_display_cursor (selected_frame, 1);
Jim Blandy's avatar
Jim Blandy committed
432 433 434 435 436 437 438 439 440 441 442 443
      XFlushQueue ();
      UNBLOCK_INPUT;
    }
}

/* Display a sequence of N glyphs found at GP.
   WINDOW is the x-window to output to.  LEFT and TOP are starting coords.
   HL is 1 if this text is highlighted, 2 if the cursor is on it.

   FONT is the default font to use (for glyphs whose font-code is 0).  */

static void
Jim Blandy's avatar
Jim Blandy committed
444 445
dumpglyphs (f, left, top, gp, n, hl, font)
     struct frame *f;
Jim Blandy's avatar
Jim Blandy committed
446 447 448 449 450 451 452
     int left, top;
     register GLYPH *gp; /* Points to first GLYPH. */
     register int n;  /* Number of glyphs to display. */
     int hl;
     FONT_TYPE *font;
{
  register int len;
Jim Blandy's avatar
Jim Blandy committed
453 454 455 456
  Window window = f->display.x->window_desc;
  GC drawing_gc =   (hl == 2 ? f->display.x->cursor_gc
		             : (hl ? f->display.x->reverse_gc
				   : f->display.x->normal_gc));
Jim Blandy's avatar
Jim Blandy committed
457

Jim Blandy's avatar
Jim Blandy committed
458 459 460 461 462 463 464 465 466 467
  if (sizeof (GLYPH) == sizeof (XChar2b))
    XDrawImageString16 (x_current_display, window, drawing_gc,
			left, top + FONT_BASE (font), (XChar2b *) gp, n);
  else if (sizeof (GLYPH) == sizeof (unsigned char))
    XDrawImageString (x_current_display, window, drawing_gc,
		      left, top + FONT_BASE (font), (char *) gp, n);
  else
    /* What size of glyph ARE you using?  And does X have a function to
       draw them?  */
    abort ();
Jim Blandy's avatar
Jim Blandy committed
468 469 470 471
}

#if 0
static void
Jim Blandy's avatar
Jim Blandy committed
472 473
dumpglyphs (f, left, top, gp, n, hl, font)
     struct frame *f;
Jim Blandy's avatar
Jim Blandy committed
474 475 476 477 478 479
     int left, top;
     register GLYPH *gp; /* Points to first GLYPH. */
     register int n;  /* Number of glyphs to display. */
     int hl;
     FONT_TYPE *font;
{
Jim Blandy's avatar
Jim Blandy committed
480
  char buf[f->width]; /* Holds characters to be displayed. */
Jim Blandy's avatar
Jim Blandy committed
481 482 483
  register char *cp;		/* Steps through buf[]. */
  register int tlen = GLYPH_TABLE_LENGTH;
  register Lisp_Object *tbase = GLYPH_TABLE_BASE;
Jim Blandy's avatar
Jim Blandy committed
484 485 486 487 488
  Window window = f->display.x->window_desc;
  int cursor_pixel = f->display.x->cursor_pixel;
  int fg_pixel = f->display.x->foreground_pixel;
  int bg_pixel = f->display.x->background_pixel;
  int intborder = f->display.x->internal_border_width;
Jim Blandy's avatar
Jim Blandy committed
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524

  while (n)
    {
      /* Get the face-code of the next GLYPH.  */
      int cf, len;
      int g = *gp;

      while (GLYPH_ALIAS_P (tbase, tlen, g))
	g = GLYPH_ALIAS (tbase, g);
	
      cf = g >> 8;

      /* Find the run of consecutive glyphs with the same face-code.
	 Extract their character codes into BUF.  */
      cp = buf;
      while (n > 0)
	{
	  g = *gp;
	  while (GLYPH_ALIAS_P (tbase, tlen, g))
	    g = GLYPH_ALIAS (tbase, g);
	  if ((g >> 8) != cf)
	    break;

	  *cp++ = 0377 & g;
	  --n;
	  ++gp;
	}

      /* LEN gets the length of the run.  */
      len = cp - buf;

      /* Now output this run of chars, with the font and pixel values
	 determined by the face code CF.  */
      if (cf == 0)
	{
#ifdef HAVE_X11
Jim Blandy's avatar
Jim Blandy committed
525 526 527
	  GC GC_cursor = f->display.x->cursor_gc;
	  GC GC_reverse = f->display.x->reverse_gc;
	  GC GC_normal = f->display.x->normal_gc;
Jim Blandy's avatar
Jim Blandy committed
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549

	  XDrawImageString (x_current_display, window,
			    (hl == 2
			     ? GC_cursor
			     : (hl ? GC_reverse : GC_normal)),
			    left, top + FONT_BASE (font), buf, len);
#else
	  XText (window, left, top,
		 buf,
		 len,
		 font->id,
		 (hl == 2
		  ? (cursor_pixel == fg_pixel ? bg_pixel : fg_pixel)
		  : hl ? bg_pixel : fg_pixel),
		 (hl == 2 ? cursor_pixel
		  : hl ? fg_pixel : bg_pixel));
#endif /* HAVE_X11 */
	}
      else
	{
#ifdef HAVE_X11
	  if (FACE_IS_FONT (cf))
Jim Blandy's avatar
Jim Blandy committed
550
	    XDrawImageString (x_current_display, f->display.x->window_desc,
Jim Blandy's avatar
Jim Blandy committed
551 552 553 554 555
			      FACE_GC (cf),
			      left, top + FONT_BASE (FACE_FONT (cf)),
			      buf, len);
	  else if (FACE_IS_IMAGE (cf))
	    XCopyPlane (x_current_display, FACE_IMAGE (cf),
Jim Blandy's avatar
Jim Blandy committed
556 557
			f->display.x->window_desc,
			f->display.x->normal_gc,
Jim Blandy's avatar
Jim Blandy committed
558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
			0, 0,
			FACE_IMAGE_WIDTH (cf),
			FACE_IMAGE_HEIGHT (cf), left, top);
	  else
	    abort ();
#else
	  register struct face *fp = x_face_table[cf];

	  XText (window, left, top,
		 buf,
		 len,
		 fp->font->id,
		 (hl == 2
		  ? (cursor_pixel == fp->fg ? fp->bg : fp->fg)
		  : hl ? fp->bg : fp->fg),
		 (hl == 2 ? cursor_pixel
		  : hl ? fp->fg : fp->bg));
#endif /* HAVE_X11 */
	}
      left += len * FONT_WIDTH (font);
    }
}
#endif

Jim Blandy's avatar
Jim Blandy committed
582
/* Output some text at the nominal frame cursor position,
Jim Blandy's avatar
Jim Blandy committed
583 584 585 586 587 588 589 590 591 592 593 594 595
   advancing the cursor over the text.
   Output LEN glyphs at START.

   `highlight', set up by XTreassert_line_highlight or XTchange_line_highlight,
   controls the pixel values used for foreground and background.  */

static
XTwrite_glyphs (start, len)
     register GLYPH *start;
     int len;
{
  register int temp_length;
  int mask;
Jim Blandy's avatar
Jim Blandy committed
596
  struct frame *f;
Jim Blandy's avatar
Jim Blandy committed
597 598 599

  BLOCK_INPUT;

Jim Blandy's avatar
Jim Blandy committed
600 601
  f = updating_frame;
  if (f == 0)
Jim Blandy's avatar
Jim Blandy committed
602
    {
Jim Blandy's avatar
Jim Blandy committed
603
      f = selected_frame;
Jim Blandy's avatar
Jim Blandy committed
604
      /* If not within an update,
Jim Blandy's avatar
Jim Blandy committed
605 606 607
	 output at the frame's visible cursor.  */
      curs_x = f->cursor_x;
      curs_y = f->cursor_y;
Jim Blandy's avatar
Jim Blandy committed
608 609
    }

Jim Blandy's avatar
Jim Blandy committed
610 611 612 613 614 615
  dumpglyphs (f,
	     (curs_x * FONT_WIDTH (f->display.x->font)
	      + f->display.x->internal_border_width),
	     (curs_y * FONT_HEIGHT (f->display.x->font)
	      + f->display.x->internal_border_width),
	     start, len, highlight, f->display.x->font);
Jim Blandy's avatar
Jim Blandy committed
616 617

  /* If we drew on top of the cursor, note that it is turned off.  */
Jim Blandy's avatar
Jim Blandy committed
618 619 620 621
  if (curs_y == f->phys_cursor_y
      && curs_x <= f->phys_cursor_x
      && curs_x + len > f->phys_cursor_x)
    f->phys_cursor_x = -1;
Jim Blandy's avatar
Jim Blandy committed
622
  
Jim Blandy's avatar
Jim Blandy committed
623
  if (updating_frame == 0)
Jim Blandy's avatar
Jim Blandy committed
624
    {
Jim Blandy's avatar
Jim Blandy committed
625 626 627
      f->cursor_x += len;
      x_display_cursor (f, 1);
      f->cursor_x -= len;
Jim Blandy's avatar
Jim Blandy committed
628 629 630 631 632 633 634 635 636 637 638
    }
  else
    curs_x += len;

  UNBLOCK_INPUT;
}

/* Erase the current text line from the nominal cursor position (inclusive)
   to column FIRST_UNUSED (exclusive).  The idea is that everything
   from FIRST_UNUSED onward is already erased.  */
  
Jim Blandy's avatar
Jim Blandy committed
639
static int
Jim Blandy's avatar
Jim Blandy committed
640 641 642
XTclear_end_of_line (first_unused)
     register int first_unused;
{
Jim Blandy's avatar
Jim Blandy committed
643
  struct frame *f = updating_frame;
Jim Blandy's avatar
Jim Blandy committed
644 645
  int mask;

Jim Blandy's avatar
Jim Blandy committed
646
  if (f == 0)
Jim Blandy's avatar
Jim Blandy committed
647 648
    abort ();

Jim Blandy's avatar
Jim Blandy committed
649
  if (curs_y < 0 || curs_y >= f->height)
Jim Blandy's avatar
Jim Blandy committed
650 651 652 653
    return;
  if (first_unused <= 0)
    return;

Jim Blandy's avatar
Jim Blandy committed
654 655
  if (first_unused >= f->width)
    first_unused = f->width;
Jim Blandy's avatar
Jim Blandy committed
656 657 658

  BLOCK_INPUT;

Jim Blandy's avatar
Jim Blandy committed
659
  /* Notice if the cursor will be cleared by this operation.  */
Jim Blandy's avatar
Jim Blandy committed
660 661 662 663
  if (curs_y == f->phys_cursor_y
      && curs_x <= f->phys_cursor_x
      && f->phys_cursor_x < first_unused)
    f->phys_cursor_x = -1;
Jim Blandy's avatar
Jim Blandy committed
664 665

#ifdef HAVE_X11
Jim Blandy's avatar
Jim Blandy committed
666 667 668 669 670 671 672
  XClearArea (x_current_display, f->display.x->window_desc,
	      curs_x * FONT_WIDTH (f->display.x->font)
	      + f->display.x->internal_border_width,
	      curs_y * FONT_HEIGHT (f->display.x->font)
	      + f->display.x->internal_border_width,
	      FONT_WIDTH (f->display.x->font) * (first_unused - curs_x),
	      FONT_HEIGHT (f->display.x->font), False);
Jim Blandy's avatar
Jim Blandy committed
673 674
	      
#else
Jim Blandy's avatar
Jim Blandy committed
675 676 677 678 679 680
  XPixSet (f->display.x->window_desc,
	   curs_x * FONT_WIDTH (f->display.x->font) + f->display.x->internal_border_width,
	   curs_y * FONT_HEIGHT (f->display.x->font) + f->display.x->internal_border_width,
	   FONT_WIDTH (f->display.x->font) * (first_unused - curs_x),
	   FONT_HEIGHT (f->display.x->font),
	   f->display.x->background_pixel);	
Jim Blandy's avatar
Jim Blandy committed
681 682 683 684 685 686
#endif /* HAVE_X11 */

  UNBLOCK_INPUT;
}

static
Jim Blandy's avatar
Jim Blandy committed
687
XTclear_frame ()
Jim Blandy's avatar
Jim Blandy committed
688 689
{
  int mask;
Jim Blandy's avatar
Jim Blandy committed
690
  struct frame *f = updating_frame;
Jim Blandy's avatar
Jim Blandy committed
691

Jim Blandy's avatar
Jim Blandy committed
692 693
  if (f == 0)
    f = selected_frame;
Jim Blandy's avatar
Jim Blandy committed
694

Jim Blandy's avatar
Jim Blandy committed
695
  f->phys_cursor_x = -1;	/* Cursor not visible.  */
Jim Blandy's avatar
Jim Blandy committed
696 697 698 699
  curs_x = 0;			/* Nominal cursor position is top left.  */
  curs_y = 0;
  
  BLOCK_INPUT;
Jim Blandy's avatar
Jim Blandy committed
700
  XClear (f->display.x->window_desc);
Jim Blandy's avatar
Jim Blandy committed
701
#ifndef HAVE_X11
Jim Blandy's avatar
Jim Blandy committed
702
  dumpborder (f, 0);
Jim Blandy's avatar
Jim Blandy committed
703 704 705 706 707
#endif
  XFlushQueue ();
  UNBLOCK_INPUT;
}

Jim Blandy's avatar
Jim Blandy committed
708
/* Paint horzontal bars down the frame for a visible bell.
Jim Blandy's avatar
Jim Blandy committed
709 710
   Note that this may be way too slow on some machines. */

Jim Blandy's avatar
Jim Blandy committed
711 712
XTflash (f)
     struct frame *f;
Jim Blandy's avatar
Jim Blandy committed
713
{
Jim Blandy's avatar
Jim Blandy committed
714
  register struct frame_glyphs *active_frame = FRAME_CURRENT_GLYPHS (f);
Jim Blandy's avatar
Jim Blandy committed
715 716 717
  register int i;
  int x, y;

Jim Blandy's avatar
Jim Blandy committed
718
  if (updating_frame != 0)
Jim Blandy's avatar
Jim Blandy committed
719 720 721 722 723
    abort ();

  BLOCK_INPUT;
#ifdef HAVE_X11
#if 0
Jim Blandy's avatar
Jim Blandy committed
724
  for (i = f->height * FONT_HEIGHT (f->display.x->font) - 10;
Jim Blandy's avatar
Jim Blandy committed
725 726
       i >= 0;    
       i -= 100)	   /* Should be NO LOWER than 75 for speed reasons. */
Jim Blandy's avatar
Jim Blandy committed
727 728 729 730
    XFillRectangle (x_current_display, f->display.x->window_desc,
		    f->display.x->cursor_gc,
		    0, i, f->width * FONT_WIDTH (f->display.x->font)
		    + 2 * f->display.x->internal_border_width, 25);
Jim Blandy's avatar
Jim Blandy committed
731 732
#endif

Jim Blandy's avatar
Jim Blandy committed
733 734 735 736
  x = (f->width * FONT_WIDTH (f->display.x->font)) / 4;
  y = (f->height * FONT_HEIGHT (f->display.x->font)) / 4;
  XFillRectangle (x_current_display, f->display.x->window_desc,
		  f->display.x->cursor_gc,
Jim Blandy's avatar
Jim Blandy committed
737
		  x, y, 2 * x, 2 * y);
Jim Blandy's avatar
Jim Blandy committed
738 739 740 741
  dumpglyphs (f, (x + f->display.x->internal_border_width),
	     (y + f->display.x->internal_border_width),
	     &active_frame->glyphs[(f->height / 4) + 1][(f->width / 4)],
	     1, 0, f->display.x->font);
Jim Blandy's avatar
Jim Blandy committed
742 743

#else /* X10 */
Jim Blandy's avatar
Jim Blandy committed
744
  for (i = f->height * FONT_HEIGHT (f->display.x->font) - 10;
Jim Blandy's avatar
Jim Blandy committed
745 746
       i >= 0;
       i -= 50)
Jim Blandy's avatar
Jim Blandy committed
747 748 749
    XPixFill (f->display.x->window_desc, 0, i,
	      f->width * FONT_WIDTH (f->display.x->font)
	      + 2 * f->display.x->internal_border_width, 10,
Jim Blandy's avatar
Jim Blandy committed
750 751 752 753 754 755 756
	      WHITE_PIX_DEFAULT, ClipModeClipped, GXinvert, AllPlanes);
#endif /* X10 */

  XFlushQueue ();
  UNBLOCK_INPUT;
}

Jim Blandy's avatar
Jim Blandy committed
757
/* Flip background and forground colors of the frame. */
Jim Blandy's avatar
Jim Blandy committed
758

Jim Blandy's avatar
Jim Blandy committed
759 760
x_invert_frame (f)
     struct frame *f;
Jim Blandy's avatar
Jim Blandy committed
761 762 763 764 765
{
#ifdef HAVE_X11
  GC temp;
  unsigned long pix_temp;

Jim Blandy's avatar
Jim Blandy committed
766 767 768 769 770 771 772 773 774 775 776 777
  x_display_cursor (f, 0);
  XClearWindow (x_current_display, f->display.x->window_desc);
  temp = f->display.x->normal_gc;
  f->display.x->normal_gc = f->display.x->reverse_gc;
  f->display.x->reverse_gc = temp;
  pix_temp = f->display.x->foreground_pixel;
  f->display.x->foreground_pixel = f->display.x->background_pixel;
  f->display.x->background_pixel = pix_temp;

  XSetWindowBackground (x_current_display, f->display.x->window_desc,
			f->display.x->background_pixel);
  if (f->display.x->background_pixel == f->display.x->cursor_pixel)
Jim Blandy's avatar
Jim Blandy committed
778
    {
Jim Blandy's avatar
Jim Blandy committed
779 780 781 782 783
      f->display.x->cursor_pixel = f->display.x->foreground_pixel;
      XSetBackground (x_current_display, f->display.x->cursor_gc,
		      f->display.x->cursor_pixel);
      XSetForeground (x_current_display, f->display.x->cursor_gc,
		      f->display.x->background_pixel);
Jim Blandy's avatar
Jim Blandy committed
784
    }
Jim Blandy's avatar
Jim Blandy committed
785
  redraw_frame (f);
Jim Blandy's avatar
Jim Blandy committed
786 787 788 789 790 791 792 793 794 795 796 797 798 799 800
#endif /* X11 */
}

/* Make audible bell.  */

#ifdef HAVE_X11
#define XRINGBELL XBell(x_current_display, 0)
#else
#define XRINGBELL XFeep(0);
#endif

XTring_bell ()
{
  if (visible_bell)
#if 0
Jim Blandy's avatar
Jim Blandy committed
801
    XTflash (selected_frame);
Jim Blandy's avatar
Jim Blandy committed
802 803
#endif
    {
Jim Blandy's avatar
Jim Blandy committed
804 805
      x_invert_frame (selected_frame);
      x_invert_frame (selected_frame);
Jim Blandy's avatar
Jim Blandy committed
806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842
    }
  else
    {
      BLOCK_INPUT;
      XRINGBELL;
      XFlushQueue ();
      UNBLOCK_INPUT;
    }
}

/* Insert and delete character are not supposed to be used
   because we are supposed to turn off the feature of using them.  */

static 
XTinsert_glyphs (start, len)
     register char *start;
     register int len;
{
  abort ();
}

static 
XTdelete_glyphs (n)
     register int n;
{
  abort ();
}

/* Specify how many text lines, from the top of the window,
   should be affected by insert-lines and delete-lines operations.
   This, and those operations, are used only within an update
   that is bounded by calls to XTupdate_begin and XTupdate_end.  */

static
XTset_terminal_window (n)
     register int n;
{
Jim Blandy's avatar
Jim Blandy committed
843
  if (updating_frame == 0)
Jim Blandy's avatar
Jim Blandy committed
844 845
    abort ();

Jim Blandy's avatar
Jim Blandy committed
846 847
  if ((n <= 0) || (n > updating_frame->height))
    flexlines = updating_frame->height;
Jim Blandy's avatar
Jim Blandy committed
848 849 850 851 852 853 854 855 856 857 858 859 860
  else
    flexlines = n;
}

/* Perform an insert-lines operation, inserting N lines
   at a vertical position curs_y.  */

static void
stufflines (n)
     register int n;
{
  register int topregion, bottomregion;
  register int length, newtop, mask;
Jim Blandy's avatar
Jim Blandy committed
861 862
  register struct frame *f = updating_frame;
  int intborder = f->display.x->internal_border_width;
Jim Blandy's avatar
Jim Blandy committed
863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878

  if (curs_y >= flexlines)
    return;

  topregion = curs_y;
  bottomregion = flexlines - (n + 1);
  newtop = topregion + n;
  length = (bottomregion - topregion) + 1;

#ifndef HAVE_X11
  dumpqueue ();
#endif

  if ((length > 0) && (newtop <= flexlines))
    {
#ifdef HAVE_X11
Jim Blandy's avatar
Jim Blandy committed
879 880 881 882 883 884
      XCopyArea (x_current_display, f->display.x->window_desc,
		 f->display.x->window_desc, f->display.x->normal_gc,
		 intborder, topregion * FONT_HEIGHT (f->display.x->font) + intborder,
		 f->width * FONT_WIDTH (f->display.x->font),
		 length * FONT_HEIGHT (f->display.x->font), intborder,
		 newtop * FONT_HEIGHT (f->display.x->font) + intborder);
Jim Blandy's avatar
Jim Blandy committed
885
#else
Jim Blandy's avatar
Jim Blandy committed
886 887 888 889 890
      XMoveArea (f->display.x->window_desc,
		 intborder, topregion * FONT_HEIGHT (f->display.x->font) + intborder,
		 intborder, newtop * FONT_HEIGHT (f->display.x->font) + intborder,
		 f->width * FONT_WIDTH (f->display.x->font),
		 length * FONT_HEIGHT (f->display.x->font));
Jim Blandy's avatar
Jim Blandy committed
891 892 893 894 895 896 897 898 899 900 901 902 903
      /* Now we must process any ExposeRegion events that occur
	 if the area being copied from is obscured.
	 We can't let it wait because further i/d operations
	 may want to copy this area to another area.  */
      x_read_exposes ();
#endif /* HAVE_X11 */
    }

  newtop = min (newtop, (flexlines - 1));
  length = newtop - topregion;
  if (length > 0)
    {
#ifdef HAVE_X11
Jim Blandy's avatar
Jim Blandy committed
904 905 906 907
      XClearArea (x_current_display, f->display.x->window_desc, intborder, 
		  topregion * FONT_HEIGHT (f->display.x->font) + intborder,
		  f->width * FONT_WIDTH (f->display.x->font),
		  n * FONT_HEIGHT (f->display.x->font), False);
Jim Blandy's avatar
Jim Blandy committed
908
#else
Jim Blandy's avatar
Jim Blandy committed
909
      XPixSet (f->display.x->window_desc,
Jim Blandy's avatar
Jim Blandy committed
910
	       intborder,
Jim Blandy's avatar
Jim Blandy committed
911 912 913 914
	       topregion * FONT_HEIGHT (f->display.x->font) + intborder,
	       f->width * FONT_WIDTH (f->display.x->font),
	       n * FONT_HEIGHT (f->display.x->font),
	       f->display.x->background_pixel);
Jim Blandy's avatar
Jim Blandy committed
915 916 917 918 919 920 921 922 923 924 925 926
#endif /* HAVE_X11 */
    }
}

/* Perform a delete-lines operation, deleting N lines
   at a vertical position curs_y.  */

static void
scraplines (n)
     register int n;
{
  int mask;
Jim Blandy's avatar
Jim Blandy committed
927 928
  register struct frame *f = updating_frame;
  int intborder = f->display.x->internal_border_width;
Jim Blandy's avatar
Jim Blandy committed
929 930 931 932 933 934 935 936 937 938 939 940 941

  if (curs_y >= flexlines)
    return;

#ifndef HAVE_X11
  dumpqueue ();
#endif

  if ((curs_y + n) >= flexlines)
    {
      if (flexlines >= (curs_y + 1))
	{
#ifdef HAVE_X11
Jim Blandy's avatar
Jim Blandy committed
942 943 944 945
	  XClearArea (x_current_display, f->display.x->window_desc, intborder,
		      curs_y * FONT_HEIGHT (f->display.x->font) + intborder,
		      f->width * FONT_WIDTH (f->display.x->font),
		      (flexlines - curs_y) * FONT_HEIGHT (f->display.x->font), False);
Jim Blandy's avatar
Jim Blandy committed
946
#else
Jim Blandy's avatar
Jim Blandy committed
947 948 949 950 951
	  XPixSet (f->display.x->window_desc,
		   intborder, curs_y * FONT_HEIGHT (f->display.x->font) + intborder,
		   f->width * FONT_WIDTH (f->display.x->font),
		   (flexlines - curs_y) * FONT_HEIGHT (f->display.x->font),
		   f->display.x->background_pixel);
Jim Blandy's avatar
Jim Blandy committed
952 953 954 955 956 957
#endif /* HAVE_X11 */
	}
    }
  else
    {
#ifdef HAVE_X11
Jim Blandy's avatar
Jim Blandy committed
958 959
      XCopyArea (x_current_display, f->display.x->window_desc,
		 f->display.x->window_desc, f->display.x->normal_gc,
Jim Blandy's avatar
Jim Blandy committed
960
		 intborder,
Jim Blandy's avatar
Jim Blandy committed
961 962 963 964 965
		 (curs_y + n) * FONT_HEIGHT (f->display.x->font) + intborder,
		 f->width * FONT_WIDTH (f->display.x->font),
		 (flexlines - (curs_y + n)) * FONT_HEIGHT (f->display.x->font),
		 intborder, curs_y * FONT_HEIGHT (f->display.x->font) + intborder);
      XClearArea (x_current_display, f->display.x->window_desc,
Jim Blandy's avatar
Jim Blandy committed
966
		  intborder,
Jim Blandy's avatar
Jim Blandy committed
967 968 969
		  (flexlines - n) * FONT_HEIGHT (f->display.x->font) + intborder,
		  f->width * FONT_WIDTH (f->display.x->font),
		  n * FONT_HEIGHT (f->display.x->font), False);
Jim Blandy's avatar
Jim Blandy committed
970
#else
Jim Blandy's avatar
Jim Blandy committed
971
      XMoveArea (f->display.x->window_desc,
Jim Blandy's avatar
Jim Blandy committed
972
		 intborder,
Jim Blandy's avatar
Jim Blandy committed
973 974 975 976
		 (curs_y + n) * FONT_HEIGHT (f->display.x->font) + intborder,
		 intborder, curs_y * FONT_HEIGHT (f->display.x->font) + intborder,
		 f->width * FONT_WIDTH (f->display.x->font),
		 (flexlines - (curs_y + n)) * FONT_HEIGHT (f->display.x->font));
Jim Blandy's avatar
Jim Blandy committed
977 978 979 980 981
      /* Now we must process any ExposeRegion events that occur
	 if the area being copied from is obscured.
	 We can't let it wait because further i/d operations
	 may want to copy this area to another area.  */
      x_read_exposes ();
Jim Blandy's avatar
Jim Blandy committed
982 983 984 985
      XPixSet (f->display.x->window_desc, intborder,
	       (flexlines - n) * FONT_HEIGHT (f->display.x->font) + intborder,
	       f->width * FONT_WIDTH (f->display.x->font),
	       n * FONT_HEIGHT (f->display.x->font), f->display.x->background_pixel);
Jim Blandy's avatar
Jim Blandy committed
986 987 988 989 990 991 992 993 994 995
#endif /* HAVE_X11 */
    }
}

/* Perform an insert-lines or delete-lines operation,
   inserting N lines or deleting -N lines at vertical position VPOS.  */

XTins_del_lines (vpos, n)
     int vpos, n;
{
Jim Blandy's avatar
Jim Blandy committed
996
  if (updating_frame == 0)
Jim Blandy's avatar
Jim Blandy committed
997 998
    abort ();

Jim Blandy's avatar
Jim Blandy committed
999
  /* Hide the cursor.  */
Jim Blandy's avatar
Jim Blandy committed
1000
  x_display_cursor (updating_frame, 0);
Jim Blandy's avatar
Jim Blandy committed
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014

  XTcursor_to (vpos, 0);

  BLOCK_INPUT;
  if (n >= 0)
    stufflines (n);
  else
    scraplines (-n);
  XFlushQueue ();
  UNBLOCK_INPUT;
}

static void clear_cursor ();

Jim Blandy's avatar
Jim Blandy committed
1015 1016
/* Output into a rectangle of an X-window (for frame F)
   the characters in f->phys_lines that overlap that rectangle.
Jim Blandy's avatar
Jim Blandy committed
1017 1018 1019 1020
   TOP and LEFT are the position of the upper left corner of the rectangle.
   ROWS and COLS are the size of the rectangle.  */

static void
Jim Blandy's avatar
Jim Blandy committed
1021 1022
dumprectangle (f, left, top, cols, rows)
     struct frame *f;
Jim Blandy's avatar
Jim Blandy committed
1023 1024
     register int left, top, cols, rows;
{
Jim Blandy's avatar
Jim Blandy committed
1025
  register struct frame_glyphs *active_frame = FRAME_CURRENT_GLYPHS (f);
Jim Blandy's avatar
Jim Blandy committed
1026 1027 1028 1029
  int cursor_cleared = 0;
  int bottom, right;
  register int y;

Jim Blandy's avatar
Jim Blandy committed
1030
  if (FRAME_GARBAGED_P (f))
Jim Blandy's avatar
Jim Blandy committed
1031 1032
    return;

Jim Blandy's avatar
Jim Blandy committed
1033 1034
  top -= f->display.x->internal_border_width;
  left -= f->display.x->internal_border_width;
Jim Blandy's avatar
Jim Blandy committed
1035 1036 1037 1038 1039 1040 1041 1042 1043

  /* Express rectangle as four edges, instead of position-and-size.  */
  bottom = top + rows;
  right = left + cols;

#ifndef HAVE_X11		/* Window manger does this for X11. */
  /* If the rectangle includes any of the internal border area,
     redisplay the border emphasis.  */
  if (top < 0 || left < 0
Jim Blandy's avatar
Jim Blandy committed
1044 1045 1046
      || bottom > f->height * FONT_HEIGHT (f->display.x->font)
      || right > f->width * FONT_WIDTH (f->display.x->font))
    dumpborder (f, 0);
Jim Blandy's avatar
Jim Blandy committed
1047 1048 1049 1050
#endif /* HAVE_X11 */
  
  /* Convert rectangle edges in pixels to edges in chars.
     Round down for left and top, up for right and bottom.  */
Jim Blandy's avatar
Jim Blandy committed
1051 1052 1053 1054 1055 1056
  top /= FONT_HEIGHT (f->display.x->font);
  left /= FONT_WIDTH (f->display.x->font);
  bottom += (FONT_HEIGHT (f->display.x->font) - 1);
  right += (FONT_WIDTH (f->display.x->font) - 1);
  bottom /= FONT_HEIGHT (f->display.x->font);
  right /= FONT_WIDTH (f->display.x->font);
Jim Blandy's avatar
Jim Blandy committed
1057 1058 1059 1060 1061 1062

  /* Clip the rectangle to what can be visible.  */
  if (left < 0)
    left = 0;
  if (top < 0)
    top = 0;
Jim Blandy's avatar
Jim Blandy committed
1063 1064 1065 1066
  if (right > f->width)
    right = f->width;
  if (bottom > f->height)
    bottom = f->height;
Jim Blandy's avatar
Jim Blandy committed
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077

  /* Get size in chars of the rectangle.  */
  cols = right - left;
  rows = bottom - top;

  /* If rectangle has zero area, return.  */
  if (rows <= 0) return;
  if (cols <= 0) return;

  /* Turn off the cursor if it is in the rectangle.
     We will turn it back on afterward.  */
Jim Blandy's avatar
Jim Blandy committed
1078 1079
  if ((f->phys_cursor_x >= left) && (f->phys_cursor_x < right)
      && (f->phys_cursor_y >= top) && (f->phys_cursor_y < bottom))
Jim Blandy's avatar
Jim Blandy committed
1080
    {
Jim Blandy's avatar
Jim Blandy committed
1081
      clear_cursor (f);
Jim Blandy's avatar
Jim Blandy committed
1082 1083 1084 1085 1086 1087 1088
      cursor_cleared = 1;
    }

  /* Display the text in the rectangle, one text line at a time.  */

  for (y = top; y < bottom; y++)
    {
Jim Blandy's avatar
Jim Blandy committed
1089
      GLYPH *line = &active_frame->glyphs[y][left];
Jim Blandy's avatar
Jim Blandy committed
1090

Jim Blandy's avatar
Jim Blandy committed
1091
      if (! active_frame->enable[y] || left > active_frame->used[y])
Jim Blandy's avatar
Jim Blandy committed
1092 1093
	continue;

Jim Blandy's avatar
Jim Blandy committed
1094 1095 1096 1097 1098 1099 1100
      dumpglyphs (f,
		 (left * FONT_WIDTH (f->display.x->font)
		  + f->display.x->internal_border_width),
		 (y * FONT_HEIGHT (f->display.x->font)
		  + f->display.x->internal_border_width),
		 line, min (cols, active_frame->used[y] - left),
		 active_frame->highlight[y], f->display.x->font);
Jim Blandy's avatar
Jim Blandy committed
1101 1102 1103 1104 1105
    }

  /* Turn the cursor on if we turned it off.  */

  if (cursor_cleared)
Jim Blandy's avatar
Jim Blandy committed
1106
    x_display_cursor (f, 1);
Jim Blandy's avatar
Jim Blandy committed
1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119
}

#ifndef HAVE_X11
/* Process all queued ExposeRegion events. */

static void
dumpqueue ()
{
  register int i;
  XExposeRegionEvent r;

  while (dequeue_event (&r, &x_expose_queue))
    {
Jim Blandy's avatar
Jim Blandy committed
1120 1121 1122
      struct frame *f = x_window_to_frame (r.window);
      if (f->display.x->icon_desc == r.window)
	refreshicon (f);
Jim Blandy's avatar
Jim Blandy committed
1123
      else
Jim Blandy's avatar
Jim Blandy committed
1124
	dumprectangle (f, r.x, r.y, r.width, r.height);
Jim Blandy's avatar
Jim Blandy committed
1125 1126 1127 1128 1129 1130
    }
  XFlushQueue ();
}
#endif

/* Process all expose events that are pending.
Jim Blandy's avatar
Jim Blandy committed
1131 1132
   Redraws the cursor if necessary on any frame that
   is not in the process of being updated with update_frame.  */
Jim Blandy's avatar
Jim Blandy committed
1133 1134 1135 1136 1137

static void
x_do_pending_expose ()
{
  int mask;
Jim Blandy's avatar
Jim Blandy committed
1138 1139
  struct frame *f;
  Lisp_Object tail, frame;
Jim Blandy's avatar
Jim Blandy committed
1140 1141 1142 1143

  if (expose_all_windows)
    {
      expose_all_windows = 0;
Jim Blandy's avatar
Jim Blandy committed
1144
      for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
Jim Blandy's avatar
Jim Blandy committed
1145 1146 1147 1148
	{
	  register int temp_width, temp_height;
	  int intborder;

Jim Blandy's avatar
Jim Blandy committed
1149 1150
	  frame = XCONS (tail)->car;
	  if (XTYPE (frame) != Lisp_Frame)
Jim Blandy's avatar
Jim Blandy committed
1151
	    continue;
Jim Blandy's avatar
Jim Blandy committed
1152
	  f = XFRAME (frame);
1153
	  if (! FRAME_X_P (f))
Jim Blandy's avatar
Jim Blandy committed
1154
	    continue;
Jim Blandy's avatar
Jim Blandy committed
1155
	  if (!f->visible)
Jim Blandy's avatar
Jim Blandy committed
1156
	    continue;
Jim Blandy's avatar
Jim Blandy committed
1157
	  if (!f->display.x->needs_exposure)
Jim Blandy's avatar
Jim Blandy committed
1158 1159
	    continue;

Jim Blandy's avatar
Jim Blandy committed
1160
	  intborder = f->display.x->internal_border_width;
Jim Blandy's avatar
Jim Blandy committed
1161

Jim Blandy's avatar
Jim Blandy committed
1162 1163
	  clear_cursor (f);
	  XGetWindowInfo (f->display.x->window_desc, &windowinfo);
Jim Blandy's avatar
Jim Blandy committed
1164
	  temp_width = ((windowinfo.width - 2 * intborder
Jim Blandy's avatar
Jim Blandy committed
1165 1166
			 - f->display.x->v_scrollbar_width)
			/ FONT_WIDTH (f->display.x->font));
Jim Blandy's avatar
Jim Blandy committed
1167
	  temp_height = ((windowinfo.height- 2 * intborder
Jim Blandy's avatar
Jim Blandy committed
1168 1169 1170
			  - f->display.x->h_scrollbar_height)
			 / FONT_HEIGHT (f->display.x->font));
	  if (temp_width != f->width || temp_height != f->height)
Jim Blandy's avatar
Jim Blandy committed
1171
	    {
Jim Blandy's avatar
Jim Blandy committed
1172
	      change_frame_size (f, max (1, temp_height),
1173
				  max (1, temp_width), 0, 1);
Jim Blandy's avatar
Jim Blandy committed
1174
	      x_resize_scrollbars (f);
Jim Blandy's avatar
Jim Blandy committed
1175
	    }
Jim Blandy's avatar
Jim Blandy committed
1176 1177 1178
	  f->display.x->left_pos = windowinfo.x;
	  f->display.x->top_pos = windowinfo.y;
	  dumprectangle (f, 0, 0, PIXEL_WIDTH (f), PIXEL_HEIGHT (f));
Jim Blandy's avatar
Jim Blandy committed
1179
#if 0
Jim Blandy's avatar
Jim Blandy committed
1180
	  dumpborder (f, 0);
Jim Blandy's avatar
Jim Blandy committed
1181
#endif
Jim Blandy's avatar
Jim Blandy committed
1182 1183 1184
	  f->display.x->needs_exposure = 0;
	  if (updating_frame != f)
	    x_display_cursor (f, 1);
Jim Blandy's avatar
Jim Blandy committed
1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199
	  XFlushQueue ();
	}
    }
  else
    /* Handle any individual-rectangle expose events queued
       for various windows.  */
#ifdef HAVE_X11
    ;
#else
    dumpqueue ();
#endif
}

#ifdef HAVE_X11
static void
Jim Blandy's avatar
Jim Blandy committed
1200 1201
frame_highlight (frame)
     struct frame *frame;
Jim Blandy's avatar
Jim Blandy committed
1202 1203
{
  if (! EQ (Vx_no_window_manager, Qnil))
Jim Blandy's avatar
Jim Blandy committed
1204 1205 1206
    XSetWindowBorder (x_current_display, frame->display.x->window_desc,
		      frame->display.x->border_pixel);
  x_display_cursor (frame, 1);
Jim Blandy's avatar
Jim Blandy committed
1207 1208 1209
}

static void
Jim Blandy's avatar
Jim Blandy committed
1210 1211
frame_unhighlight (frame)
     struct frame *frame;
Jim Blandy's avatar
Jim Blandy committed
1212 1213
{
  if (! EQ (Vx_no_window_manager, Qnil))
Jim Blandy's avatar
Jim Blandy committed
1214 1215 1216
    XSetWindowBorderPixmap (x_current_display, frame->display.x->window_desc,
			    frame->display.x->border_tile);
  x_display_cursor (frame, 1);
Jim Blandy's avatar
Jim Blandy committed
1217 1218
}
#else	/* X10 */
Jim Blandy's avatar
Jim Blandy committed
1219 1220
/* Dump the border-emphasis of frame F.
   If F is selected, this is a lining of the same color as the border,
Jim Blandy's avatar
Jim Blandy committed
1221
   just within the border, occupying a portion of the internal border.
Jim Blandy's avatar
Jim Blandy committed
1222
   If F is not selected, it is background in the same place.
Jim Blandy's avatar
Jim Blandy committed
1223 1224
   If ALWAYS is 0, don't bother explicitly drawing if it's background.

Jim Blandy's avatar
Jim Blandy committed
1225
   ALWAYS = 1 is used when a frame becomes selected or deselected.
Jim Blandy's avatar
Jim Blandy committed
1226 1227 1228 1229
   In that case, we also turn the cursor off and on again
   so it will appear in the proper shape (solid if selected; else hollow.)  */

static void
Jim Blandy's avatar
Jim Blandy committed
1230 1231
dumpborder (f, always)
     struct frame *f;
Jim Blandy's avatar
Jim Blandy committed
1232 1233
     int always;
{
Jim Blandy's avatar
Jim Blandy committed
1234 1235 1236
  int thickness = f->display.x->internal_border_width / 2;
  int width = PIXEL_WIDTH (f);
  int height = PIXEL_HEIGHT (f);
Jim Blandy's avatar
Jim Blandy committed
1237 1238
  int pixel;

Jim Blandy's avatar
Jim Blandy committed
1239
  if (f != selected_frame)
Jim Blandy's avatar
Jim Blandy committed
1240 1241 1242 1243
    {
      if (!always)
	return;

Jim Blandy's avatar
Jim Blandy committed
1244
      pixel = f->display.x->background_pixel;
Jim Blandy's avatar
Jim Blandy committed
1245 1246 1247
    }
  else
    {
Jim Blandy's avatar
Jim Blandy committed
1248
      pixel = f->display.x->border_pixel;
Jim Blandy's avatar
Jim Blandy committed
1249 1250
    }

Jim Blandy's avatar
Jim Blandy committed
1251 1252 1253
  XPixSet (f->display.x->window_desc, 0, 0, width, thickness, pixel);
  XPixSet (f->display.x->window_desc, 0, 0, thickness, height, pixel);
  XPixSet (f->display.x->window_desc, 0, height - thickness, width,
Jim Blandy's avatar
Jim Blandy committed
1254
	   thickness, pixel);
Jim Blandy's avatar
Jim Blandy committed
1255
  XPixSet (f->display.x->window_desc, width - thickness, 0, thickness,
Jim Blandy's avatar
Jim Blandy committed
1256 1257 1258
	   height, pixel);

  if (always)
Jim Blandy's avatar
Jim Blandy committed
1259
    x_display_cursor (f, 1);
Jim Blandy's avatar
Jim Blandy committed
1260 1261 1262
}
#endif	/* X10 */

Jim Blandy's avatar
Jim Blandy committed
1263
static void XTframe_rehighlight ();
Jim Blandy's avatar
Jim Blandy committed
1264

Jim Blandy's avatar
Jim Blandy committed
1265 1266
/* The focus has changed.  Update the frames as necessary to reflect
   the new situation.  Note that we can't change the selected frame
Jim Blandy's avatar
Jim Blandy committed
1267
   here, because the lisp code we are interrupting might become confused.
Jim Blandy's avatar
Jim Blandy committed
1268
   Each event gets marked with the frame in which it occured, so the
Jim Blandy's avatar
Jim Blandy committed
1269
   lisp code can tell when the switch took place by examining the events.  */
Jim Blandy's avatar
Jim Blandy committed
1270

Jim Blandy's avatar
Jim Blandy committed
1271
static void
Jim Blandy's avatar
Jim Blandy committed
1272 1273
x_new_focus_frame (frame)
     struct frame *frame;
Jim Blandy's avatar
Jim Blandy committed
1274
{
Jim Blandy's avatar
Jim Blandy committed
1275
  struct frame *old_focus = x_focus_frame;
Jim Blandy's avatar
Jim Blandy committed
1276 1277
  int events_enqueued = 0;

Jim Blandy's avatar
Jim Blandy committed
1278
  if (frame != x_focus_frame)
Jim Blandy's avatar
Jim Blandy committed
1279
    {
Jim Blandy's avatar
Jim Blandy committed
1280
      /* Set this before calling other routines, so that they see 
Jim Blandy's avatar
Jim Blandy committed
1281 1282
	 the correct value of x_focus_frame.  */
      x_focus_frame = frame;
Jim Blandy's avatar
Jim Blandy committed
1283 1284

      if (old_focus && old_focus->auto_lower)
Jim Blandy's avatar
Jim Blandy committed
1285
	x_lower_frame (old_focus);
Jim Blandy's avatar
Jim Blandy committed
1286 1287

#if 0
Jim Blandy's avatar
Jim Blandy committed
1288 1289 1290 1291 1292
      selected_frame = frame;
      XSET (XWINDOW (selected_frame->selected_window)->frame,
	    Lisp_Frame, selected_frame);
      Fselect_window (selected_frame->selected_window);
      choose_minibuf_frame ();
Jim Blandy's avatar
Jim Blandy committed
1293 1294
#endif

Jim Blandy's avatar
Jim Blandy committed
1295 1296
      if (x_focus_frame && x_focus_frame->auto_raise)
	x_raise_frame (x_focus_frame);
Jim Blandy's avatar
Jim Blandy committed
1297
    }
Jim Blandy's avatar
Jim Blandy committed
1298

Jim Blandy's avatar
Jim Blandy committed
1299
  XTframe_rehighlight ();
Jim Blandy's avatar
Jim Blandy committed
1300 1301 1302
}


Jim Blandy's avatar
Jim Blandy committed
1303 1304 1305
/* The focus has changed, or we have make a frame's selected window
   point to a window on a different frame (this happens with global
   minibuffer frames).  Shift the highlight as appropriate.  */
Jim Blandy's avatar
Jim Blandy committed
1306
static void
Jim Blandy's avatar
Jim Blandy committed
1307
XTframe_rehighlight ()
Jim Blandy's avatar
Jim Blandy committed
1308
{
Jim Blandy's avatar
Jim Blandy committed
1309
  struct frame *old_highlight = x_highlight_frame;
Jim Blandy's avatar
Jim Blandy committed
1310

Jim Blandy's avatar
Jim Blandy committed
1311
  if (x_focus_frame)
Jim Blandy's avatar
Jim Blandy committed
1312
    {
Jim Blandy's avatar
Jim Blandy committed
1313 1314 1315 1316
      x_highlight_frame = XFRAME (FRAME_FOCUS_FRAME (x_focus_frame));
      if (x_highlight_frame->display.nothing == 0)
	XSET (FRAME_FOCUS_FRAME (x_focus_frame), Lisp_Frame,
	      (x_highlight_frame = x_focus_frame));
Jim Blandy's avatar
Jim Blandy committed
1317
    }
Jim Blandy's avatar
Jim Blandy committed
1318
  else
Jim Blandy's avatar
Jim Blandy committed
1319
    x_highlight_frame = 0;
Jim Blandy's avatar
Jim Blandy committed
1320

Jim Blandy's avatar
Jim Blandy committed
1321
  if (x_highlight_frame != old_highlight)
Jim Blandy's avatar
Jim Blandy committed
1322 1323
    {
      if (old_highlight)
Jim Blandy's avatar
Jim Blandy committed
1324 1325 1326
	frame_unhighlight (old_highlight);
      if (x_highlight_frame)
	frame_highlight (x_highlight_frame);
Jim Blandy's avatar
Jim Blandy committed
1327
    }
Jim Blandy's avatar
Jim Blandy committed
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341