Mercurial > emacs
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 ¤t_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 */ |