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 {