comparison src/xterm.c @ 429:10b1795f3ae9

*** empty log message ***
author Jim Blandy <jimb@redhat.com>
date Fri, 08 Nov 1991 01:52:59 +0000
parents a60eafebd43f
children 8c615e453683
comparison
equal deleted inserted replaced
428:a24ab90a6983 429:10b1795f3ae9
249 /* From time to time we get info on an Emacs window, here. */ 249 /* From time to time we get info on an Emacs window, here. */
250 250
251 static WINDOWINFO_TYPE windowinfo; 251 static WINDOWINFO_TYPE windowinfo;
252 252
253 extern int errno; 253 extern int errno;
254
255 extern Lisp_Object Vglobal_minibuffer_screen;
256 254
257 extern Display *XOpenDisplay (); 255 extern Display *XOpenDisplay ();
258 extern Window XCreateWindow (); 256 extern Window XCreateWindow ();
259 257
260 extern Cursor XCreateCursor (); 258 extern Cursor XCreateCursor ();
294 292
295 BLOCK_INPUT; 293 BLOCK_INPUT;
296 #ifndef HAVE_X11 294 #ifndef HAVE_X11
297 dumpqueue (); 295 dumpqueue ();
298 #endif 296 #endif
299 x_display_cursor (s, 0);
300 UNBLOCK_INPUT; 297 UNBLOCK_INPUT;
301 } 298 }
302 299
303 static void x_do_pending_expose (); 300 static void x_do_pending_expose ();
304 301
562 output at the screen's visible cursor. */ 559 output at the screen's visible cursor. */
563 curs_x = s->cursor_x; 560 curs_x = s->cursor_x;
564 curs_y = s->cursor_y; 561 curs_y = s->cursor_y;
565 } 562 }
566 563
567 /* Clear the cursor if it appears on this line. */
568 if (curs_y == s->cursor_y)
569 x_display_cursor (s, 0);
570
571 dumpglyphs (s, 564 dumpglyphs (s,
572 (curs_x * FONT_WIDTH (s->display.x->font) 565 (curs_x * FONT_WIDTH (s->display.x->font)
573 + s->display.x->internal_border_width), 566 + s->display.x->internal_border_width),
574 (curs_y * FONT_HEIGHT (s->display.x->font) 567 (curs_y * FONT_HEIGHT (s->display.x->font)
575 + s->display.x->internal_border_width), 568 + s->display.x->internal_border_width),
576 start, len, highlight, s->display.x->font); 569 start, len, highlight, s->display.x->font);
570
571 /* If we drew on top of the cursor, note that it is turned off. */
572 if (curs_y == s->phys_cursor_y
573 && curs_x <= s->phys_cursor_x
574 && curs_x + len > s->phys_cursor_x)
575 s->phys_cursor_x = -1;
577 576
578 if (updating_screen == 0) 577 if (updating_screen == 0)
579 { 578 {
580 s->cursor_x += len; 579 s->cursor_x += len;
581 x_display_cursor (s, 1); 580 x_display_cursor (s, 1);
609 if (first_unused >= s->width) 608 if (first_unused >= s->width)
610 first_unused = s->width; 609 first_unused = s->width;
611 610
612 BLOCK_INPUT; 611 BLOCK_INPUT;
613 612
614 /* Clear the cursor if it appears on this line. */ 613 /* Notice if the cursor will be cleared by this operation. */
615 if (curs_y == s->cursor_y) 614 if (curs_y == s->phys_cursor_y
616 x_display_cursor (s, 0); 615 && curs_x <= s->phys_cursor_x
616 && s->phys_cursor_x < first_unused)
617 s->phys_cursor_x = -1;
617 618
618 #ifdef HAVE_X11 619 #ifdef HAVE_X11
619 XClearArea (x_current_display, s->display.x->window_desc, 620 XClearArea (x_current_display, s->display.x->window_desc,
620 curs_x * FONT_WIDTH (s->display.x->font) 621 curs_x * FONT_WIDTH (s->display.x->font)
621 + s->display.x->internal_border_width, 622 + s->display.x->internal_border_width,
947 int vpos, n; 948 int vpos, n;
948 { 949 {
949 if (updating_screen == 0) 950 if (updating_screen == 0)
950 abort (); 951 abort ();
951 952
952 /* Clear the cursor. */ 953 /* Hide the cursor. */
953 x_display_cursor (updating_screen, 0); 954 x_display_cursor (updating_screen, 0);
954 955
955 XTcursor_to (vpos, 0); 956 XTcursor_to (vpos, 0);
956 957
957 BLOCK_INPUT; 958 BLOCK_INPUT;
1101 1102
1102 screen = XCONS (tail)->car; 1103 screen = XCONS (tail)->car;
1103 if (XTYPE (screen) != Lisp_Screen) 1104 if (XTYPE (screen) != Lisp_Screen)
1104 continue; 1105 continue;
1105 s = XSCREEN (screen); 1106 s = XSCREEN (screen);
1106 if (s->output_method != output_x_window) 1107 if (! SCREEN_IS_X (s))
1107 continue; 1108 continue;
1108 if (!s->visible) 1109 if (!s->visible)
1109 continue; 1110 continue;
1110 if (!s->display.x->needs_exposure) 1111 if (!s->display.x->needs_exposure)
1111 continue; 1112 continue;
1300 extern int mouse_buffer_offset; 1301 extern int mouse_buffer_offset;
1301 1302
1302 /* Part of the screen the mouse is in. */ 1303 /* Part of the screen the mouse is in. */
1303 extern Lisp_Object Vmouse_screen_part; 1304 extern Lisp_Object Vmouse_screen_part;
1304 1305
1305 extern void pixel_to_glyph_translation ();
1306 extern int buffer_posn_from_coords (); 1306 extern int buffer_posn_from_coords ();
1307 1307
1308 /* Symbols from xfns.c to denote the different parts of a window. */ 1308 /* Symbols from xfns.c to denote the different parts of a window. */
1309 extern Lisp_Object Qmodeline_part, Qtext_part; 1309 extern Lisp_Object Qmodeline_part, Qtext_part;
1310 1310
1395 1395
1396 return; 1396 return;
1397 } 1397 }
1398 #endif 1398 #endif
1399 1399
1400 /* Given a pixel position (pix_x, pix_y) on the screen s, return 1400
1401 character co-ordinates in (*x, *y). */ 1401 /* Mouse clicks and mouse movement. Rah. */
1402 void 1402 #ifdef HAVE_X11
1403 pixel_to_glyph_translation (s, pix_x, pix_y, x, y) 1403
1404 /* Given a pixel position (PIX_X, PIX_Y) on the screen S, return
1405 glyph co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle
1406 that the glyph at X, Y occupies, if BOUNDS != 0. */
1407 static void
1408 pixel_to_glyph_coords (s, pix_x, pix_y, x, y, bounds)
1404 SCREEN_PTR s; 1409 SCREEN_PTR s;
1405 register unsigned int pix_x, pix_y; 1410 register unsigned int pix_x, pix_y;
1406 register int *x, *y; 1411 register int *x, *y;
1407 { 1412 XRectangle *bounds;
1408 register struct screen_glyphs *s_glyphs = SCREEN_CURRENT_GLYPHS (s); 1413 {
1409 register int line = SCREEN_HEIGHT (s) - 1;
1410 int ibw = s->display.x->internal_border_width; 1414 int ibw = s->display.x->internal_border_width;
1415 int width, height;
1416 FONT_TYPE *font = s->display.x->font;
1417
1418 width = FONT_WIDTH (font);
1419 height = FONT_HEIGHT (font);
1411 1420
1412 /* What line is it on? */ 1421 /* What line is it on? */
1413 line = SCREEN_HEIGHT (s) - 1; 1422 if (pix_y < ibw)
1414 while (s_glyphs->top_left_y[line] > pix_y) 1423 *y = 0;
1415 line--; 1424 else if (pix_y > s->display.x->pixel_height - ibw)
1416 *y = line; 1425 *y = SCREEN_HEIGHT (s) - 1;
1417 1426 else
1418 /* Horizontally, is it in the border? */ 1427 *y = (pix_y - ibw) / height;
1428
1429 /* And what column? */
1419 if (pix_x < ibw) 1430 if (pix_x < ibw)
1420 *x = 0; 1431 *x = 0;
1421
1422 /* If it's off the right edge, clip it. */
1423 else if (pix_x > s->display.x->pixel_width - ibw) 1432 else if (pix_x > s->display.x->pixel_width - ibw)
1424 *x = SCREEN_WIDTH (s) - 1; 1433 *x = SCREEN_WIDTH (s) - 1;
1425
1426 /* It's in the midst of the screen; assume all the characters are
1427 the same width, and figure the column. */
1428 else 1434 else
1429 *x = (pix_x - ibw) / FONT_WIDTH (s->display.x->font); 1435 *x = (pix_x - ibw) / width;
1430 } 1436
1431 1437 if (bounds)
1432 #ifdef HAVE_X11 1438 {
1439 bounds->width = width;
1440 bounds->height = height;
1441 bounds->x = ibw + (*x * width);
1442 bounds->y = ibw + (*y * height);
1443 }
1444 }
1433 1445
1434 /* Any buttons grabbed. */ 1446 /* Any buttons grabbed. */
1435 unsigned int x_mouse_grabbed; 1447 unsigned int x_mouse_grabbed;
1436 1448
1437 /* Convert a set of X modifier bits to the proper form for a 1449 /* Convert a set of X modifier bits to the proper form for a
1468 /* Initialize those fields text and scrollbar clicks hold in common. 1480 /* Initialize those fields text and scrollbar clicks hold in common.
1469 Make the event type no_event; we'll change that when we decide 1481 Make the event type no_event; we'll change that when we decide
1470 otherwise. */ 1482 otherwise. */
1471 result->kind = no_event; 1483 result->kind = no_event;
1472 XSET (result->code, Lisp_Int, event->button); 1484 XSET (result->code, Lisp_Int, event->button);
1485 XSET (result->timestamp, Lisp_Int, event->time);
1473 result->modifiers = (x_convert_modifiers (event->state) 1486 result->modifiers = (x_convert_modifiers (event->state)
1474 | (event->type == ButtonRelease ? up_modifier : 0)); 1487 | (event->type == ButtonRelease ? up_modifier : 0));
1475 XSET (result->timestamp, Lisp_Int, (event->time & 0x7fffff)); 1488 XSET (result->timestamp, Lisp_Int, (event->time & 0x7fffff));
1476 1489
1477 /* Notice if the mouse is still grabbed. */ 1490 /* Notice if the mouse is still grabbed. */
1478 if (event->type == ButtonPress) 1491 if (event->type == ButtonPress)
1479 { 1492 {
1480 if (! x_mouse_grabbed) 1493 if (! x_mouse_grabbed)
1481 Vmouse_depressed = Qt; 1494 Vmouse_depressed = Qt;
1482 x_mouse_grabbed |= event->button; 1495 x_mouse_grabbed |= (1 << event->button);
1483 } 1496 }
1484 else if (event->type == ButtonRelease) 1497 else if (event->type == ButtonRelease)
1485 { 1498 {
1486 x_mouse_grabbed &= ~(event->button); 1499 x_mouse_grabbed &= ~(1 << event->button);
1487 if (!x_mouse_grabbed) 1500 if (!x_mouse_grabbed)
1488 Vmouse_depressed = Qnil; 1501 Vmouse_depressed = Qnil;
1489 } 1502 }
1490 1503
1491 if (part) /* Scrollbar event */ 1504 if (part) /* Scrollbar event */
1507 } 1520 }
1508 else /* Text Window Event */ 1521 else /* Text Window Event */
1509 { 1522 {
1510 int row, column; 1523 int row, column;
1511 1524
1512 pixel_to_glyph_translation (s, 1525 pixel_to_glyph_coords (s, event->x, event->y, &column, &row, NULL);
1513 event->x, event->y,
1514 &column, &row);
1515
1516 result->kind = mouse_click; 1526 result->kind = mouse_click;
1517 result->x = column; 1527 result->x = column;
1518 result->y = row; 1528 result->y = row;
1519 result->screen = s; 1529 result->screen = s;
1520 } 1530 }
1521 } 1531 }
1522 1532
1523 1533
1534 /* Mouse movement. Rah.
1535
1536 In order to avoid asking for motion events and then throwing most
1537 of them away or busy-polling the server for mouse positions, we ask
1538 the server for pointer motion hints. This means that we get only
1539 one event per group of mouse movements. "Groups" are delimited by
1540 other kinds of events (focus changes and button clicks, for
1541 example), or by XQueryPointer calls; when one of these happens, we
1542 get another MotionNotify event the next time the mouse moves. This
1543 is at least as efficient than getting motion events when mouse
1544 tracking is on, and I suspect only negligibly worse when tracking
1545 is off.
1546
1547 The silly O'Reilly & Associates Nutshell guides barely document
1548 pointer motion hints at all (I think you have to infer how they
1549 work from an example), and the description of XQueryPointer doesn't
1550 mention that calling it causes you to get another motion hint from
1551 the server, which is very important. */
1552
1553 /* Where the mouse was last time we reported a mouse event. */
1554 static SCREEN_PTR last_mouse_screen;
1555 static XRectangle last_mouse_glyph;
1556
1557 /* Function to report a mouse movement to the mainstream Emacs code.
1558 The input handler calls this.
1559
1560 We have received a mouse movement event, which is given in *event.
1561 If the mouse is over a different glyph than it was last time, tell
1562 the mainstream emacs code by setting mouse_moved. If not, ask for
1563 another motion event, so we can check again the next time it moves. */
1564 static void
1565 note_mouse_position (screen, event)
1566 SCREEN_PTR screen;
1567 XMotionEvent *event;
1568
1569 {
1570 /* Has the mouse moved off the glyph it was on at the last sighting? */
1571 if (event->x < last_mouse_glyph.x
1572 || event->x >= last_mouse_glyph.x + last_mouse_glyph.width
1573 || event->y < last_mouse_glyph.y
1574 || event->y >= last_mouse_glyph.y + last_mouse_glyph.height)
1575 mouse_moved = 1;
1576 else
1577 {
1578 /* It's on the same glyph. Call XQueryPointer so we'll get an
1579 event the next time the mouse moves and we can see if it's
1580 *still* on the same glyph. */
1581 int dummy;
1582
1583 XQueryPointer (event->display, event->window,
1584 (Window *) &dummy, (Window *) &dummy,
1585 &dummy, &dummy, &dummy, &dummy,
1586 (unsigned int *) &dummy);
1587 }
1588 }
1589
1590 /* Return the current position of the mouse.
1591
1592 This clears the mouse_moved flag, so we can wait for the next mouse
1593 position. This also calls XQueryPointer, which will cause the
1594 server to give us another MotionNotify when the mouse moves again.
1595 */
1596
1597 static void
1598 XTmouse_position (s, x, y, time)
1599 SCREEN_PTR *s;
1600 Lisp_Object *x, *y;
1601 Lisp_Object *time;
1602 {
1603 int ix, iy, dummy;
1604 Display *d = x_current_display;
1605 Window guess, root, child;
1606
1607 BLOCK_INPUT;
1608
1609 /* I would like to have an X function that just told me the
1610 innermost window containing the mouse.
1611
1612 /* There doesn't seem to be any way to just get the innermost window
1613 containing the pointer, no matter what X screen it's on; you have
1614 to guess a window, and then X will tell you which one of that
1615 window's children it's in. If the pointer isn't in any of that
1616 window's children, it gives you a root window that contains it.
1617
1618 So we start with the selected screen's window and chase down
1619 branches under the guidance of XQueryPointer until we hit a leaf
1620 (all of the Emacs windows we care about are leaf windows). If at
1621 any time XQueryPointer returns false, that means that the current
1622 window does not contain the pointer any more (perhaps it moved),
1623 so we start with the root window XQueryPointer has given us and
1624 start again. */
1625
1626 guess = selected_screen->display.x->window_desc;
1627 for (;;)
1628 if (XQueryPointer (d, guess, &root, &child,
1629 &dummy, &dummy, &ix, &iy, (unsigned int *) &dummy))
1630 {
1631 if (child == None)
1632 /* Guess is a leaf window, and it contains the pointer. */
1633 break;
1634 else
1635 guess = child;
1636 }
1637 else
1638 /* When XQueryPointer returns False, the pointer isn't in guess
1639 anymore, but root is the root window of the screen we should
1640 try instead. */
1641 guess = root;
1642
1643 *s = last_mouse_screen = x_window_to_screen (guess);
1644 if (! *s)
1645 *x = *y = Qnil;
1646 else
1647 {
1648 pixel_to_glyph_coords (*s, ix, iy, &ix, &iy, &last_mouse_glyph);
1649 XSET (*x, Lisp_Int, ix);
1650 XSET (*y, Lisp_Int, iy);
1651 }
1652
1653 mouse_moved = 0;
1654
1655 /* I don't know how to find the time for the last movement; it seems
1656 like XQueryPointer ought to return it, but it doesn't. */
1657 *time = Qnil;
1658
1659 UNBLOCK_INPUT;
1660 }
1661
1662
1524 static char *events[] = 1663 static char *events[] =
1525 { 1664 {
1526 "0: ERROR!", 1665 "0: ERROR!",
1527 "1: REPLY", 1666 "1: REPLY",
1528 "KeyPress", 1667 "KeyPress",
1811 || IsMiscFunctionKey (keysym) /* 0xff60 <= x < 0xff80 */ 1950 || IsMiscFunctionKey (keysym) /* 0xff60 <= x < 0xff80 */
1812 || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */ 1951 || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
1813 || IsFunctionKey (keysym)) /* 0xffbe <= x < 0xffe1 */ 1952 || IsFunctionKey (keysym)) /* 0xffbe <= x < 0xffe1 */
1814 { 1953 {
1815 bufp->kind = non_ascii_keystroke; 1954 bufp->kind = non_ascii_keystroke;
1816 bufp->code = (unsigned) keysym - 0xff50; 1955 XSET (bufp->code, Lisp_Int, (unsigned) keysym - 0xff50);
1817 bufp->screen = XSCREEN (SCREEN_FOCUS_SCREEN (s)); 1956 bufp->screen = XSCREEN (SCREEN_FOCUS_SCREEN (s));
1818 bufp->modifiers = x_convert_modifiers (event.xkey.state); 1957 bufp->modifiers = x_convert_modifiers (event.xkey.state);
1958 XSET (bufp->timestamp, Lisp_Int, event.xkey.time);
1819 bufp++; 1959 bufp++;
1820 count++; 1960 count++;
1821 numchars--; 1961 numchars--;
1822 } 1962 }
1823 else if (numchars > nbytes) 1963 else if (numchars > nbytes)
1829 if (event.xkey.state & Mod1Mask) 1969 if (event.xkey.state & Mod1Mask)
1830 *copy_buffer |= METABIT; 1970 *copy_buffer |= METABIT;
1831 bufp->kind = ascii_keystroke; 1971 bufp->kind = ascii_keystroke;
1832 bufp->screen = XSCREEN (SCREEN_FOCUS_SCREEN (s)); 1972 bufp->screen = XSCREEN (SCREEN_FOCUS_SCREEN (s));
1833 XSET (bufp->code, Lisp_Int, *copy_buffer); 1973 XSET (bufp->code, Lisp_Int, *copy_buffer);
1974 XSET (bufp->timestamp, Lisp_Int, event.xkey.time);
1834 bufp++; 1975 bufp++;
1835 } 1976 }
1836 else 1977 else
1837 for (i = nbytes - 1; i > 1; i--) 1978 for (i = nbytes - 1; i > 1; i--)
1838 { 1979 {
1839 bufp->kind = ascii_keystroke; 1980 bufp->kind = ascii_keystroke;
1840 XSET (bufp->code, Lisp_Int, copy_buffer[i]); 1981 XSET (bufp->code, Lisp_Int, copy_buffer[i]);
1982 XSET (bufp->timestamp, Lisp_Int, event.xkey.time);
1841 bufp->screen = XSCREEN (SCREEN_FOCUS_SCREEN (s)); 1983 bufp->screen = XSCREEN (SCREEN_FOCUS_SCREEN (s));
1842 bufp++; 1984 bufp++;
1843 } 1985 }
1844 1986
1845 count += nbytes; 1987 count += nbytes;
1884 2026
1885 for (i = 0; i < nbytes; i++) 2027 for (i = 0; i < nbytes; i++)
1886 { 2028 {
1887 bufp->kind = ascii_keystroke; 2029 bufp->kind = ascii_keystroke;
1888 XSET (bufp->code, Lisp_Int, where_mapping[i]); 2030 XSET (bufp->code, Lisp_Int, where_mapping[i]);
2031 XSET (bufp->time, Lisp_Int, event.xkey.time);
1889 bufp->screen = XSCREEN (SCREEN_FOCUS_SCREEN (s)); 2032 bufp->screen = XSCREEN (SCREEN_FOCUS_SCREEN (s));
1890 bufp++; 2033 bufp++;
1891 } 2034 }
1892 count += nbytes; 2035 count += nbytes;
1893 numchars -= nbytes; 2036 numchars -= nbytes;
2015 #ifdef HAVE_X11 2158 #ifdef HAVE_X11
2016 case MotionNotify: 2159 case MotionNotify:
2017 { 2160 {
2018 s = x_window_to_screen (event.xmotion.window); 2161 s = x_window_to_screen (event.xmotion.window);
2019 if (s) 2162 if (s)
2020 { 2163 note_mouse_position (s, &event.xmotion);
2021 int row, column;
2022
2023 pixel_to_glyph_translation (s,
2024 event.xmotion.x, event.xmotion.y,
2025 &column, &row);
2026
2027 note_mouse_position (s, column, row, event.xmotion.time);
2028 }
2029 #if 0 2164 #if 0
2030 else if ((s = x_window_to_scrollbar (event.xmotion.window, 2165 else if ((s = x_window_to_scrollbar (event.xmotion.window,
2031 &part, &prefix))) 2166 &part, &prefix)))
2032 { 2167 {
2033 What should go here? 2168 What should go here?
2050 rows = ((event.xconfigure.height - 2185 rows = ((event.xconfigure.height -
2051 (2 * s->display.x->internal_border_width) 2186 (2 * s->display.x->internal_border_width)
2052 - s->display.x->h_scrollbar_height) 2187 - s->display.x->h_scrollbar_height)
2053 / FONT_HEIGHT (s->display.x->font)); 2188 / FONT_HEIGHT (s->display.x->font));
2054 2189
2055 if (columns != s->width || rows != s->height) 2190 /* Even if the number of character rows and columns has
2191 not changed, the font size may have changed, so we need
2192 to check the pixel dimensions as well. */
2193 if (columns != s->width
2194 || rows != s->height
2195 || event.xconfigure.width != s->display.x->pixel_width
2196 || event.xconfigure.height != s->display.x->pixel_height)
2056 { 2197 {
2057 XEvent ignored_event;
2058
2059 change_screen_size (s, rows, columns, 0); 2198 change_screen_size (s, rows, columns, 0);
2060 x_resize_scrollbars (s); 2199 x_resize_scrollbars (s);
2061 SET_SCREEN_GARBAGED (s); 2200 SET_SCREEN_GARBAGED (s);
2062 #if 0
2063 dumprectangle (s, 0, 0, PIXEL_WIDTH (s), PIXEL_HEIGHT (s));
2064 /* Throw away the exposures generated by this reconfigure. */
2065 while (XCheckWindowEvent (x_current_display,
2066 event.xconfigure.window,
2067 ExposureMask, &ignored_event)
2068 == True);
2069 #endif
2070 } 2201 }
2071 2202
2203 s->display.x->pixel_width = event.xconfigure.width;
2204 s->display.x->pixel_height = event.xconfigure.height;
2072 s->display.x->left_pos = event.xconfigure.x; 2205 s->display.x->left_pos = event.xconfigure.x;
2073 s->display.x->top_pos = event.xconfigure.y; 2206 s->display.x->top_pos = event.xconfigure.y;
2074 s->display.x->pixel_width = event.xconfigure.width;
2075 s->display.x->pixel_height = event.xconfigure.height;
2076 break; 2207 break;
2077 } 2208 }
2078 2209
2079 case ButtonPress: 2210 case ButtonPress:
2080 case ButtonRelease: 2211 case ButtonRelease:
2136 if (numchars >= 2) 2267 if (numchars >= 2)
2137 { 2268 {
2138 bufp->kind = ascii_keystroke; 2269 bufp->kind = ascii_keystroke;
2139 bufp->code = (char) 'X' & 037; /* C-x */ 2270 bufp->code = (char) 'X' & 037; /* C-x */
2140 bufp->screen = XSCREEN (SCREEN_FOCUS_SCREEN (s)); 2271 bufp->screen = XSCREEN (SCREEN_FOCUS_SCREEN (s));
2272 XSET (bufp->time, Lisp_Int, event.xkey.time);
2141 bufp++; 2273 bufp++;
2142 2274
2143 bufp->kind = ascii_keystroke; 2275 bufp->kind = ascii_keystroke;
2144 bufp->code = (char) 0; /* C-@ */ 2276 bufp->code = (char) 0; /* C-@ */
2145 bufp->screen = XSCREEN (SCREEN_FOCUS_SCREEN (s)); 2277 bufp->screen = XSCREEN (SCREEN_FOCUS_SCREEN (s));
2278 XSET (bufp->time, Lisp_Int, event.xkey.time);
2146 bufp++; 2279 bufp++;
2147 2280
2148 count += 2; 2281 count += 2;
2149 numchars -= 2; 2282 numchars -= 2;
2150 } 2283 }
2261 } 2394 }
2262 } 2395 }
2263 } 2396 }
2264 #endif /* HAVE_X11 */ 2397 #endif /* HAVE_X11 */
2265 2398
2266 static int
2267 XTmouse_tracking_enable (enable)
2268 int enable;
2269 {
2270 Lisp_Object tail;
2271
2272 /* Go through the list of screens and turn on/off mouse tracking for
2273 each of them. */
2274 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
2275 {
2276 if (XTYPE (XCONS (tail)->car) != Lisp_Screen)
2277 abort ();
2278 if (XSCREEN (XCONS (tail)->car)->output_method == output_x_window)
2279 XSelectInput (x_current_display,
2280 XSCREEN (XCONS (tail)->car)->display.x->window_desc,
2281 (enable
2282 ? (STANDARD_EVENT_SET
2283 | PointerMotionMask
2284 | ButtonReleaseMask)
2285 : STANDARD_EVENT_SET));
2286 }
2287 }
2288
2289
2290 static Lisp_Object
2291 XTmouse_position ()
2292 {
2293
2294 }
2295
2296
2297 2399
2298 /* Draw a hollow box cursor. Don't change the inside of the box. */ 2400 /* Draw a hollow box cursor. Don't change the inside of the box. */
2299 2401
2300 static void 2402 static void
2301 x_draw_box (s) 2403 x_draw_box (s)
2365 s->display.x->background_pixel); 2467 s->display.x->background_pixel);
2366 #endif /* HAVE_X11 */ 2468 #endif /* HAVE_X11 */
2367 s->phys_cursor_x = -1; 2469 s->phys_cursor_x = -1;
2368 } 2470 }
2369 2471
2472 static void
2370 x_display_bar_cursor (s, on) 2473 x_display_bar_cursor (s, on)
2371 struct screen *s; 2474 struct screen *s;
2372 int on; 2475 int on;
2373 { 2476 {
2374 register int phys_x = s->phys_cursor_x; 2477 register int phys_x = s->phys_cursor_x;
2414 Give it up, dude. 2517 Give it up, dude.
2415 #endif /* X10 */ 2518 #endif /* X10 */
2416 } 2519 }
2417 2520
2418 2521
2419 /* Redraw the glyph at ROW, COLUMN on screen S, in the style HIGHLIGHT. 2522 /* Redraw the glyph at ROW, COLUMN on screen S, in the style
2420 If there is no character there, erase the area. HIGHLIGHT is as 2523 HIGHLIGHT. HIGHLIGHT is as defined for dumpglyphs. Return the
2421 defined for dumpglyphs. */ 2524 glyph drawn. */
2422 2525
2423 static void 2526 static void
2424 x_draw_single_glyph (s, row, column, highlight) 2527 x_draw_single_glyph (s, row, column, glyph, highlight)
2425 struct screen *s; 2528 struct screen *s;
2426 int row, column; 2529 int row, column;
2530 GLYPH glyph;
2427 int highlight; 2531 int highlight;
2428 { 2532 {
2429 register struct screen_glyphs *current_screen = SCREEN_CURRENT_GLYPHS (s); 2533 dumpglyphs (s,
2430 2534 (column * FONT_WIDTH (s->display.x->font)
2431 /* If there is supposed to be a character there, redraw it 2535 + s->display.x->internal_border_width),
2432 in that line's normal video. */ 2536 (row * FONT_HEIGHT (s->display.x->font)
2433 if (current_screen->enable[row] 2537 + s->display.x->internal_border_width),
2434 && column < current_screen->used[row]) 2538 &glyph, 1, highlight, s->display.x->font);
2435 dumpglyphs (s,
2436 (column * FONT_WIDTH (s->display.x->font)
2437 + s->display.x->internal_border_width),
2438 (row * FONT_HEIGHT (s->display.x->font)
2439 + s->display.x->internal_border_width),
2440 &current_screen->glyphs[row][column],
2441 1, highlight, s->display.x->font);
2442 else
2443 {
2444 #ifdef HAVE_X11
2445 static GLYPH a_space_glyph = SPACEGLYPH;
2446 dumpglyphs (s,
2447 (column * FONT_WIDTH (s->display.x->font)
2448 + s->display.x->internal_border_width),
2449 (row * FONT_HEIGHT (s->display.x->font)
2450 + s->display.x->internal_border_width),
2451 &a_space_glyph, 1, highlight, s->display.x->font);
2452 #else
2453 XPixSet (s->display.x->window_desc,
2454 (column * FONT_WIDTH (s->display.x->font)
2455 + s->display.x->internal_border_width),
2456 (row * FONT_HEIGHT (s->display.x->font)
2457 + s->display.x->internal_border_width),
2458 FONT_WIDTH (s->display.x->font),
2459 FONT_HEIGHT (s->display.x->font),
2460 (highlight == 0
2461 ? s->display.x->background_pixel
2462 : (highlight == 1
2463 ? s->display.x->foreground_pixel
2464 : s->display.x->cursor_pixel)));
2465 #endif /* HAVE_X11 */
2466 }
2467 } 2539 }
2468 2540
2469 /* Turn the displayed cursor of screen S on or off according to ON. 2541 /* Turn the displayed cursor of screen S on or off according to ON.
2470 If ON is nonzero, where to put the cursor is specified 2542 If ON is nonzero, where to put the cursor is specified
2471 by S->cursor_x and S->cursor_y. */ 2543 by S->cursor_x and S->cursor_y. */
2473 static void 2545 static void
2474 x_display_box_cursor (s, on) 2546 x_display_box_cursor (s, on)
2475 struct screen *s; 2547 struct screen *s;
2476 int on; 2548 int on;
2477 { 2549 {
2550 struct screen_glyphs *current_glyphs = SCREEN_CURRENT_GLYPHS (s);
2551
2478 if (! s->visible) 2552 if (! s->visible)
2479 return; 2553 return;
2480 2554
2481 /* If cursor is off and we want it off, return quickly. */ 2555 /* If cursor is off and we want it off, return quickly. */
2482
2483 if (!on && s->phys_cursor_x < 0) 2556 if (!on && s->phys_cursor_x < 0)
2484 return; 2557 return;
2485 2558
2486 /* If cursor is currently being shown and we don't want it to be 2559 /* If cursor is currently being shown and we don't want it to be
2487 or it is in the wrong place, 2560 or it is in the wrong place,
2494 || (s->display.x->text_cursor_kind != hollow_box_cursor 2567 || (s->display.x->text_cursor_kind != hollow_box_cursor
2495 && (s != x_highlight_screen)))) 2568 && (s != x_highlight_screen))))
2496 { 2569 {
2497 /* Erase the cursor by redrawing the character underneath it. */ 2570 /* Erase the cursor by redrawing the character underneath it. */
2498 x_draw_single_glyph (s, s->phys_cursor_y, s->phys_cursor_x, 2571 x_draw_single_glyph (s, s->phys_cursor_y, s->phys_cursor_x,
2499 (SCREEN_CURRENT_GLYPHS (s) 2572 s->phys_cursor_glyph,
2500 ->highlight[s->phys_cursor_y])); 2573 current_glyphs->highlight[s->phys_cursor_y]);
2501
2502 s->phys_cursor_x = -1; 2574 s->phys_cursor_x = -1;
2503 } 2575 }
2504 2576
2505 /* If we want to show a cursor, 2577 /* If we want to show a cursor,
2506 or we want a box cursor and it's not so, 2578 or we want a box cursor and it's not so,
2508 if (on 2580 if (on
2509 && (s->phys_cursor_x < 0 2581 && (s->phys_cursor_x < 0
2510 || (s->display.x->text_cursor_kind != filled_box_cursor 2582 || (s->display.x->text_cursor_kind != filled_box_cursor
2511 && s == x_highlight_screen))) 2583 && s == x_highlight_screen)))
2512 { 2584 {
2585 s->phys_cursor_glyph
2586 = ((current_glyphs->enable[s->cursor_y]
2587 && s->cursor_x < current_glyphs->used[s->cursor_y])
2588 ? current_glyphs->glyphs[s->cursor_y][s->cursor_x]
2589 : SPACEGLYPH);
2513 if (s != x_highlight_screen) 2590 if (s != x_highlight_screen)
2514 { 2591 {
2515 x_draw_box (s); 2592 x_draw_box (s);
2516 s->display.x->text_cursor_kind = hollow_box_cursor; 2593 s->display.x->text_cursor_kind = hollow_box_cursor;
2517 } 2594 }
2518 else 2595 else
2519 { 2596 {
2520 x_draw_single_glyph (s, s->cursor_y, s->cursor_x, 2); 2597 x_draw_single_glyph (s, s->cursor_y, s->cursor_x,
2598 s->phys_cursor_glyph, 2);
2521 s->display.x->text_cursor_kind = filled_box_cursor; 2599 s->display.x->text_cursor_kind = filled_box_cursor;
2522 } 2600 }
2523 2601
2524 s->phys_cursor_x = s->cursor_x; 2602 s->phys_cursor_x = s->cursor_x;
2525 s->phys_cursor_y = s->cursor_y; 2603 s->phys_cursor_y = s->cursor_y;
2950 /* If the server couldn't find any fonts whose named matched fontname, 3028 /* If the server couldn't find any fonts whose named matched fontname,
2951 return an error code. */ 3029 return an error code. */
2952 if (n_matching_fonts == 0) 3030 if (n_matching_fonts == 0)
2953 return 1; 3031 return 1;
2954 3032
2955 /* See if we've already loaded this font. */ 3033 /* See if we've already loaded a matching font. */
2956 { 3034 {
2957 int i, j; 3035 int i, j;
2958 3036
2959 already_loaded = 0; 3037 already_loaded = 0;
2960 for (i = 0; i < n_fonts; i++) 3038 for (i = 0; i < n_fonts; i++)
2967 } 3045 }
2968 found_font: 3046 found_font:
2969 3047
2970 /* If we have, just return it from the table. */ 3048 /* If we have, just return it from the table. */
2971 if (already_loaded) 3049 if (already_loaded)
2972 { 3050 s->display.x->font = x_font_table[already_loaded];
2973 s->display.x->font = x_font_table[already_loaded]; 3051
2974 }
2975
2976 /* Otherwise, load the font and add it to the table. */ 3052 /* Otherwise, load the font and add it to the table. */
2977 else 3053 else
2978 { 3054 {
2979 XFontStruct *font; 3055 XFontStruct *font;
2980 3056
2991 * sizeof (x_font_table[0])); 3067 * sizeof (x_font_table[0]));
2992 } 3068 }
2993 /* Do we need to grow the table? */ 3069 /* Do we need to grow the table? */
2994 else if (n_fonts >= x_font_table_size) 3070 else if (n_fonts >= x_font_table_size)
2995 { 3071 {
2996 x_font_table_size <<= 1; 3072 x_font_table_size *= 2;
2997 x_font_table 3073 x_font_table
2998 = (XFontStruct **) xrealloc (x_font_table, 3074 = (XFontStruct **) xrealloc (x_font_table,
2999 (x_font_table_size 3075 (x_font_table_size
3000 * sizeof (x_font_table[0]))); 3076 * sizeof (x_font_table[0])));
3001 } 3077 }
3222 x_make_screen_visible (s) 3298 x_make_screen_visible (s)
3223 struct screen *s; 3299 struct screen *s;
3224 { 3300 {
3225 int mask; 3301 int mask;
3226 3302
3227 if (s->visible)
3228 {
3229 BLOCK_INPUT;
3230 XRaiseWindow (XDISPLAY s->display.x->window_desc);
3231 XFlushQueue ();
3232 UNBLOCK_INPUT;
3233 return;
3234 }
3235
3236 BLOCK_INPUT; 3303 BLOCK_INPUT;
3237 #ifdef HAVE_X11 3304
3238 3305 if (! SCREEN_VISIBLE_P (s))
3239 if (! EQ (Vx_no_window_manager, Qt)) 3306 {
3240 x_wm_set_window_state (s, NormalState); 3307 #ifdef HAVE_X11
3241 3308 if (! EQ (Vx_no_window_manager, Qt))
3242 XMapWindow (XDISPLAY s->display.x->window_desc); 3309 x_wm_set_window_state (s, NormalState);
3243 if (s->display.x->v_scrollbar != 0 || s->display.x->h_scrollbar != 0) 3310
3244 XMapSubwindows (x_current_display, s->display.x->window_desc); 3311 XMapWindow (XDISPLAY s->display.x->window_desc);
3245 3312 if (s->display.x->v_scrollbar != 0 || s->display.x->h_scrollbar != 0)
3313 XMapSubwindows (x_current_display, s->display.x->window_desc);
3246 #else 3314 #else
3247 XMapWindow (XDISPLAY s->display.x->window_desc); 3315 XMapWindow (XDISPLAY s->display.x->window_desc);
3248 if (s->display.x->icon_desc != 0) 3316 if (s->display.x->icon_desc != 0)
3249 XUnmapWindow (s->display.x->icon_desc); 3317 XUnmapWindow (s->display.x->icon_desc);
3250 3318
3251 /* Handled by the MapNotify event for X11 */ 3319 /* Handled by the MapNotify event for X11 */
3252 s->visible = 1; 3320 s->visible = 1;
3253 s->iconified = 0; 3321 s->iconified = 0;
3254 3322
3255 /* NOTE: this may cause problems for the first screen. */ 3323 /* NOTE: this may cause problems for the first screen. */
3256 XTcursor_to (0, 0); 3324 XTcursor_to (0, 0);
3257 #endif /* not HAVE_X11 */ 3325 #endif /* not HAVE_X11 */
3326 }
3258 3327
3259 XRaiseWindow (XDISPLAY s->display.x->window_desc); 3328 XRaiseWindow (XDISPLAY s->display.x->window_desc);
3260 XFlushQueue (); 3329 XFlushQueue ();
3330
3261 UNBLOCK_INPUT; 3331 UNBLOCK_INPUT;
3262 } 3332 }
3263 3333
3264 /* Change from mapped state to withdrawn state. */ 3334 /* Change from mapped state to withdrawn state. */
3265 3335
3665 set_terminal_window_hook = XTset_terminal_window; 3735 set_terminal_window_hook = XTset_terminal_window;
3666 read_socket_hook = XTread_socket; 3736 read_socket_hook = XTread_socket;
3667 cursor_to_hook = XTcursor_to; 3737 cursor_to_hook = XTcursor_to;
3668 reassert_line_highlight_hook = XTreassert_line_highlight; 3738 reassert_line_highlight_hook = XTreassert_line_highlight;
3669 screen_rehighlight_hook = XTscreen_rehighlight; 3739 screen_rehighlight_hook = XTscreen_rehighlight;
3670 mouse_tracking_enable_hook = XTmouse_tracking_enable; 3740 mouse_position_hook = XTmouse_position;
3671 3741
3672 scroll_region_ok = 1; /* we'll scroll partial screens */ 3742 scroll_region_ok = 1; /* we'll scroll partial screens */
3673 char_ins_del_ok = 0; /* just as fast to write the line */ 3743 char_ins_del_ok = 0; /* just as fast to write the line */
3674 line_ins_del_ok = 1; /* we'll just blt 'em */ 3744 line_ins_del_ok = 1; /* we'll just blt 'em */
3675 fast_clear_end_of_line = 1; /* X does this well */ 3745 fast_clear_end_of_line = 1; /* X does this well */