Mercurial > emacs
comparison src/xterm.c @ 6022:713d4d840a11
(x_had_errors_p): New function.
(construct_menu_click): Convert x pos from pixels to glyphs.
Move function after pixel_to_glyph_coords.
[!USE_X_TOOLKIT] (x_any_window_to_frame):
Define as x_window_to_frame.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Mon, 21 Feb 1994 21:54:33 +0000 |
parents | 1f9f36411af8 |
children | 67aa546e4ff1 |
comparison
equal
deleted
inserted
replaced
6021:de651e959736 | 6022:713d4d840a11 |
---|---|
95 #ifdef USE_X_TOOLKIT | 95 #ifdef USE_X_TOOLKIT |
96 extern XtAppContext Xt_app_con; | 96 extern XtAppContext Xt_app_con; |
97 extern Widget Xt_app_shell; | 97 extern Widget Xt_app_shell; |
98 extern void free_frame_menubar (); | 98 extern void free_frame_menubar (); |
99 #endif /* USE_X_TOOLKIT */ | 99 #endif /* USE_X_TOOLKIT */ |
100 | |
101 #ifndef USE_X_TOOLKIT | |
102 #define x_any_window_to_frame x_window_to_frame | |
103 #endif | |
100 | 104 |
101 #ifdef HAVE_X11 | 105 #ifdef HAVE_X11 |
102 #define XMapWindow XMapRaised /* Raise them when mapping. */ | 106 #define XMapWindow XMapRaised /* Raise them when mapping. */ |
103 #else /* ! defined (HAVE_X11) */ | 107 #else /* ! defined (HAVE_X11) */ |
104 #include <X/Xkeyboard.h> | 108 #include <X/Xkeyboard.h> |
1617 | 1621 |
1618 XFree ((char *) syms); | 1622 XFree ((char *) syms); |
1619 XFreeModifiermap (mods); | 1623 XFreeModifiermap (mods); |
1620 } | 1624 } |
1621 | 1625 |
1626 /* Convert between the modifier bits X uses and the modifier bits | |
1627 Emacs uses. */ | |
1628 static unsigned int | |
1629 x_x_to_emacs_modifiers (state) | |
1630 unsigned int state; | |
1631 { | |
1632 return ( ((state & (ShiftMask | x_shift_lock_mask)) ? shift_modifier : 0) | |
1633 | ((state & ControlMask) ? ctrl_modifier : 0) | |
1634 | ((state & x_meta_mod_mask) ? meta_modifier : 0) | |
1635 | ((state & x_alt_mod_mask) ? alt_modifier : 0) | |
1636 | ((state & x_super_mod_mask) ? super_modifier : 0) | |
1637 | ((state & x_hyper_mod_mask) ? hyper_modifier : 0)); | |
1638 } | |
1639 | |
1640 static unsigned int | |
1641 x_emacs_to_x_modifiers (state) | |
1642 unsigned int state; | |
1643 { | |
1644 return ( ((state & alt_modifier) ? x_alt_mod_mask : 0) | |
1645 | ((state & super_modifier) ? x_super_mod_mask : 0) | |
1646 | ((state & hyper_modifier) ? x_hyper_mod_mask : 0) | |
1647 | ((state & shift_modifier) ? ShiftMask : 0) | |
1648 | ((state & ctrl_modifier) ? ControlMask : 0) | |
1649 | ((state & meta_modifier) ? x_meta_mod_mask : 0)); | |
1650 } | |
1651 | |
1652 /* Return true iff KEYSYM is a vendor-specific keysym that we should | |
1653 return as a function key. If you add a keysym to this, you should | |
1654 make sure that the tables make_lispy_event uses contain a suitable | |
1655 name for it. */ | |
1656 static int | |
1657 x_is_vendor_fkey (sym) | |
1658 KeySym sym; | |
1659 { | |
1660 return 0 | |
1661 #ifdef DXK_Remove | |
1662 || (sym == DXK_Remove) | |
1663 #endif | |
1664 ; | |
1665 } | |
1666 | |
1667 | |
1668 /* Mouse clicks and mouse movement. Rah. */ | |
1669 #ifdef HAVE_X11 | |
1670 | |
1671 /* Given a pixel position (PIX_X, PIX_Y) on the frame F, return | |
1672 glyph co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle | |
1673 that the glyph at X, Y occupies, if BOUNDS != 0. | |
1674 If NOCLIP is nonzero, do not force the value into range. */ | |
1675 | |
1676 static void | |
1677 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip) | |
1678 FRAME_PTR f; | |
1679 register int pix_x, pix_y; | |
1680 register int *x, *y; | |
1681 XRectangle *bounds; | |
1682 int noclip; | |
1683 { | |
1684 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down | |
1685 even for negative values. */ | |
1686 if (pix_x < 0) | |
1687 pix_x -= FONT_WIDTH ((f)->display.x->font) - 1; | |
1688 if (pix_y < 0) | |
1689 pix_y -= FONT_HEIGHT ((f)->display.x->font) - 1; | |
1690 | |
1691 pix_x = PIXEL_TO_CHAR_COL (f, pix_x); | |
1692 pix_y = PIXEL_TO_CHAR_ROW (f, pix_y); | |
1693 | |
1694 if (bounds) | |
1695 { | |
1696 bounds->width = FONT_WIDTH (f->display.x->font); | |
1697 bounds->height = FONT_HEIGHT (f->display.x->font); | |
1698 bounds->x = CHAR_TO_PIXEL_COL (f, pix_x); | |
1699 bounds->y = CHAR_TO_PIXEL_ROW (f, pix_y); | |
1700 } | |
1701 | |
1702 if (!noclip) | |
1703 { | |
1704 if (pix_x < 0) | |
1705 pix_x = 0; | |
1706 else if (pix_x > f->width) | |
1707 pix_x = f->width; | |
1708 | |
1709 if (pix_y < 0) | |
1710 pix_y = 0; | |
1711 else if (pix_y > f->height) | |
1712 pix_y = f->height; | |
1713 } | |
1714 | |
1715 *x = pix_x; | |
1716 *y = pix_y; | |
1717 } | |
1718 | |
1719 /* Prepare a mouse-event in *RESULT for placement in the input queue. | |
1720 | |
1721 If the event is a button press, then note that we have grabbed | |
1722 the mouse. */ | |
1723 | |
1724 static Lisp_Object | |
1725 construct_mouse_click (result, event, f) | |
1726 struct input_event *result; | |
1727 XButtonEvent *event; | |
1728 struct frame *f; | |
1729 { | |
1730 /* Make the event type no_event; we'll change that when we decide | |
1731 otherwise. */ | |
1732 result->kind = mouse_click; | |
1733 result->code = event->button - Button1; | |
1734 result->timestamp = event->time; | |
1735 result->modifiers = (x_x_to_emacs_modifiers (event->state) | |
1736 | (event->type == ButtonRelease | |
1737 ? up_modifier | |
1738 : down_modifier)); | |
1739 | |
1740 /* Notice if the mouse is still grabbed. */ | |
1741 if (event->type == ButtonPress) | |
1742 { | |
1743 if (! x_mouse_grabbed) | |
1744 Vmouse_depressed = Qt; | |
1745 x_mouse_grabbed |= (1 << event->button); | |
1746 last_mouse_frame = f; | |
1747 } | |
1748 else if (event->type == ButtonRelease) | |
1749 { | |
1750 x_mouse_grabbed &= ~(1 << event->button); | |
1751 if (!x_mouse_grabbed) | |
1752 Vmouse_depressed = Qnil; | |
1753 } | |
1754 | |
1755 { | |
1756 int row, column; | |
1757 | |
1758 pixel_to_glyph_coords (f, event->x, event->y, &column, &row, NULL, 0); | |
1759 XFASTINT (result->x) = column; | |
1760 XFASTINT (result->y) = row; | |
1761 XSET (result->frame_or_window, Lisp_Frame, f); | |
1762 } | |
1763 } | |
1764 | |
1622 /* Prepare a menu-event in *RESULT for placement in the input queue. */ | 1765 /* Prepare a menu-event in *RESULT for placement in the input queue. */ |
1623 | 1766 |
1624 static Lisp_Object | 1767 static Lisp_Object |
1625 construct_menu_click (result, event, f) | 1768 construct_menu_click (result, event, f) |
1626 struct input_event *result; | 1769 struct input_event *result; |
1636 | (event->type == ButtonRelease | 1779 | (event->type == ButtonRelease |
1637 ? up_modifier | 1780 ? up_modifier |
1638 : down_modifier)); | 1781 : down_modifier)); |
1639 | 1782 |
1640 { | 1783 { |
1641 XFASTINT (result->x) = event->x; | |
1642 XFASTINT (result->y) = -1; /* special meaning for menubar */ | |
1643 XSET (result->frame_or_window, Lisp_Frame, f); | |
1644 } | |
1645 } | |
1646 | |
1647 /* Convert between the modifier bits X uses and the modifier bits | |
1648 Emacs uses. */ | |
1649 static unsigned int | |
1650 x_x_to_emacs_modifiers (state) | |
1651 unsigned int state; | |
1652 { | |
1653 return ( ((state & (ShiftMask | x_shift_lock_mask)) ? shift_modifier : 0) | |
1654 | ((state & ControlMask) ? ctrl_modifier : 0) | |
1655 | ((state & x_meta_mod_mask) ? meta_modifier : 0) | |
1656 | ((state & x_alt_mod_mask) ? alt_modifier : 0) | |
1657 | ((state & x_super_mod_mask) ? super_modifier : 0) | |
1658 | ((state & x_hyper_mod_mask) ? hyper_modifier : 0)); | |
1659 } | |
1660 | |
1661 static unsigned int | |
1662 x_emacs_to_x_modifiers (state) | |
1663 unsigned int state; | |
1664 { | |
1665 return ( ((state & alt_modifier) ? x_alt_mod_mask : 0) | |
1666 | ((state & super_modifier) ? x_super_mod_mask : 0) | |
1667 | ((state & hyper_modifier) ? x_hyper_mod_mask : 0) | |
1668 | ((state & shift_modifier) ? ShiftMask : 0) | |
1669 | ((state & ctrl_modifier) ? ControlMask : 0) | |
1670 | ((state & meta_modifier) ? x_meta_mod_mask : 0)); | |
1671 } | |
1672 | |
1673 /* Return true iff KEYSYM is a vendor-specific keysym that we should | |
1674 return as a function key. If you add a keysym to this, you should | |
1675 make sure that the tables make_lispy_event uses contain a suitable | |
1676 name for it. */ | |
1677 static int | |
1678 x_is_vendor_fkey (sym) | |
1679 KeySym sym; | |
1680 { | |
1681 return 0 | |
1682 #ifdef DXK_Remove | |
1683 || (sym == DXK_Remove) | |
1684 #endif | |
1685 ; | |
1686 } | |
1687 | |
1688 | |
1689 /* Mouse clicks and mouse movement. Rah. */ | |
1690 #ifdef HAVE_X11 | |
1691 | |
1692 /* Given a pixel position (PIX_X, PIX_Y) on the frame F, return | |
1693 glyph co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle | |
1694 that the glyph at X, Y occupies, if BOUNDS != 0. | |
1695 If NOCLIP is nonzero, do not force the value into range. */ | |
1696 | |
1697 static void | |
1698 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip) | |
1699 FRAME_PTR f; | |
1700 register int pix_x, pix_y; | |
1701 register int *x, *y; | |
1702 XRectangle *bounds; | |
1703 int noclip; | |
1704 { | |
1705 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down | |
1706 even for negative values. */ | |
1707 if (pix_x < 0) | |
1708 pix_x -= FONT_WIDTH ((f)->display.x->font) - 1; | |
1709 if (pix_y < 0) | |
1710 pix_y -= FONT_HEIGHT ((f)->display.x->font) - 1; | |
1711 | |
1712 pix_x = PIXEL_TO_CHAR_COL (f, pix_x); | |
1713 pix_y = PIXEL_TO_CHAR_ROW (f, pix_y); | |
1714 | |
1715 if (bounds) | |
1716 { | |
1717 bounds->width = FONT_WIDTH (f->display.x->font); | |
1718 bounds->height = FONT_HEIGHT (f->display.x->font); | |
1719 bounds->x = CHAR_TO_PIXEL_COL (f, pix_x); | |
1720 bounds->y = CHAR_TO_PIXEL_ROW (f, pix_y); | |
1721 } | |
1722 | |
1723 if (!noclip) | |
1724 { | |
1725 if (pix_x < 0) | |
1726 pix_x = 0; | |
1727 else if (pix_x > f->width) | |
1728 pix_x = f->width; | |
1729 | |
1730 if (pix_y < 0) | |
1731 pix_y = 0; | |
1732 else if (pix_y > f->height) | |
1733 pix_y = f->height; | |
1734 } | |
1735 | |
1736 *x = pix_x; | |
1737 *y = pix_y; | |
1738 } | |
1739 | |
1740 /* Prepare a mouse-event in *RESULT for placement in the input queue. | |
1741 | |
1742 If the event is a button press, then note that we have grabbed | |
1743 the mouse. */ | |
1744 | |
1745 static Lisp_Object | |
1746 construct_mouse_click (result, event, f) | |
1747 struct input_event *result; | |
1748 XButtonEvent *event; | |
1749 struct frame *f; | |
1750 { | |
1751 /* Make the event type no_event; we'll change that when we decide | |
1752 otherwise. */ | |
1753 result->kind = mouse_click; | |
1754 result->code = event->button - Button1; | |
1755 result->timestamp = event->time; | |
1756 result->modifiers = (x_x_to_emacs_modifiers (event->state) | |
1757 | (event->type == ButtonRelease | |
1758 ? up_modifier | |
1759 : down_modifier)); | |
1760 | |
1761 /* Notice if the mouse is still grabbed. */ | |
1762 if (event->type == ButtonPress) | |
1763 { | |
1764 if (! x_mouse_grabbed) | |
1765 Vmouse_depressed = Qt; | |
1766 x_mouse_grabbed |= (1 << event->button); | |
1767 last_mouse_frame = f; | |
1768 } | |
1769 else if (event->type == ButtonRelease) | |
1770 { | |
1771 x_mouse_grabbed &= ~(1 << event->button); | |
1772 if (!x_mouse_grabbed) | |
1773 Vmouse_depressed = Qnil; | |
1774 } | |
1775 | |
1776 { | |
1777 int row, column; | 1784 int row, column; |
1778 | 1785 |
1779 pixel_to_glyph_coords (f, event->x, event->y, &column, &row, NULL, 0); | 1786 pixel_to_glyph_coords (f, event->x, event->y, &column, &row, NULL, 0); |
1780 XFASTINT (result->x) = column; | 1787 XFASTINT (result->x) = column; |
1781 XFASTINT (result->y) = row; | 1788 XFASTINT (result->y) = -1; |
1782 XSET (result->frame_or_window, Lisp_Frame, f); | 1789 XSET (result->frame_or_window, Lisp_Frame, f); |
1783 } | 1790 } |
1784 } | 1791 } |
1785 | 1792 |
1786 /* Function to report a mouse movement to the mainstream Emacs code. | 1793 /* Function to report a mouse movement to the mainstream Emacs code. |
4289 x_uncatch_errors (); | 4296 x_uncatch_errors (); |
4290 error (buf); | 4297 error (buf); |
4291 } | 4298 } |
4292 } | 4299 } |
4293 | 4300 |
4301 /* Nonzero if we had any X protocol errors since we did x_catch_errors. */ | |
4302 | |
4303 int | |
4304 x_had_errors_p () | |
4305 { | |
4306 /* Make sure to catch any errors incurred so far. */ | |
4307 XSync (x_current_display, False); | |
4308 | |
4309 return x_caught_error_message[0] != 0; | |
4310 } | |
4311 | |
4294 /* Stop catching X protocol errors and let them make Emacs die. */ | 4312 /* Stop catching X protocol errors and let them make Emacs die. */ |
4295 | 4313 |
4296 void | 4314 void |
4297 x_uncatch_errors () | 4315 x_uncatch_errors () |
4298 { | 4316 { |