diff options
| author | Jim Blandy | 1991-11-08 01:52:59 +0000 |
|---|---|---|
| committer | Jim Blandy | 1991-11-08 01:52:59 +0000 |
| commit | 90e65f0739fe577304eee18642a726791ff08406 (patch) | |
| tree | 7aaffefc16508d9db00e5643874c47c5fc82ecc5 /src | |
| parent | df11cb7fbdcba6790e86ae579160cbd9efc1fb42 (diff) | |
| download | emacs-90e65f0739fe577304eee18642a726791ff08406.tar.gz emacs-90e65f0739fe577304eee18642a726791ff08406.zip | |
*** empty log message ***
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 412 |
1 files changed, 241 insertions, 171 deletions
diff --git a/src/xterm.c b/src/xterm.c index 06d54c9a62e..079f162505c 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -252,8 +252,6 @@ static WINDOWINFO_TYPE windowinfo; | |||
| 252 | 252 | ||
| 253 | extern int errno; | 253 | extern int errno; |
| 254 | 254 | ||
| 255 | extern Lisp_Object Vglobal_minibuffer_screen; | ||
| 256 | |||
| 257 | extern Display *XOpenDisplay (); | 255 | extern Display *XOpenDisplay (); |
| 258 | extern Window XCreateWindow (); | 256 | extern Window XCreateWindow (); |
| 259 | 257 | ||
| @@ -296,7 +294,6 @@ XTupdate_begin (s) | |||
| 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 | ||
| @@ -564,16 +561,18 @@ XTwrite_glyphs (start, len) | |||
| 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 | { |
| @@ -611,9 +610,11 @@ XTclear_end_of_line (first_unused) | |||
| 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, |
| @@ -949,7 +950,7 @@ XTins_del_lines (vpos, n) | |||
| 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); |
| @@ -1103,7 +1104,7 @@ x_do_pending_expose () | |||
| 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; |
| @@ -1302,7 +1303,6 @@ extern int mouse_buffer_offset; | |||
| 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. */ |
| @@ -1397,39 +1397,51 @@ notice_mouse_movement (result, motion_event, s, window_type, part) | |||
| 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; |
| 1412 | XRectangle *bounds; | ||
| 1407 | { | 1413 | { |
| 1408 | register struct screen_glyphs *s_glyphs = SCREEN_CURRENT_GLYPHS (s); | ||
| 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; |
| 1426 | else | ||
| 1427 | *y = (pix_y - ibw) / height; | ||
| 1417 | 1428 | ||
| 1418 | /* Horizontally, is it in the border? */ | 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; |
| 1436 | |||
| 1437 | if (bounds) | ||
| 1438 | { | ||
| 1439 | bounds->width = width; | ||
| 1440 | bounds->height = height; | ||
| 1441 | bounds->x = ibw + (*x * width); | ||
| 1442 | bounds->y = ibw + (*y * height); | ||
| 1443 | } | ||
| 1430 | } | 1444 | } |
| 1431 | |||
| 1432 | #ifdef HAVE_X11 | ||
| 1433 | 1445 | ||
| 1434 | /* Any buttons grabbed. */ | 1446 | /* Any buttons grabbed. */ |
| 1435 | unsigned int x_mouse_grabbed; | 1447 | unsigned int x_mouse_grabbed; |
| @@ -1470,6 +1482,7 @@ construct_mouse_click (result, event, s, part, prefix) | |||
| 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)); |
| @@ -1479,11 +1492,11 @@ construct_mouse_click (result, event, s, part, prefix) | |||
| 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 | } |
| @@ -1509,10 +1522,7 @@ construct_mouse_click (result, event, s, part, prefix) | |||
| 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; |
| @@ -1521,6 +1531,135 @@ construct_mouse_click (result, event, s, part, prefix) | |||
| 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!", |
| @@ -1813,9 +1952,10 @@ XTread_socket (sd, bufp, numchars, waitp, expected) | |||
| 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--; |
| @@ -1831,6 +1971,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) | |||
| 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 |
| @@ -1838,6 +1979,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) | |||
| 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 | } |
| @@ -1886,6 +2028,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) | |||
| 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 | } |
| @@ -2017,15 +2160,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) | |||
| 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))) |
| @@ -2052,27 +2187,23 @@ XTread_socket (sd, bufp, numchars, waitp, expected) | |||
| 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 | ||
| 2072 | s->display.x->left_pos = event.xconfigure.x; | ||
| 2073 | s->display.x->top_pos = event.xconfigure.y; | ||
| 2074 | s->display.x->pixel_width = event.xconfigure.width; | 2203 | s->display.x->pixel_width = event.xconfigure.width; |
| 2075 | s->display.x->pixel_height = event.xconfigure.height; | 2204 | s->display.x->pixel_height = event.xconfigure.height; |
| 2205 | s->display.x->left_pos = event.xconfigure.x; | ||
| 2206 | s->display.x->top_pos = event.xconfigure.y; | ||
| 2076 | break; | 2207 | break; |
| 2077 | } | 2208 | } |
| 2078 | 2209 | ||
| @@ -2138,11 +2269,13 @@ XTread_socket (sd, bufp, numchars, waitp, expected) | |||
| 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; |
| @@ -2263,37 +2396,6 @@ x_read_exposes () | |||
| 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 | ||
| @@ -2367,6 +2469,7 @@ clear_cursor (s) | |||
| 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; |
| @@ -2416,54 +2519,23 @@ x_display_bar_cursor (s, on) | |||
| 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. |
| @@ -2475,11 +2547,12 @@ 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 | ||
| @@ -2496,9 +2569,8 @@ x_display_box_cursor (s, on) | |||
| 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 | ||
| @@ -2510,6 +2582,11 @@ x_display_box_cursor (s, on) | |||
| 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); |
| @@ -2517,7 +2594,8 @@ x_display_box_cursor (s, on) | |||
| 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 | ||
| @@ -2952,7 +3030,7 @@ x_new_font (s, fontname) | |||
| 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 | ||
| @@ -2969,10 +3047,8 @@ x_new_font (s, fontname) | |||
| 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 | { |
| @@ -2993,7 +3069,7 @@ x_new_font (s, fontname) | |||
| 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 |
| @@ -3224,40 +3300,34 @@ x_make_screen_visible (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 | ||
| 3238 | |||
| 3239 | if (! EQ (Vx_no_window_manager, Qt)) | ||
| 3240 | x_wm_set_window_state (s, NormalState); | ||
| 3241 | 3304 | ||
| 3242 | XMapWindow (XDISPLAY s->display.x->window_desc); | 3305 | if (! SCREEN_VISIBLE_P (s)) |
| 3243 | if (s->display.x->v_scrollbar != 0 || s->display.x->h_scrollbar != 0) | 3306 | { |
| 3244 | XMapSubwindows (x_current_display, s->display.x->window_desc); | 3307 | #ifdef HAVE_X11 |
| 3308 | if (! EQ (Vx_no_window_manager, Qt)) | ||
| 3309 | x_wm_set_window_state (s, NormalState); | ||
| 3245 | 3310 | ||
| 3311 | XMapWindow (XDISPLAY s->display.x->window_desc); | ||
| 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 | ||
| @@ -3667,7 +3737,7 @@ x_term_init (display_name) | |||
| 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 */ |