1 ;;; xlib-xlib.el --- X library part of new xlib.
3 ;; Copyright (C) 2003-2005 by XWEM Org.
5 ;; Author: Eric M. Ludlam <zappo@gnu.ai.mit.edu>
6 ;; Zajcev Evgeny <zevlg@yandex.ru>
7 ;; Keywords: xlib, xwem
8 ;; X-CVS: $Id: xlib-xlib.el,v 1.9 2005-04-04 19:55:30 lg Exp $
10 ;; This file is part of XWEM.
12 ;; XWEM is free software; you can redistribute it and/or modify it
13 ;; under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
17 ;; XWEM is distributed in the hope that it will be useful, but WITHOUT
18 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
20 ;; License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with XEmacs; see the file COPYING. If not, write to the Free
24 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 ;;; Synched up with: Not in FSF
35 (defun XOpenDisplay (name &optional dispnum screen)
36 "Open an X connection to the display named NAME such as host:0.1.
37 Optionally you may pass DISPNUM - display number and SCREEN - screen number."
38 ;; first, open a connection to name
39 (when (string-match ":\\([0-9]*\\|[0-9]*\\)\.*\\([0-9]*\\)" name)
42 (truncate (string-to-int (substring name (match-beginning 1) (match-end 1))))))
45 (truncate (string-to-int (substring name (match-beginning 2) (match-end 2))))))
46 (setq name (substring name 0 (- (match-beginning 1) 1))))
48 (when (= (length name) 0)
49 (setq name (system-name)))
51 (let ((xdpy (X-Dpy-create-connection name dispnum)))
52 ;; Connection is open, and X-info contains connection informaion.
53 (let ((X-info (X-Dpy-send-read xdpy (X-Create-message X-client-to-open)
56 (if (null (nth 0 X-info))
57 (message "X: %s" (nth X-info 3))
59 (setf (X-Dpy-proto-maj xdpy) (nth 1 X-info))
60 (setf (X-Dpy-proto-min xdpy) (nth 2 X-info))
61 (setf (X-Dpy-resource-base xdpy) (nth 4 X-info))
62 (setf (X-Dpy-resource-mask xdpy) (nth 5 X-info))
63 (setf (X-Dpy-motion-bufsize xdpy) (nth 6 X-info))
64 (setf (X-Dpy-max-request-size xdpy) (nth 7 X-info))
65 (setf (X-Dpy-byte-order xdpy) (nth 8 X-info))
66 (setf (X-Dpy-bitmap-scanline-unit xdpy) (nth 9 X-info))
67 (setf (X-Dpy-bitmap-scanline-pad xdpy) (nth 10 X-info))
68 (setf (X-Dpy-bitmap-bit-order xdpy) (nth 11 X-info))
69 (setf (X-Dpy-min-keycode xdpy) (nth 12 X-info))
70 (setf (X-Dpy-max-keycode xdpy) (nth 13 X-info))
71 (setf (X-Dpy-vendor xdpy) (nth 14 X-info))
74 (setf (X-Dpy-formats xdpy)
75 (mapcar #'(lambda (fmt)
76 (make-X-ScreenFormat :depth (nth 0 fmt)
77 :bits-per-pixel (nth 1 fmt)
78 :scanline-pad (nth 2 fmt)))
82 (setf (X-Dpy-screens xdpy)
83 (mapcar #'(lambda (scr)
87 :root (X-Win-find-or-make xdpy (nth 0 scr))
88 :colormap (make-X-Colormap :dpy xdpy :id (nth 1 scr))
89 :white-pixel (make-X-Color :dpy xdpy :id (nth 2 scr))
90 :black-pixel (make-X-Color :dpy xdpy :id (nth 3 scr))
91 :root-event-mask (nth 4 scr)
97 :max-maps (nth 10 scr)
98 :visualid (nth 11 scr)
99 :backingstores (nth 12 scr)
100 :save-unders (nth 13 scr)
101 :root-depth (nth 14 scr)))
103 (setf (X-Screen-depths nscreen)
104 (mapcar #'(lambda (dpth)
105 (make-X-Depth :depth (nth 0 dpth)
106 :visuals (mapcar #'(lambda (vis)
107 (make-X-Visual :id (nth 0 vis)
109 :bits-per-rgb (nth 2 vis)
110 :cmap-entries (nth 3 vis)
111 :red-mask (nth 4 vis)
112 :green-mask (nth 6 vis)
113 :blue-mask (nth 5 vis)))
118 (setf (X-Screen-default-gc nscreen)
119 (XCreateGC xdpy (X-Screen-root nscreen)
120 (make-X-Gc :dpy xdpy :id (X-Dpy-get-id xdpy)
121 :foreground (X-Screen-white-pixel nscreen)
122 :background (X-Screen-black-pixel nscreen))))
127 (message "Connection opened to %s...done" name)
130 (defun XCloseDisplay (xdpy)
131 "Close the connection to display XDPY."
134 (defun XScreenCheck (xdpy scrnum)
135 "Check SCRNUM screen on display XDPY."
139 (when (> scrnum (1- (length (X-Dpy-screens xdpy))))
140 (error "xlib: screen with number %d does not exists." scrnum))
143 (defsubst XDefaultRootWindow (xdpy &optional scrnum)
144 "Return default root window on XDPY."
145 (X-Dpy-p xdpy 'XDefaultRootWindow)
146 (X-Screen-root (nth (XScreenCheck xdpy scrnum) (X-Dpy-screens xdpy))))
148 (defsubst XWhitePixel (xdpy &optional scrnum)
149 "Return white pixel for display XDPY."
150 (X-Dpy-p xdpy 'XWhitePixel)
151 (X-Screen-white-pixel (nth (XScreenCheck xdpy scrnum) (X-Dpy-screens xdpy))))
153 (defsubst XBlackPixel (xdpy &optional scrnum)
154 "Return black pixel for display XDPY."
155 (X-Dpy-p xdpy 'XBlackPixel)
156 (X-Screen-black-pixel (nth (XScreenCheck xdpy scrnum) (X-Dpy-screens xdpy))))
158 (defsubst XDefaultColormap (xdpy &optional scrnum)
159 "Return default colormap for XDPY on screen SCRNUM."
160 (X-Dpy-p xdpy 'XDefaultColormap)
161 (X-Screen-colormap (nth (XScreenCheck xdpy scrnum) (X-Dpy-screens xdpy))))
163 (defsubst XDefaultVisual (xdpy &optional scrnum)
164 "Return visual on XDPY and SCRNUM."
165 (X-Dpy-p xdpy 'XDefaultVisual)
166 (X-Screen-visualid (nth (XScreenCheck xdpy scrnum) (X-Dpy-screens xdpy))))
168 (defsubst XDefaultGC (xdpy &optional scrnum)
169 "Return default GC on XDPY and SCRNUM."
170 (X-Dpy-p xdpy 'XDefaultGC)
171 (X-Screen-default-gc (nth (XScreenCheck xdpy scrnum) (X-Dpy-screens xdpy))))
173 (defun XDefaultDepth (xdpy &optional scrnum)
174 "Return default depth on XDPY and screen SCRNUM."
175 (X-Dpy-p xdpy 'XDefaultDepth)
177 (or (X-Dpy-get-property xdpy 'default-depth)
178 (let ((vid (XDefaultVisual xdpy))
179 (depths (X-Screen-depths (nth (XScreenCheck xdpy scrnum) (X-Dpy-screens xdpy))))
181 (while (and depths (not found))
182 (setq viss (X-Depth-visuals (car depths)))
183 (while (and viss (not (= (X-Visual-id (car viss)) vid)))
184 (setq viss (cdr viss)))
187 (setq depths (cdr depths))))
191 (X-Dpy-put-property xdpy 'default-depth (X-Depth-depth (car depths)))
192 (X-Depth-depth (car depths)))
194 ;; Hmm, why not found?
195 (X-Depth-depth (car (X-Screen-depths (nth (XScreenCheck xdpy scrnum) (X-Dpy-screens xdpy)))))))))
197 (defun X-Dpy-find-visual-for-depth (xdpy depth &optional scrnum)
198 "On display XDPY find appopriate visual for DEPTH."
199 (let ((depths (X-Screen-depths (nth (XScreenCheck xdpy scrnum) (X-Dpy-screens xdpy)))))
200 (while (and depths (not (= (X-Depth-depth (car depths)) depth)))
201 (setq depths (cdr depths)))
204 (car (X-Depth-visuals (car depths))))))
207 (defun XBell (xdpy percent)
208 "Ring the bell on XDPY at PERCENT volume."
209 (X-Dpy-p xdpy 'XBell)
211 (list [1 104] ;opcode
212 [1 percent] ;percentage
213 [2 1]))) ;length of request (in 4s)
214 (X-Dpy-send xdpy (X-Create-message ListOfFields))))
217 (defun XCreateWindow (xdpy &optional parent x y width height
218 border-width depth class visual
221 (X-Dpy-p xdpy 'XCreateWindow)
223 (let* ((wid (X-Dpy-get-id xdpy))
224 (attrmsg (X-Attr-message attrs))
227 [1 (or depth X-CopyFromParent)] ;depth
228 [2 (+ 7 (/ (length attrmsg) 4))] ;8 means no attributes yet
229 [4 wid] ;newly alloced wid.
231 (if (X-Win-p parent) parent ;the parent
232 (XDefaultRootWindow xdpy))) ]
233 [2 (or x 100)] ;x position
234 [2 (or y 100)] ;y position
235 [2 (or width 100)] ;width
236 [2 (or height 100)] ;height
237 [2 (or border-width 1)] ;border width
238 [2 (or class X-CopyFromParent)] ;class
239 [4 (or visual X-CopyFromParent)] ;visual
241 (msg (concat (X-Create-message ListOfFields)
243 (X-Dpy-send xdpy msg)
244 (X-Win-find-or-make xdpy wid)))
246 (defun XChangeWindowAttributes (xdpy win attrs)
247 "On XDPY and window WIN, change to the ATTRIBUTES."
248 (X-Dpy-p xdpy 'XChangeWindowAttributes)
249 (X-Attr-p attrs 'XChangeWindowAttributes)
250 (X-Win-p win 'XChangeWindowAttributes)
252 (let* ((attrmsg (X-Attr-message attrs))
256 [2 (+ 2 (/ (length attrmsg) 4))] ;length
257 [4 (X-Win-id win)])) ;window
258 (msg (concat (X-Create-message ListOfFields) attrmsg)))
259 (X-Dpy-send xdpy msg)))
261 (defun XSelectInput (xdpy win event)
262 "On display XDPY for window WIN, set the EVENT mask."
263 (XChangeWindowAttributes xdpy win (make-X-Attr :event-mask event)))
265 (defun XSetWindowBackground (xdpy win pixel)
266 "On display XDPY for window WIN, set the background to PIXEL."
267 (XChangeWindowAttributes xdpy win (make-X-Attr :background-pixel pixel)))
269 (defun XSetWindowBackgroundPixmap (xdpy win pixmap)
270 "On display XDPY for window WIN, set the background pixmap to PIXMAP."
271 (XChangeWindowAttributes xdpy win (make-X-Attr :background-pixmap pixmap)))
273 (defun XSetWindowBorder (xdpy win pixel)
274 "On display XDPY for window WIN, set the border color to PIXEL."
275 (XChangeWindowAttributes xdpy win (make-X-Attr :border-pixel pixel)))
277 (defun XSetWindowColormap (xdpy win cmap-id)
278 "On display XDPY for window WIN, set the colormap to CMAP-ID."
279 (XChangeWindowAttributes xdpy win (make-X-Attr :colormap cmap-id)))
281 (defun XSetWindowCursor (xdpy win cursor)
282 (XChangeWindowAttributes xdpy win (make-X-Attr :cursor cursor)))
284 (defun XGetWindowAttributes (xdpy win)
285 "On display XDPY, get window's WIN attributes as an `X-Attr'."
286 (X-Dpy-p xdpy 'XGetWindowAttributes)
287 (X-Win-p win 'XGetWindowAttributes)
292 [ 2 2] ;request length
293 [ 4 (X-Win-id win)])) ;the window
295 (list [1 success ] ;status
296 nil ;generic bad response
298 ; [ 1 integerp ] ;reply
299 [ 1 integerp ] ;backingstore
300 [ 2 integerp ] ;sequence number
301 [ 4 integerp ] ;reply length
302 [ 4 integerp ] ;visual id
303 [ 2 integerp ] ;class
304 [ 1 integerp ] ;bit gravity
305 [ 1 integerp ] ;win gravity
306 [ 4 integerp ] ;backing planes
307 [ 4 integerp ] ;backing pixel
308 [ 1 integerp ] ;save under
309 [ 1 integerp ] ;map is installed
310 [ 1 integerp ] ;map state
311 [ 1 integerp ] ;override-redirect
312 [ 4 integerp ] ;colormap
313 [ 4 integerp ] ;all event masks
314 [ 4 integerp ] ;my event masks
315 [ 2 integerp ] ;do not propagate mask
319 (setq r (X-Dpy-send-read xdpy (X-Create-message ListOfFields) ReceiveFields))
322 (make-X-Attr :backing-store (nth 1 r)
324 :bit-gravity (nth 6 r)
325 :win-gravity (nth 7 r)
326 :backing-planes (nth 8 r)
327 :backing-pixel (nth 9 r)
328 :save-under (if (= (nth 10 r) 0) nil t)
330 :override-redirect (if (= (nth 13 r) 0) nil t)
331 :colormap (make-X-Colormap :dpy xdpy :id (nth 14 r))
332 :event-mask (nth 16 r)
333 :do-not-propagate-mask (nth 17 r)))))
335 (defun XConfigureWindow (xdpy win conf)
336 "On display XDPY, change window WIN to have configuration CONF.
337 CONF is an `X-Conf' structure."
338 (X-Dpy-p xdpy 'XConfigureWindow)
339 (X-Conf-p conf 'XConfigureWindow)
340 (X-Win-p win 'XConfigureWindow)
342 (let* ((cfgmsg (X-Conf-message conf))
346 [2 (+ 2 (/ (length cfgmsg) 4))] ;length
347 [4 (X-Win-id win)])) ;window
348 (msg (concat (X-Create-message ListOfFields) cfgmsg)))
349 (X-Dpy-send xdpy msg)))
351 (defun XLowerWindow (xdpy win)
352 "On display XDPY, lower window WIN."
353 (XConfigureWindow xdpy win (make-X-Conf :stackmode X-Below)))
355 (defun XRaiseWindow (xdpy win)
356 "On display XDPY, raise window WIN."
357 (XConfigureWindow xdpy win (make-X-Conf :stackmode X-Above)))
359 (defun XMoveWindow (xdpy win x y)
360 "On display XDPY, move window WIN to position X Y."
361 (XConfigureWindow xdpy win (make-X-Conf :x x :y y)))
363 (defun XResizeWindow (xdpy win w h)
364 "On display XDPY, resize window WIN to dimentions W H."
365 (XConfigureWindow xdpy win (make-X-Conf :width w :height h)))
367 (defun XMoveResizeWindow (xdpy win x y w h)
368 "On display XDPY, move and resize window WIN to X, Y, W, H."
369 (XConfigureWindow xdpy win (make-X-Conf :x x :y y :width w :height h)))
371 (defun XSetWindowBorderWidth (xdpy win width)
372 "On display XDPY, set window's WIN border to be WIDTH pixels wide."
373 (XConfigureWindow xdpy win (make-X-Conf :border-width width)))
375 (defun XMapWindow (xdpy win)
376 "On display XDPY, map WIN to the screen (to make it visible.)."
377 (X-Dpy-p xdpy 'XMapWindow)
378 (X-Win-p win 'XMapWindow)
383 [2 2] ;length of request (in 4s)
384 [4 (X-Win-id win)]))) ;window to map
385 (X-Dpy-send xdpy (X-Create-message ListOfFields))))
387 (defun XUnmapWindow (xdpy win)
388 "On display XDPY, unmap window WIN to make it hidden."
389 (X-Dpy-p xdpy 'XUnmapWindow)
390 (X-Win-p win 'XUnmapWindow)
395 [2 2] ;length of request (in 4s)
396 [4 (X-Win-id win)]))) ;window to map
397 (X-Dpy-send xdpy (X-Create-message ListOfFields))))
399 (defun XDestroyWindow (xdpy win)
400 "On display XDPY, destroy window WIN."
401 (X-Dpy-p xdpy 'XDestroyWindow)
402 (X-Win-p win 'XDestroyWindow)
407 [2 2] ;length of request (in 4s)
408 [4 (X-Win-id win)]))) ;window to map
409 (X-Dpy-send xdpy (X-Create-message ListOfFields))
411 ;; Schedule window WIN for total removing
412 (X-Win-invalidate xdpy win)))
414 (defun XDestroySubwindows (xdpy win)
415 "On display XDPY, destroy subwindows of window WIN."
416 (X-Dpy-p xdpy 'XDestroySubwindows)
417 (X-Win-p win 'XDestroySubwindows)
422 [2 2] ;length of request (in 4s)
423 [4 (X-Win-id win)]))) ;window to map
424 (X-Dpy-send xdpy (X-Create-message ListOfFields))))
426 (defun XQueryTree (xdpy win)
427 "Query display XDPY for all children of window WIN.
428 Returns a list of the form (ROOT PARENT CHILD1 CHILD2 ...)
429 on success, or nil on failure. ROOT is the root window for the display that
430 WINDOW is on. PARENT is the parent of WINDOW, and CHILDN are the
432 (X-Dpy-p xdpy 'XQueryTree)
433 (X-Win-p win 'XQueryTree)
436 (list [ 1 15] ;opcode
438 [ 2 2 ] ;request length
439 [ 4 (X-Win-id win)])) ;window we are querying.
441 (list [ 1 success] ;status
442 nil ;generic bad response
443 (list [ 1 nil] ;unused
444 [ 2 integerp ] ;sequence number
445 [ 4 length-1 ] ;length of the return in 4 blocks
446 [ 4 :X-Win ] ;root window
447 [ 4 :X-Win ] ;parent window
448 [ 2 length-2 ] ;number of children
450 [ (* 4 length-2) :X-Win])))) ;list of the children
452 (X-Dpy-send-read xdpy (X-Create-message ListOfFields) ReceiveFields)))
455 ;;; Time to play with properties and Atoms
457 (defun XInternAtom (xdpy name &optional only-if-exists)
458 "On display XDPY, return the Atom with NAME.
459 If ONLY-IF-EXISTS is nil, then the atom is created if it does not already
460 exist. The Atom object is returned."
461 (X-Dpy-p xdpy 'XInternAtom)
462 (if (not (stringp name))
463 (signal 'wrong-type-argument (list 'signal 'stringp name)))
465 (let ((a (X-Atom-find-by-name xdpy name)))
470 [1 only-if-exists] ;forcecreate flag.
471 [2 (+ 2 (X-padlen name))] ;message length
472 [2 (length name)] ;name length
474 [(length name) name] ;name
478 (list [1 success] ;status message
479 nil ;generic bad response
480 (list [1 nil] ;unused
481 [2 integerp] ;sequence
482 [4 nil] ;reply length
487 (setq r (X-Dpy-send-read xdpy (X-Create-message ListOfFields) ReceiveFields))
489 (let ((rat (nth 2 r)))
490 (setf (X-Atom-name rat) name)
491 (X-Atom-insert xdpy rat)
495 (defun XGetAtomName (xdpy atom)
496 "On display XDPY, get the textual name of ATOM.
498 (X-Dpy-p xdpy 'XGetAtomName)
499 (X-Atom-p atom 'XGetAtomName)
501 (let ((a (X-Atom-find xdpy (X-Atom-id atom))))
505 (list [ 1 17] ;opcode
508 [ 4 (X-Atom-id atom)])) ;atom id
511 [1 success ] ;status message
512 nil ;generic bad response
513 (list [ 1 nil ] ;unused
514 [ 2 integerp ] ;sequence
515 [ 4 length-1 ] ;reply length
516 [ 2 length-2 ] ;length of name
518 [ length-2 stringp ] ;the name
519 [ (X-pad length-2) nil ] ;padding
522 (setq r (X-Dpy-send-read xdpy (X-Create-message ListOfFields) ReceiveFields))
525 (setf (X-Atom-name atom) (nth 2 r))
526 (X-Atom-insert xdpy atom)
530 (defun XChangeProperty (xdpy win property type format mode data)
531 "On display XDPY for window WIN, change PROPERTY.
532 PROPERTY is changed based on a TYPE, FORMAT, and MODE with DATA.
533 There are NElements."
534 (X-Dpy-p xdpy 'XChangeProperty)
535 (X-Win-p win 'XChangeProperty)
536 (X-Atom-p property 'XChangeProperty)
537 (X-Atom-p type 'XChangeProperty)
539 (let* ((n (* (length data) (/ format 8)))
543 [1 mode] ;Mode: Replace Prepend, Append
544 (vector 2 (+ 6 (/ (+ n p) 4))) ;length, shut up compiler
545 [4 (X-Win-id win)] ;window
546 [4 (X-Atom-id property)] ;property atom
547 [4 (X-Atom-id type)] ;property type
548 [1 format] ;property format
550 [4 (/ n (/ format 8))] ;length of the list-byte thing
552 (if (and (= format 8) (stringp data))
554 (append ListOfFields (list (vector (length data) data))))
556 (let ((d (if (X-Generic-struct-p (car data))
557 (funcall (X-Generic-struct-p (car data)) (car data))
560 (append ListOfFields (list (vector (/ format 8) d )))
562 (X-Dpy-send xdpy (X-Create-message ListOfFields))))
564 (defun XDeleteProperty (xdpy win atom)
565 "On display XDPY for window WIN delete property denoted by ATOM."
566 (X-Win-p win 'XDeleteProperty)
567 (X-Atom-p atom 'XDeleteProperty)
573 [4 (X-Win-id win)] ;window
574 [4 (X-Atom-id atom)]))) ;atom
575 (X-Dpy-send xdpy (X-Create-message ListOfFields))))
577 ;; These are Xlib convenience routines
578 (defun XSetPropertyString (xdpy win atom string &optional mode)
579 "On display XDPY and window WIN set ATOM property to STRING."
580 (XChangeProperty xdpy win atom XA-string X-format-8 (or mode X-PropModeReplace)
583 (defun XSetWMProtocols (xdpy win protocol_atoms)
584 "On display XDPY, set window's WIN protocols to PROTOCOL_ATOMS.
585 Convenience routine which calls `XChangeProperty'"
586 (XChangeProperty xdpy win (XInternAtom xdpy "WM_PROTOCOLS" nil)
587 XA-atom X-format-32 X-PropModeReplace protocol_atoms))
589 (defun XSetWMClass (xdpy win wm-class)
590 "On displayX DPY, set window's WIN Class to WM-CLASS.
591 WM-CLASS should be in form '(class-name class-intance)."
592 (XChangeProperty xdpy win XA-wm-class XA-string X-format-8 X-PropModeReplace
593 (concat (car wm-class) (string 0) (cadr wm-class) (string 0))))
595 (defun XSetWMName (xdpy win wm-name)
596 (XChangeProperty xdpy win XA-wm-name XA-string X-format-8 X-PropModeReplace
599 (defun XSetWMNormalHints (xdpy win wmnh)
600 "On display XDPY, set window's WIN normal hints to HINTS.
601 HINTS is list in format (x1 x2 ... x18)."
602 (X-WMSize-p wmnh 'XSetWMNormalHints)
604 (let ((pplist (list (X-WMSize-flags wmnh) 0
607 (X-WMSize-width wmnh)
608 (X-WMSize-height wmnh)
609 (X-WMSize-min-width wmnh)
610 (X-WMSize-min-height wmnh)
611 (X-WMSize-max-width wmnh)
612 (X-WMSize-max-height wmnh)
613 (X-WMSize-width-inc wmnh)
614 (X-WMSize-height-inc wmnh)
615 (X-WMSize-min-aspect-x wmnh)
616 (X-WMSize-min-aspect-y wmnh)
617 (X-WMSize-max-aspect-x wmnh)
618 (X-WMSize-max-aspect-y wmnh)
619 (X-WMSize-base-width wmnh)
620 (X-WMSize-base-height wmnh)
621 (X-WMSize-gravity wmnh))))
623 (XChangeProperty xdpy win XA-wm-normal-hints XA-wm-size-hints X-format-32 X-PropModeReplace pplist)))
625 (defun XSetWMState (xdpy win wm-state &optional icon-id)
626 "On display XDPY, set window's WIN state to WM-STATE.
627 WM-STATE is one of `X-WithdrawnState', `X-NormalState' or `X-IconicState'."
628 (let ((wmsa (XInternAtom xdpy "WM_STATE" nil)))
629 (XChangeProperty xdpy win wmsa wmsa X-format-32 X-PropModeReplace (list wm-state (or icon-id 0.0)))))
631 (defun XSetWMCommand (xdpy win cmd)
632 "On display XDPY set window's WIN WM_COMMAND property to CMD."
634 (XChangeProperty xdpy win (XInternAtom xdpy "WM_COMMAND" nil) XA-string
635 X-format-8 X-PropModeReplace cmd))
637 (defun XGetWindowProperty (xdpy win property &optional offset length delete required-type)
638 "On display XDPY, get window's WIN PROPERTY atom value.
639 Get the data from optional OFFSET, and a maximum of LENGTH bytes.
640 OFFSET and LENGTH refer to 32 bit chunks, not 8 bit chunks.
641 Third optional argument DELETE will delete the property if Non-nil.
642 Fourth argument REQUIRED-TYPE filters only properties of the desired type.
643 If REQUIRED-TYPE is `XA-AnyPropertyType', or nil then no filtering is done.
644 The returned list is of the form:
645 (TYPE_RETURN BYTES_AFTER PROP1 PROP2 ...)
646 Where TYPE_RETURN is the type (of same for as REQUIRED-TYPE) is the actual
647 type of the data being returned.
648 FORMAT_RETURN is the format of the data (such as 8, 16, or 32).
649 BYTES_AFTER is the number of bytes still attached to the property.
650 If there are extra bytes, then a second call to `XGetWindowProperty' will
651 be needed. Lastly, PROP1 through PROPN is the list of properties
652 originally requested.
653 It is common to call `XGetWindowProperty' asking for no data so that
654 BYTES_AFTER contains the exact amount of data we want to request."
655 (X-Dpy-p xdpy 'XGetWindowProperty)
656 (X-Win-p win 'XGetWindowProperty)
657 (X-Atom-p property 'XGetWindowProperty)
659 (unless offset (setq offset 0))
660 (unless length (setq length 1024))
661 (unless required-type (setq required-type XA-AnyPropertyType))
664 (list [ 1 20] ;opcode
665 [ 1 (if delete 1 0)] ;delete flag
666 [ 2 6 ] ;request length
667 [ 4 (X-Win-id win) ] ;the window whose property we want
668 [ 4 (X-Atom-id property) ] ;The property atom we want
669 [ 4 (X-Atom-id required-type) ] ;required type filter.
670 [ 4 offset ] ;offset in the property data
671 [ 4 length ])) ;length of data we want
673 (list [1 success] ;status message
674 nil ;generic bad response
676 [ 1 length-1 ] ;format of returned data
677 [ 2 nil ] ;sequence number
678 [ 4 length-3 ] ;length of this request
679 [ 4 integerp ] ;atom representing return type
680 [ 4 integerp ] ;bytes left on server
681 [ 4 length-2 ] ;length of value in format units
685 (if (memq required-type (list XA-atom XA-window XA-rectangle))
687 (* length-2 (/ length-1 8))
690 (cond ((or (= length-1 8) (eq required-type XA-string)) 'stringp)
691 ((eq required-type XA-atom) :X-Atom)
692 ((eq required-type XA-window) :X-Win)
693 ((eq required-type XA-rectangle) :X-Rect)
694 (t '([(/ length-1 8) integerp])))]
695 [ (X-pad (* length-2 (/ length-1 8))) nil ]
700 (setq r (X-Dpy-send-read xdpy (X-Create-message ListOfFields) ReceiveFields))
704 (setq proplist (list (nth 2 r) (nth 1 r))) ; start backwards
705 (if (listp (nth 3 r))
707 (setq r (nthcdr 3 r)))
710 (setq proplist (cons r proplist))
713 (let ((item (car r)))
715 (setq item (car item)))
717 (setq proplist (cons item proplist)
719 (nreverse proplist))))
721 ;; A few functions based on GetProperty
722 (defun XGetWMHints (xdpy win)
723 "On display XDPY, get window's WIN WM_HINTS."
724 (let ((wmh (XGetWindowProperty xdpy win XA-wm-hints 0 1024 nil XA-wm-hints)))
725 (when (and wmh (= (car wmh) (X-Atom-id XA-wm-hints)))
726 (setq wmh (cddr wmh)) ; strip REQ-TYPE and BYTES-AFTER
727 (make-X-WMHints :flags (Xtruncate (nth 0 wmh))
728 :input (Xtruncate (nth 1 wmh))
729 :initial-state (Xtruncate (nth 2 wmh))
730 :icon-pixmap (nth 3 wmh)
731 :icon-window (nth 4 wmh)
732 :icon-x (Xtruncate (nth 5 wmh))
733 :icon-y (Xtruncate (nth 6 wmh))
734 :icon-mask (nth 7 wmh)
735 :window-group (nth 8 wmh)))))
737 (defun XGetWMNormalHints (xdpy win)
738 "On display XDPY, get normal hints for WIN."
739 (let ((wmnh (XGetWindowProperty xdpy win XA-wm-normal-hints 0 40 nil XA-wm-size-hints)))
740 (when (and wmnh (= (car wmnh) (X-Atom-id XA-wm-size-hints)))
741 (setq wmnh (cddr wmnh)) ; strip REQ-TYPE and BYTES-AFTER
742 (make-X-WMSize :flags (Xtruncate (nth 0 wmnh))
743 :x (Xtruncate (nth 1 wmnh))
744 :y (Xtruncate (nth 2 wmnh))
745 :width (Xtruncate (nth 3 wmnh))
746 :height (Xtruncate (nth 4 wmnh))
747 :min-width (Xtruncate (nth 5 wmnh))
748 :min-height (Xtruncate (nth 6 wmnh))
749 :max-width (Xtruncate (nth 7 wmnh))
750 :max-height (Xtruncate (nth 8 wmnh))
751 :width-inc (Xtruncate (nth 9 wmnh))
752 :height-inc (Xtruncate (nth 10 wmnh))
753 :min-aspect-x (Xtruncate (nth 11 wmnh))
754 :min-aspect-y (Xtruncate (nth 12 wmnh))
755 :max-aspect-x (Xtruncate (nth 13 wmnh))
756 :max-aspect-y (Xtruncate (nth 14 wmnh))
757 :base-width (Xtruncate (nth 15 wmnh))
758 :base-height (Xtruncate (nth 16 wmnh))
759 :gravity (Xtruncate (nth 17 wmnh))))))
761 (defun XDecodeCompoundText (text)
762 "Decode compound TEXT, to native string.
763 Evil hack, invent something better."
764 (if (string-match "\x1b\x25\x2f\x31\\(.\\)\\(.\\)\\(.*?\\)\x02" text)
765 (let ((len (+ (* (- (char-to-int (string-to-char (match-string 1 text))) 128) 128)
766 (- (char-to-int (string-to-char (match-string 2 text))) 128))))
767 (let ((seq-beg (match-beginning 0))
768 (data-beg (match-end 0))
769 (data-end (+ len (match-beginning 3)))
770 (cs (intern (match-string 3 text))))
771 (concat (substring text 0 seq-beg)
772 (if (fboundp 'decode-coding-string)
773 (decode-coding-string (substring text data-beg data-end) cs)
774 (substring text data-beg data-end))
775 (XDecodeCompoundText (substring text data-end)))))
778 (defun XGetPropertyString (xdpy win atom)
779 "On display XDPY, and window XWIN, get string property of type ATOM."
780 (let ((propdata (XGetWindowProperty xdpy win atom 0 1024))
783 (when (and propdata (setq tdata (nth 2 propdata)))
784 (setq retstring tdata)
785 (when (= (car propdata)
786 (X-Atom-id (XInternAtom xdpy "COMPOUND_TEXT")))
787 ;; Adjust RETSTRING in case of COMPOUND_TEXT
788 (setq retstring (XDecodeCompoundText retstring)))
790 (when (> (nth 1 propdata) 0.0)
792 (XGetWindowProperty xdpy win atom
793 1024 (nth 0 propdata)))
794 (when (and propdata (setq tdata (nth 2 propdata)))
795 (if (= (car propdata)
796 (X-Atom-id (XInternAtom xdpy "COMPOUND_TEXT")))
798 (concat retstring (XDecodeCompoundText tdata)))
799 (setq retstring (concat retstring tdata))))))
802 (defun XGetWMName (xdpy win)
803 "On display XDPY, get window's WIN name."
804 (XGetPropertyString xdpy win XA-wm-name))
806 (defun XGetWMCommand (xdpy win)
807 "On display XDPY, get window's WIN WM_COMMAND."
808 (let ((wmcmd (XGetPropertyString xdpy win XA-wm-command)))
809 (if (> (length wmcmd) 0)
810 (replace-in-string (substring wmcmd 0 (1- (length wmcmd))) (string 0) " ")
813 (defun XGetWMClass (xdpy win)
814 "On display XDPY, get window's WIN WM_CLASS."
815 (let ((wmclass (XGetPropertyString xdpy win XA-wm-class)))
817 (split-string wmclass (string 0)))))
819 (defun XGetWMRole (xdpy win)
820 "On display XDPY return WM_WINDOW_ROLE property for XWIN."
821 (XGetPropertyString xdpy win (XInternAtom xdpy "WM_WINDOW_ROLE" nil)))
823 (defun XGetWMClientLeader (xdpy win)
824 "Get window property for WM_CLIENT_LEADER atom."
827 (defun XGetWMTransientFor (xdpy win)
828 "Get WM_TRANSIENT_FOR property.
829 Returns list in form `(seq val window-for-wich-win-is-trasient)'."
830 (let ((awid (XGetWindowProperty xdpy win XA-wm-transient-for 0 1 nil XA-window)))
831 (when (and awid (= (car awid) (X-Atom-id XA-window)))
834 (defun XGetWMState (xdpy win)
835 "On display XDPY get WM_STATE property for WIN."
836 (let ((wmsa (XInternAtom xdpy "WM_STATE" nil)))
837 (nth 2 (XGetWindowProperty xdpy win wmsa 0 2 wmsa))))
839 (defun XGetWMProtocols (xdpy win)
840 "On display XDPY get WM_PROTOCOLS property for WIN."
841 (cddr (XGetWindowProperty xdpy win (XInternAtom xdpy "WM_PROTOCOLS" nil) 0 1024 nil XA-atom)))
843 (defun XWMProtocol-set-p (xdpy wmprotos name)
844 "Return non-nil when atom with NAME is in WM_PROTOCOLS WMPROTO."
845 (member* (XInternAtom xdpy name t) wmprotos :test 'X-Atom-equal))
848 (defun XCreateColormap (xdpy win &optional v alloc)
849 ;; checkdoc-params: (v alloc)
850 "Create a colormap. Default values are:
852 VISUALID - ID or CopyFromParent
853 ALLOCATE - All are writable (1) (0 -> none writable)
855 args (XDPY WIN &optional VISUALID ALLOCATE)"
856 (X-Dpy-p xdpy 'XCreateColormap)
857 (X-Win-p win 'XCreateColormap)
859 (let* ((ncmap (make-X-Colormap :dpy xdpy :id (X-Dpy-get-id xdpy)))
861 (list [1 78] ; opcode
862 [1 (or alloc X-AllocAll)] ; alloc type
864 [4 (X-Colormap-id ncmap)] ; id to use
865 [4 (X-Win-id win)] ; window id
866 [4 (X-Visual-id (or v (XDefaultVisual xdpy)))]))
867 (msg (X-Create-message ListOfFields)))
868 (X-Dpy-send xdpy msg)
871 (defun XFreeColormap (xdpy cmap)
872 "Frees a colormap CMAP.
874 (X-Dpy-p xdpy 'XFreeColormap)
875 (X-Colormap-p cmap 'XFreeColormap)
878 (list [1 79] ; opcode
881 [4 (X-Colormap-id cmap)])) ; id to use
882 (msg (X-Create-message ListOfFields)))
883 (X-Dpy-send xdpy msg)
885 ;; Invalidate cmap structure so noone will longer use
886 (X-invalidate-cl-struct cmap)))
888 (defun XInstallColormap (xdpy cmap)
889 "Install colormap on xdpy."
890 (X-Dpy-p xdpy 'XInstallColormap)
891 (X-Colormap-p cmap 'XInstallColormap)
894 (list [1 81] ; opcode
897 [4 (X-Colormap-id cmap)])) ; id to use
898 (msg (X-Create-message ListOfFields)))
899 (X-Dpy-send xdpy msg)))
901 (defun XUninstallColormap (xdpy cmap)
902 "Uninstall colormap on xdpy."
903 (X-Dpy-p xdpy 'XUninstallColormap)
904 (X-Colormap-p cmap 'XUninstallColormap)
907 (list [1 82] ; opcode
910 [4 (X-Colormap-id cmap)])) ; id to use
911 (msg (X-Create-message ListOfFields)))
912 (X-Dpy-send xdpy msg)))
914 (defun XListInstalledColormaps (xdpy xwin)
915 "Return list of color maps installed on XWIN."
916 (X-Dpy-p xdpy 'XListInstalledColormaps)
917 (X-Win-p xwin 'XListInstalledColormaps)
920 (list [1 83] ; opcode
923 [4 (X-Win-id xwin)])) ; x window
925 (list [1 success] ; status message
926 nil ; generic bad response
927 (list [1 nil] ; unused
928 [2 integerp] ; sequence
929 [4 length-1] ; reply length
930 [2 length-2] ; number of Colormaps
932 [(* 4 length-2) integerp])))) ; cmaps
933 (X-Dpy-send-read xdpy (X-Create-message ListOfFields) ReceiveFields)))
935 (defun XAllocColor (xdpy cmap color)
936 "On display XDPY allocate in CMAP the color struct COLOR.
937 Use `X-Color' to create.
938 Returns non-nil if successful."
939 (X-Dpy-p xdpy 'XAllocColor)
940 (X-Colormap-p cmap 'XAllocColor)
941 (X-Color-p color 'XAllocColor)
943 (let ((col (X-Colormap-lookup-by-rgb cmap color)))
948 (list [1 84] ; opcode
950 [2 4] ; request length
951 [4 (X-Colormap-id cmap)] ; colormap handle
952 [2 (X-Color-red color)] ; red
953 [2 (X-Color-green color)] ; green
954 [2 (X-Color-blue color)] ; blue
956 (msg (X-Create-message ListOfFields))
958 (list [1 success] ; status message
959 nil ; generic bad response
960 (list [1 nil] ; unused
961 [2 integerp] ; sequence
962 [4 nil] ; reply length
967 [4 integerp] ; pixel value
968 [12 nil]))) ; padding
970 (setq r (X-Dpy-send-read xdpy msg ReceiveFields))
974 (setf (X-Color-id color) (nth 5 r))
975 (setf (X-Color-red color) (nth 2 r))
976 (setf (X-Color-green color) (nth 3 r))
977 (setf (X-Color-blue color) (nth 4 r))
978 (setf (X-Color-cmap color) cmap)
980 (pushnew color (X-Colormap-colors cmap)) ; cache color
984 (defun XAllocNamedColor (xdpy cmap name &optional color-exact)
985 "Allocate a color based on the color struct COLOR-VISUAL and COLOR-EXACT.
986 If COLOR-EXACT is nil or absent, ignore.
987 args (DISPLAY CMAP NAME COLOR-VISUAL &optional COLOR-EXACT)"
988 ;; checkdoc-order: nil
989 (X-Dpy-p xdpy 'XAllocNamedColor)
990 (X-Colormap-p cmap 'XAllocNamedColor)
993 (X-Color-p color-exact 'XAllocNamedColor))
995 (let ((col (X-Colormap-lookup-by-name cmap name)))
1000 (list [1 85] ;opcode
1002 [2 (+ 3 (X-padlen name))] ;length
1003 [4 (X-Colormap-id cmap)] ;colormap
1004 [2 (length name)] ;length of name
1006 [(length name) name] ;the name
1008 (msg (X-Create-message ListOfFields))
1010 (list [1 success] ;success field
1012 (list [1 nil] ;unused
1013 [2 integerp] ;sequence
1015 [4 integerp] ;pixel id
1016 [2 integerp] ;exact red
1017 [2 integerp] ;exact green
1018 [2 integerp] ;exact blue
1019 [2 integerp] ;visual red
1020 [2 integerp] ;visual green
1021 [2 integerp] ;visual blue
1024 (setq r (X-Dpy-send-read xdpy msg ReceiveFields))
1028 (setq col (make-X-Color :dpy xdpy
1037 (setf (X-Color-id color-exact) (nth 2 r))
1038 (setf (X-Color-red color-exact) (nth 3 r))
1039 (setf (X-Color-green color-exact) (nth 4 r))
1040 (setf (X-Color-blue color-exact) (nth 5 r))
1041 (setf (X-Color-cmap color-exact) cmap))
1043 (pushnew col (X-Colormap-colors cmap))
1048 (defun XAllocColorCells (xdpy cmap ncolors nplanes &optional contiguous)
1049 "On display XDPY allocate NCOLORS in colormap CMAP."
1050 (X-Dpy-p xdpy 'XAllocColorCells)
1051 (X-Colormap-p cmap 'XAllocColorCells)
1053 (let* ((ListOfFields
1054 (list [1 86] ; opcode
1057 [4 (X-Colormap-id cmap)]
1060 (msg (X-Create-message ListOfFields))
1065 [2 integerp] ;sequence
1066 [4 integerp] ; length
1067 [2 length-1] ; number of pixels
1068 [2 length-2] ; number of masks
1070 [length-1 ([4 integerp])]
1071 [length-2 ([4 integerp])]))))
1072 (X-Dpy-send-read xdpy msg ReceiveFields)))
1074 (defun XStoreColors (xdpy cmap colors)
1075 "On display XDPY in CMAP, store COLORS. (A list of 'X-Color)
1076 These colors are X-Color lists containing the PIXEL, RGB values and
1077 FLAGs (which indicates what part of the RGB value is stored into
1079 (X-Dpy-p xdpy 'XStoreColors)
1080 (X-Colormap-p cmap 'XStoreColors)
1082 (let* ((ListOfFields
1083 (list [1 89] ;opcode
1085 [2 (+ 2 (* 3 (length colors)))] ;request length
1086 [4 (X-Colormap-id cmap)] ;COLORMAP
1088 (msg (X-Create-message ListOfFields)))
1090 (setq msg (concat msg (X-Color-message (car colors)))
1091 colors (cdr colors)))
1092 (X-Dpy-send xdpy msg)))
1094 (defun XStoreColor (xdpy cmap color &optional R G B)
1095 "On display XDPY in CMAP, store COLORS.
1096 These colors are X-Color lists containing the PIXEL, RGB values and
1097 FLAGs (which indicates what part of the RGB value is stored into
1099 Optionally, COLOR can be a float, and it's new value indicated by
1100 the values of RGB, or X-Color and it will be stored as is."
1103 (if (X-Color-p color)
1105 (make-X-Color :id color
1109 :flags (Xmask-or (if R X-DoRed 0)
1111 (if B X-DoBlue 0))))))
1113 (defun XFreeColors (xdpy cmap colors planes)
1114 "On display XDPY in CMAP, free COLORS from the server.
1115 The colors are deallocated on PLANES, which is a mask. Use 0 for
1116 PLANES if you don't know what it's for."
1117 (X-Dpy-p xdpy 'XFreeColors)
1118 (X-Colormap-p cmap 'XFreeColors)
1120 (when (not (listp colors))
1121 (signal 'wrong-type-argument (list 'signal 'listp colors)))
1122 (mapc 'X-Colormap-p colors)
1124 (let* ((ListOfFields
1125 (list [1 88] ;opcode
1127 [2 (+ 3 (length colors))];length
1128 [4 (X-Colormap-id cmap)] ;Colormap
1129 [4 planes])) ;plane mask
1130 (msg (concat (X-Create-message ListOfFields)
1131 (X-Generate-message-for-list
1133 #'(lambda (col) (int->string4 (X-Color-id col)))))))
1134 (X-Dpy-send xdpy msg)
1137 ;; - We should'nt invalidate colors, because they may be still
1138 ;; used, FreeColors actually frees colors when there no any
1139 ;; references to them.
1140 ; ;; Invalidate each color.
1141 ; (mapc 'X-invalidate-cl-struct colors)
1144 (defun XQueryColors (xdpy cmap color-ids)
1145 "On display XDPY and colormap CMAP query COLOR-IDS."
1146 (X-Dpy-p xdpy 'XQueryColors)
1147 (X-Colormap-p cmap 'XQueryColors)
1149 (let* ((ListOfFields
1150 (list [1 91] ;opcode
1152 [2 (+ 2 (length color-ids))] ;request length
1153 [4 (X-Colormap-id cmap)] ;COLORMAP
1155 (msg (concat (X-Create-message ListOfFields)
1156 (X-Generate-message-for-list
1158 #'(lambda (colid) (int->string4 colid)))))
1163 [2 integerp] ;sequence
1164 [4 integerp] ;reply length
1165 [2 length-2] ;number of rgbs
1169 [2 integerp] ; green
1173 (X-Dpy-send-read xdpy msg ReceiveFields)))
1175 ;;; Graphical context operations
1177 (defun XCreateGC (xdpy d gc)
1178 "Allocate a graphic context display XDPY on the drawable D.
1179 Base this new context on GC."
1180 (X-Dpy-p xdpy 'XCreateGC)
1181 (X-Drawable-p d 'XCreateGC)
1182 (X-Gc-p gc 'XCreateGC)
1184 (let* ((attrmsg (X-Gc-message gc))
1186 (list [1 55] ;opcode
1188 ;; 4 fields, but 1 is in attrmsg, making 3
1189 [2 (+ 3 (/ (length attrmsg) 4))] ;request length
1190 [4 (X-Gc-id gc)] ;GC id
1191 [4 (X-Drawable-id d)] ;drawable id
1193 (msg (concat (X-Create-message ListOfFields) attrmsg)))
1194 (X-Dpy-send xdpy msg)
1196 ;; Seems lame, but return the GC we were passed originally.
1199 (defun XChangeGC (xdpy gc)
1200 "On display XDPY change GC to have new VALUES.
1201 I.e. update GC's info on server."
1202 (X-Dpy-p xdpy 'XChangeGC)
1203 (X-Gc-p gc 'XChangeGC)
1205 (let* ((attrmsg (X-Gc-message gc))
1207 (list [1 56] ;opcode
1209 [2 (+ 2 (/ (length attrmsg) 4))] ;request length
1210 [4 (X-Gc-id gc)] ;the GC
1212 (msg (concat (X-Create-message ListOfFields) attrmsg)))
1213 (X-Dpy-send xdpy msg)
1216 (defun XSetDashes (xdpy gc dash-offset dashes)
1217 "On display XDPY for GC set DASH-OFFSET and DASHES for dashed line styles."
1218 (X-Dpy-p xdpy 'XSetDashes)
1219 (X-Gc-p gc 'XSetDashes)
1221 (let* ((dstr (apply 'concat (mapcar 'int->string1 dashes)))
1223 (list [1 58] ;opcode
1225 [2 (+ 3 (X-padlen dstr))] ;request length
1226 [4 (X-Gc-id gc)] ;the GC
1230 (msg (concat (X-Create-message ListOfFields) dstr)))
1231 (X-Dpy-send xdpy msg)
1234 (defun XSetClipRectangles (xdpy gc clip-x-origin clip-y-origin rectangles &optional order)
1235 "On display XDPY for GC change clip-mask according to CLIP-X-ORIGIN,
1236 CLIP-Y-ORIGIN and RECTANGLES.
1238 You may specify ORDER to speed up X server, ORDER is one of
1239 `X-UnSorted', `X-YSorted', `X-YXSorted' or `X-YXBanded'."
1240 (X-Dpy-p xdpy 'XSetClipRectangles)
1241 (X-Gc-p gc 'XSetClipRectangles)
1244 (setq order X-UnSorted))
1246 (let* ((rstr (X-Generate-message-for-list rectangles 'X-Rect-message))
1248 (list [1 59] ;opcode
1249 (vector 1 order) ;Ordeding to speedup X server
1250 [2 (+ 3 (X-padlen rstr))] ;request length
1251 [4 (X-Gc-id gc)] ;the GC
1255 (msg (concat (X-Create-message ListOfFields) rstr)))
1256 (X-Dpy-send xdpy msg)
1259 (defun XFreeGC (xdpy gc)
1260 "Allocate a graphic context display XDPY on the drawable D.
1261 Base this new context on GC."
1262 (X-Dpy-p xdpy 'XFreeGC)
1263 (X-Gc-p gc 'XFreeGC)
1265 (let* ((ListOfFields
1266 (list [1 60] ;opcode
1269 [4 (X-Gc-id gc)] ;GC id
1271 (msg (X-Create-message ListOfFields)))
1272 (X-Dpy-send xdpy msg)
1274 ;; Invalidate gc structure.
1275 (X-invalidate-cl-struct gc)
1278 (defun XClearArea (xdpy win x y width height exposures)
1279 "On display XDPY in WIN clear rectangle X Y WIDTH HEIGHT."
1280 (X-Dpy-p xdpy 'XClearArea)
1281 (X-Win-p win 'XClearArea)
1283 (let* ((ListOfFields
1284 (list [1 61] ;opcode
1285 [1 exposures] ;exposures
1287 [4 (X-Win-id win)] ;window
1292 (msg (X-Create-message ListOfFields)))
1293 (X-Dpy-send xdpy msg)))
1295 (defun XCopyArea (xdpy src-d dst-d gc src-x src-y width height dst-x dst-y)
1296 "On display XDPY combine specified rectangle of SCR-D with DST-D."
1297 (X-Dpy-p xdpy 'XCopyArea)
1298 (X-Drawable-p src-d 'XCopyArea)
1299 (X-Drawable-p src-d 'XCopyArea)
1301 (let* ((ListOfFields
1302 (list [1 62] ;opcode
1305 [4 (X-Drawable-id src-d)] ; source drawable
1306 [4 (X-Drawable-id dst-d)] ; destination drawable
1314 (msg (X-Create-message ListOfFields)))
1315 (X-Dpy-send xdpy msg)))
1317 (defmacro XCopyAreaRect (xdpy src-d dst-d gc src-rect dst-x dst-y)
1318 "Same as `XCopyArea' but rectangle specified by SRC-RECT."
1319 `(XCopyArea ,xdpy ,src-d ,dst-d ,gc
1320 (X-Rect-x ,src-rect) (X-Rect-y ,src-rect)
1321 (X-Rect-width ,src-rect) (X-Rect-height ,src-rect)
1324 (defun XCopyPlane (xdpy src-d dst-d gc src-x src-y width height dst-x dst-y bit-plane)
1325 "On display XDPY ..."
1326 (X-Dpy-p xdpy 'XCopyPlane)
1327 (X-Drawable-p src-d 'XCopyPlane)
1328 (X-Drawable-p src-d 'XCopyPlane)
1330 (let* ((ListOfFields
1331 (list [1 63] ;opcode
1334 [4 (X-Drawable-id src-d)] ; source drawable
1335 [4 (X-Drawable-id dst-d)] ; destination drawable
1344 (msg (X-Create-message ListOfFields)))
1345 (X-Dpy-send xdpy msg)))
1347 (defmacro XCopyPlaneRect (xdpy src-d dst-d gc src-rect dst-x dst-y bit-plane)
1348 "Same as `XCopyPlane' but rectangle specified by SRC-RECT."
1349 `(XCopyPlane ,xdpy ,src-d ,dst-d ,gc
1350 (X-Rect-x ,src-rect) (X-Rect-y ,src-rect)
1351 (X-Rect-width ,src-rect) (X-Rect-height ,src-rect)
1352 ,dst-x ,dst-y ,bit-plane))
1354 ;;; Drawing routines
1356 (defun XDrawPoints (xdpy d gc pts &optional mode)
1357 "Draw points on a drawable. (XDPY D GC PTS &optional MODE)."
1358 (X-Dpy-p xdpy 'XDrawPoints)
1359 (X-Drawable-p d 'XDrawPoints)
1360 (X-Gc-p gc 'XDrawPoints)
1362 (let* ((ListOfFields
1363 (list [1 64] ; opcode
1364 [1 (or mode X-Origin)] ; mode of drawing, shutup compiler
1365 [2 (+ 3 (length pts))] ; request length
1366 [4 (X-Drawable-id d)] ; drawable id
1367 [4 (X-Gc-id gc)])) ; id of the GC
1368 (msg (concat (X-Create-message ListOfFields)
1369 (X-Generate-message-for-list pts 'X-Point-message))))
1370 (X-Dpy-send xdpy msg)))
1372 (defun XDrawPoint (xdpy d gc x y)
1373 "Draw a point. (XDPY D GC X Y)."
1374 (XDrawPoints xdpy d gc (list (cons x y)) X-Origin))
1376 (defun XDrawLines (xdpy d gc pts &optional mode)
1377 "Draw a multipoint line. (XDPY D GC PTS &optional MODE)."
1378 (X-Dpy-p xdpy 'XDrawLines)
1379 (X-Drawable-p d 'XDrawLines)
1380 (X-Gc-p gc 'XDrawLines)
1382 (let* ((ListOfFields
1383 (list [1 65] ; opcode
1384 [1 (or mode X-Origin)] ; mode of drawing, shut up compiler
1385 [2 (+ 3 (length pts))] ; request length
1386 [4 (X-Drawable-id d)]
1388 (msg (concat (X-Create-message ListOfFields)
1389 (X-Generate-message-for-list pts 'X-Point-message))))
1390 (X-Dpy-send xdpy msg)))
1392 (defun XFillPoly (xdpy d gc pts &optional shape mode)
1394 (X-Dpy-p xdpy 'XFillPoly)
1395 (X-Drawable-p d 'XFillPoly)
1396 (X-Gc-p gc 'XFillPoly)
1398 (let* ((ListOfFields
1399 (list [1 69] ; opcode
1401 [2 (+ 4 (length pts))] ; request length
1402 [4 (X-Drawable-id d)]
1404 [1 (or shape X-Nonconvex)]
1405 [1 (or mode X-Origin)]
1407 (msg (concat (X-Create-message ListOfFields)
1408 (X-Generate-message-for-list pts 'X-Point-message))))
1409 (X-Dpy-send xdpy msg)))
1411 (defun XDrawLine (xdpy d gc x y x2 y2)
1412 "Draw a line on display XDPY in drawable D.
1413 args (XDPY D GC X Y X2 Y2)."
1414 (XDrawLines xdpy d gc (list (cons x y) (cons x2 y2))))
1416 (defun XDrawSegments (xdpy d gc xsegments)
1417 "Draw Segments. (XDPY D GC PTS &optional MODE).
1418 Drawing segments is different from lines in that segments are disconnected
1419 every other pair of points."
1420 (X-Dpy-p xdpy 'XDrawSegments)
1421 (X-Drawable-p d 'XDrawSegments)
1422 (X-Gc-p gc 'XDrawSegments)
1424 (let* ((ListOfFields
1425 (list [1 66] ;opcode
1427 [2 (+ 3 (* 2 (length xsegments)))]
1428 [4 (X-Drawable-id d)]
1430 (msg (concat (X-Create-message ListOfFields)
1431 (X-Generate-message-for-list xsegments 'X-Segment-message))))
1432 (X-Dpy-send xdpy msg)))
1434 (defun XDrawRectangles (xdpy d gc rectangles &optional fill)
1435 "Draw rectangles. (XDPY D GC RECTANGLES &optional FILL)."
1436 (X-Dpy-p xdpy 'XDrawRectangles)
1437 (X-Drawable-p d 'XDrawRectangles)
1438 (X-Gc-p gc 'XDrawRectangles)
1440 (let* ((ListOfFields
1441 (list [1 (if fill 70 67)] ;opcode
1442 [1 nil] ;mode of drawing
1443 [2 (+ 3 (* (length rectangles) 2))] ; number of rects *2
1444 [4 (X-Drawable-id d)] ;drawable id
1445 [4 (X-Gc-id gc)])) ;id of the GC
1446 (msg (concat (X-Create-message ListOfFields)
1447 (X-Generate-message-for-list rectangles 'X-Rect-message))))
1448 (X-Dpy-send xdpy msg)))
1450 (defun XDrawRectangle (xdpy d gc x y width height)
1451 "Draw a rectangle. (XDPY D GC X Y WIDTH HEIGHT)."
1452 (XDrawRectangles xdpy d gc (list (make-X-Rect :x x :y y :width width :height height))))
1454 (defun XFillRectangle (xdpy d gc x y width height)
1455 "Draw a rectangle. (XDPY D GC X Y WIDTH HEIGHT)."
1456 (XDrawRectangles xdpy d gc (list (make-X-Rect :x x :y y :width width :height height)) t))
1458 (defun XFillRectangles (xdpy d gc rectangles)
1459 "Draw rectangles. (XDPY D GC RECTANGLES)."
1460 (XDrawRectangles xdpy d gc rectangles t))
1462 (defun XDrawArcs (xdpy d gc xarcs &optional fill mode)
1463 "Draw arcs. (XDPY D GC ARCS &optional FILL)."
1464 (X-Dpy-p xdpy 'XDrawArcs)
1465 (X-Drawable-p d 'XDrawArcs)
1466 (X-Gc-p gc 'XDrawArcs)
1468 (let* ((ListOfFields
1469 (list [1 (if fill 71 68)] ;opcode
1470 [1 mode] ;mode of drawing
1471 [2 (+ 3 (* 3 (length xarcs)))] ; number of arcs * 3
1472 [4 (X-Drawable-id d)] ;drawable id
1473 [4 (X-Gc-id gc)])) ;id of the GC
1474 (msg (concat (X-Create-message ListOfFields)
1475 (X-Generate-message-for-list xarcs 'X-Arc-message))))
1476 (X-Dpy-send xdpy msg)))
1478 (defun XDrawArc (xdpy d gc x y width height angle1 angle2 &optional fill mode)
1479 "Draw an arc on display XDPY in drawable D.
1480 args (DISPLAY D GC X Y WIDTH HEIGHT ANGLE1 ANGLE2)"
1481 (XDrawArcs xdpy d gc (list (make-X-Arc :x x :y y :width width :height height :angle1 angle1 :angle2 angle2)) fill))
1483 (defun XFillArc (xdpy d gc x y width height angle1 angle2 &optional mode)
1484 "Draw a filled arc on display XDPY in drawable D.
1485 args (DISPLAY D GC X Y WIDTH HEIGHT ANGLE1 ANGLE2)"
1486 (XDrawArcs xdpy d gc (list (make-X-Arc :x x :y y :width width :height height :angle1 angle1 :angle2 angle2)) t mode))
1488 (defun XFillArcs (xdpy d gc arcs &optional mode)
1489 "Draw filled arcs. (XDPY D GC ARCS)."
1490 (XDrawArcs xdpy d gc arcs t mode))
1492 (defun XDrawString (xdpy d gc x y str &optional len)
1493 "Draw a string at specified point. (XDPY D GC X Y STR &optional LEN)."
1494 (X-Dpy-p xdpy 'XDrawString)
1495 (X-Drawable-p d 'XDrawString)
1496 (X-Gc-p gc 'XDrawString)
1498 ;; Check len, must be < 255
1499 (when (or (and len (>= len 255))
1500 (>= (length str) 255))
1501 (setq str (substring str 0 254)))
1503 (let* ((slen (if len len (length str))) ;make len optional
1505 (list [1 74] ;opcode
1507 [2 (+ 4 (X-padlen (concat "12" str)))] ;length
1508 [4 (X-Drawable-id d)] ;drawable id
1509 [4 (X-Gc-id gc)] ;gc id
1512 (vector 1 slen) ;text length, shutup compiler
1513 [1 0] ;delta????????
1514 [slen str] ;the string
1516 ;; auto-padding in X-create
1517 (msg (X-Create-message ListOfFields)))
1518 (X-Dpy-send xdpy msg)))
1520 (defun XImageString (xdpy d gc x y str &optional len)
1521 "Draw a string using ImageText8 request.
1522 XDPY, D, GC, X, Y, STR and LEN are the same as in `XDrawString'."
1523 (X-Dpy-p xdpy 'XImageString)
1524 (X-Drawable-p d 'XImageString)
1525 (X-Gc-p gc 'XImageString)
1527 (let* ((slen (if len len (length str))) ; make len optional
1529 (list [1 76] ; opcode
1530 (vector 1 slen) ; string length, shutup compiler
1531 [2 (+ 4 (/ (+ (X-pad slen) slen) 4))] ;length
1532 [4 (X-Drawable-id d)] ;drawable id
1533 [4 (X-Gc-id gc)] ;gc id
1538 ;; auto-padding in X-create
1539 (msg (X-Create-message ListOfFields)))
1540 (X-Dpy-send xdpy msg)))
1542 (defun XDrawText8 ()
1545 (defun XDrawText16 ()
1548 (defun XPutImage (xdpy d gc depth width height dst-x dst-y left-pad format data)
1549 "On display XDPY and drawable D, put an image."
1550 (X-Dpy-p xdpy 'XPutImage)
1551 (X-Drawable-p d 'XPutImage)
1552 (X-Gc-p gc 'XPutImage)
1554 (let* ((ListOfFields
1555 (list [1 72] ; opcode
1557 [2 (+ 6 (X-padlen data))]
1558 [4 (X-Drawable-id d)]
1567 [(length data) data]
1568 [(X-pad (length data)) nil]))
1569 (msg (X-Create-message ListOfFields)))
1570 (X-Dpy-send xdpy msg)))
1572 (defun XGetImage (xdpy d x y width height plane-mask format)
1573 "On display XDPY and drawable D, get image with geometry WIDTHxHEIGHT+X+Y in FORMAT.
1574 PLANE-MASK is one of `X-AllPlanes' or something elese."
1575 (X-Dpy-p xdpy 'XGetImage)
1576 (X-Drawable-p d 'XGetImage)
1578 (let* ((ListOfFields
1579 (list [1 73] ; opcode
1582 [4 (X-Drawable-id d)] ; drawable
1588 (msg (X-Create-message ListOfFields))
1592 (list [1 integerp] ; depth
1593 [2 integerp] ; sequence
1594 [4 length-1] ; length
1595 [4 integerp] ; visual id or X-None
1597 [(* length-1 4) stringp])))) ;data
1598 (X-Dpy-send-read xdpy msg ReceiveFields)))
1599 ; [(X-mod-4 length-1) nil])))) ; padding
1601 ;;; Selections operations
1602 (defun XSetSelectionOwner (xdpy selection-atom &optional owner-win time)
1603 "Set SELECTION-ATOM to be owned by OWNER-WIN."
1604 (X-Dpy-p xdpy 'XSetSelectionOwner)
1606 (let* ((ListOfFields
1607 (list [1 22] ;opcode
1610 [4 (if owner-win (X-Win-id owner-win) X-None)] ;owner window
1611 [4 (X-Atom-id selection-atom)] ; selection atom
1612 [4 (if time time X-CurrentTime)]))
1613 (msg (X-Create-message ListOfFields)))
1614 (X-Dpy-send xdpy msg)))
1616 (defun XGetSelectionOwner (xdpy selection-atom)
1617 "Get owner of SELECTION-ATOM on display XDPY.
1618 Returns nil or X-Win structure."
1619 (X-Dpy-p xdpy 'XGetSelectionOwner)
1621 (let* ((ListOfFields
1622 (list [1 23] ;opcode
1625 [4 (X-Atom-id selection-atom)])) ;selection atom
1626 (msg (X-Create-message ListOfFields))
1628 (list [1 success] ;success field
1630 (list [1 nil] ;unused
1631 [2 integerp] ;sequence
1633 [4 integerp] ;owner window
1636 (setq r (X-Dpy-send-read xdpy msg ReceiveFields))
1638 (setq win (X-Win-find-or-make xdpy (nth 2 r))))
1641 (defun XConvertSelection (xdpy selection target prop requestor &optional time)
1643 (X-Dpy-p xdpy 'XConvertSelection)
1645 (let* ((ListOfFields
1646 (list [1 24] ;opcode
1649 [4 (if requestor (X-Win-id requestor) X-None)] ;owner window
1650 [4 (X-Atom-id selection)] ; selection atom
1651 [4 (X-Atom-id target)] ; target atom
1652 [4 (if prop (X-Atom-id prop) X-None)] ; property atom
1653 [4 (or time X-CurrentTime)]))
1654 (msg (X-Create-message ListOfFields)))
1655 (X-Dpy-send xdpy msg)))
1658 (defun XWarpPointer (xdpy src-win dst-win src-x src-y src-width src-height dest-x dest-y)
1659 "On display XDPY warp pointer to DEST-X DEST-Y"
1660 (X-Dpy-p xdpy 'XWarpPointer)
1661 ; (X-Win-p src-win 'XWarpPointer)
1662 ; (X-Win-p dst-win 'XWarpPointer)
1664 (let* ((srcid (or (and (X-Win-p src-win) (X-Win-id src-win)) src-win))
1665 (dstid (or (and (X-Win-p dst-win) (X-Win-id dst-win)) dst-win))
1667 (list [1 41] ; opcode
1670 (vector 4 srcid) ; source window
1671 (vector 4 dstid) ; dst window
1678 (msg (X-Create-message ListOfFields)))
1679 (X-Dpy-send xdpy msg)))
1682 (defun XGrabServer (xdpy)
1683 "Grabs X server on display XDPY"
1684 (X-Dpy-p xdpy 'XGrabServer)
1686 (let* ((ListOfFields
1687 (list [1 36] ;opcode
1690 (msg (X-Create-message ListOfFields)))
1691 (X-Dpy-send xdpy msg)))
1693 (defun XUngrabServer (xdpy)
1694 "Ungrab X server on display XDPY."
1695 (X-Dpy-p xdpy 'XUngrabServer)
1697 (let* ((ListOfFields
1698 (list [1 37] ;opcode
1701 (msg (X-Create-message ListOfFields)))
1702 (X-Dpy-send xdpy msg)))
1704 (defun XQueryPointer (xdpy xwin)
1705 "In display XDPY and window XWIN query pointer position."
1706 (X-Dpy-p xdpy 'XQueryPointer)
1708 (let* ((ListOfFields
1709 (list [1 38] ; opcode
1712 [4 (X-Win-id xwin)]))
1713 (msg (X-Create-message ListOfFields))
1715 (list [1 success] ;success field
1717 (list [1 integerp] ; same-screen
1718 [2 integerp] ; sequence
1722 [2 integerp] ; root-x
1723 [2 integerp] ; root-y
1724 [2 integerp] ; win-x
1725 [2 integerp] ; win-y
1728 (X-Dpy-send-read xdpy msg ReceiveFields)))
1730 (defun XGrabKeyboard (xdpy grab-win &optional owe pmode kmode time)
1731 "On display XDPY in window GRAB-WIN start grabbing keyboard.
1732 OWE - owner events (default `nil')
1733 PMODE - Pointer grabbing mode (default `X-GrabModeAsync')
1734 KMODE - Keyboard grabbing mode (default `X-GrabModeAsync')
1735 TIME - Time when start to grab (default `X-CurrentTime')"
1736 (X-Dpy-p xdpy 'XGrabKeyboard)
1737 (X-Win-p grab-win 'XGrabKeyboard)
1739 (let* ((ListOfFields
1740 (list [1 31] ; opcode
1741 [1 owe] ; owner_events
1743 [4 (X-Win-id grab-win)] ; grab window
1744 [4 (or time X-CurrentTime)] ; time
1745 [1 (or pmode X-GrabModeAsync)] ; pointer mode
1746 [1 (or kmode X-GrabModeAsync)] ; keyboard mode
1748 (msg (X-Create-message ListOfFields))
1750 (list [1 success] ;success field
1752 (list [1 integerp] ;status
1753 [2 integerp] ;sequence
1754 [4 integerp] ;length . Hmm length-1
1757 ; ([4 nil]) ])))) ;pad
1758 (X-Dpy-send-read xdpy msg ReceiveFields)))
1760 (defun XUngrabKeyboard (xdpy &optional time)
1761 "On display XDPY at TIME stop grabbing keyboard.
1762 Default TIME is `X-CurrentTime'."
1763 (X-Dpy-p xdpy 'XUngrabKeyboard)
1765 (let* ((ListOfFields
1766 (list [1 32] ; opcode
1767 [1 nil] ; owner_events
1769 [4 (if time time X-CurrentTime)]))
1770 (msg (X-Create-message ListOfFields)))
1771 (X-Dpy-send xdpy msg)))
1773 (defun XGrabPointer (xdpy grab-win ev-mask &optional cursor owe pmode kmode confto-win time)
1774 "On display XDPY in window GRAB-WIN start grabbing pointer.
1775 CURSOR - Cursor to use while grabbing.
1776 EV-MASK - Mask for events to receive. Result of `Xmask-or'.
1777 OWE - owner events (default `nil')
1778 PMODE - Pointer grabbing mode (default `X-GrabModeAsync')
1779 KMODE - Keyboard grabbing mode (default `X-GrabModeAsync')
1780 CONFTO-WIN - Confine to window (default `nil'
1781 TIME - Time when start to grab (default `X-CurrentTime')"
1782 (X-Dpy-p xdpy 'XGrabPointer)
1783 (X-Win-p grab-win 'XGrabPointer)
1785 (let* ((ListOfFields
1786 (list [1 26] ;opcode
1789 [4 (X-Win-id grab-win)] ;grab window
1790 [2 ev-mask] ;event mask
1791 [1 (or pmode X-GrabModeAsync)] ;pointerMode
1792 [1 (or kmode X-GrabModeAsync)] ;keyboardMode
1793 [4 (if confto-win (X-Win-id confto-win) 0.0)] ;confineTo window
1794 [4 (if cursor (X-Cursor-id cursor) 0.0)] ;Cursor
1795 [4 (or time X-CurrentTime)]))
1796 (msg (X-Create-message ListOfFields))
1800 (list [1 nil] ;unsed
1801 [2 integerp] ;sequence
1802 [28 nil])))) ;padding
1803 (X-Dpy-send-read xdpy msg ReceiveFields)))
1805 (defun XUngrabPointer (xdpy &optional time)
1806 "On display XDPY at TIME, stop grabbing pointer."
1807 (X-Dpy-p xdpy 'XUngrabPointer)
1809 (let* ((ListOfFields
1810 (list [1 27] ;opcode
1813 [4 (or time X-CurrentTime)]))
1814 (msg (X-Create-message ListOfFields)))
1815 (X-Dpy-send xdpy msg)))
1817 (defun XGrabButton (xdpy button mods grab-win ev-mask &optional cursor owe pmode kmode conf-to)
1818 "On display XDPY in window GRAB-WIN, start grabbing for BUTTON with MODS.
1819 TODO: Describe optional arguments."
1820 (X-Dpy-p xdpy 'XGrabButton)
1821 (X-Win-p grab-win 'XGrabButton)
1823 (let* ((ListOfFields
1824 (list [1 28] ; opcode
1825 [1 (if owe owe nil)]
1827 [4 (X-Win-id grab-win)]
1829 [1 (or pmode X-GrabModeAsync)]
1830 [1 (or kmode X-GrabModeAsync)]
1831 [4 (if conf-to (X-Win-id conf-to) 0.0)]
1832 [4 (if cursor (X-Cursor-id cursor) 0.0)]
1836 (msg (X-Create-message ListOfFields)))
1837 (X-Dpy-send xdpy msg)))
1839 (defun XUngrabButton (xdpy button mods grab-win)
1840 "On display XDPY in window GRAB-WIN stop grabbing for BUTTON with MODS."
1841 (X-Dpy-p xdpy 'XUngrabButton)
1842 (X-Win-p grab-win 'XUngrabButton)
1844 (let* ((ListOfFields
1845 (list [1 29] ; opcode
1848 [4 (X-Win-id grab-win)]
1851 (msg (X-Create-message ListOfFields)))
1852 (X-Dpy-send xdpy msg)))
1854 (defun XGrabKey (xdpy keycode mods grab-win &optional owe pmode kmode)
1855 "On display XDPY in window GRAB-WIN start grabbing for KEYCODE with MODS.
1856 TODO: Description for OWE, PMODE and KMODE."
1857 (X-Dpy-p xdpy 'XGrabKey)
1858 (X-Win-p grab-win 'XGrabKey)
1860 (let ((ListOfFields `([1 33] ; opcode
1861 [1 ,owe] ; owner_events
1863 [4 ,(X-Win-id grab-win)] ; grab window
1864 [2 ,mods] ; modifiers
1866 [1 ,(or pmode X-GrabModeAsync)] ; pointer mode
1867 [1 ,(or kmode X-GrabModeAsync)] ; keyboard mode
1869 (X-Dpy-send xdpy (X-Create-message ListOfFields))))
1871 (defun XUngrabKey (xdpy keycode mods grab-win)
1872 "On display XDPY in window GRAB-WIN stop grabbing KEYCODE with MODS."
1873 (X-Dpy-p xdpy 'XUngrabKey)
1874 (X-Win-p grab-win 'XUngrabKey)
1876 (let* ((ListOfFields
1877 (list [1 34] ; opcode
1878 [1 keycode] ; keycode
1880 [4 (X-Win-id grab-win)] ; grab window
1881 [2 mods] ; modifiers
1883 (msg (X-Create-message ListOfFields)))
1884 (X-Dpy-send xdpy msg)))
1886 (defun XAllowEvents (xdpy mode &optional time)
1887 "On display XDPY allow events in MODE."
1888 (X-Dpy-p xdpy 'XAllowEvents)
1890 (let* ((ListOfFields
1894 [4 (or time X-CurrentTime)]))
1895 (msg (X-Create-message ListOfFields)))
1896 (X-Dpy-send xdpy msg)))
1900 (defun XGetInputFocus (xdpy)
1901 "On display XDPY get curret input focus."
1902 (X-Dpy-p xdpy 'XGetInputFocus)
1904 (let* ((ListOfFields
1905 (list [1 43] ;opcode
1908 (msg (X-Create-message ListOfFields))
1912 (list [1 integerp] ;revertTo
1913 [2 integerp] ;sequence
1915 [4 integerp] ;focus win
1918 (setq r (X-Dpy-send-read xdpy msg ReceiveFields))
1921 (if (member (nth 3 r) (list X-PointerRoot X-None))
1922 (setq thing (nth 3 r))
1923 (setq thing (X-Win-find xdpy (nth 3 r)))))
1926 (defun XSetInputFocus (xdpy win-or-val rev-to &optional time)
1927 "On display XDPY set input focus to window WIN-OR-VAL.
1928 REV-TO - Focus revert to when WIN-OR-VAL will lost input focus.
1929 TIME - Set input focus at this time (default `X-CurrentTime')"
1930 (X-Dpy-p xdpy 'XSetInputFocus)
1932 (let* ((ListOfFields
1933 (list [1 42] ; opcode
1934 [1 rev-to] ; Revert to
1936 [4 (cond ((integerp win-or-val) win-or-val) ;X-PointerRoot, X-None, etc
1937 ((X-Win-p win-or-val) (X-Win-id win-or-val)) ;window
1940 (msg (X-Create-message ListOfFields)))
1941 (X-Dpy-send xdpy msg)))
1944 (defun XReparentWindow (xdpy win parwin x y)
1945 "On display XDPY reparent window WIN to PARWIN at X Y."
1946 (X-Dpy-p xdpy 'XReparentWindow)
1947 (X-Win-p win 'XReparentWindow)
1948 (X-Win-p parwin 'XReparentWindow)
1950 (let* ((ListOfFields
1954 [4 (X-Win-id win)] ;win
1955 [4 (X-Win-id parwin)] ;parent window
1958 (msg (X-Create-message ListOfFields)))
1959 (X-Dpy-send xdpy msg)))
1961 (defun XGetGeometry (xdpy d)
1962 "On display XDPY return geomtry for drawable D.
1963 Side effect of this function is to set 'xdepth property in drawable
1965 (X-Dpy-p xdpy 'XGetGeometry)
1966 (X-Drawable-p d 'XGetGeometry)
1968 (let* ((ListOfFields
1969 (list [1 14] ;opcode
1972 [4 (X-Drawable-id d)])) ;chars in string
1973 (msg (X-Create-message ListOfFields))
1977 (list [1 integerp] ;depth
1978 [2 integerp] ;sequence
1984 [2 integerp] ;height
1985 [2 integerp] ;border width
1988 (setq r (X-Dpy-send-read xdpy msg ReceiveFields))
1991 (X-Win-put-prop d 'xdepth (nth 1 r))
1992 (X-Pixmap-put-prop d 'xdepth (nth 1 r)))
1993 (setq rgeom (make-X-Geom :x (nth 4 r)
1997 :border-width (nth 8 r))))
2000 (defun XGetDepth (xdpy d)
2001 "On display xdpy return drawable's D depth."
2003 (X-Win-get-prop d 'xdepth)
2004 (X-Pixmap-get-prop d 'xdepth))
2006 (XGetGeometry xdpy d)
2008 (X-Win-get-prop d 'xdepth)
2009 (X-Pixmap-get-prop d 'xdepth)))))
2011 ;; TODO: XTranslateCoordinates
2012 (defun XTranslateCoordinates (xdpy src-win dst-win src-x src-y)
2013 "On display XDPY translate SCR-X SCR-y coordinates to coordinates on DST-WIN."
2014 (X-Dpy-p xdpy 'XTranslateCoordinates)
2015 (X-Win-p src-win 'XTranslateCoordinates)
2016 (X-Win-p dst-win 'XTranslateCoordinates)
2018 (let* ((ListOfFields
2019 (list [1 40] ;opcode
2022 [4 (X-Win-id src-win)] ;source win
2023 [4 (X-Win-id dst-win)] ;destination win
2026 (msg (X-Create-message ListOfFields))
2030 (list [1 booleanp] ;same-screen
2031 [2 integerp] ;sequence
2038 (setq r (X-Dpy-send-read xdpy msg ReceiveFields))
2040 (cons (cons (nth 4 r) (nth 5 r)) (nth 3 r))
2043 (defun XChangeSaveSet (xdpy win change-mode)
2044 "On display XDPY change SaveSet according to CHANGE-MODE."
2045 (X-Dpy-p xdpy 'XChangeSaveSet)
2046 (X-Win-p win 'XChangeSaveSet)
2048 (let* ((ListOfFields
2049 (list [1 6] ; opcode
2052 [4 (X-Win-id win)]))
2053 (msg (X-Create-message ListOfFields)))
2054 (X-Dpy-send xdpy msg)))
2056 (defun XSendEvent (xdpy win propogate ev_mask xevent)
2057 "WIN is X11 window or one of X-InputFocus, X-XXXxxxXXX.
2058 Evil hack, do not use this function."
2059 (X-Dpy-p xdpy 'XSendEvent)
2061 (let* ((ListOfFields
2062 (list [1 25] ; opcode
2064 [2 11] ;(+ 3 (X-padlen xevent))] ;length
2065 [4 (if (X-Win-p win) (X-Win-id win) win)]
2066 [4 ev_mask])) ;event mask
2067 (padding (make-string (- 44 12 (length xevent)) 0))
2068 (msg (concat (X-Create-message ListOfFields) xevent padding)))
2069 (X-Dpy-send xdpy msg)))
2072 ;;; Keyboard mapping
2073 (defun XQueryKeymap (xdpy)
2074 "On display XDPY query keyboard mapping."
2075 (X-Dpy-p xdpy 'XQueryKeymap)
2077 (let* ((ListOfFields
2078 (list [1 44] ;opcode
2081 (msg (X-Create-message ListOfFields))
2085 (list [1 nil] ;unused
2086 [2 integerp] ;sequence
2087 [4 integerp] ;length
2088 [32 nil])))) ;unknown
2090 (X-Dpy-send-read xdpy msg ReceiveFields)))
2092 (defun XGetKeyboardMapping (xdpy keycode count)
2093 "On display XDPY get keyboard mapping."
2094 (X-Dpy-p xdpy 'XGetKeyboardMapping)
2096 (let* ((ListOfFields
2097 (list [1 101] ;opcode
2100 [1 keycode] ;first_keycode
2103 (msg (X-Create-message ListOfFields))
2107 (list [1 length-1] ;keySymsPerKeyCode
2108 [2 integerp] ;sequence
2109 [4 length-2] ;length
2111 [count ;list of the children
2112 (make-list length-1 [4 integerp])]))))
2114 (X-Dpy-send-read xdpy msg ReceiveFields)))
2116 (defun XGetModifierMapping (xdpy)
2117 "On display XDPY get modifiers mapping."
2118 (X-Dpy-p xdpy 'XGetModifierMapping)
2120 (let* ((ListOfFields
2121 (list [1 119] ;opcode
2124 (msg (X-Create-message ListOfFields))
2128 (list [1 length-2] ;numKeyPerModifier
2129 [2 integerp] ;sequence
2130 [4 length-1] ;length
2137 [(/ (* length-1 4) length-2) ;list of the children
2138 (make-list length-2 [1 integerp])]))))
2140 (X-Dpy-send-read xdpy msg ReceiveFields)))
2143 (defun XOpenFont (xdpy font)
2144 "On display XDPY open FONT, created using `X-Font'."
2145 (X-Dpy-p xdpy 'XOpenFont)
2146 (X-Font-p font 'XOpenFont)
2148 (let* ((name (X-Font-name font))
2150 (list [1 45] ; opcode
2152 [2 (+ 3 (X-padlen name))] ;length
2153 [4 (X-Font-id font)]
2156 (msg (concat (X-Create-message ListOfFields) name (make-string (- (* 4 (X-padlen name)) (length name)) ?\0))))
2157 (X-Dpy-send xdpy msg)))
2159 (defun XQueryFont (xdpy font)
2160 "On display XDPY query for FONT."
2161 (X-Dpy-p xdpy 'XQueryFont)
2163 (let* ((ListOfFields
2164 (list [1 47] ; opcode
2167 [4 (X-Font-id font)]))
2168 (msg (X-Create-message ListOfFields))
2170 (list [1 success] ;success field
2172 (list [1 nil] ;unused
2173 [2 integerp] ;sequence
2174 [4 length-1] ;length
2176 ;; xCharInfo minBounds and maxBounds
2177 [2 ([2 integerp] ;leftSideBearing
2178 [2 integerp] ;rightSideBearing
2179 [2 integerp] ;characterWidth
2180 [2 integerp] ;ascent
2181 [2 integerp] ;descent
2182 [2 integerp] ;attributes
2185 [2 integerp] ;minCharOrByte2
2186 [2 integerp] ;maxCharOrByte2
2187 [2 integerp] ;defaultChar
2188 [2 length-2] ;nFontProps
2189 [1 integerp] ;drawDirection
2190 [1 integerp] ;minByte1
2191 [1 integerp] ;maxByte1
2192 [1 booleanp] ;allCharsExist
2193 [2 integerp] ;fontAscent
2194 [2 integerp] ;fontDescent
2195 [4 length-3] ;nCharInfos
2198 [length-2 ([4 integerp] ;atom name
2199 [4 integerp])] ;value
2202 [length-3 ([2 integerp] ; leftSideBearing
2203 [2 integerp] ; rightSideBearing
2204 [2 integerp] ; characterWidth
2205 [2 integerp] ; ascent
2206 [2 integerp] ; descent
2207 [2 integerp])] ; attributes
2210 (setq r (X-Dpy-send-read xdpy msg ReceiveFields))
2213 (let ((bounds (nth 2 r))
2215 (chinfo (nth 13 r)))
2217 (setf (X-Font-minb font) (vconcat (nth 0 bounds)))
2218 (setf (X-Font-maxb font) (vconcat (nth 1 bounds)))
2219 (setf (X-Font-micob font) (nth 3 r))
2220 (setf (X-Font-macob font) (nth 4 r))
2221 (setf (X-Font-defchar font) (nth 5 r))
2222 (setf (X-Font-nprops font) (length props))
2223 (setf (X-Font-dd font) (nth 6 r))
2224 (setf (X-Font-minbyte font) (nth 7 r))
2225 (setf (X-Font-maxbyte font) (nth 8 r))
2226 (setf (X-Font-allce font) (nth 9 r))
2227 (setf (X-Font-fontascent font) (nth 10 r))
2228 (setf (X-Font-fontdescent font) (nth 11 r))
2229 (setf (X-Font-ncinfo font) (length chinfo))
2230 (setf (X-Font-props font) (vconcat (mapcar 'vconcat props)))
2231 (setf (X-Font-chinfo font) (vconcat (mapcar 'vconcat chinfo)))
2235 (defun XQueryTextExtents (xdpy font string)
2236 "On display XDPY fetch FONT's info for STRING."
2237 (X-Dpy-p xdpy 'XQueryTextExtents)
2238 (X-Font-p font 'XQueryTextExtents)
2240 (let* ((ListOfFields
2241 (list [1 48] ; opcode
2242 [1 (% (length string) 2)] ;oddLength
2243 [2 (+ 2 (X-padlen (concat string string)))] ;length
2244 [4 (X-Font-id font)]))
2245 (msg (concat (X-Create-message ListOfFields)
2247 (mapcar #'(lambda (c) (string ?\0 c)) string))
2248 (when (> (% (length string) 2) 0) (make-string 2 ?\0))
2251 (list [1 success] ;success field
2253 (list [1 integerp] ;draw direction (> 0 - left to right, < - right to left)
2254 [2 integerp] ;sequence
2256 [2 integerp] ;font ascent
2257 [2 integerp] ;font descent
2258 [2 integerp] ;over all ascent
2259 [2 integerp] ;over all descont
2260 [4 numberp] ;over all width
2261 [4 numberp] ;over all left
2262 [4 numberp] ;over all right
2265 (X-Dpy-send-read xdpy msg ReceiveFields)))
2269 (defun XCreatePixmap (xdpy pixmap d depth width height)
2270 "On display XDPY create PIXMAP using drawable D.
2271 Return X-Pixmap structure."
2272 (X-Dpy-p xdpy 'XCreatePixmap)
2273 (X-Pixmap-p pixmap 'XCreatePixmap)
2276 (setf (X-Pixmap-width pixmap) width)
2277 (setf (X-Pixmap-height pixmap) height)
2278 (setf (X-Pixmap-depth pixmap) depth)
2280 ;; Set pixmap's drawable
2281 (setf (X-Pixmap-d pixmap) d)
2283 (let* ((ListOfFields
2284 (list [1 53] ; opcode
2287 [4 (X-Pixmap-id pixmap)]
2288 [4 (X-Drawable-id d)]
2291 (msg (X-Create-message ListOfFields)))
2292 (X-Dpy-send xdpy msg)
2295 (defun XFreePixmap (xdpy pixmap)
2296 "On display XDPY free pixmap."
2297 (X-Dpy-p xdpy 'XFreePixmap)
2298 (X-Pixmap-p pixmap 'XFreePixmap)
2300 (let* ((ListOfFields
2301 (list [1 54] ; opcode
2304 [4 (X-Pixmap-id pixmap)]))
2305 (msg (X-Create-message ListOfFields)))
2306 (X-Dpy-send xdpy msg)
2308 ;; Invalidate pixmap
2309 (X-invalidate-cl-struct pixmap)
2313 (defun XCreateCursor (xdpy type)
2314 "On display XDPY create cursor of TYPE."
2315 (X-Dpy-p xdpy 'XCreateCursor)
2317 (let* ((ListOfFields
2318 (list [1 93] ;opcode
2322 (msg (X-Create-message ListOfFields)))
2323 (X-Dpy-send xdpy msg)))
2325 (defun XCreateGlyphCursor (xdpy cursor)
2326 "On display XDPY create CURSOR.
2327 CURSOR is `X-Cursor' structure."
2328 (X-Dpy-p xdpy 'XCreateGlyphCursor)
2329 (X-Cursor-p cursor 'XCreateGlyphCursor)
2331 (unless (X-Cursor-id cursor)
2332 (setf (X-Cursor-id cursor) (X-Dpy-get-id xdpy)))
2334 (let* ((attrmsg (X-Cursor-message cursor))
2336 (list [1 94] ;opcode
2338 [2 (+ 2 (/ (length attrmsg) 4))] ;length
2339 [4 (X-Cursor-id cursor)])) ;cursor id
2340 (msg (concat (X-Create-message ListOfFields) attrmsg)))
2341 (X-Dpy-send xdpy msg)))
2343 (defun XFreeCursor (xdpy cursor)
2344 "On display XDPY free resources associated with CURSOR."
2346 (list [1 95] ;opcode
2349 [4 (X-Cursor-id cursor)]))) ;cursor id
2350 (X-Dpy-send xdpy (X-Create-message ListOfFields)))
2351 (X-invalidate-cl-struct cursor))
2353 (defun XRecolorCursor (xdpy cursor fore-red fore-green fore-blue &optional back-red back-green back-blue)
2354 "On display XDPY recolorize CURSOR."
2356 (setf (X-Cursor-fgred cursor) fore-red))
2358 (setf (X-Cursor-fggreen cursor) fore-green))
2360 (setf (X-Cursor-fgblue cursor) fore-blue))
2362 (setf (X-Cursor-bgred cursor) back-red))
2364 (setf (X-Cursor-bggreen cursor) back-green))
2366 (setf (X-Cursor-bgblue cursor) back-blue))
2369 (list [1 96] ;opcode
2372 [4 (X-Cursor-id cursor)] ;cursor id
2373 [2 (X-Cursor-fgred cursor)]
2374 [2 (X-Cursor-fggreen cursor)]
2375 [2 (X-Cursor-fgblue cursor)]
2376 [2 (X-Cursor-bgred cursor)]
2377 [2 (X-Cursor-bggreen cursor)]
2378 [2 (X-Cursor-bgblue cursor)])))
2379 (X-Dpy-send xdpy (X-Create-message ListOfFields))))
2381 (defun XChangeActivePointerGrab (xdpy cursor ev-mask &optional time)
2382 "Change active pointer grabbing."
2383 (X-Dpy-p xdpy 'XChangeActivePointerGrab)
2384 (X-Cursor-p cursor 'XChangeActivePointerGrab)
2386 (let* ((ListOfFields
2387 (list [1 30] ;opcode
2390 [4 (X-Cursor-id cursor)] ;cursor
2391 [4 (or time X-CurrentTime)]
2394 (msg (X-Create-message ListOfFields)))
2395 (X-Dpy-send xdpy msg)))
2397 ;;; Extensions support
2399 (defun XQueryExtension (xdpy name)
2400 "On display XDPY query for extension with NAME."
2401 (X-Dpy-p xdpy 'XQueryExtension)
2403 (let* ((ListOfFields
2404 (list [1 98] ;opcode
2406 [2 (+ 2 (X-padlen name))] ;length
2407 [2 (length name)] ;chars in string
2409 (msg (concat (X-Create-message ListOfFields)
2411 (make-string (- (* 4 (X-padlen name)) (length name)) 0)))
2415 (list [1 nil] ;unused
2416 [2 integerp] ;sequence
2418 [1 booleanp] ;present
2419 [1 integerp] ;major_opcode
2420 [1 integerp] ;first_event
2421 [1 integerp] ;first_error
2422 [20 nil]))) ;padding
2425 (setq r (X-Dpy-send-read xdpy msg ReceiveFields))
2426 (X-Dpy-log xdpy 'x-misc "Get reply for query ext: %s" 'r)
2429 (nth 2 r)) ; present field
2430 (pushnew (cons name r) (X-Dpy-extensions xdpy))
2433 (defun X-Dpy-get-extension (xdpy extname &optional sig)
2434 "On display XDPY get extension with EXTNAME.
2435 If SIG, then signal an error if extension is not available."
2436 (let ((ext (or (assoc extname (X-Dpy-extensions xdpy))
2437 (car (XQueryExtension xdpy extname)))))
2438 (if (and (null ext) sig)
2439 (signal 'search-failed (list sig 'X-Dpy-get-extension extname))
2442 ;; Screen saver support
2443 (defun XSetScreenSaver (xdpy timeout interval prefer-blacking allow-exposures)
2444 "On dispay XDPY set screen saver parameters."
2445 (X-Dpy-p xdpy 'XSetScreenSaver)
2447 (let* ((ListOfFields
2448 (list [1 107] ; opcode
2456 (msg (X-Create-message ListOfFields)))
2457 (X-Dpy-send xdpy msg)))
2459 (defun XGetScreenSaver (xdpy)
2460 "On display XDPY get info about screen saver."
2461 (X-Dpy-p xdpy 'XGetScreenSaver)
2463 (let* ((ListOfFields
2464 (list [1 108] ;opcode
2467 (msg (X-Create-message ListOfFields))
2474 [2 integerp] ; timeout
2475 [2 integerp] ; interval
2476 [1 booleanp] ; prefer-blacking
2477 [1 booleanp] ; allow-exposures
2479 (X-Dpy-send-read xdpy msg ReceiveFields)))
2481 (defun XKillClient (xdpy resource)
2482 "On display XDPY kill client RESOURCE."
2483 (X-Dpy-p xdpy 'XKillClient)
2485 (let* ((ListOfFields
2486 (list [1 113] ; opcode
2489 [4 resource])) ; resource ID
2490 (msg (X-Create-message ListOfFields)))
2491 (X-Dpy-send xdpy msg)))
2493 (defun XForceScreenSaver (xdpy &optional mode)
2494 "On display XDPY force screen saver in mode."
2495 (X-Dpy-p xdpy 'XForceScreenSaver)
2497 (let* ((ListOfFields
2498 (list [1 115] ; opcode
2501 (msg (X-Create-message ListOfFields)))
2502 (X-Dpy-send xdpy msg)))
2504 ;; Additional events queue operations
2505 (defun XNextEvent (xdpy &optional timeout predict)
2506 "On display XDPY get next X Event.
2507 Optionally you can specify TIMEOUT.
2508 If TIMEOUT specified and no event arrived in TIMEOUT period, return nil.
2509 If PREDICT is non-nil return only events which on which PREDICT returns non-nil,
2510 others(not matched) events continue processing normally."
2511 (let ((timo (and timeout (add-timeout timeout nil 'XNextEvent-timeout)))
2515 (let* ((nev (next-event))
2516 (type (event-type nev))
2518 (setq ret (cond ((and (eq type 'timeout)
2519 (eq (event-object nev) 'XNextEvent-timeout))
2520 (setq timo nil) ; unset it
2523 ((and (eq type 'eval)
2524 (X-Event-p (setq obj (event-object nev)))
2526 (funcall predict obj)))
2529 (t (dispatch-event nev) nil)))))
2532 (disable-timeout timo))
2535 (defun XIfEvent (xdpy predict)
2536 "Return next X event on XDPY, who match PREDICT."
2537 (XNextEvent xdpy nil predict))
2539 (defun XSyncEvents (xdpy)
2540 "Syncronize events ready for XDPY."
2541 (funcall (X-Dpy-parse-guess-dispatcher xdpy) xdpy))
2543 (defun XSync (xdpy &optional discard)
2545 When DISCARD is non nil, remove all events in events queue, even these
2546 who was before entering `XSync'."
2547 (XGetInputFocus xdpy))
2549 (defun XSetFont (xdpy gc font)
2550 "On display XDPY for GC set FONT."
2551 (X-Dpy-p xdpy 'XSetFont)
2552 (X-Gc-p gc 'XSetFont)
2553 (X-Font-p font 'XSetFont)
2555 (setf (X-Gc-font gc) font)
2556 (XChangeGC xdpy gc))
2558 (defalias 'XFlush 'X-Dpy-send-flush)
2561 (provide 'xlib-xlib)
2563 ;;; xlib-xlib.el ends here