diff options
| author | Po Lu | 2021-12-17 14:23:07 +0800 |
|---|---|---|
| committer | Po Lu | 2021-12-17 14:23:07 +0800 |
| commit | 5e5cde55e5be6e2d388252c3ccb0d019aee6b89e (patch) | |
| tree | 339463076073de968bfe854c4813f0d47b6e34d5 /src | |
| parent | 32b9b22f66b1afcc614d5f76860d56d5630c5bc4 (diff) | |
| parent | f6339412eebdc027b00263ae2b5c38a029e2f7b4 (diff) | |
| download | emacs-5e5cde55e5be6e2d388252c3ccb0d019aee6b89e.tar.gz emacs-5e5cde55e5be6e2d388252c3ccb0d019aee6b89e.zip | |
Merge remote-tracking branch 'origin/master' into feature/pgtk
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyboard.c | 43 | ||||
| -rw-r--r-- | src/systime.h | 3 | ||||
| -rw-r--r-- | src/termhooks.h | 13 | ||||
| -rw-r--r-- | src/timefns.c | 73 | ||||
| -rw-r--r-- | src/xfns.c | 21 | ||||
| -rw-r--r-- | src/xterm.c | 604 | ||||
| -rw-r--r-- | src/xterm.h | 11 |
7 files changed, 507 insertions, 261 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index df07cf290b8..821a1b576be 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -6013,6 +6013,46 @@ make_lispy_event (struct input_event *event) | |||
| 6013 | return list2 (Qtouch_end, position); | 6013 | return list2 (Qtouch_end, position); |
| 6014 | } | 6014 | } |
| 6015 | 6015 | ||
| 6016 | case TOUCHSCREEN_BEGIN_EVENT: | ||
| 6017 | case TOUCHSCREEN_END_EVENT: | ||
| 6018 | { | ||
| 6019 | Lisp_Object x, y, id, position; | ||
| 6020 | struct frame *f = XFRAME (event->frame_or_window); | ||
| 6021 | |||
| 6022 | id = event->arg; | ||
| 6023 | x = event->x; | ||
| 6024 | y = event->y; | ||
| 6025 | |||
| 6026 | position = make_lispy_position (f, x, y, event->timestamp); | ||
| 6027 | |||
| 6028 | return list2 (((event->kind | ||
| 6029 | == TOUCHSCREEN_BEGIN_EVENT) | ||
| 6030 | ? Qtouchscreen_begin | ||
| 6031 | : Qtouchscreen_end), | ||
| 6032 | Fcons (id, position)); | ||
| 6033 | } | ||
| 6034 | |||
| 6035 | case TOUCHSCREEN_UPDATE_EVENT: | ||
| 6036 | { | ||
| 6037 | Lisp_Object x, y, id, position, tem, it, evt; | ||
| 6038 | struct frame *f = XFRAME (event->frame_or_window); | ||
| 6039 | evt = Qnil; | ||
| 6040 | |||
| 6041 | for (tem = event->arg; CONSP (tem); tem = XCDR (tem)) | ||
| 6042 | { | ||
| 6043 | it = XCAR (tem); | ||
| 6044 | |||
| 6045 | x = XCAR (it); | ||
| 6046 | y = XCAR (XCDR (it)); | ||
| 6047 | id = XCAR (XCDR (XCDR (it))); | ||
| 6048 | |||
| 6049 | position = make_lispy_position (f, x, y, event->timestamp); | ||
| 6050 | evt = Fcons (Fcons (id, position), evt); | ||
| 6051 | } | ||
| 6052 | |||
| 6053 | return list2 (Qtouchscreen_update, evt); | ||
| 6054 | } | ||
| 6055 | |||
| 6016 | #ifdef USE_TOOLKIT_SCROLL_BARS | 6056 | #ifdef USE_TOOLKIT_SCROLL_BARS |
| 6017 | 6057 | ||
| 6018 | /* We don't have down and up events if using toolkit scroll bars, | 6058 | /* We don't have down and up events if using toolkit scroll bars, |
| @@ -12266,6 +12306,9 @@ See also `pre-command-hook'. */); | |||
| 12266 | doc: /* Normal hook run when clearing the echo area. */); | 12306 | doc: /* Normal hook run when clearing the echo area. */); |
| 12267 | #endif | 12307 | #endif |
| 12268 | DEFSYM (Qecho_area_clear_hook, "echo-area-clear-hook"); | 12308 | DEFSYM (Qecho_area_clear_hook, "echo-area-clear-hook"); |
| 12309 | DEFSYM (Qtouchscreen_begin, "touchscreen-begin"); | ||
| 12310 | DEFSYM (Qtouchscreen_end, "touchscreen-end"); | ||
| 12311 | DEFSYM (Qtouchscreen_update, "touchscreen-update"); | ||
| 12269 | Fset (Qecho_area_clear_hook, Qnil); | 12312 | Fset (Qecho_area_clear_hook, Qnil); |
| 12270 | 12313 | ||
| 12271 | DEFVAR_LISP ("lucid-menu-bar-dirty-flag", Vlucid_menu_bar_dirty_flag, | 12314 | DEFVAR_LISP ("lucid-menu-bar-dirty-flag", Vlucid_menu_bar_dirty_flag, |
diff --git a/src/systime.h b/src/systime.h index 08ab5bdde33..ce9403c931d 100644 --- a/src/systime.h +++ b/src/systime.h | |||
| @@ -80,8 +80,7 @@ struct lisp_time | |||
| 80 | /* Clock count as a Lisp integer. */ | 80 | /* Clock count as a Lisp integer. */ |
| 81 | Lisp_Object ticks; | 81 | Lisp_Object ticks; |
| 82 | 82 | ||
| 83 | /* Clock frequency (ticks per second) as a positive Lisp integer. | 83 | /* Clock frequency (ticks per second) as a positive Lisp integer. */ |
| 84 | (TICKS . HZ) is a valid Lisp timestamp unless HZ < 65536. */ | ||
| 85 | Lisp_Object hz; | 84 | Lisp_Object hz; |
| 86 | }; | 85 | }; |
| 87 | 86 | ||
diff --git a/src/termhooks.h b/src/termhooks.h index b124e995292..9f22187b841 100644 --- a/src/termhooks.h +++ b/src/termhooks.h | |||
| @@ -280,6 +280,19 @@ enum event_kind | |||
| 280 | In the future, this may take into account other multi-touch | 280 | In the future, this may take into account other multi-touch |
| 281 | events generated from touchscreens and such. */ | 281 | events generated from touchscreens and such. */ |
| 282 | , TOUCH_END_EVENT | 282 | , TOUCH_END_EVENT |
| 283 | |||
| 284 | /* In a TOUCHSCREEN_UPDATE_EVENT, ARG is a list of elements of the | ||
| 285 | form (X Y ID), where X and Y are the coordinates of the | ||
| 286 | touchpoint relative to the top-left corner of the frame, and ID | ||
| 287 | is a unique number identifying the touchpoint. | ||
| 288 | |||
| 289 | In TOUCHSCREEN_BEGIN_EVENT and TOUCHSCREEN_END_EVENT, ARG is the | ||
| 290 | unique ID of the touchpoint, and X and Y are the frame-relative | ||
| 291 | positions of the touchpoint. */ | ||
| 292 | |||
| 293 | , TOUCHSCREEN_UPDATE_EVENT | ||
| 294 | , TOUCHSCREEN_BEGIN_EVENT | ||
| 295 | , TOUCHSCREEN_END_EVENT | ||
| 283 | }; | 296 | }; |
| 284 | 297 | ||
| 285 | /* Bit width of an enum event_kind tag at the start of structs and unions. */ | 298 | /* Bit width of an enum event_kind tag at the start of structs and unions. */ |
diff --git a/src/timefns.c b/src/timefns.c index a9921cdc108..74b5ca8d515 100644 --- a/src/timefns.c +++ b/src/timefns.c | |||
| @@ -69,16 +69,6 @@ enum { TM_YEAR_BASE = 1900 }; | |||
| 69 | # define FASTER_TIMEFNS 1 | 69 | # define FASTER_TIMEFNS 1 |
| 70 | #endif | 70 | #endif |
| 71 | 71 | ||
| 72 | /* Whether to warn about Lisp timestamps (TICKS . HZ) that may be | ||
| 73 | instances of obsolete-format timestamps (HI . LO) where HI is | ||
| 74 | the high-order bits and LO the low-order 16 bits. Currently this | ||
| 75 | is true, but it should change to false in a future version of | ||
| 76 | Emacs. Compile with -DWARN_OBSOLETE_TIMESTAMPS=0 to see what the | ||
| 77 | future will be like. */ | ||
| 78 | #ifndef WARN_OBSOLETE_TIMESTAMPS | ||
| 79 | enum { WARN_OBSOLETE_TIMESTAMPS = true }; | ||
| 80 | #endif | ||
| 81 | |||
| 82 | /* Although current-time etc. generate list-format timestamps | 72 | /* Although current-time etc. generate list-format timestamps |
| 83 | (HI LO US PS), the plan is to change these functions to generate | 73 | (HI LO US PS), the plan is to change these functions to generate |
| 84 | frequency-based timestamps (TICKS . HZ) in a future release. | 74 | frequency-based timestamps (TICKS . HZ) in a future release. |
| @@ -817,14 +807,10 @@ decode_time_components (enum timeform form, | |||
| 817 | return decode_ticks_hz (make_integer_mpz (), hz, result, dresult); | 807 | return decode_ticks_hz (make_integer_mpz (), hz, result, dresult); |
| 818 | } | 808 | } |
| 819 | 809 | ||
| 820 | enum { DECODE_SECS_ONLY = WARN_OBSOLETE_TIMESTAMPS + 1 }; | ||
| 821 | |||
| 822 | /* Decode a Lisp timestamp SPECIFIED_TIME that represents a time. | 810 | /* Decode a Lisp timestamp SPECIFIED_TIME that represents a time. |
| 823 | 811 | ||
| 824 | FLAGS specifies conversion flags. If FLAGS & DECODE_SECS_ONLY, | 812 | If DECODE_SECS_ONLY, ignore and do not validate any sub-second |
| 825 | ignore and do not validate any sub-second components of an | 813 | components of an old-format SPECIFIED_TIME. |
| 826 | old-format SPECIFIED_TIME. If FLAGS & WARN_OBSOLETE_TIMESTAMPS, | ||
| 827 | diagnose what could be obsolete (HIGH . LOW) timestamps. | ||
| 828 | 814 | ||
| 829 | If RESULT is not null, store into *RESULT the converted time; | 815 | If RESULT is not null, store into *RESULT the converted time; |
| 830 | otherwise, store into *DRESULT the number of seconds since the | 816 | otherwise, store into *DRESULT the number of seconds since the |
| @@ -833,7 +819,7 @@ enum { DECODE_SECS_ONLY = WARN_OBSOLETE_TIMESTAMPS + 1 }; | |||
| 833 | 819 | ||
| 834 | Return the form of SPECIFIED-TIME. Signal an error if unsuccessful. */ | 820 | Return the form of SPECIFIED-TIME. Signal an error if unsuccessful. */ |
| 835 | static enum timeform | 821 | static enum timeform |
| 836 | decode_lisp_time (Lisp_Object specified_time, int flags, | 822 | decode_lisp_time (Lisp_Object specified_time, bool decode_secs_only, |
| 837 | struct lisp_time *result, double *dresult) | 823 | struct lisp_time *result, double *dresult) |
| 838 | { | 824 | { |
| 839 | Lisp_Object high = make_fixnum (0); | 825 | Lisp_Object high = make_fixnum (0); |
| @@ -854,7 +840,7 @@ decode_lisp_time (Lisp_Object specified_time, int flags, | |||
| 854 | { | 840 | { |
| 855 | Lisp_Object low_tail = XCDR (low); | 841 | Lisp_Object low_tail = XCDR (low); |
| 856 | low = XCAR (low); | 842 | low = XCAR (low); |
| 857 | if (! (flags & DECODE_SECS_ONLY)) | 843 | if (! decode_secs_only) |
| 858 | { | 844 | { |
| 859 | if (CONSP (low_tail)) | 845 | if (CONSP (low_tail)) |
| 860 | { | 846 | { |
| @@ -877,9 +863,6 @@ decode_lisp_time (Lisp_Object specified_time, int flags, | |||
| 877 | } | 863 | } |
| 878 | else | 864 | else |
| 879 | { | 865 | { |
| 880 | if (flags & WARN_OBSOLETE_TIMESTAMPS | ||
| 881 | && RANGED_FIXNUMP (0, low, (1 << LO_TIME_BITS) - 1)) | ||
| 882 | message ("obsolete timestamp with cdr %"pI"d", XFIXNUM (low)); | ||
| 883 | form = TIMEFORM_TICKS_HZ; | 866 | form = TIMEFORM_TICKS_HZ; |
| 884 | } | 867 | } |
| 885 | 868 | ||
| @@ -1008,8 +991,7 @@ static struct lisp_time | |||
| 1008 | lisp_time_struct (Lisp_Object specified_time, enum timeform *pform) | 991 | lisp_time_struct (Lisp_Object specified_time, enum timeform *pform) |
| 1009 | { | 992 | { |
| 1010 | struct lisp_time t; | 993 | struct lisp_time t; |
| 1011 | enum timeform form | 994 | enum timeform form = decode_lisp_time (specified_time, false, &t, 0); |
| 1012 | = decode_lisp_time (specified_time, WARN_OBSOLETE_TIMESTAMPS, &t, 0); | ||
| 1013 | if (pform) | 995 | if (pform) |
| 1014 | *pform = form; | 996 | *pform = form; |
| 1015 | return t; | 997 | return t; |
| @@ -1034,9 +1016,8 @@ lisp_time_argument (Lisp_Object specified_time) | |||
| 1034 | static time_t | 1016 | static time_t |
| 1035 | lisp_seconds_argument (Lisp_Object specified_time) | 1017 | lisp_seconds_argument (Lisp_Object specified_time) |
| 1036 | { | 1018 | { |
| 1037 | int flags = WARN_OBSOLETE_TIMESTAMPS | DECODE_SECS_ONLY; | ||
| 1038 | struct lisp_time lt; | 1019 | struct lisp_time lt; |
| 1039 | decode_lisp_time (specified_time, flags, <, 0); | 1020 | decode_lisp_time (specified_time, true, <, 0); |
| 1040 | struct timespec t = lisp_to_timespec (lt); | 1021 | struct timespec t = lisp_to_timespec (lt); |
| 1041 | if (! timespec_valid_p (t)) | 1022 | if (! timespec_valid_p (t)) |
| 1042 | time_overflow (); | 1023 | time_overflow (); |
| @@ -1138,24 +1119,6 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract) | |||
| 1138 | mpz_t *ihz = &mpz[0]; | 1119 | mpz_t *ihz = &mpz[0]; |
| 1139 | mpz_mul (*ihz, *fa, *db); | 1120 | mpz_mul (*ihz, *fa, *db); |
| 1140 | 1121 | ||
| 1141 | /* When warning about obsolete timestamps, if the smaller | ||
| 1142 | denominator comes from a non-(TICKS . HZ) timestamp and could | ||
| 1143 | generate a (TICKS . HZ) timestamp that would look obsolete, | ||
| 1144 | arrange for the result to have a higher HZ to avoid a | ||
| 1145 | spurious warning by a later consumer of this function's | ||
| 1146 | returned value. */ | ||
| 1147 | verify (1 << LO_TIME_BITS <= ULONG_MAX); | ||
| 1148 | if (WARN_OBSOLETE_TIMESTAMPS | ||
| 1149 | && (da_lt_db ? aform : bform) == TIMEFORM_FLOAT | ||
| 1150 | && (da_lt_db ? bform : aform) != TIMEFORM_TICKS_HZ | ||
| 1151 | && mpz_cmp_ui (*hzmin, 1) > 0 | ||
| 1152 | && mpz_cmp_ui (*hzmin, 1 << LO_TIME_BITS) < 0) | ||
| 1153 | { | ||
| 1154 | mpz_t *hzmin1 = &mpz[2 - da_lt_db]; | ||
| 1155 | mpz_set_ui (*hzmin1, 1 << LO_TIME_BITS); | ||
| 1156 | hzmin = hzmin1; | ||
| 1157 | } | ||
| 1158 | |||
| 1159 | /* iticks = (fb * na) OP (fa * nb), where OP is + or -. */ | 1122 | /* iticks = (fb * na) OP (fa * nb), where OP is + or -. */ |
| 1160 | mpz_t const *na = bignum_integer (iticks, ta.ticks); | 1123 | mpz_t const *na = bignum_integer (iticks, ta.ticks); |
| 1161 | mpz_mul (*iticks, *fb, *na); | 1124 | mpz_mul (*iticks, *fb, *na); |
| @@ -1177,8 +1140,7 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract) | |||
| 1177 | upwards by multiplying the normalized numerator and denominator | 1140 | upwards by multiplying the normalized numerator and denominator |
| 1178 | so that the resulting denominator becomes at least hzmin. | 1141 | so that the resulting denominator becomes at least hzmin. |
| 1179 | This rescaling avoids returning a timestamp that is less precise | 1142 | This rescaling avoids returning a timestamp that is less precise |
| 1180 | than both a and b, or a timestamp that looks obsolete when that | 1143 | than both a and b. */ |
| 1181 | might be a problem. */ | ||
| 1182 | if (!FASTER_TIMEFNS || mpz_cmp (*ihz, *hzmin) < 0) | 1144 | if (!FASTER_TIMEFNS || mpz_cmp (*ihz, *hzmin) < 0) |
| 1183 | { | 1145 | { |
| 1184 | /* Rescale straightforwardly. Although this might not | 1146 | /* Rescale straightforwardly. Although this might not |
| @@ -1303,7 +1265,7 @@ or (if you need time as a string) `format-time-string'. */) | |||
| 1303 | (Lisp_Object specified_time) | 1265 | (Lisp_Object specified_time) |
| 1304 | { | 1266 | { |
| 1305 | double t; | 1267 | double t; |
| 1306 | decode_lisp_time (specified_time, 0, 0, &t); | 1268 | decode_lisp_time (specified_time, false, 0, &t); |
| 1307 | return make_float (t); | 1269 | return make_float (t); |
| 1308 | } | 1270 | } |
| 1309 | 1271 | ||
| @@ -1651,12 +1613,11 @@ saving flag to be guessed. | |||
| 1651 | 1613 | ||
| 1652 | As an obsolescent calling convention, if this function is called with | 1614 | As an obsolescent calling convention, if this function is called with |
| 1653 | 6 or more arguments, the first 6 arguments are SECOND, MINUTE, HOUR, | 1615 | 6 or more arguments, the first 6 arguments are SECOND, MINUTE, HOUR, |
| 1654 | DAY, MONTH, and YEAR, and specify the components of a decoded time, | 1616 | DAY, MONTH, and YEAR, and specify the components of a decoded time. |
| 1655 | where DST assumed to be -1 and FORM is omitted. If there are more | 1617 | If there are more than 6 arguments the *last* argument is used as ZONE |
| 1656 | than 6 arguments the *last* argument is used as ZONE and any other | 1618 | and any other extra arguments are ignored, so that (apply |
| 1657 | extra arguments are ignored, so that (apply #\\='encode-time | 1619 | #\\='encode-time (decode-time ...)) works. In this obsolescent |
| 1658 | (decode-time ...)) works. In this obsolescent convention, DST and | 1620 | convention, DST and ZONE default to -1 and nil respectively. |
| 1659 | ZONE default to -1 and nil respectively. | ||
| 1660 | 1621 | ||
| 1661 | Years before 1970 are not guaranteed to work. On some systems, | 1622 | Years before 1970 are not guaranteed to work. On some systems, |
| 1662 | year values as low as 1901 do work. | 1623 | year values as low as 1901 do work. |
| @@ -1703,7 +1664,7 @@ usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS) */) | |||
| 1703 | 1664 | ||
| 1704 | /* Let SEC = floor (LT.ticks / HZ), with SUBSECTICKS the remainder. */ | 1665 | /* Let SEC = floor (LT.ticks / HZ), with SUBSECTICKS the remainder. */ |
| 1705 | struct lisp_time lt; | 1666 | struct lisp_time lt; |
| 1706 | decode_lisp_time (secarg, 0, <, 0); | 1667 | decode_lisp_time (secarg, false, <, 0); |
| 1707 | Lisp_Object hz = lt.hz, sec, subsecticks; | 1668 | Lisp_Object hz = lt.hz, sec, subsecticks; |
| 1708 | if (FASTER_TIMEFNS && EQ (hz, make_fixnum (1))) | 1669 | if (FASTER_TIMEFNS && EQ (hz, make_fixnum (1))) |
| 1709 | { | 1670 | { |
| @@ -1756,9 +1717,7 @@ Truncate the returned value toward minus infinity. | |||
| 1756 | If FORM is nil (the default), return the same form as `current-time'. | 1717 | If FORM is nil (the default), return the same form as `current-time'. |
| 1757 | If FORM is a positive integer, return a pair of integers (TICKS . FORM), | 1718 | If FORM is a positive integer, return a pair of integers (TICKS . FORM), |
| 1758 | where TICKS is the number of clock ticks and FORM is the clock frequency | 1719 | where TICKS is the number of clock ticks and FORM is the clock frequency |
| 1759 | in ticks per second. (Currently the positive integer should be at least | 1720 | in ticks per second. If FORM is t, return (TICKS . PHZ), where |
| 1760 | 65536 if the returned value is expected to be given to standard functions | ||
| 1761 | expecting Lisp timestamps.) If FORM is t, return (TICKS . PHZ), where | ||
| 1762 | PHZ is a suitable clock frequency in ticks per second. If FORM is | 1721 | PHZ is a suitable clock frequency in ticks per second. If FORM is |
| 1763 | `integer', return an integer count of seconds. If FORM is `list', | 1722 | `integer', return an integer count of seconds. If FORM is `list', |
| 1764 | return an integer list (HIGH LOW USEC PSEC), where HIGH has the most | 1723 | return an integer list (HIGH LOW USEC PSEC), where HIGH has the most |
| @@ -1767,7 +1726,7 @@ bits, and USEC and PSEC are the microsecond and picosecond counts. */) | |||
| 1767 | (Lisp_Object time, Lisp_Object form) | 1726 | (Lisp_Object time, Lisp_Object form) |
| 1768 | { | 1727 | { |
| 1769 | struct lisp_time t; | 1728 | struct lisp_time t; |
| 1770 | enum timeform input_form = decode_lisp_time (time, 0, &t, 0); | 1729 | enum timeform input_form = decode_lisp_time (time, false, &t, 0); |
| 1771 | if (NILP (form)) | 1730 | if (NILP (form)) |
| 1772 | form = CURRENT_TIME_LIST ? Qlist : Qt; | 1731 | form = CURRENT_TIME_LIST ? Qlist : Qt; |
| 1773 | if (EQ (form, Qlist)) | 1732 | if (EQ (form, Qlist)) |
diff --git a/src/xfns.c b/src/xfns.c index b5694829aef..dc25d7bfca2 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -2916,7 +2916,7 @@ initial_set_up_x_back_buffer (struct frame *f) | |||
| 2916 | unblock_input (); | 2916 | unblock_input (); |
| 2917 | } | 2917 | } |
| 2918 | 2918 | ||
| 2919 | #if defined HAVE_XINPUT2 && !defined USE_GTK | 2919 | #if defined HAVE_XINPUT2 |
| 2920 | static void | 2920 | static void |
| 2921 | setup_xi_event_mask (struct frame *f) | 2921 | setup_xi_event_mask (struct frame *f) |
| 2922 | { | 2922 | { |
| @@ -2927,6 +2927,9 @@ setup_xi_event_mask (struct frame *f) | |||
| 2927 | mask.mask = m = alloca (l); | 2927 | mask.mask = m = alloca (l); |
| 2928 | memset (m, 0, l); | 2928 | memset (m, 0, l); |
| 2929 | mask.mask_len = l; | 2929 | mask.mask_len = l; |
| 2930 | |||
| 2931 | block_input (); | ||
| 2932 | #ifndef USE_GTK | ||
| 2930 | mask.deviceid = XIAllMasterDevices; | 2933 | mask.deviceid = XIAllMasterDevices; |
| 2931 | 2934 | ||
| 2932 | XISetMask (m, XI_ButtonPress); | 2935 | XISetMask (m, XI_ButtonPress); |
| @@ -2945,14 +2948,25 @@ setup_xi_event_mask (struct frame *f) | |||
| 2945 | &mask, 1); | 2948 | &mask, 1); |
| 2946 | 2949 | ||
| 2947 | memset (m, 0, l); | 2950 | memset (m, 0, l); |
| 2951 | #endif /* !USE_GTK */ | ||
| 2952 | |||
| 2948 | mask.deviceid = XIAllDevices; | 2953 | mask.deviceid = XIAllDevices; |
| 2949 | 2954 | ||
| 2950 | XISetMask (m, XI_PropertyEvent); | 2955 | XISetMask (m, XI_PropertyEvent); |
| 2951 | XISetMask (m, XI_HierarchyChanged); | 2956 | XISetMask (m, XI_HierarchyChanged); |
| 2952 | XISetMask (m, XI_DeviceChanged); | 2957 | XISetMask (m, XI_DeviceChanged); |
| 2958 | #ifdef XI_TouchBegin | ||
| 2959 | if (FRAME_DISPLAY_INFO (f)->xi2_version >= 2) | ||
| 2960 | { | ||
| 2961 | XISetMask (m, XI_TouchBegin); | ||
| 2962 | XISetMask (m, XI_TouchUpdate); | ||
| 2963 | XISetMask (m, XI_TouchEnd); | ||
| 2964 | } | ||
| 2965 | #endif | ||
| 2953 | XISelectEvents (FRAME_X_DISPLAY (f), | 2966 | XISelectEvents (FRAME_X_DISPLAY (f), |
| 2954 | FRAME_X_WINDOW (f), | 2967 | FRAME_X_WINDOW (f), |
| 2955 | &mask, 1); | 2968 | &mask, 1); |
| 2969 | unblock_input (); | ||
| 2956 | } | 2970 | } |
| 2957 | #endif | 2971 | #endif |
| 2958 | 2972 | ||
| @@ -3249,6 +3263,11 @@ x_window (struct frame *f) | |||
| 3249 | unblock_input (); | 3263 | unblock_input (); |
| 3250 | } | 3264 | } |
| 3251 | #endif | 3265 | #endif |
| 3266 | |||
| 3267 | #ifdef HAVE_XINPUT2 | ||
| 3268 | if (FRAME_DISPLAY_INFO (f)->supports_xi2) | ||
| 3269 | setup_xi_event_mask (f); | ||
| 3270 | #endif | ||
| 3252 | } | 3271 | } |
| 3253 | 3272 | ||
| 3254 | #else /*! USE_GTK */ | 3273 | #else /*! USE_GTK */ |
diff --git a/src/xterm.c b/src/xterm.c index 646985bdc20..fa60a4e8745 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -353,6 +353,8 @@ x_extension_initialize (struct x_display_info *dpyinfo) | |||
| 353 | static void | 353 | static void |
| 354 | x_free_xi_devices (struct x_display_info *dpyinfo) | 354 | x_free_xi_devices (struct x_display_info *dpyinfo) |
| 355 | { | 355 | { |
| 356 | struct xi_touch_point_t *tem, *last; | ||
| 357 | |||
| 356 | block_input (); | 358 | block_input (); |
| 357 | 359 | ||
| 358 | if (dpyinfo->num_devices) | 360 | if (dpyinfo->num_devices) |
| @@ -362,6 +364,14 @@ x_free_xi_devices (struct x_display_info *dpyinfo) | |||
| 362 | XIUngrabDevice (dpyinfo->display, dpyinfo->devices[i].device_id, | 364 | XIUngrabDevice (dpyinfo->display, dpyinfo->devices[i].device_id, |
| 363 | CurrentTime); | 365 | CurrentTime); |
| 364 | xfree (dpyinfo->devices[i].valuators); | 366 | xfree (dpyinfo->devices[i].valuators); |
| 367 | |||
| 368 | tem = dpyinfo->devices[i].touchpoints; | ||
| 369 | while (tem) | ||
| 370 | { | ||
| 371 | last = tem; | ||
| 372 | tem = tem->next; | ||
| 373 | xfree (last); | ||
| 374 | } | ||
| 365 | } | 375 | } |
| 366 | 376 | ||
| 367 | xfree (dpyinfo->devices); | 377 | xfree (dpyinfo->devices); |
| @@ -407,7 +417,7 @@ x_init_master_valuators (struct x_display_info *dpyinfo) | |||
| 407 | block_input (); | 417 | block_input (); |
| 408 | x_free_xi_devices (dpyinfo); | 418 | x_free_xi_devices (dpyinfo); |
| 409 | infos = XIQueryDevice (dpyinfo->display, | 419 | infos = XIQueryDevice (dpyinfo->display, |
| 410 | XIAllMasterDevices, | 420 | XIAllDevices, |
| 411 | &ndevices); | 421 | &ndevices); |
| 412 | 422 | ||
| 413 | if (!ndevices) | 423 | if (!ndevices) |
| @@ -432,6 +442,10 @@ x_init_master_valuators (struct x_display_info *dpyinfo) | |||
| 432 | xi_device->grab = 0; | 442 | xi_device->grab = 0; |
| 433 | xi_device->valuators = | 443 | xi_device->valuators = |
| 434 | xmalloc (sizeof *xi_device->valuators * device->num_classes); | 444 | xmalloc (sizeof *xi_device->valuators * device->num_classes); |
| 445 | xi_device->touchpoints = NULL; | ||
| 446 | xi_device->master_p = (device->use == XIMasterKeyboard | ||
| 447 | || device->use == XIMasterPointer); | ||
| 448 | xi_device->direct_p = false; | ||
| 435 | 449 | ||
| 436 | for (int c = 0; c < device->num_classes; ++c) | 450 | for (int c = 0; c < device->num_classes; ++c) |
| 437 | { | 451 | { |
| @@ -442,22 +456,36 @@ x_init_master_valuators (struct x_display_info *dpyinfo) | |||
| 442 | { | 456 | { |
| 443 | XIScrollClassInfo *info = | 457 | XIScrollClassInfo *info = |
| 444 | (XIScrollClassInfo *) device->classes[c]; | 458 | (XIScrollClassInfo *) device->classes[c]; |
| 445 | struct xi_scroll_valuator_t *valuator = | 459 | struct xi_scroll_valuator_t *valuator; |
| 446 | &xi_device->valuators[actual_valuator_count++]; | 460 | |
| 447 | 461 | if (xi_device->master_p) | |
| 448 | valuator->horizontal | 462 | { |
| 449 | = (info->scroll_type == XIScrollTypeHorizontal); | 463 | valuator = &xi_device->valuators[actual_valuator_count++]; |
| 450 | valuator->invalid_p = true; | 464 | valuator->horizontal |
| 451 | valuator->emacs_value = DBL_MIN; | 465 | = (info->scroll_type == XIScrollTypeHorizontal); |
| 452 | valuator->increment = info->increment; | 466 | valuator->invalid_p = true; |
| 453 | valuator->number = info->number; | 467 | valuator->emacs_value = DBL_MIN; |
| 468 | valuator->increment = info->increment; | ||
| 469 | valuator->number = info->number; | ||
| 470 | } | ||
| 471 | |||
| 454 | break; | 472 | break; |
| 455 | } | 473 | } |
| 456 | #endif | 474 | #endif |
| 475 | #ifdef XITouchClass /* XInput 2.2 */ | ||
| 476 | case XITouchClass: | ||
| 477 | { | ||
| 478 | XITouchClassInfo *info; | ||
| 479 | |||
| 480 | info = (XITouchClassInfo *) device->classes[c]; | ||
| 481 | xi_device->direct_p = info->mode == XIDirectTouch; | ||
| 482 | } | ||
| 483 | #endif | ||
| 457 | default: | 484 | default: |
| 458 | break; | 485 | break; |
| 459 | } | 486 | } |
| 460 | } | 487 | } |
| 488 | |||
| 461 | xi_device->scroll_valuator_count = actual_valuator_count; | 489 | xi_device->scroll_valuator_count = actual_valuator_count; |
| 462 | } | 490 | } |
| 463 | } | 491 | } |
| @@ -484,7 +512,7 @@ x_get_scroll_valuator_delta (struct x_display_info *dpyinfo, int device_id, | |||
| 484 | { | 512 | { |
| 485 | struct xi_device_t *device = &dpyinfo->devices[i]; | 513 | struct xi_device_t *device = &dpyinfo->devices[i]; |
| 486 | 514 | ||
| 487 | if (device->device_id == device_id) | 515 | if (device->device_id == device_id && device->master_p) |
| 488 | { | 516 | { |
| 489 | for (int j = 0; j < device->scroll_valuator_count; ++j) | 517 | for (int j = 0; j < device->scroll_valuator_count; ++j) |
| 490 | { | 518 | { |
| @@ -534,6 +562,61 @@ xi_device_from_id (struct x_display_info *dpyinfo, int deviceid) | |||
| 534 | return NULL; | 562 | return NULL; |
| 535 | } | 563 | } |
| 536 | 564 | ||
| 565 | #ifdef XI_TouchBegin | ||
| 566 | |||
| 567 | static void | ||
| 568 | xi_link_touch_point (struct xi_device_t *device, | ||
| 569 | int detail, double x, double y) | ||
| 570 | { | ||
| 571 | struct xi_touch_point_t *touchpoint; | ||
| 572 | |||
| 573 | touchpoint = xmalloc (sizeof *touchpoint); | ||
| 574 | touchpoint->next = device->touchpoints; | ||
| 575 | touchpoint->x = x; | ||
| 576 | touchpoint->y = y; | ||
| 577 | touchpoint->number = detail; | ||
| 578 | |||
| 579 | device->touchpoints = touchpoint; | ||
| 580 | } | ||
| 581 | |||
| 582 | static void | ||
| 583 | xi_unlink_touch_point (int detail, | ||
| 584 | struct xi_device_t *device) | ||
| 585 | { | ||
| 586 | struct xi_touch_point_t *last, *tem; | ||
| 587 | |||
| 588 | for (last = NULL, tem = device->touchpoints; tem; | ||
| 589 | last = tem, tem = tem->next) | ||
| 590 | { | ||
| 591 | if (tem->number == detail) | ||
| 592 | { | ||
| 593 | if (!last) | ||
| 594 | device->touchpoints = tem->next; | ||
| 595 | else | ||
| 596 | last->next = tem->next; | ||
| 597 | |||
| 598 | xfree (tem); | ||
| 599 | return; | ||
| 600 | } | ||
| 601 | } | ||
| 602 | } | ||
| 603 | |||
| 604 | static struct xi_touch_point_t * | ||
| 605 | xi_find_touch_point (struct xi_device_t *device, int detail) | ||
| 606 | { | ||
| 607 | struct xi_touch_point_t *point; | ||
| 608 | |||
| 609 | for (point = device->touchpoints; point; point = point->next) | ||
| 610 | { | ||
| 611 | if (point->number == detail) | ||
| 612 | return point; | ||
| 613 | } | ||
| 614 | |||
| 615 | return NULL; | ||
| 616 | } | ||
| 617 | |||
| 618 | #endif /* XI_TouchBegin */ | ||
| 619 | |||
| 537 | static void | 620 | static void |
| 538 | xi_grab_or_ungrab_device (struct xi_device_t *device, | 621 | xi_grab_or_ungrab_device (struct xi_device_t *device, |
| 539 | struct x_display_info *dpyinfo, | 622 | struct x_display_info *dpyinfo, |
| @@ -570,7 +653,7 @@ xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo, int id) | |||
| 570 | struct xi_device_t *device = xi_device_from_id (dpyinfo, id); | 653 | struct xi_device_t *device = xi_device_from_id (dpyinfo, id); |
| 571 | struct xi_scroll_valuator_t *valuator; | 654 | struct xi_scroll_valuator_t *valuator; |
| 572 | 655 | ||
| 573 | if (!device) | 656 | if (!device || !device->master_p) |
| 574 | return; | 657 | return; |
| 575 | 658 | ||
| 576 | if (!device->scroll_valuator_count) | 659 | if (!device->scroll_valuator_count) |
| @@ -9981,242 +10064,250 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 9981 | #endif | 10064 | #endif |
| 9982 | goto XI_OTHER; | 10065 | goto XI_OTHER; |
| 9983 | case XI_Motion: | 10066 | case XI_Motion: |
| 9984 | states = &xev->valuators; | 10067 | { |
| 9985 | values = states->values; | 10068 | struct xi_device_t *device; |
| 9986 | 10069 | ||
| 9987 | x_display_set_last_user_time (dpyinfo, xi_event->time); | 10070 | states = &xev->valuators; |
| 10071 | values = states->values; | ||
| 10072 | device = xi_device_from_id (dpyinfo, xev->deviceid); | ||
| 10073 | |||
| 10074 | if (!device || !device->master_p) | ||
| 10075 | goto XI_OTHER; | ||
| 10076 | |||
| 10077 | x_display_set_last_user_time (dpyinfo, xi_event->time); | ||
| 9988 | 10078 | ||
| 9989 | #ifdef HAVE_XWIDGETS | 10079 | #ifdef HAVE_XWIDGETS |
| 9990 | struct xwidget_view *xv = xwidget_view_from_window (xev->event); | 10080 | struct xwidget_view *xv = xwidget_view_from_window (xev->event); |
| 9991 | double xv_total_x = 0.0; | 10081 | double xv_total_x = 0.0; |
| 9992 | double xv_total_y = 0.0; | 10082 | double xv_total_y = 0.0; |
| 9993 | #endif | 10083 | #endif |
| 9994 | 10084 | ||
| 9995 | for (int i = 0; i < states->mask_len * 8; i++) | 10085 | for (int i = 0; i < states->mask_len * 8; i++) |
| 9996 | { | 10086 | { |
| 9997 | if (XIMaskIsSet (states->mask, i)) | 10087 | if (XIMaskIsSet (states->mask, i)) |
| 9998 | { | 10088 | { |
| 9999 | struct xi_scroll_valuator_t *val; | 10089 | struct xi_scroll_valuator_t *val; |
| 10000 | double delta, scroll_unit; | 10090 | double delta, scroll_unit; |
| 10001 | int scroll_height; | 10091 | int scroll_height; |
| 10002 | Lisp_Object window; | 10092 | Lisp_Object window; |
| 10003 | 10093 | ||
| 10004 | 10094 | ||
| 10005 | /* See the comment on top of | 10095 | /* See the comment on top of |
| 10006 | x_init_master_valuators for more details on how | 10096 | x_init_master_valuators for more details on how |
| 10007 | scroll wheel movement is reported on XInput 2. */ | 10097 | scroll wheel movement is reported on XInput 2. */ |
| 10008 | delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid, | 10098 | delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid, |
| 10009 | i, *values, &val); | 10099 | i, *values, &val); |
| 10010 | 10100 | ||
| 10011 | if (delta != DBL_MAX) | 10101 | if (delta != DBL_MAX) |
| 10012 | { | 10102 | { |
| 10013 | #ifdef HAVE_XWIDGETS | 10103 | #ifdef HAVE_XWIDGETS |
| 10014 | if (xv) | 10104 | if (xv) |
| 10015 | { | 10105 | { |
| 10016 | if (val->horizontal) | 10106 | if (val->horizontal) |
| 10017 | xv_total_x += delta; | 10107 | xv_total_x += delta; |
| 10018 | else | 10108 | else |
| 10019 | xv_total_y += delta; | 10109 | xv_total_y += delta; |
| 10020 | 10110 | ||
| 10021 | found_valuator = true; | 10111 | found_valuator = true; |
| 10022 | 10112 | ||
| 10023 | if (delta == 0.0) | 10113 | if (delta == 0.0) |
| 10024 | any_stop_p = true; | 10114 | any_stop_p = true; |
| 10025 | 10115 | ||
| 10026 | continue; | 10116 | continue; |
| 10027 | } | 10117 | } |
| 10028 | #endif | 10118 | #endif |
| 10029 | if (!f) | 10119 | if (!f) |
| 10030 | { | 10120 | { |
| 10031 | f = x_any_window_to_frame (dpyinfo, xev->event); | 10121 | f = x_any_window_to_frame (dpyinfo, xev->event); |
| 10032 | 10122 | ||
| 10033 | if (!f) | 10123 | if (!f) |
| 10034 | goto XI_OTHER; | 10124 | goto XI_OTHER; |
| 10035 | } | 10125 | } |
| 10036 | 10126 | ||
| 10037 | found_valuator = true; | 10127 | found_valuator = true; |
| 10038 | 10128 | ||
| 10039 | if (signbit (delta) != signbit (val->emacs_value)) | 10129 | if (signbit (delta) != signbit (val->emacs_value)) |
| 10040 | val->emacs_value = 0; | 10130 | val->emacs_value = 0; |
| 10041 | 10131 | ||
| 10042 | val->emacs_value += delta; | 10132 | val->emacs_value += delta; |
| 10043 | 10133 | ||
| 10044 | if (mwheel_coalesce_scroll_events | 10134 | if (mwheel_coalesce_scroll_events |
| 10045 | && (fabs (val->emacs_value) < 1) | 10135 | && (fabs (val->emacs_value) < 1) |
| 10046 | && (fabs (delta) > 0)) | 10136 | && (fabs (delta) > 0)) |
| 10047 | continue; | 10137 | continue; |
| 10048 | 10138 | ||
| 10049 | bool s = signbit (val->emacs_value); | 10139 | bool s = signbit (val->emacs_value); |
| 10050 | inev.ie.kind = (fabs (delta) > 0 | 10140 | inev.ie.kind = (fabs (delta) > 0 |
| 10051 | ? (val->horizontal | 10141 | ? (val->horizontal |
| 10052 | ? HORIZ_WHEEL_EVENT | 10142 | ? HORIZ_WHEEL_EVENT |
| 10053 | : WHEEL_EVENT) | 10143 | : WHEEL_EVENT) |
| 10054 | : TOUCH_END_EVENT); | 10144 | : TOUCH_END_EVENT); |
| 10055 | inev.ie.timestamp = xev->time; | 10145 | inev.ie.timestamp = xev->time; |
| 10056 | 10146 | ||
| 10057 | XSETINT (inev.ie.x, lrint (xev->event_x)); | 10147 | XSETINT (inev.ie.x, lrint (xev->event_x)); |
| 10058 | XSETINT (inev.ie.y, lrint (xev->event_y)); | 10148 | XSETINT (inev.ie.y, lrint (xev->event_y)); |
| 10059 | XSETFRAME (inev.ie.frame_or_window, f); | 10149 | XSETFRAME (inev.ie.frame_or_window, f); |
| 10060 | 10150 | ||
| 10061 | if (fabs (delta) > 0) | 10151 | if (fabs (delta) > 0) |
| 10062 | { | 10152 | { |
| 10063 | inev.ie.modifiers = !s ? up_modifier : down_modifier; | 10153 | inev.ie.modifiers = !s ? up_modifier : down_modifier; |
| 10064 | inev.ie.modifiers | 10154 | inev.ie.modifiers |
| 10065 | |= x_x_to_emacs_modifiers (dpyinfo, | 10155 | |= x_x_to_emacs_modifiers (dpyinfo, |
| 10066 | xev->mods.effective); | 10156 | xev->mods.effective); |
| 10067 | } | 10157 | } |
| 10068 | 10158 | ||
| 10069 | window = window_from_coordinates (f, xev->event_x, | 10159 | window = window_from_coordinates (f, xev->event_x, |
| 10070 | xev->event_y, NULL, | 10160 | xev->event_y, NULL, |
| 10071 | false, false); | 10161 | false, false); |
| 10072 | 10162 | ||
| 10073 | if (WINDOWP (window)) | 10163 | if (WINDOWP (window)) |
| 10074 | scroll_height = XWINDOW (window)->pixel_height; | 10164 | scroll_height = XWINDOW (window)->pixel_height; |
| 10075 | else | 10165 | else |
| 10076 | /* EVENT_X and EVENT_Y can be outside the | 10166 | /* EVENT_X and EVENT_Y can be outside the |
| 10077 | frame if F holds the input grab, so fall | 10167 | frame if F holds the input grab, so fall |
| 10078 | back to the height of the frame instead. */ | 10168 | back to the height of the frame instead. */ |
| 10079 | scroll_height = FRAME_PIXEL_HEIGHT (f); | 10169 | scroll_height = FRAME_PIXEL_HEIGHT (f); |
| 10080 | 10170 | ||
| 10081 | scroll_unit = pow (scroll_height, 2.0 / 3.0); | 10171 | scroll_unit = pow (scroll_height, 2.0 / 3.0); |
| 10082 | 10172 | ||
| 10083 | if (NUMBERP (Vx_scroll_event_delta_factor)) | 10173 | if (NUMBERP (Vx_scroll_event_delta_factor)) |
| 10084 | scroll_unit *= XFLOATINT (Vx_scroll_event_delta_factor); | 10174 | scroll_unit *= XFLOATINT (Vx_scroll_event_delta_factor); |
| 10085 | 10175 | ||
| 10086 | if (fabs (delta) > 0) | 10176 | if (fabs (delta) > 0) |
| 10087 | { | 10177 | { |
| 10088 | if (val->horizontal) | 10178 | if (val->horizontal) |
| 10089 | { | 10179 | { |
| 10090 | inev.ie.arg | 10180 | inev.ie.arg |
| 10091 | = list3 (Qnil, | 10181 | = list3 (Qnil, |
| 10092 | make_float (val->emacs_value | 10182 | make_float (val->emacs_value |
| 10093 | * scroll_unit), | 10183 | * scroll_unit), |
| 10094 | make_float (0)); | 10184 | make_float (0)); |
| 10095 | } | 10185 | } |
| 10096 | else | 10186 | else |
| 10097 | { | 10187 | { |
| 10098 | inev.ie.arg = list3 (Qnil, make_float (0), | 10188 | inev.ie.arg = list3 (Qnil, make_float (0), |
| 10099 | make_float (val->emacs_value | 10189 | make_float (val->emacs_value |
| 10100 | * scroll_unit)); | 10190 | * scroll_unit)); |
| 10101 | } | 10191 | } |
| 10102 | } | 10192 | } |
| 10103 | else | 10193 | else |
| 10104 | { | 10194 | { |
| 10105 | inev.ie.arg = Qnil; | 10195 | inev.ie.arg = Qnil; |
| 10106 | } | 10196 | } |
| 10107 | 10197 | ||
| 10108 | kbd_buffer_store_event_hold (&inev.ie, hold_quit); | 10198 | kbd_buffer_store_event_hold (&inev.ie, hold_quit); |
| 10109 | 10199 | ||
| 10110 | val->emacs_value = 0; | 10200 | val->emacs_value = 0; |
| 10111 | } | 10201 | } |
| 10112 | values++; | 10202 | values++; |
| 10113 | } | 10203 | } |
| 10114 | 10204 | ||
| 10115 | inev.ie.kind = NO_EVENT; | 10205 | inev.ie.kind = NO_EVENT; |
| 10116 | } | 10206 | } |
| 10117 | 10207 | ||
| 10118 | #ifdef HAVE_XWIDGETS | 10208 | #ifdef HAVE_XWIDGETS |
| 10119 | if (xv) | 10209 | if (xv) |
| 10120 | { | 10210 | { |
| 10121 | if (found_valuator) | 10211 | if (found_valuator) |
| 10122 | xwidget_scroll (xv, xev->event_x, xev->event_y, | 10212 | xwidget_scroll (xv, xev->event_x, xev->event_y, |
| 10123 | xv_total_x, xv_total_y, xev->mods.effective, | 10213 | xv_total_x, xv_total_y, xev->mods.effective, |
| 10124 | xev->time, any_stop_p); | 10214 | xev->time, any_stop_p); |
| 10125 | else | 10215 | else |
| 10126 | xwidget_motion_notify (xv, xev->event_x, xev->event_y, | 10216 | xwidget_motion_notify (xv, xev->event_x, xev->event_y, |
| 10127 | xev->mods.effective, xev->time); | 10217 | xev->mods.effective, xev->time); |
| 10128 | 10218 | ||
| 10129 | goto XI_OTHER; | 10219 | goto XI_OTHER; |
| 10130 | } | 10220 | } |
| 10131 | #endif | 10221 | #endif |
| 10132 | if (found_valuator) | 10222 | if (found_valuator) |
| 10133 | goto XI_OTHER; | 10223 | goto XI_OTHER; |
| 10134 | 10224 | ||
| 10135 | ev.x = lrint (xev->event_x); | 10225 | ev.x = lrint (xev->event_x); |
| 10136 | ev.y = lrint (xev->event_y); | 10226 | ev.y = lrint (xev->event_y); |
| 10137 | ev.window = xev->event; | 10227 | ev.window = xev->event; |
| 10138 | ev.time = xev->time; | 10228 | ev.time = xev->time; |
| 10139 | 10229 | ||
| 10140 | previous_help_echo_string = help_echo_string; | 10230 | previous_help_echo_string = help_echo_string; |
| 10141 | help_echo_string = Qnil; | 10231 | help_echo_string = Qnil; |
| 10142 | 10232 | ||
| 10143 | if (hlinfo->mouse_face_hidden) | 10233 | if (hlinfo->mouse_face_hidden) |
| 10144 | { | 10234 | { |
| 10145 | hlinfo->mouse_face_hidden = false; | 10235 | hlinfo->mouse_face_hidden = false; |
| 10146 | clear_mouse_face (hlinfo); | 10236 | clear_mouse_face (hlinfo); |
| 10147 | } | 10237 | } |
| 10148 | 10238 | ||
| 10149 | f = mouse_or_wdesc_frame (dpyinfo, xev->event); | 10239 | f = mouse_or_wdesc_frame (dpyinfo, xev->event); |
| 10150 | 10240 | ||
| 10151 | #ifdef USE_GTK | 10241 | #ifdef USE_GTK |
| 10152 | if (f && xg_event_is_for_scrollbar (f, event)) | 10242 | if (f && xg_event_is_for_scrollbar (f, event)) |
| 10153 | f = 0; | 10243 | f = 0; |
| 10154 | #endif | 10244 | #endif |
| 10155 | if (f) | 10245 | if (f) |
| 10156 | { | 10246 | { |
| 10157 | /* Maybe generate a SELECT_WINDOW_EVENT for | 10247 | /* Maybe generate a SELECT_WINDOW_EVENT for |
| 10158 | `mouse-autoselect-window' but don't let popup menus | 10248 | `mouse-autoselect-window' but don't let popup menus |
| 10159 | interfere with this (Bug#1261). */ | 10249 | interfere with this (Bug#1261). */ |
| 10160 | if (!NILP (Vmouse_autoselect_window) | 10250 | if (!NILP (Vmouse_autoselect_window) |
| 10161 | && !popup_activated () | 10251 | && !popup_activated () |
| 10162 | /* Don't switch if we're currently in the minibuffer. | 10252 | /* Don't switch if we're currently in the minibuffer. |
| 10163 | This tries to work around problems where the | 10253 | This tries to work around problems where the |
| 10164 | minibuffer gets unselected unexpectedly, and where | 10254 | minibuffer gets unselected unexpectedly, and where |
| 10165 | you then have to move your mouse all the way down to | 10255 | you then have to move your mouse all the way down to |
| 10166 | the minibuffer to select it. */ | 10256 | the minibuffer to select it. */ |
| 10167 | && !MINI_WINDOW_P (XWINDOW (selected_window)) | 10257 | && !MINI_WINDOW_P (XWINDOW (selected_window)) |
| 10168 | /* With `focus-follows-mouse' non-nil create an event | 10258 | /* With `focus-follows-mouse' non-nil create an event |
| 10169 | also when the target window is on another frame. */ | 10259 | also when the target window is on another frame. */ |
| 10170 | && (f == XFRAME (selected_frame) | 10260 | && (f == XFRAME (selected_frame) |
| 10171 | || !NILP (focus_follows_mouse))) | 10261 | || !NILP (focus_follows_mouse))) |
| 10172 | { | 10262 | { |
| 10173 | static Lisp_Object last_mouse_window; | 10263 | static Lisp_Object last_mouse_window; |
| 10174 | Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false); | 10264 | Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false); |
| 10175 | 10265 | ||
| 10176 | /* A window will be autoselected only when it is not | 10266 | /* A window will be autoselected only when it is not |
| 10177 | selected now and the last mouse movement event was | 10267 | selected now and the last mouse movement event was |
| 10178 | not in it. The remainder of the code is a bit vague | 10268 | not in it. The remainder of the code is a bit vague |
| 10179 | wrt what a "window" is. For immediate autoselection, | 10269 | wrt what a "window" is. For immediate autoselection, |
| 10180 | the window is usually the entire window but for GTK | 10270 | the window is usually the entire window but for GTK |
| 10181 | where the scroll bars don't count. For delayed | 10271 | where the scroll bars don't count. For delayed |
| 10182 | autoselection the window is usually the window's text | 10272 | autoselection the window is usually the window's text |
| 10183 | area including the margins. */ | 10273 | area including the margins. */ |
| 10184 | if (WINDOWP (window) | 10274 | if (WINDOWP (window) |
| 10185 | && !EQ (window, last_mouse_window) | 10275 | && !EQ (window, last_mouse_window) |
| 10186 | && !EQ (window, selected_window)) | 10276 | && !EQ (window, selected_window)) |
| 10187 | { | 10277 | { |
| 10188 | inev.ie.kind = SELECT_WINDOW_EVENT; | 10278 | inev.ie.kind = SELECT_WINDOW_EVENT; |
| 10189 | inev.ie.frame_or_window = window; | 10279 | inev.ie.frame_or_window = window; |
| 10190 | } | 10280 | } |
| 10191 | 10281 | ||
| 10192 | /* Remember the last window where we saw the mouse. */ | 10282 | /* Remember the last window where we saw the mouse. */ |
| 10193 | last_mouse_window = window; | 10283 | last_mouse_window = window; |
| 10194 | } | 10284 | } |
| 10195 | 10285 | ||
| 10196 | if (!x_note_mouse_movement (f, &ev)) | 10286 | if (!x_note_mouse_movement (f, &ev)) |
| 10197 | help_echo_string = previous_help_echo_string; | 10287 | help_echo_string = previous_help_echo_string; |
| 10198 | } | 10288 | } |
| 10199 | else | 10289 | else |
| 10200 | { | 10290 | { |
| 10201 | #ifndef USE_TOOLKIT_SCROLL_BARS | 10291 | #ifndef USE_TOOLKIT_SCROLL_BARS |
| 10202 | struct scroll_bar *bar | 10292 | struct scroll_bar *bar |
| 10203 | = x_window_to_scroll_bar (xi_event->display, xev->event, 2); | 10293 | = x_window_to_scroll_bar (xi_event->display, xev->event, 2); |
| 10204 | 10294 | ||
| 10205 | if (bar) | 10295 | if (bar) |
| 10206 | x_scroll_bar_note_movement (bar, &ev); | 10296 | x_scroll_bar_note_movement (bar, &ev); |
| 10207 | #endif /* USE_TOOLKIT_SCROLL_BARS */ | 10297 | #endif /* USE_TOOLKIT_SCROLL_BARS */ |
| 10208 | 10298 | ||
| 10209 | /* If we move outside the frame, then we're | 10299 | /* If we move outside the frame, then we're |
| 10210 | certainly no longer on any text in the frame. */ | 10300 | certainly no longer on any text in the frame. */ |
| 10211 | clear_mouse_face (hlinfo); | 10301 | clear_mouse_face (hlinfo); |
| 10212 | } | 10302 | } |
| 10213 | 10303 | ||
| 10214 | /* If the contents of the global variable help_echo_string | 10304 | /* If the contents of the global variable help_echo_string |
| 10215 | has changed, generate a HELP_EVENT. */ | 10305 | has changed, generate a HELP_EVENT. */ |
| 10216 | if (!NILP (help_echo_string) | 10306 | if (!NILP (help_echo_string) |
| 10217 | || !NILP (previous_help_echo_string)) | 10307 | || !NILP (previous_help_echo_string)) |
| 10218 | do_help = 1; | 10308 | do_help = 1; |
| 10219 | goto XI_OTHER; | 10309 | goto XI_OTHER; |
| 10310 | } | ||
| 10220 | case XI_ButtonRelease: | 10311 | case XI_ButtonRelease: |
| 10221 | case XI_ButtonPress: | 10312 | case XI_ButtonPress: |
| 10222 | { | 10313 | { |
| @@ -10242,6 +10333,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 10242 | 10333 | ||
| 10243 | device = xi_device_from_id (dpyinfo, xev->deviceid); | 10334 | device = xi_device_from_id (dpyinfo, xev->deviceid); |
| 10244 | 10335 | ||
| 10336 | if (!device || !device->master_p) | ||
| 10337 | goto XI_OTHER; | ||
| 10338 | |||
| 10245 | bv.button = xev->detail; | 10339 | bv.button = xev->detail; |
| 10246 | bv.type = xev->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease; | 10340 | bv.type = xev->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease; |
| 10247 | bv.x = lrint (xev->event_x); | 10341 | bv.x = lrint (xev->event_x); |
| @@ -10408,6 +10502,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 10408 | int copy_bufsiz = sizeof (copy_buffer); | 10502 | int copy_bufsiz = sizeof (copy_buffer); |
| 10409 | ptrdiff_t i; | 10503 | ptrdiff_t i; |
| 10410 | int nchars, len; | 10504 | int nchars, len; |
| 10505 | struct xi_device_t *device; | ||
| 10506 | |||
| 10507 | device = xi_device_from_id (dpyinfo, xev->deviceid); | ||
| 10508 | |||
| 10509 | if (!device || !device->master_p) | ||
| 10510 | goto XI_OTHER; | ||
| 10411 | 10511 | ||
| 10412 | #if defined (USE_X_TOOLKIT) || defined (USE_GTK) | 10512 | #if defined (USE_X_TOOLKIT) || defined (USE_GTK) |
| 10413 | /* Dispatch XI_KeyPress events when in menu. */ | 10513 | /* Dispatch XI_KeyPress events when in menu. */ |
| @@ -10765,6 +10865,108 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 10765 | case XI_DeviceChanged: | 10865 | case XI_DeviceChanged: |
| 10766 | x_init_master_valuators (dpyinfo); | 10866 | x_init_master_valuators (dpyinfo); |
| 10767 | goto XI_OTHER; | 10867 | goto XI_OTHER; |
| 10868 | #ifdef XI_TouchBegin | ||
| 10869 | case XI_TouchBegin: | ||
| 10870 | { | ||
| 10871 | struct xi_device_t *device; | ||
| 10872 | device = xi_device_from_id (dpyinfo, xev->deviceid); | ||
| 10873 | |||
| 10874 | if (!device) | ||
| 10875 | goto XI_OTHER; | ||
| 10876 | |||
| 10877 | if (xi_find_touch_point (device, xev->detail)) | ||
| 10878 | emacs_abort (); | ||
| 10879 | |||
| 10880 | f = x_any_window_to_frame (dpyinfo, xev->event); | ||
| 10881 | |||
| 10882 | if (f && device->direct_p) | ||
| 10883 | { | ||
| 10884 | xi_link_touch_point (device, xev->detail, xev->event_x, | ||
| 10885 | xev->event_y); | ||
| 10886 | |||
| 10887 | inev.ie.kind = TOUCHSCREEN_BEGIN_EVENT; | ||
| 10888 | inev.ie.timestamp = xev->time; | ||
| 10889 | XSETFRAME (inev.ie.frame_or_window, f); | ||
| 10890 | XSETINT (inev.ie.x, lrint (xev->event_x)); | ||
| 10891 | XSETINT (inev.ie.y, lrint (xev->event_y)); | ||
| 10892 | XSETINT (inev.ie.arg, xev->detail); | ||
| 10893 | |||
| 10894 | XIAllowTouchEvents (dpyinfo->display, xev->deviceid, | ||
| 10895 | xev->detail, xev->event, XIAcceptTouch); | ||
| 10896 | } | ||
| 10897 | else | ||
| 10898 | XIAllowTouchEvents (dpyinfo->display, xev->deviceid, | ||
| 10899 | xev->detail, xev->event, XIRejectTouch); | ||
| 10900 | |||
| 10901 | goto XI_OTHER; | ||
| 10902 | } | ||
| 10903 | case XI_TouchUpdate: | ||
| 10904 | { | ||
| 10905 | struct xi_device_t *device; | ||
| 10906 | struct xi_touch_point_t *touchpoint; | ||
| 10907 | Lisp_Object arg = Qnil; | ||
| 10908 | |||
| 10909 | device = xi_device_from_id (dpyinfo, xev->deviceid); | ||
| 10910 | |||
| 10911 | if (!device) | ||
| 10912 | goto XI_OTHER; | ||
| 10913 | |||
| 10914 | touchpoint = xi_find_touch_point (device, xev->detail); | ||
| 10915 | |||
| 10916 | if (!touchpoint) | ||
| 10917 | emacs_abort (); | ||
| 10918 | |||
| 10919 | touchpoint->x = xev->event_x; | ||
| 10920 | touchpoint->y = xev->event_y; | ||
| 10921 | |||
| 10922 | f = x_any_window_to_frame (dpyinfo, xev->event); | ||
| 10923 | |||
| 10924 | if (f && device->direct_p) | ||
| 10925 | { | ||
| 10926 | inev.ie.kind = TOUCHSCREEN_UPDATE_EVENT; | ||
| 10927 | inev.ie.timestamp = xev->time; | ||
| 10928 | XSETFRAME (inev.ie.frame_or_window, f); | ||
| 10929 | |||
| 10930 | for (touchpoint = device->touchpoints; | ||
| 10931 | touchpoint; touchpoint = touchpoint->next) | ||
| 10932 | { | ||
| 10933 | arg = Fcons (list3i (lrint (touchpoint->x), | ||
| 10934 | lrint (touchpoint->y), | ||
| 10935 | lrint (touchpoint->number)), | ||
| 10936 | arg); | ||
| 10937 | } | ||
| 10938 | |||
| 10939 | inev.ie.arg = arg; | ||
| 10940 | } | ||
| 10941 | |||
| 10942 | goto XI_OTHER; | ||
| 10943 | } | ||
| 10944 | case XI_TouchEnd: | ||
| 10945 | { | ||
| 10946 | struct xi_device_t *device; | ||
| 10947 | |||
| 10948 | device = xi_device_from_id (dpyinfo, xev->deviceid); | ||
| 10949 | |||
| 10950 | if (!device) | ||
| 10951 | goto XI_OTHER; | ||
| 10952 | |||
| 10953 | xi_unlink_touch_point (xev->detail, device); | ||
| 10954 | |||
| 10955 | f = x_any_window_to_frame (dpyinfo, xev->event); | ||
| 10956 | |||
| 10957 | if (f && device->direct_p) | ||
| 10958 | { | ||
| 10959 | inev.ie.kind = TOUCHSCREEN_END_EVENT; | ||
| 10960 | inev.ie.timestamp = xev->time; | ||
| 10961 | XSETFRAME (inev.ie.frame_or_window, f); | ||
| 10962 | XSETINT (inev.ie.x, lrint (xev->event_x)); | ||
| 10963 | XSETINT (inev.ie.y, lrint (xev->event_y)); | ||
| 10964 | XSETINT (inev.ie.arg, xev->detail); | ||
| 10965 | } | ||
| 10966 | |||
| 10967 | goto XI_OTHER; | ||
| 10968 | } | ||
| 10969 | #endif | ||
| 10768 | default: | 10970 | default: |
| 10769 | goto XI_OTHER; | 10971 | goto XI_OTHER; |
| 10770 | } | 10972 | } |
diff --git a/src/xterm.h b/src/xterm.h index 7abe168bc6f..d9ace002d58 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -179,13 +179,24 @@ struct xi_scroll_valuator_t | |||
| 179 | int horizontal; | 179 | int horizontal; |
| 180 | }; | 180 | }; |
| 181 | 181 | ||
| 182 | struct xi_touch_point_t | ||
| 183 | { | ||
| 184 | struct xi_touch_point_t *next; | ||
| 185 | |||
| 186 | int number; | ||
| 187 | double x, y; | ||
| 188 | }; | ||
| 189 | |||
| 182 | struct xi_device_t | 190 | struct xi_device_t |
| 183 | { | 191 | { |
| 184 | int device_id; | 192 | int device_id; |
| 185 | int scroll_valuator_count; | 193 | int scroll_valuator_count; |
| 186 | int grab; | 194 | int grab; |
| 195 | bool master_p; | ||
| 196 | bool direct_p; | ||
| 187 | 197 | ||
| 188 | struct xi_scroll_valuator_t *valuators; | 198 | struct xi_scroll_valuator_t *valuators; |
| 199 | struct xi_touch_point_t *touchpoints; | ||
| 189 | }; | 200 | }; |
| 190 | #endif | 201 | #endif |
| 191 | 202 | ||