mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-09 08:21:30 -07:00
Merge remote-tracking branch 'origin/master' into feature/pgtk
This commit is contained in:
commit
5e5cde55e5
31 changed files with 670 additions and 365 deletions
|
|
@ -1175,6 +1175,7 @@ intended by Lisp code to be used as an event.
|
|||
* Button-Down Events:: A button was pushed and not yet released.
|
||||
* Repeat Events:: Double and triple click (or drag, or down).
|
||||
* Motion Events:: Just moving the mouse, not pushing a button.
|
||||
* Touchscreen Events:: Tapping and moving fingers on a touchscreen.
|
||||
* Focus Events:: Moving the mouse between frames.
|
||||
* Xwidget Events:: Events generated by xwidgets.
|
||||
* Misc Events:: Other events the system can generate.
|
||||
|
|
@ -1835,6 +1836,60 @@ small movements. Otherwise, motion events are not generated as long
|
|||
as the mouse cursor remains pointing to the same glyph in the text.
|
||||
@end defvar
|
||||
|
||||
@node Touchscreen Events
|
||||
@subsection Touchscreen Events
|
||||
@cindex touchscreen events
|
||||
@cindex support for touchscreens
|
||||
|
||||
Some window systems provide support for input devices that react to
|
||||
the user's finger, and translate those finger movements into points at
|
||||
an on-screen position. These input devices are known as touchscreens,
|
||||
and Emacs reports the movements they generate as @dfn{touchscreen
|
||||
events}.
|
||||
|
||||
Most individual events generated by a touchscreen only have meaning as
|
||||
part of a larger sequence of other events: for instance, the simple
|
||||
operation of tapping the touchscreen involves the user placing and
|
||||
releasing a finger on the touchscreen, and swiping the display to
|
||||
scroll it involves placing a finger, moving it many times upwards or
|
||||
downwards, and then releasing the finger.
|
||||
|
||||
While a simplistic model consisting of one finger is adequate for taps
|
||||
and scrolling, more complicated gestures require support for keeping
|
||||
track of multiple fingers, where the position of each finger is
|
||||
represented by a @dfn{touch point}. For example, a ``pinch to zoom''
|
||||
gesture might consist of the user placing two fingers and moving them
|
||||
individually in opposite directions, where the distance between the
|
||||
positions of their individual points determine the amount by which to
|
||||
zoom the display, and the center of an imaginary line between those
|
||||
positions determines where to pan the display after zooming.
|
||||
|
||||
@cindex touch point representation
|
||||
The low-level touchscreen events described below can be used to
|
||||
implement all the touch sequences described above. In those events,
|
||||
each point is represented by a cons of an arbitrary number identifying
|
||||
the point and a mouse position list (@pxref{Click Events}) specifying
|
||||
the position of the finger when the event occurred.
|
||||
|
||||
@table @code
|
||||
@cindex @code{touchscreen-begin} event
|
||||
@item (touchscreen-begin @var{point})
|
||||
This event is sent when @var{point} is created by the user pressing a
|
||||
finger against the touchscreen.
|
||||
|
||||
@cindex @code{touchscreen-update} event
|
||||
@item (touchscreen-update @var{points})
|
||||
This event is sent when an point on the touchscreen has changed
|
||||
position. @var{points} is a list of touchpoints containing the
|
||||
up-to-date positions of each touchpoint currently on the touchscreen.
|
||||
|
||||
@cindex @code{touchscreen-end} event
|
||||
@item (touchscreen-end @var{point})
|
||||
This event is sent when @var{point} is no longer present on the
|
||||
display, because another program took the grab, or because the user
|
||||
released the finger.
|
||||
@end table
|
||||
|
||||
@node Focus Events
|
||||
@subsection Focus Events
|
||||
@cindex focus event
|
||||
|
|
|
|||
|
|
@ -1352,7 +1352,7 @@ may change as higher-resolution clocks become available.
|
|||
|
||||
@cindex time value
|
||||
Function arguments, e.g., the @var{time} argument to
|
||||
@code{current-time-string}, accept a more-general @dfn{time value}
|
||||
@code{format-time-string}, accept a more-general @dfn{time value}
|
||||
format, which can be a Lisp timestamp, @code{nil} for the current
|
||||
time, a single floating-point number for seconds, or a list
|
||||
@code{(@var{high} @var{low} @var{micro})} or @code{(@var{high}
|
||||
|
|
@ -1507,10 +1507,7 @@ The optional @var{form} argument specifies the timestamp form to be
|
|||
returned. If @var{form} is the symbol @code{integer}, this function
|
||||
returns an integer count of seconds. If @var{form} is a positive
|
||||
integer, it specifies a clock frequency and this function returns an
|
||||
integer-pair timestamp @code{(@var{ticks}
|
||||
. @var{form})}.@footnote{Currently a positive integer @var{form}
|
||||
should be at least 65536 if the returned value is intended to be given
|
||||
to standard functions expecting Lisp timestamps.} If @var{form} is
|
||||
integer-pair timestamp @code{(@var{ticks} . @var{form})}. If @var{form} is
|
||||
@code{t}, this function treats it as a positive integer suitable for
|
||||
representing the timestamp; for example, it is treated as 1000000000
|
||||
if @var{time} is nil and the platform timestamp has nanosecond
|
||||
|
|
|
|||
12
etc/NEWS
12
etc/NEWS
|
|
@ -1151,11 +1151,23 @@ cookies set by web pages on disk.
|
|||
** New variable 'help-buffer-under-preparation'.
|
||||
This variable is bound to t during the preparation of a "*Help*" buffer.
|
||||
|
||||
+++
|
||||
** Timestamps like (1 . 1000) now work without warnings being generated.
|
||||
For example, (time-add nil '(1 . 1000)) no longer warns that the
|
||||
(1 . 1000) acts like (1000 . 1000000). This warning, which was a
|
||||
temporary transition aid for Emacs 27, has served its purpose.
|
||||
|
||||
+++
|
||||
** 'date-to-time' now assumes earliest values if its argument lacks
|
||||
month, day, or time. For example, (date-to-time "2021-12-04") now
|
||||
assumes a time of 00:00 instead of signaling an error.
|
||||
|
||||
+++
|
||||
** New events for taking advantage of touchscreen devices.
|
||||
The events 'touchscreen-down', 'touchscreen-update' and
|
||||
'touchscreen-end' have been added to take better advantage of
|
||||
touch-capable display panels.
|
||||
|
||||
|
||||
* Changes in Emacs 29.1 on Non-Free Operating Systems
|
||||
|
||||
|
|
|
|||
|
|
@ -617,12 +617,8 @@ OLDMODE will be modified accordingly just like chmod(2) would have done."
|
|||
|
||||
(defun archive-unixdate (low high)
|
||||
"Stringify Unix (LOW HIGH) date."
|
||||
(let* ((time (list high low))
|
||||
(str (current-time-string time)))
|
||||
(format "%s-%s-%s"
|
||||
(substring str 8 10)
|
||||
(substring str 4 7)
|
||||
(format-time-string "%Y" time))))
|
||||
(let ((system-time-locale "C"))
|
||||
(format-time-string "%e-%b-%Y" (list high low))))
|
||||
|
||||
(defun archive-unixtime (low high)
|
||||
"Stringify Unix (LOW HIGH) time."
|
||||
|
|
|
|||
|
|
@ -645,10 +645,10 @@ FIXME: multiple comma-separated values should be allowed!"
|
|||
(setq second (read (substring isodatetimestring 13 15))))
|
||||
;; FIXME: Support subseconds.
|
||||
(when (> (length isodatetimestring) 15)
|
||||
(cl-case (aref isodatetimestring 15)
|
||||
(pcase (aref isodatetimestring 15)
|
||||
(?Z
|
||||
(setq source-zone t))
|
||||
((?- ?+)
|
||||
((or ?- ?+)
|
||||
(setq source-zone
|
||||
(concat "UTC" (substring isodatetimestring 15))))))
|
||||
;; shift if necessary
|
||||
|
|
|
|||
|
|
@ -295,12 +295,12 @@ enough, since keyservers have strict timeout settings."
|
|||
:created
|
||||
(and (match-string 4)
|
||||
(not (string-empty-p (match-string 4)))
|
||||
(seconds-to-time
|
||||
(time-convert
|
||||
(string-to-number (match-string 4))))
|
||||
:expires
|
||||
(and (match-string 5)
|
||||
(not (string-empty-p (match-string 5)))
|
||||
(seconds-to-time
|
||||
(time-convert
|
||||
(string-to-number (match-string 5))))
|
||||
:flags
|
||||
(mapcar (lambda (flag)
|
||||
|
|
@ -319,15 +319,11 @@ enough, since keyservers have strict timeout settings."
|
|||
:created
|
||||
(and (match-string 2)
|
||||
(not (string-empty-p (match-string 2)))
|
||||
(decode-time (seconds-to-time
|
||||
(string-to-number
|
||||
(match-string 2)))))
|
||||
(decode-time (string-to-number (match-string 2))))
|
||||
:expires
|
||||
(and (match-string 3)
|
||||
(not (string-empty-p (match-string 3)))
|
||||
(decode-time (seconds-to-time
|
||||
(string-to-number
|
||||
(match-string 3)))))
|
||||
(decode-time (string-to-number (match-string 3))))
|
||||
:flags
|
||||
(mapcar (lambda (flag)
|
||||
(cdr (assq flag '((?r revoked)
|
||||
|
|
|
|||
|
|
@ -578,7 +578,7 @@ REL-DATE, or (current-time) if REL-DATE is nil."
|
|||
(seq-subseq
|
||||
(decode-time
|
||||
(time-subtract
|
||||
(apply #'encode-time now)
|
||||
(encode-time now)
|
||||
(days-to-time
|
||||
(* (string-to-number (match-string 1 value))
|
||||
(cdr (assoc (match-string 2 value)
|
||||
|
|
@ -597,7 +597,7 @@ REL-DATE, or (current-time) if REL-DATE is nil."
|
|||
;; If DOW is given, handle that specially.
|
||||
(if (and (seq-elt d-time 6) (null (seq-elt d-time 3)))
|
||||
(decode-time
|
||||
(time-subtract (apply #'encode-time now)
|
||||
(time-subtract (encode-time now)
|
||||
(days-to-time
|
||||
(+ (if (> (seq-elt d-time 6)
|
||||
(seq-elt now 6))
|
||||
|
|
@ -1257,9 +1257,7 @@ elements are present."
|
|||
(setq dmonth 1))))
|
||||
(format-time-string
|
||||
"%e-%b-%Y"
|
||||
(apply #'encode-time
|
||||
(append '(0 0 0)
|
||||
(list dday dmonth dyear))))))
|
||||
(encode-time 0 0 0 dday dmonth dyear))))
|
||||
|
||||
(cl-defmethod gnus-search-imap-handle-string ((engine gnus-search-imap)
|
||||
(str string))
|
||||
|
|
|
|||
|
|
@ -1308,7 +1308,7 @@ all. This may very well take some time.")
|
|||
(let ((minute (nndiary-max (nth 0 sched)))
|
||||
(hour (nndiary-max (nth 1 sched)))
|
||||
(year (nndiary-max (nth 4 sched)))
|
||||
(time-zone (or (and (nth 6 sched) (car (nth 6 sched)))
|
||||
(time-zone (or (car (nth 6 sched))
|
||||
(current-time-zone))))
|
||||
(when year
|
||||
(or minute (setq minute 59))
|
||||
|
|
@ -1405,7 +1405,7 @@ all. This may very well take some time.")
|
|||
t))
|
||||
(dow-list (nth 5 sched))
|
||||
(year (1- this-year))
|
||||
(time-zone (or (and (nth 6 sched) (car (nth 6 sched)))
|
||||
(time-zone (or (car (nth 6 sched))
|
||||
(current-time-zone))))
|
||||
;; Special case: an asterisk in one of the days specifications means that
|
||||
;; only the other should be taken into account. If both are unspecified,
|
||||
|
|
|
|||
|
|
@ -450,7 +450,7 @@ nnrss: %s: Not valid XML %s and libxml-parse-html-region doesn't work %s"
|
|||
This function handles the ISO 8601 date format described in
|
||||
URL `https://www.w3.org/TR/NOTE-datetime', and also the RFC 822 style
|
||||
which RSS 2.0 allows."
|
||||
(let (case-fold-search vector year month day time zone cts given)
|
||||
(let (case-fold-search vector year month day time zone given)
|
||||
(cond ((null date)) ; do nothing for this case
|
||||
;; if the date is just digits (unix time stamp):
|
||||
((string-match "^[0-9]+$" date)
|
||||
|
|
@ -481,13 +481,13 @@ which RSS 2.0 allows."
|
|||
0
|
||||
(decoded-time-zone decoded))))))
|
||||
(if month
|
||||
(progn
|
||||
(setq cts (current-time-string (encode-time 0 0 0 day month year)))
|
||||
(format "%s, %02d %s %04d %s%s"
|
||||
(substring cts 0 3) day (substring cts 4 7) year time
|
||||
(if zone
|
||||
(concat " " (format-time-string "%z" nil zone))
|
||||
"")))
|
||||
(concat (let ((system-time-locale "C"))
|
||||
(format-time-string "%a, %d %b %Y "
|
||||
(encode-time 0 0 0 day month year)))
|
||||
time
|
||||
(if zone
|
||||
(format-time-string " %z" nil zone)
|
||||
""))
|
||||
(message-make-date given))))
|
||||
|
||||
;;; data functions
|
||||
|
|
|
|||
|
|
@ -718,10 +718,9 @@ representing leap seconds."
|
|||
second)
|
||||
minute hour day month year second-fraction datatype time-zone)
|
||||
(let ((time
|
||||
(apply
|
||||
#'encode-time (list
|
||||
(if new-decode-time new-decode-time-second second)
|
||||
minute hour day month year nil nil time-zone))))
|
||||
(encode-time (list
|
||||
(if new-decode-time new-decode-time-second second)
|
||||
minute hour day month year nil nil time-zone))))
|
||||
(if new-decode-time
|
||||
(with-no-warnings (decode-time time nil t))
|
||||
(decode-time time))))))
|
||||
|
|
|
|||
|
|
@ -416,9 +416,9 @@ Emacs dired can't find files."
|
|||
"Sort \"ls\" output by time, descending."
|
||||
(let (time-a time-b)
|
||||
(string-match tramp-adb-ls-date-regexp a)
|
||||
(setq time-a (apply #'encode-time (parse-time-string (match-string 0 a))))
|
||||
(setq time-a (encode-time (parse-time-string (match-string 0 a))))
|
||||
(string-match tramp-adb-ls-date-regexp b)
|
||||
(setq time-b (apply #'encode-time (parse-time-string (match-string 0 b))))
|
||||
(setq time-b (encode-time (parse-time-string (match-string 0 b))))
|
||||
(time-less-p time-b time-a)))
|
||||
|
||||
(defun tramp-adb-ls-output-name-less-p (a b)
|
||||
|
|
|
|||
|
|
@ -1575,7 +1575,7 @@ non-nil."
|
|||
(setq link
|
||||
(format-time-string
|
||||
(car org-time-stamp-formats)
|
||||
(apply 'encode-time
|
||||
(encode-time
|
||||
(list 0 0 0 (nth 1 cd) (nth 0 cd) (nth 2 cd)
|
||||
nil nil nil))))
|
||||
(org-link-store-props :type "calendar" :date cd)))
|
||||
|
|
|
|||
|
|
@ -1904,11 +1904,11 @@ PROPNAME lets you set a custom text property instead of :org-clock-minutes."
|
|||
((match-end 2)
|
||||
;; Two time stamps.
|
||||
(let* ((ts (float-time
|
||||
(apply #'encode-time
|
||||
(encode-time
|
||||
(save-match-data
|
||||
(org-parse-time-string (match-string 2))))))
|
||||
(te (float-time
|
||||
(apply #'encode-time
|
||||
(encode-time
|
||||
(org-parse-time-string (match-string 3)))))
|
||||
(dt (- (if tend (min te tend) te)
|
||||
(if tstart (max ts tstart) ts))))
|
||||
|
|
@ -2837,7 +2837,7 @@ a number of clock tables."
|
|||
(pcase (if range (car range) (plist-get params :tstart))
|
||||
((and (pred numberp) n)
|
||||
(pcase-let ((`(,m ,d ,y) (calendar-gregorian-from-absolute n)))
|
||||
(apply #'encode-time (list 0 0 org-extend-today-until d m y))))
|
||||
(encode-time 0 0 org-extend-today-until d m y)))
|
||||
(timestamp
|
||||
(seconds-to-time
|
||||
(org-matcher-time (or timestamp
|
||||
|
|
@ -2847,7 +2847,7 @@ a number of clock tables."
|
|||
(pcase (if range (nth 1 range) (plist-get params :tend))
|
||||
((and (pred numberp) n)
|
||||
(pcase-let ((`(,m ,d ,y) (calendar-gregorian-from-absolute n)))
|
||||
(apply #'encode-time (list 0 0 org-extend-today-until d m y))))
|
||||
(encode-time 0 0 org-extend-today-until d m y)))
|
||||
(timestamp (seconds-to-time (org-matcher-time timestamp))))))
|
||||
(while (time-less-p start end)
|
||||
(unless (bolp) (insert "\n"))
|
||||
|
|
@ -3042,9 +3042,9 @@ Otherwise, return nil."
|
|||
(setq ts (match-string 1)
|
||||
te (match-string 3))
|
||||
(setq s (- (float-time
|
||||
(apply #'encode-time (org-parse-time-string te)))
|
||||
(encode-time (org-parse-time-string te)))
|
||||
(float-time
|
||||
(apply #'encode-time (org-parse-time-string ts))))
|
||||
(encode-time (org-parse-time-string ts))))
|
||||
neg (< s 0)
|
||||
s (abs s)
|
||||
h (floor (/ s 3600))
|
||||
|
|
|
|||
|
|
@ -782,7 +782,7 @@ around it."
|
|||
(setq time-after (copy-sequence time))
|
||||
(setf (nth 3 time-before) (1- (nth 3 time)))
|
||||
(setf (nth 3 time-after) (1+ (nth 3 time)))
|
||||
(mapcar (lambda (x) (format-time-string fmt (apply #'encode-time x)))
|
||||
(mapcar (lambda (x) (format-time-string fmt (encode-time x)))
|
||||
(list time-before time time-after)))))
|
||||
|
||||
(defun org-columns-open-link (&optional arg)
|
||||
|
|
|
|||
|
|
@ -378,7 +378,7 @@ Return value as a string."
|
|||
(buffer-substring
|
||||
(point) (line-end-position)))))
|
||||
(when (cl-some #'identity time)
|
||||
(setq date (apply #'encode-time time))))))))
|
||||
(setq date (encode-time time))))))))
|
||||
(let ((proc (get-buffer-process buf)))
|
||||
(while (and proc (accept-process-output proc .5 nil t)))))
|
||||
(kill-buffer buf))
|
||||
|
|
|
|||
|
|
@ -1185,7 +1185,7 @@ nil, just return 0."
|
|||
((numberp s) s)
|
||||
((stringp s)
|
||||
(condition-case nil
|
||||
(float-time (apply #'encode-time (org-parse-time-string s)))
|
||||
(float-time (encode-time (org-parse-time-string s)))
|
||||
(error 0)))
|
||||
(t 0)))
|
||||
|
||||
|
|
@ -1252,7 +1252,7 @@ following special strings: \"<now>\", \"<today>\",
|
|||
\"<tomorrow>\", and \"<yesterday>\".
|
||||
|
||||
Return 0. if S is not recognized as a valid value."
|
||||
(let ((today (float-time (apply #'encode-time
|
||||
(let ((today (float-time (encode-time
|
||||
(append '(0 0 0) (nthcdr 3 (decode-time)))))))
|
||||
(save-match-data
|
||||
(cond
|
||||
|
|
|
|||
|
|
@ -2606,7 +2606,7 @@ location of point."
|
|||
(format-time-string
|
||||
(org-time-stamp-format
|
||||
(string-match-p "[0-9]\\{1,2\\}:[0-9]\\{2\\}" ts))
|
||||
(apply #'encode-time
|
||||
(encode-time
|
||||
(save-match-data (org-parse-time-string ts))))))
|
||||
form t t))
|
||||
|
||||
|
|
|
|||
|
|
@ -13987,7 +13987,7 @@ user."
|
|||
(when (< (nth 2 org-defdecode) org-extend-today-until)
|
||||
(setf (nth 2 org-defdecode) -1)
|
||||
(setf (nth 1 org-defdecode) 59)
|
||||
(setq org-def (apply #'encode-time org-defdecode))
|
||||
(setq org-def (encode-time org-defdecode))
|
||||
(setq org-defdecode (decode-time org-def)))
|
||||
(let* ((timestr (format-time-string
|
||||
(if org-with-time "%Y-%m-%d %H:%M" "%Y-%m-%d")
|
||||
|
|
@ -14471,7 +14471,7 @@ The command returns the inserted time stamp."
|
|||
time (org-fix-decoded-time t1)
|
||||
str (org-add-props
|
||||
(format-time-string
|
||||
(substring tf 1 -1) (apply 'encode-time time))
|
||||
(substring tf 1 -1) (encode-time time))
|
||||
nil 'mouse-face 'highlight))
|
||||
(put-text-property beg end 'display str)))
|
||||
|
||||
|
|
@ -14726,7 +14726,7 @@ days in order to avoid rounding problems."
|
|||
|
||||
(defun org-time-string-to-time (s)
|
||||
"Convert timestamp string S into internal time."
|
||||
(apply #'encode-time (org-parse-time-string s)))
|
||||
(encode-time (org-parse-time-string s)))
|
||||
|
||||
(defun org-time-string-to-seconds (s)
|
||||
"Convert a timestamp string S into a number of seconds."
|
||||
|
|
@ -15156,7 +15156,7 @@ When SUPPRESS-TMP-DELAY is non-nil, suppress delays like
|
|||
(setcar time0 (or (car time0) 0))
|
||||
(setcar (nthcdr 1 time0) (or (nth 1 time0) 0))
|
||||
(setcar (nthcdr 2 time0) (or (nth 2 time0) 0))
|
||||
(setq time (apply 'encode-time time0))))
|
||||
(setq time (encode-time time0))))
|
||||
;; Insert the new time-stamp, and ensure point stays in the same
|
||||
;; category as before (i.e. not after the last position in that
|
||||
;; category).
|
||||
|
|
|
|||
|
|
@ -824,8 +824,7 @@ as a communication channel."
|
|||
(if (not (plist-get info :with-author)) ""
|
||||
(org-export-data (plist-get info :author) info))
|
||||
;; Timezone.
|
||||
(if (org-string-nw-p org-icalendar-timezone) org-icalendar-timezone
|
||||
(cadr (current-time-zone)))
|
||||
(or (org-string-nw-p org-icalendar-timezone) (format-time-string "%Z"))
|
||||
;; Description.
|
||||
(org-export-data (plist-get info :title) info)
|
||||
contents))
|
||||
|
|
@ -972,7 +971,7 @@ This function assumes major mode for current buffer is
|
|||
(org-icalendar--vcalendar
|
||||
org-icalendar-combined-name
|
||||
user-full-name
|
||||
(or (org-string-nw-p org-icalendar-timezone) (cadr (current-time-zone)))
|
||||
(or (org-string-nw-p org-icalendar-timezone) (format-time-string "%Z"))
|
||||
org-icalendar-combined-description
|
||||
contents)))
|
||||
(run-hook-with-args 'org-icalendar-after-save-hook file)))
|
||||
|
|
@ -995,7 +994,7 @@ FILES is a list of files to build the calendar from."
|
|||
user-full-name
|
||||
;; Timezone.
|
||||
(or (org-string-nw-p org-icalendar-timezone)
|
||||
(cadr (current-time-zone)))
|
||||
(format-time-string "Z"))
|
||||
;; Description.
|
||||
org-icalendar-combined-description
|
||||
;; Contents.
|
||||
|
|
|
|||
|
|
@ -1175,6 +1175,7 @@ displayed."
|
|||
(derived-mode . dired-mode)
|
||||
(derived-mode . diff-mode)
|
||||
(derived-mode . comint-mode)
|
||||
(derived-mode . eshell-mode)
|
||||
(derived-mode . change-log-mode))
|
||||
"List of conditions to kill buffers related to a project.
|
||||
This list is used by `project-kill-buffers'.
|
||||
|
|
|
|||
|
|
@ -467,8 +467,8 @@ checksum before doing the check."
|
|||
|
||||
(defun tar-clip-time-string (time)
|
||||
(declare (obsolete format-time-string "27.1"))
|
||||
(let ((str (current-time-string time)))
|
||||
(concat " " (substring str 4 16) (format-time-string " %Y" time))))
|
||||
(let ((system-time-locale "C"))
|
||||
(format-time-string " %b %e %H:%M %Y" time)))
|
||||
|
||||
(defun tar-grind-file-mode (mode)
|
||||
"Construct a `rw-r--r--' string indicating MODE.
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ update which can wait for the next redisplay."
|
|||
(am-pm (if (>= hour 12) "pm" "am"))
|
||||
(minutes (substring time 14 16))
|
||||
(seconds (substring time 17 19))
|
||||
(time-zone (car (cdr (current-time-zone now))))
|
||||
(time-zone (format-time-string "%Z" now))
|
||||
(day (substring time 8 10))
|
||||
(year (format-time-string "%Y" now))
|
||||
(monthname (substring time 4 7))
|
||||
|
|
|
|||
|
|
@ -299,11 +299,10 @@ Return a list in the same format as `current-time-zone's result,
|
|||
or nil if the local time zone could not be computed.
|
||||
DATE is the number of days elapsed since the (imaginary)
|
||||
Gregorian date Sunday, December 31, 1 BC."
|
||||
(and (fboundp 'current-time-zone)
|
||||
(let ((utc-time (timezone-time-from-absolute date seconds)))
|
||||
(and utc-time
|
||||
(let ((zone (current-time-zone utc-time)))
|
||||
(and (car zone) zone))))))
|
||||
(let ((utc-time (timezone-time-from-absolute date seconds)))
|
||||
(and utc-time
|
||||
(let ((zone (current-time-zone utc-time)))
|
||||
(and (car zone) zone)))))
|
||||
|
||||
(defun timezone-fix-time (date local timezone)
|
||||
"Convert DATE (default timezone LOCAL) to YYYY-MM-DD-HH-MM-SS-ZONE vector.
|
||||
|
|
|
|||
|
|
@ -127,8 +127,12 @@ preserve the setting."
|
|||
:group 'vc)
|
||||
|
||||
(defcustom vc-command-messages nil
|
||||
"If non-nil, display run messages from back-end commands."
|
||||
:type 'boolean
|
||||
"If non-nil, display and log messages about running back-end commands.
|
||||
If the value is `log', messages about running VC back-end commands are
|
||||
logged in the *Messages* buffer, but not displayed."
|
||||
:type '(choice (const :tag "No messages" nil)
|
||||
(const :tag "Display and log messages" t)
|
||||
(const :tag "Log messages, but don't display" log))
|
||||
:group 'vc)
|
||||
|
||||
(defcustom vc-suppress-confirm nil
|
||||
|
|
@ -311,7 +315,10 @@ case, and the process object in the asynchronous case."
|
|||
(substring command 0 -1)
|
||||
command)
|
||||
" " (vc-delistify flags)
|
||||
" " (vc-delistify files))))
|
||||
" " (vc-delistify files)))
|
||||
(vc-inhibit-message
|
||||
(or (eq vc-command-messages 'log)
|
||||
(eq (selected-window) (active-minibuffer-window)))))
|
||||
(save-current-buffer
|
||||
(unless (or (eq buffer t)
|
||||
(and (stringp buffer)
|
||||
|
|
@ -335,7 +342,7 @@ case, and the process object in the asynchronous case."
|
|||
(apply #'start-file-process command (current-buffer)
|
||||
command squeezed))))
|
||||
(when vc-command-messages
|
||||
(let ((inhibit-message (eq (selected-window) (active-minibuffer-window))))
|
||||
(let ((inhibit-message vc-inhibit-message))
|
||||
(message "Running in background: %s" full-command)))
|
||||
;; Get rid of the default message insertion, in case we don't
|
||||
;; set a sentinel explicitly.
|
||||
|
|
@ -345,11 +352,11 @@ case, and the process object in the asynchronous case."
|
|||
(when vc-command-messages
|
||||
(vc-run-delayed
|
||||
(let ((message-truncate-lines t)
|
||||
(inhibit-message (eq (selected-window) (active-minibuffer-window))))
|
||||
(inhibit-message vc-inhibit-message))
|
||||
(message "Done in background: %s" full-command)))))
|
||||
;; Run synchronously
|
||||
(when vc-command-messages
|
||||
(let ((inhibit-message (eq (selected-window) (active-minibuffer-window))))
|
||||
(let ((inhibit-message vc-inhibit-message))
|
||||
(message "Running in foreground: %s" full-command)))
|
||||
(let ((buffer-undo-list t))
|
||||
(setq status (apply #'process-file command nil t nil squeezed)))
|
||||
|
|
@ -364,7 +371,7 @@ case, and the process object in the asynchronous case."
|
|||
(if (integerp status) (format "status %d" status) status)
|
||||
full-command))
|
||||
(when vc-command-messages
|
||||
(let ((inhibit-message (eq (selected-window) (active-minibuffer-window))))
|
||||
(let ((inhibit-message vc-inhibit-message))
|
||||
(message "Done (status=%d): %s" status full-command)))))
|
||||
(vc-run-delayed
|
||||
(run-hook-with-args 'vc-post-command-functions
|
||||
|
|
|
|||
|
|
@ -6013,6 +6013,46 @@ make_lispy_event (struct input_event *event)
|
|||
return list2 (Qtouch_end, position);
|
||||
}
|
||||
|
||||
case TOUCHSCREEN_BEGIN_EVENT:
|
||||
case TOUCHSCREEN_END_EVENT:
|
||||
{
|
||||
Lisp_Object x, y, id, position;
|
||||
struct frame *f = XFRAME (event->frame_or_window);
|
||||
|
||||
id = event->arg;
|
||||
x = event->x;
|
||||
y = event->y;
|
||||
|
||||
position = make_lispy_position (f, x, y, event->timestamp);
|
||||
|
||||
return list2 (((event->kind
|
||||
== TOUCHSCREEN_BEGIN_EVENT)
|
||||
? Qtouchscreen_begin
|
||||
: Qtouchscreen_end),
|
||||
Fcons (id, position));
|
||||
}
|
||||
|
||||
case TOUCHSCREEN_UPDATE_EVENT:
|
||||
{
|
||||
Lisp_Object x, y, id, position, tem, it, evt;
|
||||
struct frame *f = XFRAME (event->frame_or_window);
|
||||
evt = Qnil;
|
||||
|
||||
for (tem = event->arg; CONSP (tem); tem = XCDR (tem))
|
||||
{
|
||||
it = XCAR (tem);
|
||||
|
||||
x = XCAR (it);
|
||||
y = XCAR (XCDR (it));
|
||||
id = XCAR (XCDR (XCDR (it)));
|
||||
|
||||
position = make_lispy_position (f, x, y, event->timestamp);
|
||||
evt = Fcons (Fcons (id, position), evt);
|
||||
}
|
||||
|
||||
return list2 (Qtouchscreen_update, evt);
|
||||
}
|
||||
|
||||
#ifdef USE_TOOLKIT_SCROLL_BARS
|
||||
|
||||
/* We don't have down and up events if using toolkit scroll bars,
|
||||
|
|
@ -12266,6 +12306,9 @@ See also `pre-command-hook'. */);
|
|||
doc: /* Normal hook run when clearing the echo area. */);
|
||||
#endif
|
||||
DEFSYM (Qecho_area_clear_hook, "echo-area-clear-hook");
|
||||
DEFSYM (Qtouchscreen_begin, "touchscreen-begin");
|
||||
DEFSYM (Qtouchscreen_end, "touchscreen-end");
|
||||
DEFSYM (Qtouchscreen_update, "touchscreen-update");
|
||||
Fset (Qecho_area_clear_hook, Qnil);
|
||||
|
||||
DEFVAR_LISP ("lucid-menu-bar-dirty-flag", Vlucid_menu_bar_dirty_flag,
|
||||
|
|
|
|||
|
|
@ -80,8 +80,7 @@ struct lisp_time
|
|||
/* Clock count as a Lisp integer. */
|
||||
Lisp_Object ticks;
|
||||
|
||||
/* Clock frequency (ticks per second) as a positive Lisp integer.
|
||||
(TICKS . HZ) is a valid Lisp timestamp unless HZ < 65536. */
|
||||
/* Clock frequency (ticks per second) as a positive Lisp integer. */
|
||||
Lisp_Object hz;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -280,6 +280,19 @@ enum event_kind
|
|||
In the future, this may take into account other multi-touch
|
||||
events generated from touchscreens and such. */
|
||||
, TOUCH_END_EVENT
|
||||
|
||||
/* In a TOUCHSCREEN_UPDATE_EVENT, ARG is a list of elements of the
|
||||
form (X Y ID), where X and Y are the coordinates of the
|
||||
touchpoint relative to the top-left corner of the frame, and ID
|
||||
is a unique number identifying the touchpoint.
|
||||
|
||||
In TOUCHSCREEN_BEGIN_EVENT and TOUCHSCREEN_END_EVENT, ARG is the
|
||||
unique ID of the touchpoint, and X and Y are the frame-relative
|
||||
positions of the touchpoint. */
|
||||
|
||||
, TOUCHSCREEN_UPDATE_EVENT
|
||||
, TOUCHSCREEN_BEGIN_EVENT
|
||||
, TOUCHSCREEN_END_EVENT
|
||||
};
|
||||
|
||||
/* Bit width of an enum event_kind tag at the start of structs and unions. */
|
||||
|
|
|
|||
|
|
@ -69,16 +69,6 @@ enum { TM_YEAR_BASE = 1900 };
|
|||
# define FASTER_TIMEFNS 1
|
||||
#endif
|
||||
|
||||
/* Whether to warn about Lisp timestamps (TICKS . HZ) that may be
|
||||
instances of obsolete-format timestamps (HI . LO) where HI is
|
||||
the high-order bits and LO the low-order 16 bits. Currently this
|
||||
is true, but it should change to false in a future version of
|
||||
Emacs. Compile with -DWARN_OBSOLETE_TIMESTAMPS=0 to see what the
|
||||
future will be like. */
|
||||
#ifndef WARN_OBSOLETE_TIMESTAMPS
|
||||
enum { WARN_OBSOLETE_TIMESTAMPS = true };
|
||||
#endif
|
||||
|
||||
/* Although current-time etc. generate list-format timestamps
|
||||
(HI LO US PS), the plan is to change these functions to generate
|
||||
frequency-based timestamps (TICKS . HZ) in a future release.
|
||||
|
|
@ -817,14 +807,10 @@ decode_time_components (enum timeform form,
|
|||
return decode_ticks_hz (make_integer_mpz (), hz, result, dresult);
|
||||
}
|
||||
|
||||
enum { DECODE_SECS_ONLY = WARN_OBSOLETE_TIMESTAMPS + 1 };
|
||||
|
||||
/* Decode a Lisp timestamp SPECIFIED_TIME that represents a time.
|
||||
|
||||
FLAGS specifies conversion flags. If FLAGS & DECODE_SECS_ONLY,
|
||||
ignore and do not validate any sub-second components of an
|
||||
old-format SPECIFIED_TIME. If FLAGS & WARN_OBSOLETE_TIMESTAMPS,
|
||||
diagnose what could be obsolete (HIGH . LOW) timestamps.
|
||||
If DECODE_SECS_ONLY, ignore and do not validate any sub-second
|
||||
components of an old-format SPECIFIED_TIME.
|
||||
|
||||
If RESULT is not null, store into *RESULT the converted time;
|
||||
otherwise, store into *DRESULT the number of seconds since the
|
||||
|
|
@ -833,7 +819,7 @@ enum { DECODE_SECS_ONLY = WARN_OBSOLETE_TIMESTAMPS + 1 };
|
|||
|
||||
Return the form of SPECIFIED-TIME. Signal an error if unsuccessful. */
|
||||
static enum timeform
|
||||
decode_lisp_time (Lisp_Object specified_time, int flags,
|
||||
decode_lisp_time (Lisp_Object specified_time, bool decode_secs_only,
|
||||
struct lisp_time *result, double *dresult)
|
||||
{
|
||||
Lisp_Object high = make_fixnum (0);
|
||||
|
|
@ -854,7 +840,7 @@ decode_lisp_time (Lisp_Object specified_time, int flags,
|
|||
{
|
||||
Lisp_Object low_tail = XCDR (low);
|
||||
low = XCAR (low);
|
||||
if (! (flags & DECODE_SECS_ONLY))
|
||||
if (! decode_secs_only)
|
||||
{
|
||||
if (CONSP (low_tail))
|
||||
{
|
||||
|
|
@ -877,9 +863,6 @@ decode_lisp_time (Lisp_Object specified_time, int flags,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (flags & WARN_OBSOLETE_TIMESTAMPS
|
||||
&& RANGED_FIXNUMP (0, low, (1 << LO_TIME_BITS) - 1))
|
||||
message ("obsolete timestamp with cdr %"pI"d", XFIXNUM (low));
|
||||
form = TIMEFORM_TICKS_HZ;
|
||||
}
|
||||
|
||||
|
|
@ -1008,8 +991,7 @@ static struct lisp_time
|
|||
lisp_time_struct (Lisp_Object specified_time, enum timeform *pform)
|
||||
{
|
||||
struct lisp_time t;
|
||||
enum timeform form
|
||||
= decode_lisp_time (specified_time, WARN_OBSOLETE_TIMESTAMPS, &t, 0);
|
||||
enum timeform form = decode_lisp_time (specified_time, false, &t, 0);
|
||||
if (pform)
|
||||
*pform = form;
|
||||
return t;
|
||||
|
|
@ -1034,9 +1016,8 @@ lisp_time_argument (Lisp_Object specified_time)
|
|||
static time_t
|
||||
lisp_seconds_argument (Lisp_Object specified_time)
|
||||
{
|
||||
int flags = WARN_OBSOLETE_TIMESTAMPS | DECODE_SECS_ONLY;
|
||||
struct lisp_time lt;
|
||||
decode_lisp_time (specified_time, flags, <, 0);
|
||||
decode_lisp_time (specified_time, true, <, 0);
|
||||
struct timespec t = lisp_to_timespec (lt);
|
||||
if (! timespec_valid_p (t))
|
||||
time_overflow ();
|
||||
|
|
@ -1138,24 +1119,6 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
|
|||
mpz_t *ihz = &mpz[0];
|
||||
mpz_mul (*ihz, *fa, *db);
|
||||
|
||||
/* When warning about obsolete timestamps, if the smaller
|
||||
denominator comes from a non-(TICKS . HZ) timestamp and could
|
||||
generate a (TICKS . HZ) timestamp that would look obsolete,
|
||||
arrange for the result to have a higher HZ to avoid a
|
||||
spurious warning by a later consumer of this function's
|
||||
returned value. */
|
||||
verify (1 << LO_TIME_BITS <= ULONG_MAX);
|
||||
if (WARN_OBSOLETE_TIMESTAMPS
|
||||
&& (da_lt_db ? aform : bform) == TIMEFORM_FLOAT
|
||||
&& (da_lt_db ? bform : aform) != TIMEFORM_TICKS_HZ
|
||||
&& mpz_cmp_ui (*hzmin, 1) > 0
|
||||
&& mpz_cmp_ui (*hzmin, 1 << LO_TIME_BITS) < 0)
|
||||
{
|
||||
mpz_t *hzmin1 = &mpz[2 - da_lt_db];
|
||||
mpz_set_ui (*hzmin1, 1 << LO_TIME_BITS);
|
||||
hzmin = hzmin1;
|
||||
}
|
||||
|
||||
/* iticks = (fb * na) OP (fa * nb), where OP is + or -. */
|
||||
mpz_t const *na = bignum_integer (iticks, ta.ticks);
|
||||
mpz_mul (*iticks, *fb, *na);
|
||||
|
|
@ -1177,8 +1140,7 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
|
|||
upwards by multiplying the normalized numerator and denominator
|
||||
so that the resulting denominator becomes at least hzmin.
|
||||
This rescaling avoids returning a timestamp that is less precise
|
||||
than both a and b, or a timestamp that looks obsolete when that
|
||||
might be a problem. */
|
||||
than both a and b. */
|
||||
if (!FASTER_TIMEFNS || mpz_cmp (*ihz, *hzmin) < 0)
|
||||
{
|
||||
/* Rescale straightforwardly. Although this might not
|
||||
|
|
@ -1303,7 +1265,7 @@ or (if you need time as a string) `format-time-string'. */)
|
|||
(Lisp_Object specified_time)
|
||||
{
|
||||
double t;
|
||||
decode_lisp_time (specified_time, 0, 0, &t);
|
||||
decode_lisp_time (specified_time, false, 0, &t);
|
||||
return make_float (t);
|
||||
}
|
||||
|
||||
|
|
@ -1651,12 +1613,11 @@ saving flag to be guessed.
|
|||
|
||||
As an obsolescent calling convention, if this function is called with
|
||||
6 or more arguments, the first 6 arguments are SECOND, MINUTE, HOUR,
|
||||
DAY, MONTH, and YEAR, and specify the components of a decoded time,
|
||||
where DST assumed to be -1 and FORM is omitted. If there are more
|
||||
than 6 arguments the *last* argument is used as ZONE and any other
|
||||
extra arguments are ignored, so that (apply #\\='encode-time
|
||||
(decode-time ...)) works. In this obsolescent convention, DST and
|
||||
ZONE default to -1 and nil respectively.
|
||||
DAY, MONTH, and YEAR, and specify the components of a decoded time.
|
||||
If there are more than 6 arguments the *last* argument is used as ZONE
|
||||
and any other extra arguments are ignored, so that (apply
|
||||
#\\='encode-time (decode-time ...)) works. In this obsolescent
|
||||
convention, DST and ZONE default to -1 and nil respectively.
|
||||
|
||||
Years before 1970 are not guaranteed to work. On some systems,
|
||||
year values as low as 1901 do work.
|
||||
|
|
@ -1703,7 +1664,7 @@ usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS) */)
|
|||
|
||||
/* Let SEC = floor (LT.ticks / HZ), with SUBSECTICKS the remainder. */
|
||||
struct lisp_time lt;
|
||||
decode_lisp_time (secarg, 0, <, 0);
|
||||
decode_lisp_time (secarg, false, <, 0);
|
||||
Lisp_Object hz = lt.hz, sec, subsecticks;
|
||||
if (FASTER_TIMEFNS && EQ (hz, make_fixnum (1)))
|
||||
{
|
||||
|
|
@ -1756,9 +1717,7 @@ Truncate the returned value toward minus infinity.
|
|||
If FORM is nil (the default), return the same form as `current-time'.
|
||||
If FORM is a positive integer, return a pair of integers (TICKS . FORM),
|
||||
where TICKS is the number of clock ticks and FORM is the clock frequency
|
||||
in ticks per second. (Currently the positive integer should be at least
|
||||
65536 if the returned value is expected to be given to standard functions
|
||||
expecting Lisp timestamps.) If FORM is t, return (TICKS . PHZ), where
|
||||
in ticks per second. If FORM is t, return (TICKS . PHZ), where
|
||||
PHZ is a suitable clock frequency in ticks per second. If FORM is
|
||||
`integer', return an integer count of seconds. If FORM is `list',
|
||||
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. */)
|
|||
(Lisp_Object time, Lisp_Object form)
|
||||
{
|
||||
struct lisp_time t;
|
||||
enum timeform input_form = decode_lisp_time (time, 0, &t, 0);
|
||||
enum timeform input_form = decode_lisp_time (time, false, &t, 0);
|
||||
if (NILP (form))
|
||||
form = CURRENT_TIME_LIST ? Qlist : Qt;
|
||||
if (EQ (form, Qlist))
|
||||
|
|
|
|||
21
src/xfns.c
21
src/xfns.c
|
|
@ -2916,7 +2916,7 @@ initial_set_up_x_back_buffer (struct frame *f)
|
|||
unblock_input ();
|
||||
}
|
||||
|
||||
#if defined HAVE_XINPUT2 && !defined USE_GTK
|
||||
#if defined HAVE_XINPUT2
|
||||
static void
|
||||
setup_xi_event_mask (struct frame *f)
|
||||
{
|
||||
|
|
@ -2927,6 +2927,9 @@ setup_xi_event_mask (struct frame *f)
|
|||
mask.mask = m = alloca (l);
|
||||
memset (m, 0, l);
|
||||
mask.mask_len = l;
|
||||
|
||||
block_input ();
|
||||
#ifndef USE_GTK
|
||||
mask.deviceid = XIAllMasterDevices;
|
||||
|
||||
XISetMask (m, XI_ButtonPress);
|
||||
|
|
@ -2945,14 +2948,25 @@ setup_xi_event_mask (struct frame *f)
|
|||
&mask, 1);
|
||||
|
||||
memset (m, 0, l);
|
||||
#endif /* !USE_GTK */
|
||||
|
||||
mask.deviceid = XIAllDevices;
|
||||
|
||||
XISetMask (m, XI_PropertyEvent);
|
||||
XISetMask (m, XI_HierarchyChanged);
|
||||
XISetMask (m, XI_DeviceChanged);
|
||||
#ifdef XI_TouchBegin
|
||||
if (FRAME_DISPLAY_INFO (f)->xi2_version >= 2)
|
||||
{
|
||||
XISetMask (m, XI_TouchBegin);
|
||||
XISetMask (m, XI_TouchUpdate);
|
||||
XISetMask (m, XI_TouchEnd);
|
||||
}
|
||||
#endif
|
||||
XISelectEvents (FRAME_X_DISPLAY (f),
|
||||
FRAME_X_WINDOW (f),
|
||||
&mask, 1);
|
||||
unblock_input ();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -3249,6 +3263,11 @@ x_window (struct frame *f)
|
|||
unblock_input ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
if (FRAME_DISPLAY_INFO (f)->supports_xi2)
|
||||
setup_xi_event_mask (f);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /*! USE_GTK */
|
||||
|
|
|
|||
658
src/xterm.c
658
src/xterm.c
|
|
@ -353,6 +353,8 @@ x_extension_initialize (struct x_display_info *dpyinfo)
|
|||
static void
|
||||
x_free_xi_devices (struct x_display_info *dpyinfo)
|
||||
{
|
||||
struct xi_touch_point_t *tem, *last;
|
||||
|
||||
block_input ();
|
||||
|
||||
if (dpyinfo->num_devices)
|
||||
|
|
@ -362,6 +364,14 @@ x_free_xi_devices (struct x_display_info *dpyinfo)
|
|||
XIUngrabDevice (dpyinfo->display, dpyinfo->devices[i].device_id,
|
||||
CurrentTime);
|
||||
xfree (dpyinfo->devices[i].valuators);
|
||||
|
||||
tem = dpyinfo->devices[i].touchpoints;
|
||||
while (tem)
|
||||
{
|
||||
last = tem;
|
||||
tem = tem->next;
|
||||
xfree (last);
|
||||
}
|
||||
}
|
||||
|
||||
xfree (dpyinfo->devices);
|
||||
|
|
@ -407,7 +417,7 @@ x_init_master_valuators (struct x_display_info *dpyinfo)
|
|||
block_input ();
|
||||
x_free_xi_devices (dpyinfo);
|
||||
infos = XIQueryDevice (dpyinfo->display,
|
||||
XIAllMasterDevices,
|
||||
XIAllDevices,
|
||||
&ndevices);
|
||||
|
||||
if (!ndevices)
|
||||
|
|
@ -432,6 +442,10 @@ x_init_master_valuators (struct x_display_info *dpyinfo)
|
|||
xi_device->grab = 0;
|
||||
xi_device->valuators =
|
||||
xmalloc (sizeof *xi_device->valuators * device->num_classes);
|
||||
xi_device->touchpoints = NULL;
|
||||
xi_device->master_p = (device->use == XIMasterKeyboard
|
||||
|| device->use == XIMasterPointer);
|
||||
xi_device->direct_p = false;
|
||||
|
||||
for (int c = 0; c < device->num_classes; ++c)
|
||||
{
|
||||
|
|
@ -442,22 +456,36 @@ x_init_master_valuators (struct x_display_info *dpyinfo)
|
|||
{
|
||||
XIScrollClassInfo *info =
|
||||
(XIScrollClassInfo *) device->classes[c];
|
||||
struct xi_scroll_valuator_t *valuator =
|
||||
&xi_device->valuators[actual_valuator_count++];
|
||||
struct xi_scroll_valuator_t *valuator;
|
||||
|
||||
if (xi_device->master_p)
|
||||
{
|
||||
valuator = &xi_device->valuators[actual_valuator_count++];
|
||||
valuator->horizontal
|
||||
= (info->scroll_type == XIScrollTypeHorizontal);
|
||||
valuator->invalid_p = true;
|
||||
valuator->emacs_value = DBL_MIN;
|
||||
valuator->increment = info->increment;
|
||||
valuator->number = info->number;
|
||||
}
|
||||
|
||||
valuator->horizontal
|
||||
= (info->scroll_type == XIScrollTypeHorizontal);
|
||||
valuator->invalid_p = true;
|
||||
valuator->emacs_value = DBL_MIN;
|
||||
valuator->increment = info->increment;
|
||||
valuator->number = info->number;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef XITouchClass /* XInput 2.2 */
|
||||
case XITouchClass:
|
||||
{
|
||||
XITouchClassInfo *info;
|
||||
|
||||
info = (XITouchClassInfo *) device->classes[c];
|
||||
xi_device->direct_p = info->mode == XIDirectTouch;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
xi_device->scroll_valuator_count = actual_valuator_count;
|
||||
}
|
||||
}
|
||||
|
|
@ -484,7 +512,7 @@ x_get_scroll_valuator_delta (struct x_display_info *dpyinfo, int device_id,
|
|||
{
|
||||
struct xi_device_t *device = &dpyinfo->devices[i];
|
||||
|
||||
if (device->device_id == device_id)
|
||||
if (device->device_id == device_id && device->master_p)
|
||||
{
|
||||
for (int j = 0; j < device->scroll_valuator_count; ++j)
|
||||
{
|
||||
|
|
@ -534,6 +562,61 @@ xi_device_from_id (struct x_display_info *dpyinfo, int deviceid)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef XI_TouchBegin
|
||||
|
||||
static void
|
||||
xi_link_touch_point (struct xi_device_t *device,
|
||||
int detail, double x, double y)
|
||||
{
|
||||
struct xi_touch_point_t *touchpoint;
|
||||
|
||||
touchpoint = xmalloc (sizeof *touchpoint);
|
||||
touchpoint->next = device->touchpoints;
|
||||
touchpoint->x = x;
|
||||
touchpoint->y = y;
|
||||
touchpoint->number = detail;
|
||||
|
||||
device->touchpoints = touchpoint;
|
||||
}
|
||||
|
||||
static void
|
||||
xi_unlink_touch_point (int detail,
|
||||
struct xi_device_t *device)
|
||||
{
|
||||
struct xi_touch_point_t *last, *tem;
|
||||
|
||||
for (last = NULL, tem = device->touchpoints; tem;
|
||||
last = tem, tem = tem->next)
|
||||
{
|
||||
if (tem->number == detail)
|
||||
{
|
||||
if (!last)
|
||||
device->touchpoints = tem->next;
|
||||
else
|
||||
last->next = tem->next;
|
||||
|
||||
xfree (tem);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct xi_touch_point_t *
|
||||
xi_find_touch_point (struct xi_device_t *device, int detail)
|
||||
{
|
||||
struct xi_touch_point_t *point;
|
||||
|
||||
for (point = device->touchpoints; point; point = point->next)
|
||||
{
|
||||
if (point->number == detail)
|
||||
return point;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* XI_TouchBegin */
|
||||
|
||||
static void
|
||||
xi_grab_or_ungrab_device (struct xi_device_t *device,
|
||||
struct x_display_info *dpyinfo,
|
||||
|
|
@ -570,7 +653,7 @@ xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo, int id)
|
|||
struct xi_device_t *device = xi_device_from_id (dpyinfo, id);
|
||||
struct xi_scroll_valuator_t *valuator;
|
||||
|
||||
if (!device)
|
||||
if (!device || !device->master_p)
|
||||
return;
|
||||
|
||||
if (!device->scroll_valuator_count)
|
||||
|
|
@ -9981,242 +10064,250 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
#endif
|
||||
goto XI_OTHER;
|
||||
case XI_Motion:
|
||||
states = &xev->valuators;
|
||||
values = states->values;
|
||||
{
|
||||
struct xi_device_t *device;
|
||||
|
||||
x_display_set_last_user_time (dpyinfo, xi_event->time);
|
||||
|
||||
#ifdef HAVE_XWIDGETS
|
||||
struct xwidget_view *xv = xwidget_view_from_window (xev->event);
|
||||
double xv_total_x = 0.0;
|
||||
double xv_total_y = 0.0;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < states->mask_len * 8; i++)
|
||||
{
|
||||
if (XIMaskIsSet (states->mask, i))
|
||||
{
|
||||
struct xi_scroll_valuator_t *val;
|
||||
double delta, scroll_unit;
|
||||
int scroll_height;
|
||||
Lisp_Object window;
|
||||
|
||||
|
||||
/* See the comment on top of
|
||||
x_init_master_valuators for more details on how
|
||||
scroll wheel movement is reported on XInput 2. */
|
||||
delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid,
|
||||
i, *values, &val);
|
||||
|
||||
if (delta != DBL_MAX)
|
||||
{
|
||||
#ifdef HAVE_XWIDGETS
|
||||
if (xv)
|
||||
{
|
||||
if (val->horizontal)
|
||||
xv_total_x += delta;
|
||||
else
|
||||
xv_total_y += delta;
|
||||
|
||||
found_valuator = true;
|
||||
|
||||
if (delta == 0.0)
|
||||
any_stop_p = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (!f)
|
||||
{
|
||||
f = x_any_window_to_frame (dpyinfo, xev->event);
|
||||
|
||||
if (!f)
|
||||
goto XI_OTHER;
|
||||
}
|
||||
|
||||
found_valuator = true;
|
||||
|
||||
if (signbit (delta) != signbit (val->emacs_value))
|
||||
val->emacs_value = 0;
|
||||
|
||||
val->emacs_value += delta;
|
||||
|
||||
if (mwheel_coalesce_scroll_events
|
||||
&& (fabs (val->emacs_value) < 1)
|
||||
&& (fabs (delta) > 0))
|
||||
continue;
|
||||
|
||||
bool s = signbit (val->emacs_value);
|
||||
inev.ie.kind = (fabs (delta) > 0
|
||||
? (val->horizontal
|
||||
? HORIZ_WHEEL_EVENT
|
||||
: WHEEL_EVENT)
|
||||
: TOUCH_END_EVENT);
|
||||
inev.ie.timestamp = xev->time;
|
||||
|
||||
XSETINT (inev.ie.x, lrint (xev->event_x));
|
||||
XSETINT (inev.ie.y, lrint (xev->event_y));
|
||||
XSETFRAME (inev.ie.frame_or_window, f);
|
||||
|
||||
if (fabs (delta) > 0)
|
||||
{
|
||||
inev.ie.modifiers = !s ? up_modifier : down_modifier;
|
||||
inev.ie.modifiers
|
||||
|= x_x_to_emacs_modifiers (dpyinfo,
|
||||
xev->mods.effective);
|
||||
}
|
||||
|
||||
window = window_from_coordinates (f, xev->event_x,
|
||||
xev->event_y, NULL,
|
||||
false, false);
|
||||
|
||||
if (WINDOWP (window))
|
||||
scroll_height = XWINDOW (window)->pixel_height;
|
||||
else
|
||||
/* EVENT_X and EVENT_Y can be outside the
|
||||
frame if F holds the input grab, so fall
|
||||
back to the height of the frame instead. */
|
||||
scroll_height = FRAME_PIXEL_HEIGHT (f);
|
||||
|
||||
scroll_unit = pow (scroll_height, 2.0 / 3.0);
|
||||
|
||||
if (NUMBERP (Vx_scroll_event_delta_factor))
|
||||
scroll_unit *= XFLOATINT (Vx_scroll_event_delta_factor);
|
||||
|
||||
if (fabs (delta) > 0)
|
||||
{
|
||||
if (val->horizontal)
|
||||
{
|
||||
inev.ie.arg
|
||||
= list3 (Qnil,
|
||||
make_float (val->emacs_value
|
||||
* scroll_unit),
|
||||
make_float (0));
|
||||
}
|
||||
else
|
||||
{
|
||||
inev.ie.arg = list3 (Qnil, make_float (0),
|
||||
make_float (val->emacs_value
|
||||
* scroll_unit));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
inev.ie.arg = Qnil;
|
||||
}
|
||||
|
||||
kbd_buffer_store_event_hold (&inev.ie, hold_quit);
|
||||
|
||||
val->emacs_value = 0;
|
||||
}
|
||||
values++;
|
||||
}
|
||||
|
||||
inev.ie.kind = NO_EVENT;
|
||||
}
|
||||
|
||||
#ifdef HAVE_XWIDGETS
|
||||
if (xv)
|
||||
{
|
||||
if (found_valuator)
|
||||
xwidget_scroll (xv, xev->event_x, xev->event_y,
|
||||
xv_total_x, xv_total_y, xev->mods.effective,
|
||||
xev->time, any_stop_p);
|
||||
else
|
||||
xwidget_motion_notify (xv, xev->event_x, xev->event_y,
|
||||
xev->mods.effective, xev->time);
|
||||
states = &xev->valuators;
|
||||
values = states->values;
|
||||
device = xi_device_from_id (dpyinfo, xev->deviceid);
|
||||
|
||||
if (!device || !device->master_p)
|
||||
goto XI_OTHER;
|
||||
}
|
||||
|
||||
x_display_set_last_user_time (dpyinfo, xi_event->time);
|
||||
|
||||
#ifdef HAVE_XWIDGETS
|
||||
struct xwidget_view *xv = xwidget_view_from_window (xev->event);
|
||||
double xv_total_x = 0.0;
|
||||
double xv_total_y = 0.0;
|
||||
#endif
|
||||
if (found_valuator)
|
||||
goto XI_OTHER;
|
||||
|
||||
ev.x = lrint (xev->event_x);
|
||||
ev.y = lrint (xev->event_y);
|
||||
ev.window = xev->event;
|
||||
ev.time = xev->time;
|
||||
for (int i = 0; i < states->mask_len * 8; i++)
|
||||
{
|
||||
if (XIMaskIsSet (states->mask, i))
|
||||
{
|
||||
struct xi_scroll_valuator_t *val;
|
||||
double delta, scroll_unit;
|
||||
int scroll_height;
|
||||
Lisp_Object window;
|
||||
|
||||
previous_help_echo_string = help_echo_string;
|
||||
help_echo_string = Qnil;
|
||||
|
||||
if (hlinfo->mouse_face_hidden)
|
||||
{
|
||||
hlinfo->mouse_face_hidden = false;
|
||||
clear_mouse_face (hlinfo);
|
||||
}
|
||||
/* See the comment on top of
|
||||
x_init_master_valuators for more details on how
|
||||
scroll wheel movement is reported on XInput 2. */
|
||||
delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid,
|
||||
i, *values, &val);
|
||||
|
||||
f = mouse_or_wdesc_frame (dpyinfo, xev->event);
|
||||
if (delta != DBL_MAX)
|
||||
{
|
||||
#ifdef HAVE_XWIDGETS
|
||||
if (xv)
|
||||
{
|
||||
if (val->horizontal)
|
||||
xv_total_x += delta;
|
||||
else
|
||||
xv_total_y += delta;
|
||||
|
||||
found_valuator = true;
|
||||
|
||||
if (delta == 0.0)
|
||||
any_stop_p = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (!f)
|
||||
{
|
||||
f = x_any_window_to_frame (dpyinfo, xev->event);
|
||||
|
||||
if (!f)
|
||||
goto XI_OTHER;
|
||||
}
|
||||
|
||||
found_valuator = true;
|
||||
|
||||
if (signbit (delta) != signbit (val->emacs_value))
|
||||
val->emacs_value = 0;
|
||||
|
||||
val->emacs_value += delta;
|
||||
|
||||
if (mwheel_coalesce_scroll_events
|
||||
&& (fabs (val->emacs_value) < 1)
|
||||
&& (fabs (delta) > 0))
|
||||
continue;
|
||||
|
||||
bool s = signbit (val->emacs_value);
|
||||
inev.ie.kind = (fabs (delta) > 0
|
||||
? (val->horizontal
|
||||
? HORIZ_WHEEL_EVENT
|
||||
: WHEEL_EVENT)
|
||||
: TOUCH_END_EVENT);
|
||||
inev.ie.timestamp = xev->time;
|
||||
|
||||
XSETINT (inev.ie.x, lrint (xev->event_x));
|
||||
XSETINT (inev.ie.y, lrint (xev->event_y));
|
||||
XSETFRAME (inev.ie.frame_or_window, f);
|
||||
|
||||
if (fabs (delta) > 0)
|
||||
{
|
||||
inev.ie.modifiers = !s ? up_modifier : down_modifier;
|
||||
inev.ie.modifiers
|
||||
|= x_x_to_emacs_modifiers (dpyinfo,
|
||||
xev->mods.effective);
|
||||
}
|
||||
|
||||
window = window_from_coordinates (f, xev->event_x,
|
||||
xev->event_y, NULL,
|
||||
false, false);
|
||||
|
||||
if (WINDOWP (window))
|
||||
scroll_height = XWINDOW (window)->pixel_height;
|
||||
else
|
||||
/* EVENT_X and EVENT_Y can be outside the
|
||||
frame if F holds the input grab, so fall
|
||||
back to the height of the frame instead. */
|
||||
scroll_height = FRAME_PIXEL_HEIGHT (f);
|
||||
|
||||
scroll_unit = pow (scroll_height, 2.0 / 3.0);
|
||||
|
||||
if (NUMBERP (Vx_scroll_event_delta_factor))
|
||||
scroll_unit *= XFLOATINT (Vx_scroll_event_delta_factor);
|
||||
|
||||
if (fabs (delta) > 0)
|
||||
{
|
||||
if (val->horizontal)
|
||||
{
|
||||
inev.ie.arg
|
||||
= list3 (Qnil,
|
||||
make_float (val->emacs_value
|
||||
* scroll_unit),
|
||||
make_float (0));
|
||||
}
|
||||
else
|
||||
{
|
||||
inev.ie.arg = list3 (Qnil, make_float (0),
|
||||
make_float (val->emacs_value
|
||||
* scroll_unit));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
inev.ie.arg = Qnil;
|
||||
}
|
||||
|
||||
kbd_buffer_store_event_hold (&inev.ie, hold_quit);
|
||||
|
||||
val->emacs_value = 0;
|
||||
}
|
||||
values++;
|
||||
}
|
||||
|
||||
inev.ie.kind = NO_EVENT;
|
||||
}
|
||||
|
||||
#ifdef HAVE_XWIDGETS
|
||||
if (xv)
|
||||
{
|
||||
if (found_valuator)
|
||||
xwidget_scroll (xv, xev->event_x, xev->event_y,
|
||||
xv_total_x, xv_total_y, xev->mods.effective,
|
||||
xev->time, any_stop_p);
|
||||
else
|
||||
xwidget_motion_notify (xv, xev->event_x, xev->event_y,
|
||||
xev->mods.effective, xev->time);
|
||||
|
||||
goto XI_OTHER;
|
||||
}
|
||||
#endif
|
||||
if (found_valuator)
|
||||
goto XI_OTHER;
|
||||
|
||||
ev.x = lrint (xev->event_x);
|
||||
ev.y = lrint (xev->event_y);
|
||||
ev.window = xev->event;
|
||||
ev.time = xev->time;
|
||||
|
||||
previous_help_echo_string = help_echo_string;
|
||||
help_echo_string = Qnil;
|
||||
|
||||
if (hlinfo->mouse_face_hidden)
|
||||
{
|
||||
hlinfo->mouse_face_hidden = false;
|
||||
clear_mouse_face (hlinfo);
|
||||
}
|
||||
|
||||
f = mouse_or_wdesc_frame (dpyinfo, xev->event);
|
||||
|
||||
#ifdef USE_GTK
|
||||
if (f && xg_event_is_for_scrollbar (f, event))
|
||||
f = 0;
|
||||
if (f && xg_event_is_for_scrollbar (f, event))
|
||||
f = 0;
|
||||
#endif
|
||||
if (f)
|
||||
{
|
||||
/* Maybe generate a SELECT_WINDOW_EVENT for
|
||||
`mouse-autoselect-window' but don't let popup menus
|
||||
interfere with this (Bug#1261). */
|
||||
if (!NILP (Vmouse_autoselect_window)
|
||||
&& !popup_activated ()
|
||||
/* Don't switch if we're currently in the minibuffer.
|
||||
This tries to work around problems where the
|
||||
minibuffer gets unselected unexpectedly, and where
|
||||
you then have to move your mouse all the way down to
|
||||
the minibuffer to select it. */
|
||||
&& !MINI_WINDOW_P (XWINDOW (selected_window))
|
||||
/* With `focus-follows-mouse' non-nil create an event
|
||||
also when the target window is on another frame. */
|
||||
&& (f == XFRAME (selected_frame)
|
||||
|| !NILP (focus_follows_mouse)))
|
||||
{
|
||||
static Lisp_Object last_mouse_window;
|
||||
Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false);
|
||||
if (f)
|
||||
{
|
||||
/* Maybe generate a SELECT_WINDOW_EVENT for
|
||||
`mouse-autoselect-window' but don't let popup menus
|
||||
interfere with this (Bug#1261). */
|
||||
if (!NILP (Vmouse_autoselect_window)
|
||||
&& !popup_activated ()
|
||||
/* Don't switch if we're currently in the minibuffer.
|
||||
This tries to work around problems where the
|
||||
minibuffer gets unselected unexpectedly, and where
|
||||
you then have to move your mouse all the way down to
|
||||
the minibuffer to select it. */
|
||||
&& !MINI_WINDOW_P (XWINDOW (selected_window))
|
||||
/* With `focus-follows-mouse' non-nil create an event
|
||||
also when the target window is on another frame. */
|
||||
&& (f == XFRAME (selected_frame)
|
||||
|| !NILP (focus_follows_mouse)))
|
||||
{
|
||||
static Lisp_Object last_mouse_window;
|
||||
Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false);
|
||||
|
||||
/* A window will be autoselected only when it is not
|
||||
selected now and the last mouse movement event was
|
||||
not in it. The remainder of the code is a bit vague
|
||||
wrt what a "window" is. For immediate autoselection,
|
||||
the window is usually the entire window but for GTK
|
||||
where the scroll bars don't count. For delayed
|
||||
autoselection the window is usually the window's text
|
||||
area including the margins. */
|
||||
if (WINDOWP (window)
|
||||
&& !EQ (window, last_mouse_window)
|
||||
&& !EQ (window, selected_window))
|
||||
{
|
||||
inev.ie.kind = SELECT_WINDOW_EVENT;
|
||||
inev.ie.frame_or_window = window;
|
||||
}
|
||||
/* A window will be autoselected only when it is not
|
||||
selected now and the last mouse movement event was
|
||||
not in it. The remainder of the code is a bit vague
|
||||
wrt what a "window" is. For immediate autoselection,
|
||||
the window is usually the entire window but for GTK
|
||||
where the scroll bars don't count. For delayed
|
||||
autoselection the window is usually the window's text
|
||||
area including the margins. */
|
||||
if (WINDOWP (window)
|
||||
&& !EQ (window, last_mouse_window)
|
||||
&& !EQ (window, selected_window))
|
||||
{
|
||||
inev.ie.kind = SELECT_WINDOW_EVENT;
|
||||
inev.ie.frame_or_window = window;
|
||||
}
|
||||
|
||||
/* Remember the last window where we saw the mouse. */
|
||||
last_mouse_window = window;
|
||||
}
|
||||
/* Remember the last window where we saw the mouse. */
|
||||
last_mouse_window = window;
|
||||
}
|
||||
|
||||
if (!x_note_mouse_movement (f, &ev))
|
||||
help_echo_string = previous_help_echo_string;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!x_note_mouse_movement (f, &ev))
|
||||
help_echo_string = previous_help_echo_string;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef USE_TOOLKIT_SCROLL_BARS
|
||||
struct scroll_bar *bar
|
||||
= x_window_to_scroll_bar (xi_event->display, xev->event, 2);
|
||||
struct scroll_bar *bar
|
||||
= x_window_to_scroll_bar (xi_event->display, xev->event, 2);
|
||||
|
||||
if (bar)
|
||||
x_scroll_bar_note_movement (bar, &ev);
|
||||
if (bar)
|
||||
x_scroll_bar_note_movement (bar, &ev);
|
||||
#endif /* USE_TOOLKIT_SCROLL_BARS */
|
||||
|
||||
/* If we move outside the frame, then we're
|
||||
certainly no longer on any text in the frame. */
|
||||
clear_mouse_face (hlinfo);
|
||||
}
|
||||
/* If we move outside the frame, then we're
|
||||
certainly no longer on any text in the frame. */
|
||||
clear_mouse_face (hlinfo);
|
||||
}
|
||||
|
||||
/* If the contents of the global variable help_echo_string
|
||||
has changed, generate a HELP_EVENT. */
|
||||
if (!NILP (help_echo_string)
|
||||
|| !NILP (previous_help_echo_string))
|
||||
do_help = 1;
|
||||
goto XI_OTHER;
|
||||
/* If the contents of the global variable help_echo_string
|
||||
has changed, generate a HELP_EVENT. */
|
||||
if (!NILP (help_echo_string)
|
||||
|| !NILP (previous_help_echo_string))
|
||||
do_help = 1;
|
||||
goto XI_OTHER;
|
||||
}
|
||||
case XI_ButtonRelease:
|
||||
case XI_ButtonPress:
|
||||
{
|
||||
|
|
@ -10242,6 +10333,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
|
||||
device = xi_device_from_id (dpyinfo, xev->deviceid);
|
||||
|
||||
if (!device || !device->master_p)
|
||||
goto XI_OTHER;
|
||||
|
||||
bv.button = xev->detail;
|
||||
bv.type = xev->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease;
|
||||
bv.x = lrint (xev->event_x);
|
||||
|
|
@ -10408,6 +10502,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
int copy_bufsiz = sizeof (copy_buffer);
|
||||
ptrdiff_t i;
|
||||
int nchars, len;
|
||||
struct xi_device_t *device;
|
||||
|
||||
device = xi_device_from_id (dpyinfo, xev->deviceid);
|
||||
|
||||
if (!device || !device->master_p)
|
||||
goto XI_OTHER;
|
||||
|
||||
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
|
||||
/* Dispatch XI_KeyPress events when in menu. */
|
||||
|
|
@ -10765,6 +10865,108 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
case XI_DeviceChanged:
|
||||
x_init_master_valuators (dpyinfo);
|
||||
goto XI_OTHER;
|
||||
#ifdef XI_TouchBegin
|
||||
case XI_TouchBegin:
|
||||
{
|
||||
struct xi_device_t *device;
|
||||
device = xi_device_from_id (dpyinfo, xev->deviceid);
|
||||
|
||||
if (!device)
|
||||
goto XI_OTHER;
|
||||
|
||||
if (xi_find_touch_point (device, xev->detail))
|
||||
emacs_abort ();
|
||||
|
||||
f = x_any_window_to_frame (dpyinfo, xev->event);
|
||||
|
||||
if (f && device->direct_p)
|
||||
{
|
||||
xi_link_touch_point (device, xev->detail, xev->event_x,
|
||||
xev->event_y);
|
||||
|
||||
inev.ie.kind = TOUCHSCREEN_BEGIN_EVENT;
|
||||
inev.ie.timestamp = xev->time;
|
||||
XSETFRAME (inev.ie.frame_or_window, f);
|
||||
XSETINT (inev.ie.x, lrint (xev->event_x));
|
||||
XSETINT (inev.ie.y, lrint (xev->event_y));
|
||||
XSETINT (inev.ie.arg, xev->detail);
|
||||
|
||||
XIAllowTouchEvents (dpyinfo->display, xev->deviceid,
|
||||
xev->detail, xev->event, XIAcceptTouch);
|
||||
}
|
||||
else
|
||||
XIAllowTouchEvents (dpyinfo->display, xev->deviceid,
|
||||
xev->detail, xev->event, XIRejectTouch);
|
||||
|
||||
goto XI_OTHER;
|
||||
}
|
||||
case XI_TouchUpdate:
|
||||
{
|
||||
struct xi_device_t *device;
|
||||
struct xi_touch_point_t *touchpoint;
|
||||
Lisp_Object arg = Qnil;
|
||||
|
||||
device = xi_device_from_id (dpyinfo, xev->deviceid);
|
||||
|
||||
if (!device)
|
||||
goto XI_OTHER;
|
||||
|
||||
touchpoint = xi_find_touch_point (device, xev->detail);
|
||||
|
||||
if (!touchpoint)
|
||||
emacs_abort ();
|
||||
|
||||
touchpoint->x = xev->event_x;
|
||||
touchpoint->y = xev->event_y;
|
||||
|
||||
f = x_any_window_to_frame (dpyinfo, xev->event);
|
||||
|
||||
if (f && device->direct_p)
|
||||
{
|
||||
inev.ie.kind = TOUCHSCREEN_UPDATE_EVENT;
|
||||
inev.ie.timestamp = xev->time;
|
||||
XSETFRAME (inev.ie.frame_or_window, f);
|
||||
|
||||
for (touchpoint = device->touchpoints;
|
||||
touchpoint; touchpoint = touchpoint->next)
|
||||
{
|
||||
arg = Fcons (list3i (lrint (touchpoint->x),
|
||||
lrint (touchpoint->y),
|
||||
lrint (touchpoint->number)),
|
||||
arg);
|
||||
}
|
||||
|
||||
inev.ie.arg = arg;
|
||||
}
|
||||
|
||||
goto XI_OTHER;
|
||||
}
|
||||
case XI_TouchEnd:
|
||||
{
|
||||
struct xi_device_t *device;
|
||||
|
||||
device = xi_device_from_id (dpyinfo, xev->deviceid);
|
||||
|
||||
if (!device)
|
||||
goto XI_OTHER;
|
||||
|
||||
xi_unlink_touch_point (xev->detail, device);
|
||||
|
||||
f = x_any_window_to_frame (dpyinfo, xev->event);
|
||||
|
||||
if (f && device->direct_p)
|
||||
{
|
||||
inev.ie.kind = TOUCHSCREEN_END_EVENT;
|
||||
inev.ie.timestamp = xev->time;
|
||||
XSETFRAME (inev.ie.frame_or_window, f);
|
||||
XSETINT (inev.ie.x, lrint (xev->event_x));
|
||||
XSETINT (inev.ie.y, lrint (xev->event_y));
|
||||
XSETINT (inev.ie.arg, xev->detail);
|
||||
}
|
||||
|
||||
goto XI_OTHER;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
goto XI_OTHER;
|
||||
}
|
||||
|
|
|
|||
11
src/xterm.h
11
src/xterm.h
|
|
@ -179,13 +179,24 @@ struct xi_scroll_valuator_t
|
|||
int horizontal;
|
||||
};
|
||||
|
||||
struct xi_touch_point_t
|
||||
{
|
||||
struct xi_touch_point_t *next;
|
||||
|
||||
int number;
|
||||
double x, y;
|
||||
};
|
||||
|
||||
struct xi_device_t
|
||||
{
|
||||
int device_id;
|
||||
int scroll_valuator_count;
|
||||
int grab;
|
||||
bool master_p;
|
||||
bool direct_p;
|
||||
|
||||
struct xi_scroll_valuator_t *valuators;
|
||||
struct xi_touch_point_t *touchpoints;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue