diff options
author | Christoph Lohmann <20h@r-36.net> | 2013-06-01 14:37:30 +0200 |
---|---|---|
committer | Christoph Lohmann <20h@r-36.net> | 2013-06-01 14:37:30 +0200 |
commit | 7530694987596642b0b83db1c4a61f2794c20397 (patch) | |
tree | 3ec6ded55f1bc34e1cec5762268e0be7c8eac638 | |
parent | d743b93fdaee4900052a94b37c24073008888002 (diff) | |
download | st-7530694987596642b0b83db1c4a61f2794c20397.tar.gz st-7530694987596642b0b83db1c4a61f2794c20397.zip |
Adding true mouse motion support.
-rw-r--r-- | st.c | 87 |
1 files changed, 55 insertions, 32 deletions
@@ -108,7 +108,6 @@ enum term_mode { | |||
108 | MODE_CRLF = 16, | 108 | MODE_CRLF = 16, |
109 | MODE_MOUSEBTN = 32, | 109 | MODE_MOUSEBTN = 32, |
110 | MODE_MOUSEMOTION = 64, | 110 | MODE_MOUSEMOTION = 64, |
111 | MODE_MOUSE = 32|64, | ||
112 | MODE_REVERSE = 128, | 111 | MODE_REVERSE = 128, |
113 | MODE_KBDLOCK = 256, | 112 | MODE_KBDLOCK = 256, |
114 | MODE_HIDE = 512, | 113 | MODE_HIDE = 512, |
@@ -119,6 +118,10 @@ enum term_mode { | |||
119 | MODE_BLINK = 16384, | 118 | MODE_BLINK = 16384, |
120 | MODE_FBLINK = 32768, | 119 | MODE_FBLINK = 32768, |
121 | MODE_FOCUS = 65536, | 120 | MODE_FOCUS = 65536, |
121 | MODE_MOUSEX10 = 131072, | ||
122 | MODE_MOUSEMANY = 262144, | ||
123 | MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\ | ||
124 | |MODE_MOUSEMANY, | ||
122 | }; | 125 | }; |
123 | 126 | ||
124 | enum escape_state { | 127 | enum escape_state { |
@@ -219,6 +222,7 @@ typedef struct { | |||
219 | XIC xic; | 222 | XIC xic; |
220 | Draw draw; | 223 | Draw draw; |
221 | Visual *vis; | 224 | Visual *vis; |
225 | XSetWindowAttributes attrs; | ||
222 | int scr; | 226 | int scr; |
223 | bool isfixed; /* is fixed geometry? */ | 227 | bool isfixed; /* is fixed geometry? */ |
224 | int fx, fy, fw, fh; /* fixed geometry */ | 228 | int fx, fy, fw, fh; /* fixed geometry */ |
@@ -245,7 +249,6 @@ typedef struct { | |||
245 | signed char crlf; /* crlf mode */ | 249 | signed char crlf; /* crlf mode */ |
246 | } Key; | 250 | } Key; |
247 | 251 | ||
248 | /* TODO: use better name for vars... */ | ||
249 | typedef struct { | 252 | typedef struct { |
250 | int mode; | 253 | int mode; |
251 | int type; | 254 | int type; |
@@ -373,6 +376,7 @@ static void xloadfonts(char *, int); | |||
373 | static int xloadfontset(Font *); | 376 | static int xloadfontset(Font *); |
374 | static void xsettitle(char *); | 377 | static void xsettitle(char *); |
375 | static void xresettitle(void); | 378 | static void xresettitle(void); |
379 | static void xsetpointermotion(int); | ||
376 | static void xseturgency(int); | 380 | static void xseturgency(int); |
377 | static void xsetsel(char*); | 381 | static void xsetsel(char*); |
378 | static void xtermclear(int, int, int, int); | 382 | static void xtermclear(int, int, int, int); |
@@ -446,6 +450,7 @@ static char *opt_title = NULL; | |||
446 | static char *opt_embed = NULL; | 450 | static char *opt_embed = NULL; |
447 | static char *opt_class = NULL; | 451 | static char *opt_class = NULL; |
448 | static char *opt_font = NULL; | 452 | static char *opt_font = NULL; |
453 | static int oldbutton = 3; /* button event on startup: 3 = release */ | ||
449 | 454 | ||
450 | static char *usedfont = NULL; | 455 | static char *usedfont = NULL; |
451 | static int usedfontsize = 0; | 456 | static int usedfontsize = 0; |
@@ -806,13 +811,19 @@ mousereport(XEvent *e) { | |||
806 | button = e->xbutton.button, state = e->xbutton.state, | 811 | button = e->xbutton.button, state = e->xbutton.state, |
807 | len; | 812 | len; |
808 | char buf[40]; | 813 | char buf[40]; |
809 | static int ob, ox, oy; | 814 | static int ox, oy; |
810 | 815 | ||
811 | /* from urxvt */ | 816 | /* from urxvt */ |
812 | if(e->xbutton.type == MotionNotify) { | 817 | if(e->xbutton.type == MotionNotify) { |
813 | if(!IS_SET(MODE_MOUSEMOTION) || (x == ox && y == oy)) | 818 | if(x == ox && y == oy) |
819 | return; | ||
820 | if(!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY)) | ||
821 | return; | ||
822 | /* MOUSE_MOTION: no reporting if no button is pressed */ | ||
823 | if(IS_SET(MODE_MOUSEMOTION) && oldbutton == 3) | ||
814 | return; | 824 | return; |
815 | button = ob + 32; | 825 | |
826 | button = oldbutton + 32; | ||
816 | ox = x; | 827 | ox = x; |
817 | oy = y; | 828 | oy = y; |
818 | } else if(!IS_SET(MODE_MOUSESGR) | 829 | } else if(!IS_SET(MODE_MOUSESGR) |
@@ -824,15 +835,17 @@ mousereport(XEvent *e) { | |||
824 | if(button >= 3) | 835 | if(button >= 3) |
825 | button += 64 - 3; | 836 | button += 64 - 3; |
826 | if(e->xbutton.type == ButtonPress) { | 837 | if(e->xbutton.type == ButtonPress) { |
827 | ob = button; | 838 | oldbutton = button; |
828 | ox = x; | 839 | ox = x; |
829 | oy = y; | 840 | oy = y; |
830 | } | 841 | } |
831 | } | 842 | } |
832 | 843 | ||
833 | button += (state & ShiftMask ? 4 : 0) | 844 | if(!IS_SET(MODE_MOUSEX10)) { |
834 | + (state & Mod4Mask ? 8 : 0) | 845 | button += (state & ShiftMask ? 4 : 0) |
835 | + (state & ControlMask ? 16 : 0); | 846 | + (state & Mod4Mask ? 8 : 0) |
847 | + (state & ControlMask ? 16 : 0); | ||
848 | } | ||
836 | 849 | ||
837 | len = 0; | 850 | len = 0; |
838 | if(IS_SET(MODE_MOUSESGR)) { | 851 | if(IS_SET(MODE_MOUSESGR)) { |
@@ -841,7 +854,8 @@ mousereport(XEvent *e) { | |||
841 | e->xbutton.type == ButtonRelease ? 'm' : 'M'); | 854 | e->xbutton.type == ButtonRelease ? 'm' : 'M'); |
842 | } else if(x < 223 && y < 223) { | 855 | } else if(x < 223 && y < 223) { |
843 | len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", | 856 | len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", |
844 | 32+button, 32+x+1, 32+y+1); | 857 | IS_SET(MODE_MOUSEX10)? button-1 : 32+button, |
858 | 32+x+1, 32+y+1); | ||
845 | } else { | 859 | } else { |
846 | return; | 860 | return; |
847 | } | 861 | } |
@@ -1775,21 +1789,30 @@ tsetmode(bool priv, bool set, int *args, int narg) { | |||
1775 | case 25: /* DECTCEM -- Text Cursor Enable Mode */ | 1789 | case 25: /* DECTCEM -- Text Cursor Enable Mode */ |
1776 | MODBIT(term.mode, !set, MODE_HIDE); | 1790 | MODBIT(term.mode, !set, MODE_HIDE); |
1777 | break; | 1791 | break; |
1778 | case 1000: /* 1000,1002: enable xterm mouse report */ | 1792 | case 9: /* X10 mouse compatibility mode */ |
1793 | xsetpointermotion(0); | ||
1794 | MODBIT(term.mode, 0, MODE_MOUSE); | ||
1795 | MODBIT(term.mode, set, MODE_MOUSEX10); | ||
1796 | break; | ||
1797 | case 1000: /* 1000: report button press */ | ||
1798 | xsetpointermotion(0); | ||
1799 | MODBIT(term.mode, 0, MODE_MOUSE); | ||
1779 | MODBIT(term.mode, set, MODE_MOUSEBTN); | 1800 | MODBIT(term.mode, set, MODE_MOUSEBTN); |
1780 | MODBIT(term.mode, 0, MODE_MOUSEMOTION); | ||
1781 | break; | 1801 | break; |
1782 | case 1002: | 1802 | case 1002: /* 1002: report motion on button press */ |
1803 | xsetpointermotion(0); | ||
1804 | MODBIT(term.mode, 0, MODE_MOUSE); | ||
1783 | MODBIT(term.mode, set, MODE_MOUSEMOTION); | 1805 | MODBIT(term.mode, set, MODE_MOUSEMOTION); |
1784 | MODBIT(term.mode, 0, MODE_MOUSEBTN); | ||
1785 | break; | 1806 | break; |
1786 | case 1003: /* 1003: enable all mouse reports */ | 1807 | case 1003: /* 1003: enable all mouse motions */ |
1787 | MODBIT(term.mode, set, MODE_MOUSE); | 1808 | xsetpointermotion(set); |
1809 | MODBIT(term.mode, 0, MODE_MOUSE); | ||
1810 | MODBIT(term.mode, set, MODE_MOUSEMANY); | ||
1788 | break; | 1811 | break; |
1789 | case 1004: | 1812 | case 1004: /* 1004: send focus events to tty */ |
1790 | MODBIT(term.mode, set, MODE_FOCUS); | 1813 | MODBIT(term.mode, set, MODE_FOCUS); |
1791 | break; | 1814 | break; |
1792 | case 1006: | 1815 | case 1006: /* 1006: extended reporting mode */ |
1793 | MODBIT(term.mode, set, MODE_MOUSESGR); | 1816 | MODBIT(term.mode, set, MODE_MOUSESGR); |
1794 | break; | 1817 | break; |
1795 | case 1034: | 1818 | case 1034: |
@@ -1815,7 +1838,6 @@ tsetmode(bool priv, bool set, int *args, int narg) { | |||
1815 | tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); | 1838 | tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); |
1816 | break; | 1839 | break; |
1817 | /* Not implemented mouse modes. See comments there. */ | 1840 | /* Not implemented mouse modes. See comments there. */ |
1818 | case 9: /* X10 compatibility mode */ | ||
1819 | case 1001: /* mouse highlight mode; can hang the | 1841 | case 1001: /* mouse highlight mode; can hang the |
1820 | terminal by design when implemented. */ | 1842 | terminal by design when implemented. */ |
1821 | case 1005: /* UTF-8 mouse mode; will confuse | 1843 | case 1005: /* UTF-8 mouse mode; will confuse |
@@ -1855,8 +1877,6 @@ tsetmode(bool priv, bool set, int *args, int narg) { | |||
1855 | } | 1877 | } |
1856 | } | 1878 | } |
1857 | } | 1879 | } |
1858 | #undef MODBIT | ||
1859 | |||
1860 | 1880 | ||
1861 | void | 1881 | void |
1862 | csihandle(void) { | 1882 | csihandle(void) { |
@@ -2799,7 +2819,6 @@ xzoom(const Arg *arg) { | |||
2799 | 2819 | ||
2800 | void | 2820 | void |
2801 | xinit(void) { | 2821 | xinit(void) { |
2802 | XSetWindowAttributes attrs; | ||
2803 | XGCValues gcvalues; | 2822 | XGCValues gcvalues; |
2804 | Cursor cursor; | 2823 | Cursor cursor; |
2805 | Window parent; | 2824 | Window parent; |
@@ -2841,22 +2860,20 @@ xinit(void) { | |||
2841 | } | 2860 | } |
2842 | 2861 | ||
2843 | /* Events */ | 2862 | /* Events */ |
2844 | attrs.background_pixel = dc.col[defaultbg].pixel; | 2863 | xw.attrs.background_pixel = dc.col[defaultbg].pixel; |
2845 | attrs.border_pixel = dc.col[defaultbg].pixel; | 2864 | xw.attrs.border_pixel = dc.col[defaultbg].pixel; |
2846 | attrs.bit_gravity = NorthWestGravity; | 2865 | xw.attrs.bit_gravity = NorthWestGravity; |
2847 | attrs.event_mask = FocusChangeMask | KeyPressMask | 2866 | xw.attrs.event_mask = FocusChangeMask | KeyPressMask |
2848 | | ExposureMask | VisibilityChangeMask | StructureNotifyMask | 2867 | | ExposureMask | VisibilityChangeMask | StructureNotifyMask |
2849 | | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; | 2868 | | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; |
2850 | attrs.colormap = xw.cmap; | 2869 | xw.attrs.colormap = xw.cmap; |
2851 | 2870 | ||
2852 | parent = opt_embed ? strtol(opt_embed, NULL, 0) : \ | 2871 | parent = opt_embed ? strtol(opt_embed, NULL, 0) : \ |
2853 | XRootWindow(xw.dpy, xw.scr); | 2872 | XRootWindow(xw.dpy, xw.scr); |
2854 | xw.win = XCreateWindow(xw.dpy, parent, xw.fx, xw.fy, | 2873 | xw.win = XCreateWindow(xw.dpy, parent, xw.fx, xw.fy, |
2855 | xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, | 2874 | xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, |
2856 | xw.vis, | 2875 | xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity |
2857 | CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask | 2876 | | CWEventMask | CWColormap, &xw.attrs); |
2858 | | CWColormap, | ||
2859 | &attrs); | ||
2860 | 2877 | ||
2861 | memset(&gcvalues, 0, sizeof(gcvalues)); | 2878 | memset(&gcvalues, 0, sizeof(gcvalues)); |
2862 | gcvalues.graphics_exposures = False; | 2879 | gcvalues.graphics_exposures = False; |
@@ -2871,7 +2888,7 @@ xinit(void) { | |||
2871 | xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); | 2888 | xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); |
2872 | 2889 | ||
2873 | /* input methods */ | 2890 | /* input methods */ |
2874 | if((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { | 2891 | if((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { |
2875 | XSetLocaleModifiers("@im=local"); | 2892 | XSetLocaleModifiers("@im=local"); |
2876 | if((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { | 2893 | if((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { |
2877 | XSetLocaleModifiers("@im="); | 2894 | XSetLocaleModifiers("@im="); |
@@ -3307,6 +3324,12 @@ unmap(XEvent *ev) { | |||
3307 | } | 3324 | } |
3308 | 3325 | ||
3309 | void | 3326 | void |
3327 | xsetpointermotion(int set) { | ||
3328 | MODBIT(xw.attrs.event_mask, set, PointerMotionMask); | ||
3329 | XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); | ||
3330 | } | ||
3331 | |||
3332 | void | ||
3310 | xseturgency(int add) { | 3333 | xseturgency(int add) { |
3311 | XWMHints *h = XGetWMHints(xw.dpy, xw.win); | 3334 | XWMHints *h = XGetWMHints(xw.dpy, xw.win); |
3312 | 3335 | ||