PageRenderTime 65ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/clx/new-clx/clx.lisp

https://github.com/ynd/clisp-branch--ynd-devel
Lisp | 1837 lines | 1477 code | 190 blank | 170 comment | 10 complexity | 49fad498f922208ff578919a3346b0c3 MD5 | raw file
Possible License(s): LGPL-2.0, GPL-2.0, BSD-3-Clause
  1. ;;;; Copyright (C) 1996 by Gilbert Baumann
  2. ;;;; Copyright (C) 2001-2007 by Sam Steingold
  3. ;;;; Distributed under GPL.
  4. ;;;; Some parts are from the MIT-CLX Distribution, copyrighted by
  5. ;;;; Texas Instruments Incorporated, but freely distributable
  6. ;;;; for details see image.lisp or the MIT-CLX distribution.
  7. (defpackage #:xlib)
  8. (provide "clx")
  9. (in-package :xlib)
  10. (defvar *displays* nil)
  11. (push :clx *features*)
  12. (push :clx-ansi-common-lisp *features*)
  13. (declaim (declaration values))
  14. (defconstant *version* "CLISP-CLX 1997-06-12")
  15. ;;;; --------------------------------------------------------------------------
  16. ;;;; Exports
  17. ;;;; --------------------------------------------------------------------------
  18. (export
  19. '(*version* access-control access-error access-hosts activate-screen-saver
  20. add-access-host add-resource add-to-save-set alist alloc-color
  21. alloc-color-cells alloc-color-planes alloc-error allow-events angle
  22. arc-seq array-index atom-error atom-name bell bit-gravity bitmap
  23. bitmap-format bitmap-format-lsb-first-p bitmap-format-p
  24. bitmap-format-pad bitmap-format-unit bitmap-image boole-constant boolean
  25. card16 card29 card32 card8 card8->char change-active-pointer-grab
  26. change-keyboard-control change-keyboard-mapping change-pointer-control
  27. change-property char->card8 char-ascent char-attributes char-descent
  28. char-left-bearing char-right-bearing char-width character->keysyms
  29. character-in-map-p circulate-window-down circulate-window-up clear-area
  30. close-display close-down-mode close-font closed-display color color-blue
  31. color-green color-p color-red color-rgb colormap colormap-display
  32. colormap-equal colormap-error colormap-id colormap-p colormap-plist
  33. colormap-visual-info connection-failure convert-selection copy-area
  34. copy-colormap-and-free copy-gcontext copy-gcontext-components copy-image
  35. copy-plane create-colormap create-cursor create-gcontext
  36. create-glyph-cursor create-image create-pixmap create-window cursor
  37. cursor-display cursor-equal cursor-error cursor-id cursor-p cursor-plist
  38. cut-buffer declare-event decode-core-error default-error-handler
  39. default-keysym-index default-keysym-translate define-error
  40. define-extension define-gcontext-accessor define-keysym
  41. define-keysym-set delete-property delete-resource destroy-subwindows
  42. destroy-window device-busy device-event-mask device-event-mask-class
  43. discard-current-event discard-font-info display display-after-function
  44. display-authorization ; extension
  45. display-authorization-data display-authorization-name
  46. display-bitmap-format display-byte-order display-default-screen
  47. display-display display-error-handler display-finish-output
  48. display-force-output display-host display-image-lsb-first-p
  49. display-invoke-after-function display-keycode-range display-max-keycode
  50. display-max-request-length display-min-keycode
  51. display-motion-buffer-size display-nscreens display-p
  52. display-pixmap-formats display-plist display-protocol-major-version
  53. display-protocol-minor-version display-protocol-version
  54. display-release-number display-report-asynchronous-errors
  55. display-resource-id-base display-resource-id-mask display-roots
  56. display-vendor display-vendor-name display-xid draw-arc draw-arcs
  57. draw-direction draw-glyph draw-glyphs draw-image-glyph draw-image-glyphs
  58. draw-line draw-lines draw-point draw-points draw-rectangle
  59. draw-rectangles draw-segments drawable drawable-border-width
  60. drawable-depth drawable-display drawable-equal drawable-error
  61. drawable-height drawable-id drawable-p drawable-plist drawable-root
  62. drawable-width drawable-x drawable-y error-key event-case event-cond
  63. event-handler event-key event-listen event-mask event-mask-class
  64. extension-opcode find-atom font font-all-chars-exist-p font-ascent
  65. font-default-char font-descent font-direction font-display font-equal
  66. font-error font-id font-max-byte1 font-max-byte2 font-max-char
  67. font-min-byte1 font-min-byte2 font-min-char font-name font-p font-path
  68. font-plist font-properties font-property fontable force-gcontext-changes
  69. free-colormap free-colors free-cursor free-gcontext free-pixmap gcontext
  70. gcontext-arc-mode gcontext-background gcontext-cache-p
  71. gcontext-cap-style gcontext-clip-mask gcontext-clip-ordering
  72. gcontext-clip-x gcontext-clip-y gcontext-dash-offset gcontext-dashes
  73. gcontext-display gcontext-equal gcontext-error gcontext-exposures
  74. gcontext-fill-rule gcontext-fill-style gcontext-font gcontext-foreground
  75. gcontext-function gcontext-id gcontext-join-style gcontext-key
  76. gcontext-line-style gcontext-line-width gcontext-p gcontext-plane-mask
  77. gcontext-plist gcontext-stipple gcontext-subwindow-mode gcontext-tile
  78. gcontext-ts-x gcontext-ts-y get-external-event-code get-image
  79. get-property get-raw-image get-resource get-search-resource
  80. get-search-table get-standard-colormap get-wm-class
  81. global-pointer-position grab-button grab-key grab-keyboard grab-pointer
  82. grab-server grab-status icon-sizes iconify-window id-choice-error
  83. illegal-request-error image image-blue-mask image-depth image-green-mask
  84. image-height image-name image-pixmap image-plist image-red-mask
  85. image-width image-x image-x-hot image-x-p image-xy image-xy-bitmap-list
  86. image-xy-p image-y-hot image-z image-z-bits-per-pixel image-z-p
  87. image-z-pixarray implementation-error input-focus install-colormap
  88. installed-colormaps int16 int32 int8 intern-atom invalid-font
  89. keyboard-control keyboard-mapping keycode->character keycode->keysym
  90. keysym keysym->character keysym->keycodes keysym-in-map-p keysym-set
  91. kill-client kill-temporary-clients length-error list-extensions
  92. list-font-names list-fonts list-properties lookup-color lookup-error
  93. make-color make-event-handlers make-event-keys make-event-mask
  94. make-resource-database make-state-keys make-state-mask make-wm-hints
  95. make-wm-size-hints map-resource map-subwindows map-window mapping-notify
  96. mask16 mask32 match-error max-char-ascent max-char-attributes
  97. max-char-descent max-char-left-bearing max-char-right-bearing
  98. max-char-width merge-resources min-char-ascent min-char-attributes
  99. min-char-descent min-char-left-bearing min-char-right-bearing
  100. min-char-width missing-parameter modifier-key modifier-mapping
  101. modifier-mask motion-events name-error no-operation open-display
  102. open-font pixarray pixel pixmap pixmap-display pixmap-equal pixmap-error
  103. pixmap-format pixmap-format-bits-per-pixel pixmap-format-depth
  104. pixmap-format-p pixmap-format-scanline-pad pixmap-id pixmap-p
  105. pixmap-plist point-seq pointer-control pointer-event-mask
  106. pointer-event-mask-class pointer-mapping pointer-position process-event
  107. put-image put-raw-image query-best-cursor query-best-stipple
  108. query-best-tile query-colors query-extension query-keymap query-pointer
  109. query-tree queue-event read-bitmap-file read-resources recolor-cursor
  110. rect-seq remove-access-host remove-from-save-set reparent-window
  111. repeat-seq reply-length-error reply-timeout request-error
  112. reset-screen-saver resource-database resource-database-timestamp
  113. resource-error resource-id resource-key rgb-colormaps rgb-val
  114. root-resources rotate-cut-buffers rotate-properties screen
  115. screen-backing-stores screen-black-pixel screen-default-colormap
  116. screen-depths screen-event-mask-at-open screen-height
  117. screen-height-in-millimeters screen-max-installed-maps
  118. screen-min-installed-maps screen-p screen-plist screen-root
  119. screen-root-depth screen-root-visual screen-root-visual-info
  120. screen-save-unders-p screen-saver screen-white-pixel screen-width
  121. screen-width-in-millimeters seg-seq selection-owner set-selection-owner
  122. send-event sequence-error set-input-focus
  123. set-modifier-mapping set-screen-saver
  124. set-standard-colormap set-standard-properties
  125. set-wm-class set-wm-properties set-wm-resources state-keysym-p
  126. state-mask-key store-color store-colors stringable text-extents
  127. text-width timestamp transient-for translate-coordinates
  128. translate-default translation-function #-cmu type-error undefine-keysym
  129. unexpected-reply ungrab-button ungrab-key ungrab-keyboard ungrab-pointer
  130. ungrab-server uninstall-colormap unknown-error unmap-subwindows
  131. unmap-window value-error visual-info visual-info-bits-per-rgb
  132. visual-info-blue-mask visual-info-class visual-info-colormap-entries
  133. visual-info-display visual-info-green-mask visual-info-id visual-info-p
  134. visual-info-plist visual-info-red-mask warp-pointer
  135. warp-pointer-if-inside warp-pointer-relative
  136. warp-pointer-relative-if-inside win-gravity window
  137. window-all-event-masks window-background window-backing-pixel
  138. window-backing-planes window-backing-store window-bit-gravity
  139. window-border window-class window-colormap window-colormap-installed-p
  140. window-cursor window-display window-do-not-propagate-mask window-equal
  141. window-error window-event-mask window-gravity window-id window-map-state
  142. window-override-redirect window-p window-plist window-priority
  143. window-save-under window-visual window-visual-info with-display
  144. with-event-queue with-gcontext with-server-grabbed with-state
  145. withdraw-window wm-client-machine wm-colormap-windows wm-command
  146. wm-hints wm-hints-flags wm-hints-icon-mask wm-hints-icon-pixmap
  147. wm-hints-icon-window wm-hints-icon-x wm-hints-icon-y
  148. wm-hints-initial-state wm-hints-input wm-hints-p wm-hints-window-group
  149. wm-icon-name wm-name wm-normal-hints wm-protocols wm-resources
  150. wm-size-hints wm-size-hints-base-height wm-size-hints-base-width
  151. wm-size-hints-height wm-size-hints-height-inc wm-size-hints-max-aspect
  152. wm-size-hints-max-height wm-size-hints-max-width
  153. wm-size-hints-min-aspect wm-size-hints-min-height
  154. wm-size-hints-min-width wm-size-hints-p
  155. wm-size-hints-user-specified-position-p
  156. wm-size-hints-user-specified-size-p wm-size-hints-width
  157. wm-size-hints-width-inc wm-size-hints-win-gravity wm-size-hints-x
  158. wm-size-hints-y wm-zoom-hints write-bitmap-file write-resources xatom
  159. x-error
  160. keysym-name
  161. trace-display suspend-display-tracing resume-display-tracing
  162. untrace-display show-trace
  163. display-trace ; for backwards compatibility describe-request describe-event describe-reply
  164. closed-display-p
  165. ;; extensions
  166. open-default-display
  167. ;; display-xdefaults resource-database-to-string resource-database-of-string
  168. ;; resource-database-locale
  169. ;; not implemented
  170. describe-error describe-trace))
  171. ;;; SHAPE extension
  172. (export '(shape-version shape-combine shape-offset shape-extents shape-rectangles))
  173. ;;;; --------------------------------------------------------------------------
  174. ;;;; Types
  175. ;;;; --------------------------------------------------------------------------
  176. ;;;;
  177. ;;;; Lots of deftypes randomly gathered from MIT-CLX implementation
  178. ;;;;
  179. (deftype card4 () '(unsigned-byte 4)) ;not exported
  180. (deftype card8 () '(unsigned-byte 8))
  181. (deftype card16 () '(unsigned-byte 16))
  182. (deftype card24 () '(unsigned-byte 24)) ;not exported
  183. (deftype card29 () '(unsigned-byte 29))
  184. (deftype card32 () '(unsigned-byte 32))
  185. (deftype int8 () '(signed-byte 8))
  186. (deftype int16 () '(signed-byte 16))
  187. (deftype int32 () '(signed-byte 32))
  188. (deftype rgb-val () '(real 0 1))
  189. (deftype stringable () '(or string symbol))
  190. (deftype fontable () '(or stringable font))
  191. (deftype array-index () `(integer 0 ,array-dimension-limit))
  192. (deftype angle () '(real #.(* -2 pi) #.(* 2 pi)))
  193. (deftype mask32 () 'card32)
  194. (deftype mask16 () 'card16)
  195. (deftype pixel () '(unsigned-byte 32))
  196. (deftype image-depth () '(integer 0 32))
  197. (deftype resource-id () 'card29)
  198. (deftype keysym () 'card32)
  199. (deftype alist (key-type-and-name datum-type-and-name)
  200. (declare (ignore key-type-and-name datum-type-and-name))
  201. 'list)
  202. (deftype repeat-seq (&rest elts) elts 'sequence)
  203. (deftype point-seq () '(repeat-seq (int16 x) (int16 y)))
  204. (deftype seg-seq () '(repeat-seq (int16 x1) (int16 y1) (int16 x2) (int16 y2)))
  205. (deftype rect-seq () '(repeat-seq (int16 x) (int16 y) (card16 width) (card16 height)))
  206. (deftype arc-seq ()
  207. '(repeat-seq (int16 x) (int16 y) (card16 width) (card16 height)
  208. (angle angle1) (angle angle2)))
  209. (deftype timestamp () '(or null card32))
  210. (deftype bit-gravity () '(member :forget :north-west :north :north-east :west :center :east :south-west :south :south-east :static))
  211. (deftype boole-constant ()
  212. `(member ,boole-clr ,boole-and ,boole-andc2 ,boole-1
  213. ,boole-andc1 ,boole-2 ,boole-xor ,boole-ior
  214. ,boole-nor ,boole-eqv ,boole-c2 ,boole-orc2
  215. ,boole-c1 ,boole-orc1 ,boole-nand ,boole-set))
  216. (deftype device-event-mask ()
  217. '(or mask32 list)) ;; '(or integer (list device-event-mask-class)))
  218. (deftype device-event-mask-class ()
  219. '(member :key-press :key-release :button-press :button-release :pointer-motion
  220. :button-1-motion :button-2-motion :button-3-motion :button-4-motion
  221. :button-5-motion :button-motion))
  222. (deftype draw-direction ()
  223. '(member :left-to-right :right-to-left))
  224. (deftype error-key ()
  225. '(member :access :alloc :atom :colormap :cursor :drawable :font :gcontext :id-choice
  226. :illegal-request :implementation :length :match :name :pixmap :value :window))
  227. (deftype gcontext-key ()
  228. '(member :function :plane-mask :foreground :background
  229. :line-width :line-style :cap-style :join-style :fill-style
  230. :fill-rule :tile :stipple :ts-x :ts-y :font :subwindow-mode
  231. :exposures :clip-x :clip-y :clip-mask :dash-offset :dashes
  232. :arc-mode))
  233. (deftype event-key ()
  234. '(member :key-press :key-release :button-press :button-release :motion-notify
  235. :enter-notify :leave-notify :focus-in :focus-out :keymap-notify
  236. :exposure :graphics-exposure :no-exposure :visibility-notify
  237. :create-notify :destroy-notify :unmap-notify :map-notify :map-request
  238. :reparent-notify :configure-notify :gravity-notify :resize-request
  239. :configure-request :circulate-notify :circulate-request :property-notify
  240. :selection-clear :selection-request :selection-notify
  241. :colormap-notify :client-message :mapping-notify))
  242. (deftype event-mask-class ()
  243. '(member :key-press :key-release :owner-grab-button :button-press :button-release
  244. :enter-window :leave-window :pointer-motion :pointer-motion-hint
  245. :button-1-motion :button-2-motion :button-3-motion :button-4-motion
  246. :button-5-motion :button-motion :exposure :visibility-change
  247. :structure-notify :resize-redirect :substructure-notify :substructure-redirect
  248. :focus-change :property-change :colormap-change :keymap-state))
  249. (deftype event-mask ()
  250. '(or mask32 list)) ;; (OR integer (LIST event-mask-class))
  251. (deftype grab-status ()
  252. '(member :success :already-grabbed :invalid-time :not-viewable))
  253. (deftype modifier-key ()
  254. '(member :shift :lock :control :mod-1 :mod-2 :mod-3 :mod-4 :mod-5))
  255. (deftype modifier-mask ()
  256. '(or (member :any) mask16 list)) ;; '(or (member :any) integer (list modifier-key)))
  257. (deftype state-mask-key ()
  258. '(or modifier-key (member :button-1 :button-2 :button-3 :button-4 :button-5)))
  259. (deftype translation-function ()
  260. '(function (sequence array-index array-index (or null font) vector array-index)
  261. (values array-index (or null int16 font) (or null int32))))
  262. (deftype win-gravity ()
  263. '(member :unmap :north-west :north :north-east :west :center :east :south-west :south :south-east :static))
  264. (deftype xatom () '(or string symbol))
  265. (deftype pointer-event-mask-class ()
  266. '(member :button-press :button-release
  267. :enter-window :leave-window :pointer-motion :pointer-motion-hint
  268. :button-1-motion :button-2-motion :button-3-motion :button-4-motion
  269. :button-5-motion :button-motion :keymap-state))
  270. (deftype pointer-event-mask ()
  271. '(or mask32 list)) ;; '(or integer (list pointer-event-mask-class)))
  272. ;; ***************************************************************************
  273. ;; ****************************** C A U T I O N ******************************
  274. ;; ***************************************************************************
  275. ;; THE LAYOUT OF THESE STRUCTURE DEFINITIONS HAS TO BE IN SYNC WITH CLX.D
  276. ;; ***************************************************************************
  277. (defstruct bitmap-format unit pad lsb-first-p)
  278. (defstruct pixmap-format depth bits-per-pixel scanline-pad)
  279. (defstruct (color (:constructor make-color-internal (red green blue))
  280. (:copier nil))
  281. ;; Short floats are good enough (no consing)
  282. (red 0.0s0 :type rgb-val)
  283. (green 0.0s0 :type rgb-val)
  284. (blue 0.0s0 :type rgb-val))
  285. (defstruct (visual-info (:copier nil))
  286. id
  287. class
  288. red-mask green-mask blue-mask
  289. bits-per-rgb
  290. colormap-entries
  291. ;; There appears also a plist and a display slot in the MIT-CLX,
  292. ;; but not in the manual!
  293. ;; With what should we be compatible?!
  294. ;; plist display
  295. )
  296. (defstruct (display (:predicate nil)
  297. (:constructor nil)
  298. (:copier nil)
  299. (:conc-name %display-))
  300. foreign-pointer ;; these two slots are for use in clx.d only.
  301. hash-table ;; .. so keep hands off here!
  302. plist
  303. after-function
  304. error-handler
  305. display)
  306. ;; (defstruct (resource-database (:constructor %make-rdb (foreign-pointer)))
  307. ;; (foreign-pointer nil :read-only t))
  308. ;; (defstruct (search-table (:constructor %make-search-table (foreign-pointer)))
  309. ;; (foreign-pointer nil :read-only t))
  310. ;; ***************************************************************************
  311. ;; ... CAUTION ending here (resume careless coding)
  312. ;; ***************************************************************************
  313. ;; (eval-when (:compile-toplevel)
  314. ;; (defpackage #:posix (:export #:mkstemp)))
  315. ;; (defun resource-database-to-string (rdb)
  316. ;; (let ((tmp-file (posix:mkstemp "/tmp/rdb")))
  317. ;; (close tmp-file)
  318. ;; (write-resources rdb tmp-file)
  319. ;; (unwind-protect
  320. ;; (with-open-file (in tmp-file)
  321. ;; (let ((st (make-string (file-length in))))
  322. ;; (read-sequence st in)
  323. ;; st))
  324. ;; (delete-file tmp-file))))
  325. (defun make-color (&key (red 1.0s0) (green 1.0s0) (blue 1.0s0)
  326. &allow-other-keys)
  327. (make-color-internal red green blue))
  328. (defun color-rgb (color)
  329. (values (color-red color) (color-green color) (color-blue color)))
  330. (defclass xlib-object ()
  331. ((plist :initarg :plist :initform nil)
  332. (display :initarg :display)))
  333. (defclass xid-object (xlib-object) ((id :initarg :id)))
  334. (defclass ptr-object (xlib-object) ((ptr :initarg :ptr)))
  335. (defclass drawable (xid-object) ())
  336. (defclass window (drawable) ())
  337. (defclass pixmap (drawable) ())
  338. (defclass cursor (xid-object) ())
  339. (defclass colormap (xid-object) (#|(visual-info :initarg :visual-info :accessor colormap-visual-info)|#))
  340. (defclass gcontext (ptr-object) ((%dashes) (%clip-mask) (%timestamp :accessor gcontext-internal-timestamp :initform 0)))
  341. (defclass screen (ptr-object) ())
  342. (defclass font (xid-object)
  343. ((font-info :initform nil :initarg :font-info)
  344. (name :initarg :name)
  345. (encoding :initform nil :initarg :encoding)))
  346. ;;;; --------------------------------------------------------------------------
  347. ;;;; Setf Methods
  348. ;;;; --------------------------------------------------------------------------
  349. (defsetf ACCESS-CONTROL SET-ACCESS-CONTROL)
  350. (defsetf CLOSE-DOWN-MODE (display) (mode)
  351. `(SET-CLOSE-DOWN-MODE ,mode ,display))
  352. (defsetf DISPLAY-AFTER-FUNCTION SET-DISPLAY-AFTER-FUNCTION)
  353. (defsetf DISPLAY-ERROR-HANDLER SET-DISPLAY-ERROR-HANDLER)
  354. (defsetf DISPLAY-PLIST SET-DISPLAY-PLIST)
  355. (defsetf DISPLAY-DEFAULT-SCREEN SET-DISPLAY-DEFAULT-SCREEN)
  356. (defsetf DISPLAY-XDEFAULTS SET-DISPLAY-XDEFAULTS)
  357. (defsetf DRAWABLE-BORDER-WIDTH SET-DRAWABLE-BORDER-WIDTH)
  358. (defsetf DRAWABLE-HEIGHT SET-DRAWABLE-HEIGHT)
  359. (defsetf DRAWABLE-PLIST SET-DRAWABLE-PLIST)
  360. (defsetf DRAWABLE-WIDTH SET-DRAWABLE-WIDTH)
  361. (defsetf DRAWABLE-X SET-DRAWABLE-X)
  362. (defsetf DRAWABLE-Y SET-DRAWABLE-Y)
  363. (defsetf FONT-PATH SET-FONT-PATH)
  364. (defsetf FONT-PLIST SET-FONT-PLIST)
  365. (defsetf GCONTEXT-ARC-MODE SET-GCONTEXT-ARC-MODE)
  366. (defsetf GCONTEXT-BACKGROUND SET-GCONTEXT-BACKGROUND)
  367. (defsetf GCONTEXT-CACHE-P SET-GCONTEXT-CACHE-P)
  368. (defsetf GCONTEXT-CAP-STYLE SET-GCONTEXT-CAP-STYLE)
  369. (defsetf GCONTEXT-CLIP-MASK (gcontext &optional ordering) (clip-mask)
  370. `(SET-GCONTEXT-CLIP-MASK ,clip-mask ,gcontext ,ordering))
  371. (defsetf GCONTEXT-CLIP-X SET-GCONTEXT-CLIP-X)
  372. (defsetf GCONTEXT-CLIP-Y SET-GCONTEXT-CLIP-Y)
  373. (defsetf GCONTEXT-DASH-OFFSET SET-GCONTEXT-DASH-OFFSET)
  374. (defsetf GCONTEXT-DASHES SET-GCONTEXT-DASHES)
  375. (defsetf GCONTEXT-EXPOSURES SET-GCONTEXT-EXPOSURES)
  376. (defsetf GCONTEXT-FILL-RULE SET-GCONTEXT-FILL-RULE)
  377. (defsetf GCONTEXT-FILL-STYLE SET-GCONTEXT-FILL-STYLE)
  378. (defsetf GCONTEXT-FONT (gcontext &optional pseudo-font-p) (font)
  379. `(SET-GCONTEXT-FONT ,font ,gcontext ,pseudo-font-p))
  380. (defsetf GCONTEXT-FOREGROUND SET-GCONTEXT-FOREGROUND)
  381. (defsetf GCONTEXT-FUNCTION SET-GCONTEXT-FUNCTION)
  382. (defsetf GCONTEXT-JOIN-STYLE SET-GCONTEXT-JOIN-STYLE)
  383. (defsetf GCONTEXT-LINE-STYLE SET-GCONTEXT-LINE-STYLE)
  384. (defsetf GCONTEXT-LINE-WIDTH SET-GCONTEXT-LINE-WIDTH)
  385. (defsetf GCONTEXT-PLANE-MASK SET-GCONTEXT-PLANE-MASK)
  386. (defsetf GCONTEXT-PLIST SET-GCONTEXT-PLIST)
  387. (defsetf GCONTEXT-STIPPLE SET-GCONTEXT-STIPPLE)
  388. (defsetf GCONTEXT-SUBWINDOW-MODE SET-GCONTEXT-SUBWINDOW-MODE)
  389. (defsetf GCONTEXT-TILE SET-GCONTEXT-TILE)
  390. (defsetf GCONTEXT-TS-X SET-GCONTEXT-TS-X)
  391. (defsetf GCONTEXT-TS-Y SET-GCONTEXT-TS-Y)
  392. (defsetf PIXMAP-PLIST SET-PIXMAP-PLIST)
  393. (defsetf POINTER-MAPPING SET-POINTER-MAPPING)
  394. (defsetf SCREEN-PLIST SET-SCREEN-PLIST)
  395. (defsetf SELECTION-OWNER (display selection &optional time) (owner)
  396. `(SET-SELECTION-OWNER ,display ,selection ,owner ,time))
  397. (defsetf WINDOW-BACKGROUND SET-WINDOW-BACKGROUND)
  398. (defsetf WINDOW-BACKING-PIXEL SET-WINDOW-BACKING-PIXEL)
  399. (defsetf WINDOW-BACKING-PLANES SET-WINDOW-BACKING-PLANES)
  400. (defsetf WINDOW-BACKING-STORE SET-WINDOW-BACKING-STORE)
  401. (defsetf WINDOW-COLORMAP SET-WINDOW-COLORMAP)
  402. (defsetf WINDOW-CURSOR SET-WINDOW-CURSOR)
  403. (defsetf WINDOW-BIT-GRAVITY SET-WINDOW-BIT-GRAVITY)
  404. (defsetf WINDOW-BORDER SET-WINDOW-BORDER)
  405. (defsetf WINDOW-EVENT-MASK SET-WINDOW-EVENT-MASK)
  406. (defsetf WINDOW-GRAVITY SET-WINDOW-GRAVITY)
  407. (defsetf WINDOW-DO-NOT-PROPAGATE-MASK SET-WINDOW-DO-NOT-PROPAGATE-MASK)
  408. (defsetf WINDOW-OVERRIDE-REDIRECT SET-WINDOW-OVERRIDE-REDIRECT)
  409. (defsetf WINDOW-PLIST SET-WINDOW-PLIST)
  410. (defsetf WINDOW-PRIORITY (window &optional sibling) (mode)
  411. `(SET-WINDOW-PRIORITY ,mode ,window ,sibling))
  412. (defsetf WINDOW-SAVE-UNDER SET-WINDOW-SAVE-UNDER)
  413. ;; for CLUE
  414. (defsetf GCONTEXT-DISPLAY SET-GCONTEXT-DISPLAY)
  415. ;;;; --------------------------------------------------------------------------
  416. ;;;; Macros
  417. ;;;; --------------------------------------------------------------------------
  418. (defmacro EVENT-COND ((display &key timeout peek-p discard-p (force-output-p t))
  419. &body clauses)
  420. (let ((slots (gensym)))
  421. ;; FIXME this implementation is not 100%
  422. `(process-event ,display
  423. :timeout ,timeout
  424. :peek-p ,peek-p
  425. :discard-p ,discard-p
  426. :force-output-p ,force-output-p
  427. :handler
  428. (lambda (&rest ,slots &key event-key &allow-other-keys)
  429. ;; (print slots)
  430. (cond ,@(mapcar
  431. (lambda (clause)
  432. (let ((event-or-events (car clause))
  433. (binding-list (cadr clause))
  434. (test-form (caddr clause))
  435. (body-forms (cdddr clause)))
  436. (cond ((member event-or-events '(t otherwise))
  437. ;;Special case
  438. `((and t
  439. ,@(if test-form
  440. (list `(apply #'(lambda (&key ,@binding-list &allow-other-keys) ,test-form) ,slots))
  441. nil))
  442. ,@(if body-forms
  443. (list `(apply (lambda (&key ,@binding-list &allow-other-keys)
  444. ,@body-forms)
  445. ,slots))
  446. nil)))
  447. (t ;; Make-up keywords from the event-keys
  448. (unless (listp event-or-events)
  449. (setq event-or-events (list event-or-events)))
  450. (setq event-or-events
  451. (mapcar #'kintern event-or-events))
  452. `((and ,(if (cdr event-or-events)
  453. `(member event-key ',event-or-events)
  454. `(eq event-key ',(car event-or-events)))
  455. ,@(if test-form
  456. (list `(apply #'(lambda (&key ,@binding-list &allow-other-keys) ,test-form) ,slots))
  457. nil))
  458. ,@(if body-forms
  459. (list `(apply #'(lambda (&key ,@binding-list &allow-other-keys)
  460. ,@body-forms)
  461. ,slots))
  462. nil))))))
  463. clauses))))))
  464. (defmacro EVENT-CASE ((&rest args) &body clauses)
  465. ;; Event-case is just event-cond with the whole body in the test-form
  466. `(event-cond ,args
  467. ,@(mapcar
  468. #'(lambda (clause)
  469. `(,(car clause) ,(cadr clause) (progn ,@(cddr clause))))
  470. clauses)))
  471. (defmacro WITH-STATE ((drawable) &body body)
  472. `(progn ,drawable ,@body))
  473. (defmacro WITH-EVENT-QUEUE ((display) &body body)
  474. `(progn ,display ,@body))
  475. (defmacro WITH-GCONTEXT ((gcontext &rest options) &body body)
  476. (let ((saved (gensym)) (gcon (gensym)) (g0 (gensym)) (g1 (gensym))
  477. (comps 0)
  478. (setf-forms nil)
  479. dashes? clip-mask?)
  480. (do ((q options (cddr q)))
  481. ((null q))
  482. (cond ((eq (car q) :dashes) (setf dashes? t))
  483. ((eq (car q) :clip-mask) (setf clip-mask? t)))
  484. (setf comps (logior comps (%gcontext-key->mask (car q)))
  485. setf-forms (nconc setf-forms
  486. (list (list (find-symbol (string-concat "GCONTEXT-" (symbol-name (car q))) :xlib)
  487. gcon)
  488. (cadr q)))) )
  489. `(LET* ((,gcon ,gcontext)
  490. (,saved (%SAVE-GCONTEXT-COMPONENTS ,gcon ,comps))
  491. ,@(if dashes? (list `(,g0 (GCONTEXT-DASHES ,gcon))))
  492. ,@(if clip-mask? (list `(,g1 (GCONTEXT-CLIP-MASK ,gcon)))) )
  493. (UNWIND-PROTECT
  494. (PROGN
  495. (SETF ,@setf-forms)
  496. ,@body)
  497. (PROGN
  498. (%RESTORE-GCONTEXT-COMPONENTS ,gcon ,saved)
  499. ,@(if dashes? (list `(SETF (GCONTEXT-DASHES ,gcon) ,g0)) )
  500. ,@(if clip-mask? (list `(SETF (GCONTEXT-CLIP-MASK ,gcon) ,g1)) )))) ))
  501. (defmacro WITH-SERVER-GRABBED ((display) &body body)
  502. ;; The body is not surrounded by a with-display.
  503. (let ((disp (if (symbolp display) display (gensym))))
  504. `(let ((,disp ,display))
  505. (declare (type display ,disp))
  506. (unwind-protect
  507. (progn
  508. (grab-server ,disp)
  509. ,@body)
  510. (ungrab-server ,disp)))))
  511. ;;;; --------------------------------------------------------------------------
  512. ;;;; Window Manager Property functions
  513. ;;;; --------------------------------------------------------------------------
  514. (defun wm-name (window)
  515. (get-property window :WM_NAME :type :STRING :result-type 'string :transform #'card8->char))
  516. (defsetf wm-name (window) (name)
  517. `(set-string-property ,window :WM_NAME ,name))
  518. (defun set-string-property (window property string)
  519. (change-property window property (string string) :STRING 8 :transform #'char->card8)
  520. string)
  521. (defun wm-icon-name (window)
  522. (get-property window :WM_ICON_NAME :type :STRING
  523. :result-type 'string :transform #'card8->char))
  524. (defsetf wm-icon-name (window) (name)
  525. `(set-string-property ,window :WM_ICON_NAME ,name))
  526. (defun wm-client-machine (window)
  527. (get-property window :WM_CLIENT_MACHINE :type :STRING :result-type 'string :transform #'card8->char))
  528. (defsetf wm-client-machine (window) (name)
  529. `(set-string-property ,window :WM_CLIENT_MACHINE ,name))
  530. (defun get-wm-class (window)
  531. (let ((value (get-property window :WM_CLASS :type :STRING :result-type 'string :transform #'card8->char)))
  532. (when value
  533. (let* ((name-len (position (load-time-value (card8->char 0)) (the string value)))
  534. (name (subseq (the string value) 0 name-len))
  535. (class (subseq (the string value) (1+ name-len) (1- (length value)))))
  536. (values (and (plusp (length name)) name)
  537. (and (plusp (length class)) class))))))
  538. (defun set-wm-class (window resource-name resource-class)
  539. (set-string-property window :WM_CLASS
  540. (string-concat
  541. (string (or resource-name ""))
  542. (load-time-value
  543. (make-string 1 :initial-element (card8->char 0)))
  544. (string (or resource-class ""))
  545. (load-time-value
  546. (make-string 1 :initial-element (card8->char 0)))))
  547. (values))
  548. (defun wm-command (window)
  549. ;; Returns a list whose car is the command and
  550. ;; whose cdr is the list of arguments
  551. (do* ((command-string (get-property window :WM_COMMAND :type :STRING
  552. :result-type 'string :transform #'card8->char))
  553. (command nil)
  554. (start 0 (1+ end))
  555. (end 0)
  556. (len (length command-string)))
  557. ((>= start len) (nreverse command))
  558. (setq end (position (load-time-value (card8->char 0)) command-string :start start))
  559. (push (subseq command-string start end) command)))
  560. (defsetf wm-command set-wm-command)
  561. (defun set-wm-command (window command)
  562. ;; Uses PRIN1 inside the ANSI common lisp form WITH-STANDARD-IO-SYNTAX
  563. ;; (or equivalent), with elements of command separated by NULL
  564. ;; characters. This enables
  565. ;; (with-standard-io-syntax (mapcar #'read-from-string (wm-command window)))
  566. ;; to recover a lisp command.
  567. (set-string-property
  568. window :WM_COMMAND
  569. (with-output-to-string (stream)
  570. (with-standard-io-syntax
  571. (dolist (c command)
  572. (prin1 c stream)
  573. (write-char (load-time-value (card8->char 0)) stream)))))
  574. command)
  575. ;;-----------------------------------------------------------------------------
  576. ;; WM_HINTS
  577. ;; Some of the functions below need decode-type and encode-type,
  578. ;; I provide here a limited implementation to get these functions working.
  579. ;;
  580. (defmacro decode-type (type value)
  581. (cond ((eq type 'pixmap) `(lookup-pixmap %buffer ,value))
  582. ((eq type 'window) `(lookup-window %buffer ,value))
  583. ((and (consp type) (eq (car type) 'member))
  584. `(aref ',(coerce (cdr type) 'vector) ,value))
  585. (t (error "Unknown type ~S." type)) ))
  586. (defmacro encode-type (type value)
  587. (cond ((eq type 'pixmap) `(pixmap-id ,value))
  588. ((eq type 'window) `(window-id ,value))
  589. ((eq type 'card16) `,value)
  590. ((eq type 'colormap) `(colormap-id ,value))
  591. ((eq type 'rgb-val) `(round (the rgb-val ,value)
  592. (load-time-value (/ 1.0s0 #xffff))))
  593. ((and (consp type) (eq (car type) 'member))
  594. `(position ,value ',(cdr type)))
  595. (t (error "Unknown type ~S." type)) ))
  596. (defstruct wm-hints
  597. (input nil )
  598. (initial-state nil )
  599. (icon-pixmap nil )
  600. (icon-window nil )
  601. (icon-x nil )
  602. (icon-y nil )
  603. (icon-mask nil )
  604. (window-group nil )
  605. (flags 0) ;; Extension-hook. Exclusive-Or'ed with the FLAGS field
  606. ;; may be extended in the future
  607. )
  608. (defun wm-hints (window)
  609. (let ((prop (get-property window :WM_HINTS :type :WM_HINTS
  610. :result-type 'vector)))
  611. (when prop
  612. (decode-wm-hints prop (window-display window)))))
  613. (defsetf wm-hints set-wm-hints)
  614. (defun set-wm-hints (window wm-hints)
  615. (change-property window :WM_HINTS (encode-wm-hints wm-hints) :WM_HINTS 32)
  616. wm-hints)
  617. (defun decode-wm-hints (vector display)
  618. (let ((input-hint 0)
  619. (state-hint 1)
  620. (icon-pixmap-hint 2)
  621. (icon-window-hint 3)
  622. (icon-position-hint 4)
  623. (icon-mask-hint 5)
  624. (window-group-hint 6))
  625. (let ((flags (aref vector 0))
  626. (hints (make-wm-hints))
  627. (%buffer display))
  628. (setf (wm-hints-flags hints) flags)
  629. (when (logbitp input-hint flags)
  630. (setf (wm-hints-input hints) (decode-type (member :off :on)
  631. (aref vector 1))))
  632. (when (logbitp state-hint flags)
  633. (setf (wm-hints-initial-state hints)
  634. (decode-type (member :dont-care :normal :zoom :iconic :inactive)
  635. (aref vector 2))))
  636. (when (logbitp icon-pixmap-hint flags)
  637. (setf (wm-hints-icon-pixmap hints) (decode-type pixmap (aref vector 3))))
  638. (when (logbitp icon-window-hint flags)
  639. (setf (wm-hints-icon-window hints) (decode-type window (aref vector 4))))
  640. (when (logbitp icon-position-hint flags)
  641. (setf (wm-hints-icon-x hints) (aref vector 5)
  642. (wm-hints-icon-y hints) (aref vector 6)))
  643. (when (logbitp icon-mask-hint flags)
  644. (setf (wm-hints-icon-mask hints) (decode-type pixmap (aref vector 7))))
  645. (when (and (logbitp window-group-hint flags) (> (length vector) 7))
  646. (setf (wm-hints-window-group hints) (aref vector 8)))
  647. hints)))
  648. (defun encode-wm-hints (wm-hints)
  649. (let ((input-hint #b1)
  650. (state-hint #b10)
  651. (icon-pixmap-hint #b100)
  652. (icon-window-hint #b1000)
  653. (icon-position-hint #b10000)
  654. (icon-mask-hint #b100000)
  655. (window-group-hint #b1000000)
  656. (mask #b1111111)
  657. )
  658. (let ((vector (make-array 9 :initial-element 0))
  659. (flags 0))
  660. (declare (type (simple-vector 9) vector)
  661. (type card16 flags))
  662. (when (wm-hints-input wm-hints)
  663. (setf flags input-hint
  664. (aref vector 1) (encode-type (member :off :on) (wm-hints-input wm-hints))))
  665. (when (wm-hints-initial-state wm-hints)
  666. (setf flags (logior flags state-hint)
  667. (aref vector 2) (encode-type (member :dont-care :normal :zoom :iconic :inactive)
  668. (wm-hints-initial-state wm-hints))))
  669. (when (wm-hints-icon-pixmap wm-hints)
  670. (setf flags (logior flags icon-pixmap-hint)
  671. (aref vector 3) (encode-type pixmap (wm-hints-icon-pixmap wm-hints))))
  672. (when (wm-hints-icon-window wm-hints)
  673. (setf flags (logior flags icon-window-hint)
  674. (aref vector 4) (encode-type window (wm-hints-icon-window wm-hints))))
  675. (when (and (wm-hints-icon-x wm-hints) (wm-hints-icon-y wm-hints))
  676. (setf flags (logior flags icon-position-hint)
  677. (aref vector 5) (encode-type card16 (wm-hints-icon-x wm-hints))
  678. (aref vector 6) (encode-type card16 (wm-hints-icon-y wm-hints))))
  679. (when (wm-hints-icon-mask wm-hints)
  680. (setf flags (logior flags icon-mask-hint)
  681. (aref vector 7) (encode-type pixmap (wm-hints-icon-mask wm-hints))))
  682. (when (wm-hints-window-group wm-hints)
  683. (setf flags (logior flags window-group-hint)
  684. (aref vector 8) (wm-hints-window-group wm-hints)))
  685. (setf (aref vector 0) (logior flags (logandc2 (wm-hints-flags wm-hints) mask)))
  686. vector)))
  687. ;;-----------------------------------------------------------------------------
  688. ;; WM_SIZE_HINTS
  689. ;; XXX
  690. ;; This code is buggy. My interpretation of change-property and get-property is
  691. ;; that they only deal with unsigned data, but the as obsolete marked fields x
  692. ;; and y are signed, and the code below does not take care. Running it
  693. ;; interpreted, hence with type checks gets errors.
  694. (defstruct wm-size-hints
  695. (user-specified-position-p nil :type boolean) ;; True when user specified x y
  696. (user-specified-size-p nil :type boolean) ;; True when user specified width height
  697. (x nil #|:type (or null int16)|#) ;; Obsolete
  698. (y nil #|:type (or null int16)|#) ;; Obsolete
  699. (width nil #|:type (or null card16)|#) ;; Obsolete
  700. (height nil #|:type (or null card16)|#) ;; Obsolete
  701. (min-width nil :type (or null card16))
  702. (min-height nil :type (or null card16))
  703. (max-width nil :type (or null card16))
  704. (max-height nil :type (or null card16))
  705. (width-inc nil :type (or null card16))
  706. (height-inc nil :type (or null card16))
  707. (min-aspect nil :type (or null number))
  708. (max-aspect nil :type (or null number))
  709. (base-width nil :type (or null card16))
  710. (base-height nil :type (or null card16))
  711. (win-gravity nil :type (or null win-gravity))
  712. (program-specified-position-p nil :type boolean) ;; True when program specified x y
  713. (program-specified-size-p nil :type boolean) ;; True when program specified width height
  714. )
  715. (defun wm-normal-hints (window)
  716. (declare (type window window))
  717. (declare (values wm-size-hints))
  718. (decode-wm-size-hints (get-property window :WM_NORMAL_HINTS :type :WM_SIZE_HINTS :result-type 'vector)))
  719. (defsetf wm-normal-hints set-wm-normal-hints)
  720. (defun set-wm-normal-hints (window hints)
  721. (declare (type window window)
  722. (type wm-size-hints hints))
  723. (declare (values wm-size-hints))
  724. (change-property window :WM_NORMAL_HINTS (encode-wm-size-hints hints) :WM_SIZE_HINTS 32)
  725. hints)
  726. ;;; OBSOLETE
  727. (defun wm-zoom-hints (window)
  728. (declare (type window window))
  729. (declare (values wm-size-hints))
  730. (decode-wm-size-hints (get-property window :WM_ZOOM_HINTS :type :WM_SIZE_HINTS :result-type 'vector)))
  731. ;;; OBSOLETE
  732. (defsetf wm-zoom-hints set-wm-zoom-hints)
  733. ;;; OBSOLETE
  734. (defun set-wm-zoom-hints (window hints)
  735. (declare (type window window)
  736. (type wm-size-hints hints))
  737. (declare (values wm-size-hints))
  738. (change-property window :WM_ZOOM_HINTS (encode-wm-size-hints hints) :WM_SIZE_HINTS 32)
  739. hints)
  740. (defun decode-wm-size-hints (vector)
  741. (declare (type (or null (simple-vector *)) vector))
  742. (declare (values (or null wm-size-hints)))
  743. (when vector
  744. (let ((flags (aref vector 0))
  745. (hints (make-wm-size-hints)))
  746. (declare (type card16 flags)
  747. (type wm-size-hints hints))
  748. (setf (wm-size-hints-user-specified-position-p hints) (logbitp 0 flags))
  749. (setf (wm-size-hints-user-specified-size-p hints) (logbitp 1 flags))
  750. (setf (wm-size-hints-program-specified-position-p hints) (logbitp 2 flags))
  751. (setf (wm-size-hints-program-specified-size-p hints) (logbitp 3 flags))
  752. (when (logbitp 4 flags)
  753. (setf (wm-size-hints-min-width hints) (aref vector 5)
  754. (wm-size-hints-min-height hints) (aref vector 6)))
  755. (when (logbitp 5 flags)
  756. (setf (wm-size-hints-max-width hints) (aref vector 7)
  757. (wm-size-hints-max-height hints) (aref vector 8)))
  758. (when (logbitp 6 flags)
  759. (setf (wm-size-hints-width-inc hints) (aref vector 9)
  760. (wm-size-hints-height-inc hints) (aref vector 10)))
  761. (when (logbitp 7 flags)
  762. (setf (wm-size-hints-min-aspect hints) (/ (aref vector 11) (aref vector 12))
  763. (wm-size-hints-max-aspect hints) (/ (aref vector 13) (aref vector 14))))
  764. (when (> (length vector) 15)
  765. ;; This test is for backwards compatibility since old Xlib programs
  766. ;; can set a size-hints structure that is too small. See ICCCM.
  767. (when (logbitp 8 flags)
  768. (setf (wm-size-hints-base-width hints) (aref vector 15)
  769. (wm-size-hints-base-height hints) (aref vector 16)))
  770. (when (logbitp 9 flags)
  771. (setf (wm-size-hints-win-gravity hints)
  772. (decode-type (member :unmap :north-west :north :north-east :west
  773. :center :east :south-west :south :south-east :static)
  774. (aref vector 17)))))
  775. ;; Obsolete fields
  776. (when (or (logbitp 0 flags) (logbitp 2 flags))
  777. (setf (wm-size-hints-x hints) (aref vector 1)
  778. (wm-size-hints-y hints) (aref vector 2)))
  779. (when (or (logbitp 1 flags) (logbitp 3 flags))
  780. (setf (wm-size-hints-width hints) (aref vector 3)
  781. (wm-size-hints-height hints) (aref vector 4)))
  782. hints)))
  783. (defun encode-wm-size-hints (hints)
  784. (declare (type wm-size-hints hints))
  785. (declare (values simple-vector))
  786. (let ((vector (make-array 18 :initial-element 0))
  787. (flags 0))
  788. (declare (type (simple-vector 18) vector)
  789. (type card16 flags))
  790. (when (wm-size-hints-user-specified-position-p hints)
  791. (setf (ldb (byte 1 0) flags) 1))
  792. (when (wm-size-hints-user-specified-size-p hints)
  793. (setf (ldb (byte 1 1) flags) 1))
  794. (when (wm-size-hints-program-specified-position-p hints)
  795. (setf (ldb (byte 1 2) flags) 1))
  796. (when (wm-size-hints-program-specified-size-p hints)
  797. (setf (ldb (byte 1 3) flags) 1))
  798. (when (and (wm-size-hints-min-width hints) (wm-size-hints-min-height hints))
  799. (setf (ldb (byte 1 4) flags) 1
  800. (aref vector 5) (wm-size-hints-min-width hints)
  801. (aref vector 6) (wm-size-hints-min-height hints)))
  802. (when (and (wm-size-hints-max-width hints) (wm-size-hints-max-height hints))
  803. (setf (ldb (byte 1 5) flags) 1
  804. (aref vector 7) (wm-size-hints-max-width hints)
  805. (aref vector 8) (wm-size-hints-max-height hints)))
  806. (when (and (wm-size-hints-width-inc hints) (wm-size-hints-height-inc hints))
  807. (setf (ldb (byte 1 6) flags) 1
  808. (aref vector 9) (wm-size-hints-width-inc hints)
  809. (aref vector 10) (wm-size-hints-height-inc hints)))
  810. (let ((min-aspect (wm-size-hints-min-aspect hints))
  811. (max-aspect (wm-size-hints-max-aspect hints)))
  812. (when (and min-aspect max-aspect)
  813. (setf (ldb (byte 1 7) flags) 1
  814. min-aspect (rationalize min-aspect)
  815. max-aspect (rationalize max-aspect)
  816. (aref vector 11) (numerator min-aspect)
  817. (aref vector 12) (denominator min-aspect)
  818. (aref vector 13) (numerator max-aspect)
  819. (aref vector 14) (denominator max-aspect))))
  820. (when (and (wm-size-hints-base-width hints)
  821. (wm-size-hints-base-height hints))
  822. (setf (ldb (byte 1 8) flags) 1
  823. (aref vector 15) (wm-size-hints-base-width hints)
  824. (aref vector 16) (wm-size-hints-base-height hints)))
  825. (when (wm-size-hints-win-gravity hints)
  826. (setf (ldb (byte 1 9) flags) 1
  827. (aref vector 17) (encode-type
  828. (member :unmap :north-west :north :north-east :west
  829. :center :east :south-west :south :south-east :static)
  830. (wm-size-hints-win-gravity hints))))
  831. ;; Obsolete fields
  832. (when (and (wm-size-hints-x hints) (wm-size-hints-y hints))
  833. (unless (wm-size-hints-user-specified-position-p hints)
  834. (setf (ldb (byte 1 2) flags) 1))
  835. (setf (aref vector 1) (wm-size-hints-x hints)
  836. (aref vector 2) (wm-size-hints-y hints)))
  837. (when (and (wm-size-hints-width hints) (wm-size-hints-height hints))
  838. (unless (wm-size-hints-user-specified-size-p hints)
  839. (setf (ldb (byte 1 3) flags) 1))
  840. (setf (aref vector 3) (wm-size-hints-width hints)
  841. (aref vector 4) (wm-size-hints-height hints)))
  842. (setf (aref vector 0) flags)
  843. vector))
  844. ;;-----------------------------------------------------------------------------
  845. ;; Icon_Size
  846. ;; Use the same intermediate structure as WM_SIZE_HINTS
  847. (defun icon-sizes (window)
  848. (let ((vector (get-property window :WM_ICON_SIZE :type :WM_ICON_SIZE :result-type 'vector)))
  849. (when vector
  850. (make-wm-size-hints
  851. :min-width (aref vector 0)
  852. :min-height (aref vector 1)
  853. :max-width (aref vector 2)
  854. :max-height (aref vector 3)
  855. :width-inc (aref vector 4)
  856. :height-inc (aref vector 5)))))
  857. (defsetf icon-sizes set-icon-sizes)
  858. (defun set-icon-sizes (window wm-size-hints)
  859. (let ((vector (vector (wm-size-hints-min-width wm-size-hints)
  860. (wm-size-hints-min-height wm-size-hints)
  861. (wm-size-hints-max-width wm-size-hints)
  862. (wm-size-hints-max-height wm-size-hints)
  863. (wm-size-hints-width-inc wm-size-hints)
  864. (wm-size-hints-height-inc wm-size-hints))))
  865. (change-property window :WM_ICON_SIZE vector :WM_ICON_SIZE 32)
  866. wm-size-hints))
  867. ;;-----------------------------------------------------------------------------
  868. ;; WM-Protocols
  869. (defun wm-protocols (window)
  870. (map 'list #'(lambda (id) (atom-name (window-display window) id))
  871. (get-property window :WM_PROTOCOLS :type :ATOM)))
  872. (defsetf wm-protocols set-wm-protocols)
  873. (defun set-wm-protocols (window protocols)
  874. (change-property window :WM_PROTOCOLS
  875. (map 'list #'(lambda (atom) (intern-atom (window-display window) atom))
  876. protocols)
  877. :ATOM 32)
  878. protocols)
  879. ;;-----------------------------------------------------------------------------
  880. ;; WM-Colormap-windows
  881. (defun wm-colormap-windows (window)
  882. (values (get-property window :WM_COLORMAP_WINDOWS :type :WINDOW
  883. :transform #'(lambda (id)
  884. (lookup-window (window-display window) id)))))
  885. (defsetf wm-colormap-windows set-wm-colormap-windows)
  886. (defun set-wm-colormap-windows (window colormap-windows)
  887. (change-property window :WM_COLORMAP_WINDOWS colormap-windows :WINDOW 32
  888. :transform #'window-id)
  889. colormap-windows)
  890. ;;-----------------------------------------------------------------------------
  891. ;; Transient-For
  892. (defun transient-for (window)
  893. (let ((prop (get-property window :WM_TRANSIENT_FOR :type :WINDOW :result-type 'list)))
  894. (and prop (lookup-window (window-display window) (car prop)))))
  895. (defsetf transient-for set-transient-for)
  896. (defun set-transient-for (window transient)
  897. (declare (type window window transient))
  898. (change-property window :WM_TRANSIENT_FOR (list (window-id transient)) :WINDOW 32)
  899. transient)
  900. ;;-----------------------------------------------------------------------------
  901. ;; Set-WM-Properties
  902. (defun set-wm-properties (window &rest options &key
  903. name icon-name resource-name resource-class command
  904. client-machine hints normal-hints zoom-hints
  905. ;; the following are used for wm-normal-hints
  906. (user-specified-position-p nil usppp)
  907. (user-specified-size-p nil usspp)
  908. (program-specified-position-p nil psppp)
  909. (program-specified-size-p nil psspp)
  910. x y width height min-width min-height max-width max-height
  911. width-inc height-inc min-aspect max-aspect
  912. base-width base-height win-gravity
  913. ;; the following are used for wm-hints
  914. input initial-state icon-pixmap icon-window
  915. icon-x icon-y icon-mask window-group)
  916. ;; Set properties for WINDOW.
  917. (when name (setf (wm-name window) name))
  918. (when icon-name (setf (wm-icon-name window) icon-name))
  919. (when client-machine (setf (wm-client-machine window) client-machine))
  920. (when (or resource-name resource-class)
  921. (set-wm-class window resource-name resource-class))
  922. (when command (setf (wm-command window) command))
  923. ;; WM-HINTS
  924. (if (dolist (arg '(:input :initial-state :icon-pixmap :icon-window
  925. :icon-x :icon-y :icon-mask :window-group))
  926. (when (getf options arg) (return t)))
  927. (let ((wm-hints (if hints (copy-wm-hints hints) (make-wm-hints))))
  928. (when input (setf (wm-hints-input wm-hints) input))
  929. (when initial-state (setf (wm-hints-initial-state wm-hints) initial-state))
  930. (when icon-pixmap (setf (wm-hints-icon-pixmap wm-hints) icon-pixmap))
  931. (when icon-window (setf (wm-hints-icon-window wm-hints) icon-window))
  932. (when icon-x (setf (wm-hints-icon-x wm-hints) icon-x))
  933. (when icon-y (setf (wm-hints-icon-y wm-hints) icon-y))
  934. (when icon-mask (setf (wm-hints-icon-mask wm-hints) icon-mask))
  935. (when window-group
  936. (setf (wm-hints-window-group wm-hints) window-group))
  937. (setf (wm-hints window) wm-hints))
  938. (when hints (setf (wm-hints window) hints)))
  939. ;; WM-NORMAL-HINTS
  940. (if (dolist (arg '(:x :y :width :height :min-width :min-height :max-width :max-height
  941. :width-inc :height-inc :min-aspect :max-aspect
  942. :user-specified-position-p :user-specified-size-p
  943. :program-specified-position-p :program-specified-size-p
  944. :base-width :base-height :win-gravity))
  945. (when (getf options arg) (return t)))
  946. (let ((size (if normal-hints (copy-wm-size-hints normal-hints) (make-wm-size-hints))))
  947. (when x (setf (wm-size-hints-x size) x))
  948. (when y (setf (wm-size-hints-y size) y))
  949. (when width (setf (wm-size-hints-width size) width))
  950. (when height (setf (wm-size-hints-height size) height))
  951. (when min-width (setf (wm-size-hints-min-width size) min-width))
  952. (when min-height (setf (wm-size-hints-min-height size) min-height))
  953. (when max-width (setf (wm-size-hints-max-width size) max-width))
  954. (when max-height (setf (wm-size-hints-max-height size) max-height))
  955. (when width-inc (setf (wm-size-hints-width-inc size) width-inc))
  956. (when height-inc (setf (wm-size-hints-height-inc size) height-inc))
  957. (when min-aspect (setf (wm-size-hints-min-aspect size) min-aspect))
  958. (when max-aspect (setf (wm-size-hints-max-aspect size) max-aspect))
  959. (when base-width (setf (wm-size-hints-base-width size) base-width))
  960. (when base-height (setf (wm-size-hints-base-height size) base-height))
  961. (when win-gravity (setf (wm-size-hints-win-gravity size) win-gravity))
  962. (when usppp
  963. (setf (wm-size-hints-user-specified-position-p size) user-specified-position-p))
  964. (when usspp
  965. (setf (wm-size-hints-user-specified-size-p size) user-specified-size-p))
  966. (when psppp
  967. (setf (wm-size-hints-program-specified-position-p size) program-specified-position-p))
  968. (when psspp
  969. (setf (wm-size-hints-program-specified-size-p size) program-specified-size-p))
  970. (setf (wm-normal-hints window) size))
  971. (when normal-hints (setf (wm-normal-hints window) normal-hints)))
  972. (when zoom-hints (setf (wm-zoom-hints window) zoom-hints))
  973. )
  974. ;;; OBSOLETE
  975. (defun set-standard-properties (window &rest options)
  976. (apply #'set-wm-properties window options))
  977. ;;-----------------------------------------------------------------------------
  978. ;; Colormaps
  979. (defstruct (standard-colormap (:copier nil) (:predicate nil))
  980. (colormap nil :type (or null colormap))
  981. (base-pixel 0 :type pixel)
  982. (max-color nil :type (or null color))
  983. (mult-color nil :type (or null color))
  984. (visual nil :type (or null visual-info))
  985. (kill nil :type (or (member nil :release-by-freeing-colormap)
  986. drawable gcontext cursor colormap font)))
  987. (defun card16->rgb-val (value)
  988. (declare (type card16 value))
  989. (declare (values short-float))
  990. (the short-float (* (the card16 value) (load-time-value (/ 1.0s0 #xffff)))))
  991. (defun rgb-colormaps (window property)
  992. (declare (type window window)
  993. (type (member :RGB_DEFAULT_MAP :RGB_BEST_MAP :RGB_RED_MAP
  994. :RGB_GREEN_MAP :RGB_BLUE_MAP) property))
  995. (let ((prop (get-property window property :type :RGB_COLOR_MAP :result-type 'vector)))
  996. (declare (type (or null simple-vector) prop))
  997. (when prop
  998. (list (make-standard-colormap
  999. :colormap (lookup-colormap (window-display window) (aref prop 0))
  1000. :base-pixel (aref prop 7)
  1001. :max-color (make-color :red (card16->rgb-val (aref prop 1))
  1002. :green (card16->rgb-val (aref prop 3))
  1003. :blue (card16->rgb-val (aref prop 5)))
  1004. :mult-color (make-color :red (card16->rgb-val (aref prop 2))
  1005. :green (card16->rgb-val (aref prop 4))
  1006. :blue (card16->rgb-val (aref prop 6)))
  1007. :visual (and (<= 9 (length prop))
  1008. (visual-info (window-display window) (aref prop 8)))
  1009. :kill (and (<= 10 (length prop))
  1010. (let ((killid (aref prop 9)))
  1011. (if (= killid 1)
  1012. :release-by-freeing-colormap
  1013. (lookup-resource-id (window-display window)
  1014. killid)))))))))
  1015. (defsetf rgb-colormaps set-rgb-colormaps)
  1016. (defun set-rgb-colormaps (window property maps)
  1017. (declare (type window window)
  1018. (type (member :RGB_DEFAULT_MAP :RGB_BEST_MAP :RGB_RED_MAP
  1019. :RGB_GREEN_MAP :RGB_BLUE_MAP) property)
  1020. (type list maps))
  1021. (let ((prop (make-array (* 10 (length maps)) :element-type 'card32))
  1022. (index -1))
  1023. (dolist (map maps)
  1024. (setf (aref prop (incf index))
  1025. (encode-type colormap (standard-colormap-colormap map)))
  1026. (setf (aref prop (incf index))
  1027. (encode-type rgb-val (color-red (standard-colormap-max-color map))))
  1028. (setf (aref prop (incf index))
  1029. (encode-type rgb-val (color-red (standard-colormap-mult-color map))))
  1030. (setf (aref prop (incf index))
  1031. (encode-type rgb-val (color-green (standard-colormap-max-color map))))
  1032. (setf (aref prop (incf index))
  1033. (encode-type rgb-val (color-green (standard-colormap-mult-color map))))
  1034. (setf (aref prop (incf index))
  1035. (encode-type rgb-val (color-blue (standard-colormap-max-color map))))
  1036. (setf (aref prop (incf index))
  1037. (encode-type rgb-val (color-blue (standard-colormap-mult-color map))))
  1038. (setf (aref prop (incf index))
  1039. (standard-colormap-base-pixel map))
  1040. (setf (aref prop (incf index))
  1041. (visual-info-id (standard-colormap-visual map)))
  1042. (setf (aref prop (incf index))
  1043. (let ((kill (standard-colormap-kill map)))
  1044. (etypecase kill
  1045. (symbol
  1046. (ecase kill
  1047. ((nil) 0)
  1048. ((:release-by-freeing-colormap) 1)))
  1049. (drawable (drawable-id kill))
  1050. (gcontext (gcontext-id kill))
  1051. (cursor (cursor-id kill))
  1052. (colormap (colormap-id kill))
  1053. (font (font-id kill))))))
  1054. (change-property window property prop :RGB_COLOR_MAP 32)))
  1055. ;;; OBSOLETE
  1056. (defun get-standard-colormap (window property)
  1057. (declare (type window window)
  1058. (type (member :RGB_DEFAULT_MAP :RGB_BEST_MAP :RGB_RED_MAP
  1059. :RGB_GREEN_MAP :RGB_BLUE_MAP) property))
  1060. (declare (values colormap base-pixel max-color mult-color))
  1061. (let ((prop (get-property window property :type :RGB_COLOR_MAP :result-type 'vector)))
  1062. (declare (type (or null simple-vector) prop))
  1063. (when prop
  1064. (values (lookup-colormap (window-display window) (aref prop 0))
  1065. (aref prop 7) ;Base Pixel
  1066. (make-color :red (card16->rgb-val (aref prop 1)) ;Max Color
  1067. :green (card16->rgb-val (aref prop 3))
  1068. :blue (card16->rgb-val (aref prop 5)))
  1069. (make-color :red (card16->rgb-val (aref prop 2)) ;Mult color
  1070. :green (card16->rgb-val (aref prop 4))
  1071. :blue (card16->rgb-val (aref prop 6)))))))
  1072. ;;; OBSOLETE
  1073. (defun set-standard-colormap (window property colormap base-pixel max-color mult-color)
  1074. (declare (type window window)
  1075. (type (member :RGB_DEFAULT_MAP :RGB_BEST_MAP :RGB_RED_MAP
  1076. :RGB_GREEN_MAP :RGB_BLUE_MAP) property)
  1077. (type colormap colormap)
  1078. (type pixel base-pixel)
  1079. (type color max-color mult-color))
  1080. (let ((prop (apply #'vector (encode-type colormap colormap)
  1081. (encode-type rgb-val (color-red max-color))
  1082. (encode-type rgb-val (color-red mult-color))
  1083. (encode-type rgb-val (color-green max-color))
  1084. (encode-type rgb-val (color-green mult-color))
  1085. (encode-type rgb-val (color-blue max-color))
  1086. (encode-type rgb-val (color-blue mult-color))
  1087. base-pixel)))
  1088. (change-property window property prop :RGB_COLOR_MAP 32)))
  1089. ;;;; --------------------------------------------------------------------------
  1090. ;;;; Cut-Buffers
  1091. ;;;; --------------------------------------------------------------------------
  1092. (defun cut-buffer (display &key (buffer 0) (type :STRING) (result-type 'string)
  1093. (transform #'card8->char) (start 0) end)
  1094. ;; Return the contents of cut-buffer BUFFER
  1095. (let* ((root (screen-root (display-default-screen display)))
  1096. (property (aref '#(:CUT_BUFFER0 :CUT_BUFFER1 :CUT_BUFFER2 :CUT_BUFFER3
  1097. :CUT_BUFFER4 :CUT_BUFFER5 :CUT_BUFFER6 :CUT_BUFFER7)
  1098. buffer)))
  1099. (get-property root property :type type :result-type result-type
  1100. :start start :end end :transform transform)))
  1101. (defun (setf cut-buffer) (data display &key (buffer 0) (type :STRING) (format 8)
  1102. (start 0) end (transform #'char->card8))
  1103. (let* ((root (screen-root (display-default-screen display)))
  1104. (property (aref '#(:CUT_BUFFER0 :CUT_BUFFER1 :CUT_BUFFER2 :CUT_BUFFER3
  1105. :CUT_BUFFER4 :CUT_BUFFER5 :CUT_BUFFER6 :CUT_BUFFER7)
  1106. buffer)))
  1107. (change-property root property data type format
  1108. :start start :end end :transform transform)
  1109. data))
  1110. (defun rotate-cut-buffers (display &optional (delta 1) (careful-p t))
  1111. ;; Positive rotates left, negative rotates right
  1112. ;; (opposite of actual protocol request).
  1113. ;; When careful-p, ensure all cut-buffer properties are defined,
  1114. ;; to prevent errors.
  1115. (let* ((root (screen-root (display-default-screen display)))
  1116. (buffers '#(:CUT_BUFFER0 :CUT_BUFFER1 :CUT_BUFFER2 :CUT_BUFFER3
  1117. :CUT_BUFFER4 :CUT_BUFFER5 :CUT_BUFFER6 :CUT_BUFFER7)))
  1118. (when careful-p
  1119. (let ((props (list-properties root)))
  1120. (dotimes (i 8)
  1121. (unless (member (aref buffers i) props)
  1122. (setf (cut-buffer display :buffer i) "")))))
  1123. (rotate-properties root buffers delta)))
  1124. ;;;; --------------------------------------------------------------------------
  1125. ;;;; Printers
  1126. ;;;; --------------------------------------------------------------------------
  1127. ;;; NOTE:
  1128. ;;; I used here a (funcall #,#'fun ..) klugde,
  1129. ;;; but by clisp-1996-07-22 this now considered illegal,
  1130. ;;; so I save the untraced functions by copying them.
  1131. ;;; This allows me to trace all or arbitrary
  1132. ;;; xlib functions without getting into infinite recursion.
  1133. (setf (fdefinition '%untraced-color-blue) #'color-blue
  1134. (fdefinition '%untraced-color-green) #'color-green
  1135. (fdefinition '%untraced-color-red) #'color-red
  1136. (fdefinition '%untraced-colormap-visual-info) #'colormap-visual-info
  1137. (fdefinition '%untraced-display-display) #'display-display
  1138. (fdefinition '%untraced-display-host) #'display-host
  1139. (fdefinition '%untraced-display-protocol-major-version)
  1140. #'display-protocol-major-version
  1141. (fdefinition '%untraced-display-protocol-minor-version)
  1142. #'display-protocol-minor-version
  1143. (fdefinition '%untraced-display-release-number) #'display-release-number
  1144. (fdefinition '%untraced-display-vendor-name) #'display-vendor-name
  1145. (fdefinition '%untraced-drawable-height) #'drawable-height
  1146. (fdefinition '%untraced-drawable-width) #'drawable-width
  1147. (fdefinition '%untraced-drawable-x) #'drawable-x
  1148. (fdefinition '%untraced-drawable-y) #'drawable-y
  1149. (fdefinition '%untraced-visual-info-class) #'visual-info-class)
  1150. (defmethod print-object ((color color) (out stream))
  1151. (if *print-readably* (call-next-method)
  1152. (print-unreadable-object (color out :type t :identity t)
  1153. (write (%untraced-color-red color) :stream out)
  1154. (write-string " " out)
  1155. (write (%untraced-color-green color) :stream out)
  1156. (write-string " " out)
  1157. (write (%untraced-color-blue color) :stream out))))
  1158. (defmethod print-object ((dpy display) (out stream))
  1159. (if *print-readably* (call-next-method)
  1160. (print-unreadable-object (dpy out :type t :identity t)
  1161. (if (closed-display-p dpy)
  1162. (write 'closed-display :stream out)
  1163. (format out "~A:~D (~A R~D) X~D.~D"
  1164. (%untraced-display-host dpy)
  1165. (%untraced-display-display dpy)
  1166. (%untraced-display-vendor-name dpy)
  1167. (%untraced-display-release-number dpy)
  1168. (%untraced-display-protocol-major-version dpy)
  1169. (%untraced-display-protocol-minor-version dpy))))))
  1170. (defmethod print-object ((xo xid-object) (out stream))
  1171. (if *print-readably* (call-next-method)
  1172. (print-unreadable-object (xo out :type t :identity t)
  1173. (with-slots (id display) xo
  1174. (format out "~A #x~8,'0X"
  1175. (if (closed-display-p display)
  1176. 'closed-display
  1177. (%untraced-display-host display))
  1178. id)))))
  1179. (defmethod print-object ((cm colormap) (out stream))
  1180. (with-slots (id display) cm
  1181. (if (or *print-readably* (closed-display-p display)) (call-next-method)
  1182. (print-unreadable-object (cm out :type t :identity t)
  1183. (let* ((visinfo (%untraced-colormap-visual-info cm))
  1184. (vclass (if visinfo (%untraced-visual-info-class visinfo)
  1185. "unknown visual class")))
  1186. (format out "~A #x~8,'0X ~A" (%untraced-display-host display)
  1187. id vclass))))))
  1188. (defmethod print-object ((fo font) (out stream))
  1189. (with-slots (id name display) fo
  1190. (if (or *print-readably* (closed-display-p display)) (call-next-method)
  1191. (print-unreadable-object (fo out :type t :identity t)
  1192. (format out "~A ~A #x~8,'0X" (%untraced-display-host display)
  1193. name id)))))
  1194. (defmethod print-object ((dr drawable) (out stream))
  1195. (with-slots (id display) dr
  1196. (if (or *print-readably* (closed-display-p display)) (call-next-method)
  1197. (print-unreadable-object (dr out :type t :identity t)
  1198. (format out "~Dx~D+~D+~D ~A #x~8,'0X"
  1199. (%untraced-drawable-width dr) (%untraced-drawable-height dr)
  1200. (%untraced-drawable-x dr) (%untraced-drawable-y dr)
  1201. (%untraced-display-host display) id)))))
  1202. ;;;; --------------------------------------------------------------------------
  1203. ;;;; Misc
  1204. ;;;; --------------------------------------------------------------------------
  1205. ;;; from dependent.lisp in http://common-lisp.net/~crhodes/clx
  1206. ;;; this particular defaulting behaviour is typical to most Unices, I think
  1207. (defun get-default-display (&optional display-name)
  1208. "Parse the argument DISPLAY-NAME, or the environment variable $DISPLAY
  1209. if it is NIL. Display names have the format
  1210. [protocol/] [hostname] : [:] displaynumber [.screennumber]
  1211. There are two special cases in parsing, to match that done in the Xlib
  1212. C language bindings
  1213. - If the hostname is ``unix'' or the empty string, any supplied
  1214. protocol is ignored and a connection is made using the :local
  1215. transport.
  1216. - If a double colon separates hostname from displaynumber, the
  1217. protocol is assumed to be decnet.
  1218. Returns a list of (host display-number screen protocol)."
  1219. (let* ((name (or display-name
  1220. (ext:getenv "DISPLAY")
  1221. (error "DISPLAY environment variable is not set")))
  1222. (slash-i (or (position #\/ name) -1))
  1223. (colon-i (position #\: name :start (1+ slash-i)))
  1224. (decnet-colon-p (eql (elt name (1+ colon-i)) #\:))
  1225. (host (subseq name (1+ slash-i) colon-i))
  1226. (dot-i (and colon-i (position #\. name :start colon-i)))
  1227. (display (when colon-i
  1228. (parse-integer name
  1229. :start (if decnet-colon-p
  1230. (+ colon-i 2)
  1231. (1+ colon-i))
  1232. :end dot-i)))
  1233. (screen (when dot-i
  1234. (parse-integer name :start (1+ dot-i))))
  1235. (protocol
  1236. (cond ((or (string= host "") (string-equal host "unix")) :local)
  1237. (decnet-colon-p :decnet)
  1238. ((> slash-i -1) (intern
  1239. (string-upcase (subseq name 0 slash-i))
  1240. :keyword))
  1241. (t :internet))))
  1242. (list host (or display 0) (or screen 0) protocol)))
  1243. (defun open-default-display (&optional display-name)
  1244. "Open a connection to DISPLAY-NAME if supplied, or to the appropriate
  1245. default display as given by GET-DEFAULT-DISPLAY otherwise."
  1246. (destructuring-bind (host display screen protocol)
  1247. (get-default-display display-name)
  1248. (let ((dpy (open-display host :display display :protocol protocol)))
  1249. (setf (display-default-screen dpy) screen)
  1250. dpy)))
  1251. ;;;; --------------------------------------------------------------------------
  1252. ;;;; Stuff, which is realy some internals of CLX,
  1253. ;;;; but needed by some programs ...
  1254. ;;;; --------------------------------------------------------------------------
  1255. (defconstant *STATE-MASK-VECTOR*
  1256. '#(:shift :lock :control :mod-1 :mod-2 :mod-3 :mod-4 :mod-5 :button-1 :button-2 :button-3 :button-4 :button-5))
  1257. (defconstant *GCONTEXT-COMPONENTS*
  1258. '(:DRAWABLE :FUNCTION :PLANE-MASK :FOREGROUND :BACKGROUND
  1259. :LINE-WIDTH :LINE-STYLE :CAP-STYLE :JOIN-STYLE :FILL-STYLE
  1260. :FILL-RULE :ARC-MODE :TILE :STIPPLE :TS-X :TS-Y :FONT
  1261. :SUBWINDOW-MODE :EXPOSURES :CLIP-X :CLIP-Y :CLIP-MASK
  1262. :CLIP-ORDERING :DASH-OFFSET :DASHES :CACHE-P))
  1263. (defun make-gcontext (&rest ignore)
  1264. (warn "~S~@[~S~] is an internal function!" 'make-gcontext ignore)
  1265. (make-instance 'gcontext))
  1266. ;; What has that to do with graphics?!
  1267. (defun kintern (name) (intern (string name) #,(find-package :keyword)))
  1268. ;;;;From depdefs.lisp
  1269. ;;;;
  1270. ;;; This defines a type which is a subtype of the integers.
  1271. ;;; This type is used to describe all variables that can be array indices.
  1272. ;;; It is here because it is used below.
  1273. ;;; This is inclusive because start/end can be 1 past the end.
  1274. ;; Note: These are ignorant version of these macros!
  1275. (defmacro index+ (&rest numbers) `(+ ,@numbers))
  1276. (defmacro index-logand (&rest numbers) `(logand ,@numbers))
  1277. (defmacro index-logior (&rest numbers) `(logior ,@numbers))
  1278. (defmacro index- (&rest numbers) `(- ,@numbers))
  1279. (defmacro index* (&rest numbers) `(* ,@numbers))
  1280. (defmacro index1+ (number) `(1+ ,number))
  1281. (defmacro index1- (number) `(1- ,number))
  1282. (defmacro index-incf (place &optional (delta 1)) `(setf ,place (index+ ,place ,delta)));Hmm?
  1283. (defmacro index-decf (place &optional (delta 1)) `(setf ,place (index- ,place ,delta)));Hmm?
  1284. (defmacro index-min (&rest numbers) `(min ,@numbers))
  1285. (defmacro index-max (&rest numbers) `(max ,@numbers))
  1286. (defmacro index-floor (number divisor) `(floor ,number ,divisor))
  1287. (defmacro index-ceiling (number divisor) `(ceiling ,number ,divisor))
  1288. (defmacro index-truncate (number divisor) `(truncate ,number ,divisor))
  1289. (defmacro index-mod (number divisor) `(mod ,number ,divisor))
  1290. (defmacro index-ash (number count) `(ash ,number ,count))
  1291. (defmacro index-plusp (number) `(plusp ,number))
  1292. (defmacro index-zerop (number) `(zerop ,number))
  1293. (defmacro index-evenp (number) `(evenp ,number))
  1294. (defmacro index-oddp (number) `(oddp ,number))
  1295. (defmacro index> (&rest numbers) `(> ,@numbers))
  1296. (defmacro index= (&rest numbers) `(= ,@numbers))
  1297. (defmacro index< (&rest numbers) `(< ,@numbers))
  1298. (defmacro index>= (&rest numbers) `(>= ,@numbers))
  1299. (defmacro index<= (&rest numbers) `(<= ,@numbers))
  1300. (defun read-bitmap-file (pathname)
  1301. ;; Creates an image from a C include file in standard X11 format
  1302. (declare (type (or pathname string stream) pathname))
  1303. (declare (values image))
  1304. (with-open-file (fstream pathname :direction :input)
  1305. (let ((line "")
  1306. (properties nil)
  1307. (name nil)
  1308. (name-end nil))
  1309. (declare (type string line)
  1310. (type stringable name)
  1311. (type list properties))
  1312. ;; Get properties
  1313. (loop
  1314. (setq line (read-line fstream))
  1315. (unless (char= (aref line 0) #\#) (return))
  1316. (flet ((read-keyword (line start end)
  1317. (kintern
  1318. (substitute
  1319. #\- #\_
  1320. (#-excl string-upcase
  1321. #+excl correct-case
  1322. (subseq line start end))
  1323. :test #'char=))))
  1324. (when (null name)
  1325. (setq name-end (position #\_ line :test #'char= :from-end t)
  1326. name (read-keyword line 8 name-end))
  1327. (unless (eq name :image)
  1328. (setf (getf properties :name) name)))
  1329. (let* ((ind-start (index1+ name-end))
  1330. (ind-end (position #\Space line :test #'char=
  1331. :start ind-start))
  1332. (ind (read-keyword line ind-start ind-end))
  1333. (val-start (index1+ ind-end))
  1334. (val (parse-integer line :start val-start)))
  1335. (setf (getf properties ind) val))))
  1336. ;; Calculate sizes
  1337. (multiple-value-bind (width height depth left-pad)
  1338. (flet ((extract-property (ind &rest default)
  1339. (prog1 (apply #'getf properties ind default)
  1340. (remf properties ind))))
  1341. (values (extract-property :width)
  1342. (extract-property :height)
  1343. (extract-property :depth 1)
  1344. (extract-property :left-pad 0)))
  1345. (declare (type (or null card16) width height)
  1346. (type image-depth depth)
  1347. (type card8 left-pad))
  1348. (unless (and width height) (error "Not a BITMAP file"))
  1349. (let* ((bits-per-pixel
  1350. (cond ((index> depth 24) 32)
  1351. ((index> depth 16) 24)
  1352. ((index> depth 8) 16)
  1353. ((index> depth 4) 8)
  1354. ((index> depth 1) 4)
  1355. (t 1)))
  1356. (bits-per-line (index* width bits-per-pixel))
  1357. (bytes-per-line (index-ceiling bits-per-line 8))
  1358. (padded-bits-per-line
  1359. (index* (index-ceiling bits-per-line 32) 32))
  1360. (padded-bytes-per-line
  1361. (index-ceiling padded-bits-per-line 8))
  1362. (data (make-array (* padded-bytes-per-line height)
  1363. :element-type 'card8))
  1364. (line-base 0)
  1365. (byte 0))
  1366. #|(declare (type array-index bits-per-line bytes-per-line
  1367. padded-bits-per-line padded-bytes-per-line
  1368. line-base byte)
  1369. (type buffer-bytes data))|#
  1370. (progn
  1371. (flet ((parse-hex (char)
  1372. (second
  1373. (assoc char
  1374. '((#\0 0) (#\1 1) (#\2 2) (#\3 3)
  1375. (#\4 4) (#\5 5) (#\6 6) (#\7 7)
  1376. (#\8 8) (#\9 9) (#\a 10) (#\b 11)
  1377. (#\c 12) (#\d 13) (#\e 14) (#\f 15))
  1378. :test #'char-equal))))
  1379. (locally
  1380. (declare (inline parse-hex))
  1381. ;; Read data
  1382. ;; Note: using read-line instead of read-char would be 20% faster,
  1383. ;; but would cons a lot of garbage...
  1384. (dotimes (i height)
  1385. (dotimes (j bytes-per-line)
  1386. (loop (when (eql (read-char fstream) #\x) (return)))
  1387. (setf (aref data (index+ line-base byte))
  1388. (index+ (index-ash (parse-hex (read-char fstream)) 4)
  1389. (parse-hex (read-char fstream))))
  1390. (incf byte))
  1391. (setq byte 0
  1392. line-base (index+ line-base padded-bytes-per-line))))))
  1393. ;; Compensate for left-pad in width and x-hot
  1394. (index-decf width left-pad)
  1395. (when (and (getf properties :x-hot) (plusp (getf properties :x-hot)))
  1396. (index-decf (getf properties :x-hot) left-pad))
  1397. (create-image
  1398. :width width :height height
  1399. :depth depth :bits-per-pixel bits-per-pixel
  1400. :data data :plist properties :format :z-pixmap
  1401. :bytes-per-line padded-bytes-per-line
  1402. :unit 32 :pad 32 :left-pad left-pad
  1403. :byte-lsb-first-p t :bit-lsb-first-p t))))))
  1404. ;; These functions are used by clue.
  1405. (defun encode-event-mask (keys)
  1406. (apply #'make-event-mask keys))
  1407. ;;These two could be provided.
  1408. ;;(defun save-id (display id object) "Register a resource-id from another display.")
  1409. ;;(defmacro deallocate-resource-id (display id type) "Deallocate a resource-id for OBJECT in DISPLAY")
  1410. ;;(defun x-type-error (object type &optional error-string))
  1411. ;;(defun get-display-modifier-mapping (display))
  1412. ;; actually exported.
  1413. ;; (defun mapping-notify (display request start count)
  1414. ;; "Called on a mapping-notify event to update the keyboard-mapping cache in DISPLAY")
  1415. ;;; Error handler, we probably want a proper condition hierarchy, but for a first approach this may be enough:
  1416. (defun default-error-handler (display error-key &rest key-vals
  1417. &key asynchronous &allow-other-keys)
  1418. (if asynchronous
  1419. (apply 'cerror "Ignore this error and proceed." error-key
  1420. :display display :error-key error-key key-vals)
  1421. (apply 'error error-key
  1422. :display display :error-key error-key key-vals)))
  1423. (defun report-request-error (condition stream)
  1424. (let ((error-key (request-error-error-key condition))
  1425. (asynchronous (request-error-asynchronous condition))
  1426. (major (request-error-major condition))
  1427. (minor (request-error-minor condition))
  1428. (sequence (request-error-sequence condition))
  1429. (current-sequence (request-error-current-sequence condition)))
  1430. (format stream "~:[~;Asynchronous ~]~a in ~:[request ~d (last request was ~d) ~;current request~2* ~] Code ~d.~d"
  1431. asynchronous error-key (= sequence current-sequence)
  1432. sequence current-sequence major minor)))
  1433. (define-condition x-error (error)
  1434. ((caller :reader x-error-caller :initarg :caller)))
  1435. (define-condition closed-display (x-error)
  1436. ((display :reader closed-display-display :initarg :display))
  1437. (:report
  1438. (lambda (condition stream)
  1439. (format stream "~s: used closed display ~s"
  1440. (x-error-caller condition)
  1441. (closed-display-display condition)))))
  1442. (define-condition request-error (x-error)
  1443. ((display :reader request-error-display :initarg :display)
  1444. (error-key :reader request-error-error-key :initarg :error-key)
  1445. (major :reader request-error-major :initarg :major)
  1446. (minor :reader request-error-minor :initarg :minor)
  1447. (sequence :reader request-error-sequence :initarg :sequence)
  1448. (current-sequence :reader request-error-current-sequence :initarg :current-sequence)
  1449. (asynchronous :reader request-error-asynchronous :initarg :asynchronous))
  1450. (:report report-request-error))
  1451. (define-condition resource-error (request-error)
  1452. ((resource-id :reader resource-error-resource-id :initarg :resource-id))
  1453. (:report
  1454. (lambda (condition stream)
  1455. (report-request-error condition stream)
  1456. (format stream " ID #x~x" (resource-error-resource-id condition)))))
  1457. (define-condition unknown-error (request-error)
  1458. ((error-code :reader unknown-error-error-code :initarg :error-code))
  1459. (:report
  1460. (lambda (condition stream)
  1461. (report-request-error condition stream)
  1462. (format stream " Error Code ~d." (unknown-error-error-code condition)))))
  1463. (define-condition access-error (request-error) ())
  1464. (define-condition alloc-error (request-error) ())
  1465. (define-condition atom-error (request-error)
  1466. ((atom-id :reader atom-error-atom-id :initarg :atom-id))
  1467. (:report
  1468. (lambda (condition stream)
  1469. (report-request-error condition stream)
  1470. (format stream " Atom-ID #x~x" (atom-error-atom-id condition)))))
  1471. (define-condition colormap-error (resource-error) ())
  1472. (define-condition cursor-error (resource-error) ())
  1473. (define-condition drawable-error (resource-error) ())
  1474. (define-condition font-error (resource-error) ())
  1475. (define-condition gcontext-error (resource-error) ())
  1476. (define-condition id-choice-error (resource-error) ())
  1477. (define-condition illegal-request-error (request-error) ())
  1478. (define-condition length-error (request-error) ())
  1479. (define-condition match-error (request-error) ())
  1480. (define-condition name-error (request-error) ())
  1481. (define-condition pixmap-error (resource-error) ())
  1482. (define-condition value-error (request-error)
  1483. ((value :reader value-error-value :initarg :value))
  1484. (:report
  1485. (lambda (condition stream)
  1486. (report-request-error condition stream)
  1487. (format stream " Value ~d." (value-error-value condition)))))
  1488. (define-condition x-type-error (type-error x-error)
  1489. ((type-string :reader x-type-error-type-string :initarg :type-string))
  1490. (:report
  1491. (lambda (condition stream)
  1492. (format stream "~s isn't a ~a"
  1493. (type-error-datum condition)
  1494. (or (x-type-error-type-string condition)
  1495. (type-error-expected-type condition))))))
  1496. (define-condition closed-display (x-error)
  1497. ((display :reader closed-display-display :initarg :display))
  1498. (:report
  1499. (lambda (condition stream)
  1500. (format stream "Attempt to use closed display ~s"
  1501. (closed-display-display condition)))))
  1502. (define-condition lookup-error (x-error)
  1503. ((id :reader lookup-error-id :initarg :id)
  1504. (display :reader lookup-error-display :initarg :display)
  1505. (type :reader lookup-error-type :initarg :type)
  1506. (object :reader lookup-error-object :initarg :object))
  1507. (:report
  1508. (lambda (condition stream)
  1509. (format stream "ID ~d from display ~s should have been a ~s, but was ~s"
  1510. (lookup-error-id condition)
  1511. (lookup-error-display condition)
  1512. (lookup-error-type condition)
  1513. (lookup-error-object condition)))))
  1514. (define-condition connection-failure (x-error)
  1515. ((major-version :reader connection-failure-major-version :initarg :major-version)
  1516. (minor-version :reader connection-failure-minor-version :initarg :minor-version)
  1517. (host :reader connection-failure-host :initarg :host)
  1518. (display :reader connection-failure-display :initarg :display)
  1519. (reason :reader connection-failure-reason :initarg :reason))
  1520. (:report
  1521. (lambda (condition stream)
  1522. (format stream "Connection failure to X~d.~d server ~a display ~d: ~a"
  1523. (connection-failure-major-version condition)
  1524. (connection-failure-minor-version condition)
  1525. (connection-failure-host condition)
  1526. (connection-failure-display condition)
  1527. (connection-failure-reason condition)))))
  1528. (define-condition reply-length-error (x-error)
  1529. ((reply-length :reader reply-length-error-reply-length :initarg :reply-length)
  1530. (expected-length :reader reply-length-error-expected-length :initarg :expected-length)
  1531. (display :reader reply-length-error-display :initarg :display))
  1532. (:report
  1533. (lambda (condition stream)
  1534. (format stream "Reply length was ~d when ~d words were expected for display ~s"
  1535. (reply-length-error-reply-length condition)
  1536. (reply-length-error-expected-length condition)
  1537. (reply-length-error-display condition)))))
  1538. (define-condition reply-timeout (x-error)
  1539. ((timeout :reader reply-timeout-timeout :initarg :timeout)
  1540. (display :reader reply-timeout-display :initarg :display))
  1541. (:report
  1542. (lambda (condition stream)
  1543. (format stream "Timeout after waiting ~d seconds for a reply for display ~s"
  1544. (reply-timeout-timeout condition)
  1545. (reply-timeout-display condition)))))
  1546. (define-condition sequence-error (x-error)
  1547. ((display :reader sequence-error-display :initarg :display)
  1548. (req-sequence :reader sequence-error-req-sequence :initarg :req-sequence)
  1549. (msg-sequence :reader sequence-error-msg-sequence :initarg :msg-sequence))
  1550. (:report
  1551. (lambda (condition stream)
  1552. (format stream "Reply out of sequence for display ~s.~% Expected ~d, Got ~d"
  1553. (sequence-error-display condition)
  1554. (sequence-error-req-sequence condition)
  1555. (sequence-error-msg-sequence condition)))))
  1556. (define-condition unexpected-reply (x-error)
  1557. ((display :reader unexpected-reply-display :initarg :display)
  1558. (msg-sequence :reader unexpected-reply-msg-sequence :initarg :msg-sequence)
  1559. (req-sequence :reader unexpected-reply-req-sequence :initarg :req-sequence)
  1560. (length :reader unexpected-reply-length :initarg :length))
  1561. (:report
  1562. (lambda (condition stream)
  1563. (format stream "Display ~s received a server reply when none was expected.~@
  1564. Last request sequence ~d Reply Sequence ~d Reply Length ~d bytes."
  1565. (unexpected-reply-display condition)
  1566. (unexpected-reply-req-sequence condition)
  1567. (unexpected-reply-msg-sequence condition)
  1568. (unexpected-reply-length condition)))))
  1569. (define-condition missing-parameter (x-error)
  1570. ((parameter :reader missing-parameter-parameter :initarg :parameter))
  1571. (:report
  1572. (lambda (condition stream)
  1573. (let ((parm (missing-parameter-parameter condition)))
  1574. (if (consp parm)
  1575. (format stream "One or more of the required parameters ~a is missing."
  1576. parm)
  1577. (format stream "Required parameter ~a is missing or null." parm))))))
  1578. ;; This can be signalled anywhere a pseudo font access fails.
  1579. (define-condition invalid-font (x-error)
  1580. ((font :reader invalid-font-font :initarg :font))
  1581. (:report
  1582. (lambda (condition stream)
  1583. (format stream "Can't access font ~s" (invalid-font-font condition)))))
  1584. (define-condition device-busy (x-error)
  1585. ((display :reader device-busy-display :initarg :display))
  1586. (:report
  1587. (lambda (condition stream)
  1588. (format stream "Device busy for display ~s"
  1589. (device-busy-display condition)))))
  1590. (define-condition unimplemented-event (x-error)
  1591. ((display :reader unimplemented-event-display :initarg :display)
  1592. (event-code :reader unimplemented-event-event-code :initarg :event-code))
  1593. (:report
  1594. (lambda (condition stream)
  1595. (format stream "Event code ~d not implemented for display ~s"
  1596. (unimplemented-event-event-code condition)
  1597. (unimplemented-event-display condition)))))
  1598. (define-condition undefined-event (x-error)
  1599. ((display :reader undefined-event-display :initarg :display)
  1600. (event-name :reader undefined-event-event-name :initarg :event-name))
  1601. (:report
  1602. (lambda (condition stream)
  1603. (format stream "Event code ~d undefined for display ~s"
  1604. (undefined-event-event-name condition)
  1605. (undefined-event-display condition)))))
  1606. (define-condition absent-extension (x-error)
  1607. ((name :reader absent-extension-name :initarg :name)
  1608. (display :reader absent-extension-display :initarg :display))
  1609. (:report
  1610. (lambda (condition stream)
  1611. (format stream "Extension ~a isn't defined for display ~s"
  1612. (absent-extension-name condition)
  1613. (absent-extension-display condition)))))
  1614. (define-condition inconsistent-parameters (x-error)
  1615. ((parameters :reader inconsistent-parameters-parameters :initarg :parameters))
  1616. (:report
  1617. (lambda (condition stream)
  1618. (format stream "inconsistent-parameters:~{ ~s~}"
  1619. (inconsistent-parameters-parameters condition)))))
  1620. (define-condition window-error (resource-error)())
  1621. (define-condition implementation-error (request-error) ())
  1622. (define-condition connection-failure (x-error) ())
  1623. (define-condition device-busy (x-error) ())
  1624. ;; (define-condition server-disconnect (x-error) ())
  1625. (pushnew "XLIB" custom:*system-package-list* :test #'string=)
  1626. (pushnew "XPM" custom:*system-package-list* :test #'string=)
  1627. ;; some functions are not implemented:
  1628. (macrolet ((undefined (name)
  1629. `(define-compiler-macro ,name (&whole form &rest args)
  1630. (declare (ignore args))
  1631. (progn (warn "~S is not implemented: ~S" ',name form)
  1632. form))))
  1633. (undefined DISPLAY-TRACE)
  1634. (undefined DRAW-GLYPH)
  1635. (undefined DRAW-IMAGE-GLYPH)
  1636. (undefined TRANSLATE-DEFAULT)
  1637. (undefined QUEUE-EVENT)
  1638. )