home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / MacHaskell 2.2 / progs / lib / X11 / xlibclx.scm < prev    next >
Encoding:
Text File  |  1994-09-27  |  38.9 KB  |  1,227 lines  |  [TEXT/CCL2]

  1. ;;; xlibclx.scm -- Lisp support for Haskell/CLX interface
  2.  
  3. ;; general
  4.  
  5. (define-syntax (nth-value n form)
  6.   (cond ((eqv? n 0)
  7.      `(values ,form))
  8.     ((number? n)
  9.      (let ((temps  '()))
  10.        (dotimes (i n)
  11.          (declare (ignorable i))
  12.          (push (gensym) temps))
  13.        `(multiple-value-bind ,(reverse temps) ,form
  14.           (declare (ignore ,@(reverse (cdr temps))))
  15.           ,(car temps))))
  16.     (else
  17.      `(lisp:nth ,n (lisp:multiple-value-list ,form)))
  18.     ))
  19.  
  20.  
  21. (define-local-syntax (keywordify string)
  22.   `(lisp:intern ,string (lisp:find-package "KEYWORD")))
  23.  
  24. (define-local-syntax (xlibify string)
  25.   `(lisp:intern ,string (lisp:find-package "XLIB")))
  26.  
  27.  
  28.  
  29. ;;; This is stuff to support slots that consist of a keyword/value
  30. ;;; pair.  Note that the value is always unboxed.
  31.  
  32. (define-syntax (make-keyword key value)
  33.   `(cons ,key ,value))
  34.  
  35. (define-syntax (is-keyword? x key)
  36.   `(eq? (car ,x) ,key))
  37.  
  38. (define-syntax (keyword-key x) `(car ,x))
  39. (define-syntax (keyword-val x) `(cdr ,x))
  40.  
  41. (define-syntax (define-keyword-constructor name)
  42.   (let* ((name-str (symbol->string name))
  43.      (key      (keywordify name-str))
  44.      (is-name  (string->symbol (string-append "IS-" name-str)))
  45.      (mk-name  (string->symbol (string-append "MK-" name-str))))
  46.     `(begin
  47.        (define (,mk-name x) (make-keyword ,key x))
  48.        (define (,is-name x) (is-keyword? x ,key)))
  49.     ))
  50.  
  51. (define-syntax (define-event-slot-finder slot)
  52.   (let* ((slot-str (symbol->string slot))
  53.      (slot-key (keywordify slot-str))
  54.      (fun      (string->symbol (string-append "X-EVENT-" slot-str))))
  55.     `(define (,fun event) (lookup-event-slot (cdr event) ,slot-key))))    
  56.     
  57. (define (lookup-event-slot event key)
  58.   (if (null? event)
  59.       (error "non-existent event slot: ~A" key)
  60.       (if (eq? key (car event))
  61.       (cadr event)
  62.       (lookup-event-slot (cddr event) key))))
  63.  
  64.  
  65. (define-syntax (define-attribute-setter entity attribute)
  66.   (let* ((entity-attr (string-append (symbol->string entity)
  67.                      "-"
  68.                      (symbol->string attribute)))
  69.      (fun-name    (string->symbol (string-append "X-SET-" entity-attr)))
  70.      (xfun-name   (xlibify entity-attr)))
  71.     `(define (,fun-name ,entity ,attribute)
  72.        (setf (,xfun-name ,entity) ,attribute))))
  73.  
  74. (define-syntax (make-h-tuple . args)
  75.   (let ((nargs (map (lambda (arg) `(box ,arg)) args)))
  76.     `(make-tuple ,@nargs)))
  77.  
  78.  
  79. ;; for type XMaybe
  80.  
  81. (define (not-null? x) (not (null? x)))
  82.  
  83.  
  84. ;; For Bitmap, Pixarray, KeysymTable
  85.  
  86. (define (array2->haskell-list a)
  87.   (let* ((dims    (lisp:array-dimensions a))
  88.      (i1max   (car dims))
  89.      (i2max   (cadr dims)))
  90.     (declare (type fixnum i1max i2max))
  91.     (do ((i1     (the fixnum (1- i1max)) (the fixnum (1- i1)))
  92.      (outer  '()))
  93.     ((< i1 0) outer)
  94.     (declare (type fixnum i1))
  95.     (setf outer
  96.           (cons
  97.             (box
  98.           (do ((i2    (the fixnum (1- i2max)) (the fixnum (1- i2)))
  99.                (inner '()))
  100.               ((< i2 0) inner)
  101.               (declare (type fixnum i2))
  102.               (setf inner
  103.                 (cons (box (lisp:aref a i1 i2))
  104.                   (box inner)))))
  105.         (box outer))))
  106.     ))
  107.  
  108.  
  109. ;; Bitmap
  110.  
  111. (define (mk-bitmap ll)
  112.   (let ((l (haskell-list->list #'haskell-list->list/identity ll)))
  113.     (lisp:make-array `(,(length l) , (length (car l))) 
  114.              :element-type 'lisp:bit
  115.              :initial-contents l)))
  116.  
  117. (define (sel-bitmap l)
  118.   (array2->haskell-list l))
  119.  
  120.  
  121. ;; XKeysymTable
  122.  
  123. (define (mk-keysym-table ll)
  124.   (let ((l (haskell-list->list #'haskell-list->list/identity ll)))
  125.     (lisp:make-array `(,(length l) , (length (car l))) 
  126.              :element-type 'xlib:card32
  127.              :initial-contents l)))
  128.  
  129. (define (sel-keysym-table l)
  130.   (array2->haskell-list l))
  131.  
  132. ;; XPixarray
  133.  
  134. (define (mk-pixarray ll)
  135.   (let ((l (haskell-list->list #'haskell-list->list/identity ll)))
  136.     (let* ((max-num  (find-max l))
  137.        (pix-type (cond ((<= max-num 1) 'lisp:bit)
  138.                ((<= max-num 15) '(lisp:unsigned-byte 4))
  139.                ((<= max-num 255) 'xlib:card8)
  140.                ((<= max-num 65535) 'xlib:card16)
  141.                (else 'xlib:card32))))
  142.       (declare (type integer max-num))
  143.       (lisp:make-array `(,(length l) , (length (car l)))
  144.                :element-type pix-type
  145.                :initial-contents l))))
  146.  
  147. (define (find-max l)
  148.   (let ((max  0))
  149.     (dolist (ll l)
  150.       (dolist (lll ll)
  151.     (when (> (the integer lll) (the integer max))
  152.       (setf max lll))))
  153.     max))
  154.  
  155. (define (sel-pixarray l)
  156.   (array2->haskell-list l))
  157.  
  158.  
  159.  
  160.  
  161. ;;; Can't use mumble vector primitives on arrays of specialized types!
  162.  
  163. (define (array1->haskell-list a)
  164.   (declare (type lisp:vector a))
  165.   (let ((imax  (lisp:length a)))
  166.     (declare (type fixnum imax))
  167.     (do ((i      (the fixnum (1- imax)) (the fixnum (1- i)))
  168.      (result '()))
  169.     ((< i 0) result)
  170.     (declare (type fixnum i))
  171.     (setf result
  172.           (cons (box (lisp:aref a i))
  173.             (box result))))))
  174.  
  175. ;; BitVec
  176.  
  177. (define (mk-bitvec ll)
  178.   (let ((l (haskell-list->list/identity ll)))
  179.     (lisp:make-array `(,(length l)) :element-type 'lisp:bit
  180.              :initial-contents l)))
  181.  
  182. (define (sel-bitvec l)
  183.   (array1->haskell-list l))
  184.  
  185. ;; ByteVec
  186.  
  187. (define (mk-bytevec ll)
  188.   (let ((l (haskell-list->list/identity ll)))
  189.     (lisp:make-array `(,(length l)) :element-type 'xlib:card8
  190.              :initial-contents l)))
  191.  
  192. (define (sel-bytevec l)
  193.   (array1->haskell-list l))
  194.  
  195.  
  196. ;; XAtom
  197. (define (mk-atom name)
  198.   (keywordify (haskell-string->string name)))
  199.  
  200. (define (sel-atom atom)
  201.   (make-haskell-string (symbol->string atom)))
  202.  
  203. ;; XProperty
  204. ;;; watch out for name conflict with :property keyword stuff
  205. (define (mk-xproperty d ty f) (list (haskell-list->list/identity d) ty f))
  206. (define (sel-xproperty-data p) (list->haskell-list/identity (car p)))
  207. (define (sel-xproperty-type p) (cadr p))
  208. (define (sel-xproperty-format p) (caddr p))
  209.  
  210. (define (mk-event type slots)
  211.   (cons type (slots->keywords (haskell-list->list/identity slots))))
  212.  
  213. (define (sel-event-type event) (car event))
  214.  
  215. (define (sel-event-slots event) 
  216.   (list->haskell-list/identity (keywords->slots (car event) (cdr event) event)))
  217.  
  218. ;; XEventSlot
  219.  
  220. (define-keyword-constructor window)
  221. (define-keyword-constructor event-window)
  222. (define-keyword-constructor code)
  223. (define-keyword-constructor pos)
  224. (define-keyword-constructor state)
  225. (define-keyword-constructor time)
  226. (define-keyword-constructor root)
  227. (define-keyword-constructor root-pos)
  228. (define-keyword-constructor child)
  229. (define-keyword-constructor same-screen-p)
  230. (define-keyword-constructor hint-p)
  231. (define-keyword-constructor mode)
  232. (define-keyword-constructor kind)
  233. (define-keyword-constructor focus-p)
  234. (define-keyword-constructor keymap)
  235. (define-keyword-constructor request)
  236. (define-keyword-constructor start)
  237. (define-keyword-constructor count)
  238. (define-keyword-constructor rect)
  239. (define-keyword-constructor drawable)
  240. (define-keyword-constructor graph-fun)
  241. (define-keyword-constructor place)
  242. (define-keyword-constructor border-width)
  243. (define-keyword-constructor above-sibling)
  244. (define-keyword-constructor override-redirect-p)
  245. (define-keyword-constructor parent)
  246. (define-keyword-constructor configure-p)
  247. (define-keyword-constructor visibility)
  248. (define-keyword-constructor new-p)
  249. (define-keyword-constructor installed-p)
  250. (define-keyword-constructor stack-mode)
  251. (define-keyword-constructor value-mask)
  252. (define-keyword-constructor size)
  253. (define-keyword-constructor message)
  254. (define-keyword-constructor property-state)
  255. (define-keyword-constructor atom)
  256. (define-keyword-constructor selection)
  257. (define-keyword-constructor target)
  258. (define-keyword-constructor property)
  259. (define-keyword-constructor requestor)
  260.  
  261. (define-event-slot-finder window)
  262. (define-event-slot-finder event-window)
  263. (define-event-slot-finder code)
  264. (define-event-slot-finder x)
  265. (define-event-slot-finder y)
  266. (define-event-slot-finder state)
  267. (define-event-slot-finder time)
  268. (define-event-slot-finder root)
  269. (define-event-slot-finder root-x)
  270. (define-event-slot-finder root-y)
  271. (define-event-slot-finder child)
  272. (define-event-slot-finder same-screen-p)
  273. (define-event-slot-finder hint-p)
  274. (define-event-slot-finder mode)
  275. (define-event-slot-finder kind)
  276. (define-event-slot-finder focus-p)
  277. (define-event-slot-finder keymap)
  278. (define-event-slot-finder request)
  279. (define-event-slot-finder start)
  280. (define-event-slot-finder count)
  281. (define-event-slot-finder width)
  282. (define-event-slot-finder height)
  283. (define-event-slot-finder drawable)
  284. (define-event-slot-finder major)
  285. (define-event-slot-finder minor)
  286. (define-event-slot-finder place)
  287. (define-event-slot-finder border-width)
  288. (define-event-slot-finder above-sibling)
  289. (define-event-slot-finder override-redirect-p)
  290. (define-event-slot-finder parent)
  291. (define-event-slot-finder configure-p)
  292. (define-event-slot-finder new-p)
  293. (define-event-slot-finder installed-p)
  294. (define-event-slot-finder stack-mode)
  295. (define-event-slot-finder value-mask)
  296. (define-event-slot-finder data)
  297. (define-event-slot-finder type)
  298. (define-event-slot-finder format)
  299. (define-event-slot-finder atom)
  300. (define-event-slot-finder selection)
  301. (define-event-slot-finder target)
  302. (define-event-slot-finder property)
  303. (define-event-slot-finder requestor)
  304.  
  305. (define (x-event-pos event) (mk-xpoint (x-event-x event) (x-event-y event)))
  306.  
  307. (define (x-event-root-pos event) 
  308.   (mk-xpoint (x-event-root-x event) (x-event-root-y event)))
  309.  
  310. (define (x-event-size event) 
  311.   (mk-xsize (x-event-width event) (x-event-height event)))
  312.  
  313. (define (x-event-rect event) 
  314.   (mk-xrect (x-event-x event) (x-event-y event)
  315.         (x-event-width event) (x-event-height event)))
  316.  
  317. (define (x-event-graph-fun event)
  318.   (cons (x-event-major event) (x-event-minor event)))
  319.  
  320. (define (x-event-message event)
  321.   (list (sequence->list (x-event-data event))
  322.     (x-event-type event)
  323.     (x-event-format event)))
  324.  
  325.  
  326. ;; XEventMask
  327.  
  328. (define (x-make-event-mask keys)
  329.   (apply (function xlib:make-event-mask) (haskell-list->list/identity keys)))
  330.  
  331. (define (x-event-mask-key-list mask)
  332.   (list->haskell-list/identity (xlib:make-event-keys mask)))
  333.  
  334. ;; XStateMask
  335.  
  336. (define (x-make-state-mask keys)
  337.   (apply (function xlib:make-state-mask) (haskell-list->list/identity keys)))
  338.  
  339. (define (x-state-mask-key-list mask)
  340.   (list->haskell-list/identity (xlib:make-state-keys mask)))
  341.  
  342.  
  343. (define-keyword-constructor background)
  344. (define-keyword-constructor foreground)
  345. (define-keyword-constructor event-mask)
  346. (define-keyword-constructor depth)
  347. (define-keyword-constructor border-width)
  348. (define-keyword-constructor class)
  349. (define-keyword-constructor visual)
  350. (define-keyword-constructor border)
  351. (define-keyword-constructor backing-store)
  352. (define-keyword-constructor backing-planes)
  353. (define-keyword-constructor backing-pixel)
  354. (define-keyword-constructor save-under)
  355. (define-keyword-constructor do-not-propagate-mask)
  356. (define-keyword-constructor override-redirect)
  357. (define-keyword-constructor colormap)
  358. (define-keyword-constructor cursor)
  359.  
  360. (define-keyword-constructor arc-mode)
  361. (define-keyword-constructor cap-style)
  362. (define-keyword-constructor clip-mask)
  363. (define-keyword-constructor clip-origin)
  364. (define-keyword-constructor dash-offset)
  365. (define-keyword-constructor dashes)
  366. (define-keyword-constructor exposures)
  367. (define-keyword-constructor fill-rule)
  368. (define-keyword-constructor fill-style)
  369. (define-keyword-constructor font)
  370. (define-keyword-constructor function)
  371. (define-keyword-constructor join-style)
  372. (define-keyword-constructor line-style)
  373. (define-keyword-constructor line-width)
  374. (define-keyword-constructor plane-mask)
  375. (define-keyword-constructor stipple)
  376. (define-keyword-constructor subwindow-mode)
  377. (define-keyword-constructor tile)
  378. (define-keyword-constructor tile-origin)
  379.  
  380. (define-keyword-constructor bit-lsb-first-p)
  381. (define-keyword-constructor bits-per-pixel)
  382. (define-keyword-constructor blue-mask)
  383. (define-keyword-constructor byte-lsb-first-p)
  384. (define-keyword-constructor bytes-per-line)
  385. (define-keyword-constructor data)
  386. (define-keyword-constructor format)
  387. (define-keyword-constructor green-mask)
  388. (define-keyword-constructor size)
  389. (define-keyword-constructor name)
  390. (define-keyword-constructor red-mask)
  391. (define-keyword-constructor hot-spot)
  392.  
  393.  
  394. (define-keyword-constructor owner-p)
  395. (define-keyword-constructor sync-pointer-p)
  396. (define-keyword-constructor sync-keyboard-p)
  397. (define-keyword-constructor confine-to)
  398.  
  399.  
  400. ;; XClipMask
  401.  
  402. (define (not-pixmap-and-list-p x) 
  403.   (and (pair? x) (not (xlib:pixmap-p x))))
  404. (define (mk-clip-mask-rects rects) 
  405.   (rects->point-seq (haskell-list->list/identity rects)))
  406. (define (sel-clip-mask-rects point-seq) 
  407.   (list->haskell-list/identity (point-seq->rects point-seq)))
  408.  
  409. ;; XPoint
  410.  
  411. (define (mk-xpoint x y) (cons x y))
  412. (define (xpoint-x x) (car x))
  413. (define (xpoint-y x) (cdr x))
  414.  
  415. ;; XSize
  416.  
  417. (define (mk-xsize x y) (cons x y))
  418. (define (xsize-w x) (car x))
  419. (define (xsize-h x) (cdr x))
  420.  
  421. ;; XRect
  422. (define (mk-xrect x y w h) (vector x y w h))
  423. (define (xrect-x x) (vector-ref x 0))
  424. (define (xrect-y x) (vector-ref x 1))
  425. (define (xrect-w x) (vector-ref x 2))
  426. (define (xrect-h x) (vector-ref x 3))
  427.  
  428. ;; XArc
  429.  
  430. (define (mk-xarc x y w h a1 a2) (vector x y w h a1 a2))
  431.  
  432. (define (xarc-x x) (vector-ref x 0))
  433. (define (xarc-y x) (vector-ref x 1))
  434. (define (xarc-w x) (vector-ref x 2))
  435. (define (xarc-h x) (vector-ref x 3))
  436. (define (xarc-a1 x) (vector-ref x 4))
  437. (define (xarc-a2 x) (vector-ref x 5))
  438.  
  439. ;; BitmapFormat
  440.  
  441. (define (mk-bitmap-format u p l) 
  442.   (xlib::make-bitmap-format :unit u :pad p :lsb-first-p l))
  443.  
  444. ;; PixmapFormat
  445.  
  446. (define (mk-pixmap-format u p l) 
  447.   (xlib::make-pixmap-format :depth u :bits-per-pixel p :scanline-pad l))
  448.  
  449. ;; XVisualInfo
  450.  
  451. (define (mk-xvisual-info id cl rm gm bm bs es) 
  452.   (xlib::make-visual-info :id id :class cl :red-mask rm :green-mask gm 
  453.               :blue-mask bm :bits-per-rgb bs :colormap-entries es))
  454.  
  455. ;; XFillContent
  456.  
  457. (define (is-fill-pixel x) (not (or (xlib:pixmap-p x) (symbol? x))))
  458.  
  459. ;; XBackingStore
  460.  
  461. ;; XImageData
  462.  
  463. (define (bitmap-list-p x) (pair? x))
  464. (define (pixarray-p x) (and (not (pair? x)) (eq? (lisp:array-rank x) 2)))
  465. (define (bytevec-p x) (and (not (pair? x)) (eq? (lisp:array-rank x) 1)))
  466.  
  467. ;; XColor
  468. (define (mk-color r g b) 
  469.   (xlib:make-color :red r :green g :blue b))
  470.  
  471.  
  472. (define (x-print x)
  473.   (print x))
  474.  
  475. (define (x-set-event-mask-key mask key-sym) 
  476.   (lisp:logior mask (xlib:make-event-mask key-sym)))
  477.  
  478. (define (x-clear-event-mask-key mask key-sym) 
  479.   (lisp:logand mask (lisp:lognot (xlib:make-event-mask key-sym))))
  480.  
  481.  
  482. (define (x-test-event-mask-key mask key-sym)
  483.   (if (eqv? 0 (lisp:logand mask (xlib:make-event-mask key-sym))) '#f '#t))
  484.  
  485. (define (x-set-state-mask-key mask key-sym) 
  486.   (lisp:logior mask (xlib:make-state-mask key-sym)))
  487.  
  488. (define (x-clear-state-mask-key mask key-sym) 
  489.   (lisp:logand mask (lisp:lognot (xlib:make-state-mask key-sym))))
  490.  
  491. (define (x-test-state-mask-key mask key-sym)
  492.   (if (eqv? 0 (lisp:logand mask (xlib:make-state-mask key-sym))) '#f '#t))
  493.  
  494.  
  495. ;;; Display is a string of the format name:d.s
  496. ;;; ignore s; if d is omitted, default it to zero.
  497.  
  498. (define (x-open-display display)
  499.   (let* ((end    (string-length display))
  500.      (colon  (or (string-position #\: display 0 end) end))
  501.      (dot    (or (string-position #\. display colon end) end)))
  502.     (declare (type fixnum end colon dot))
  503.     (xlib:open-display
  504.       (substring display 0 colon)
  505.       :display (if (eqv? colon dot)
  506.            0
  507.            (string->number (substring display (1+ colon) dot))))))
  508.  
  509. (define (x-set-display-error-handler display error-fun)
  510.   (declare (ignore display error-fun))
  511.   (error "not implemented"))
  512.  
  513. (define (x-set-display-after-function display after-fun)
  514.   (declare (ignore display after-fun))
  515.   (error "not implemented"))
  516.  
  517. (define (x-screen-depths screen)
  518.   (let ((depths (xlib:screen-depths screen)))
  519.     (map (lambda (l) (make-h-tuple (car l) (list->haskell-list/identity (cdr l))))
  520.      depths)))
  521.  
  522. (define (x-screen-size screen)
  523.   (mk-xsize (xlib:screen-width screen) (xlib:screen-height screen)))
  524.  
  525. (define (x-screen-mmsize screen)
  526.   (mk-xsize (xlib:screen-width-in-millimeters screen) 
  527.         (xlib:screen-height-in-millimeters screen)))
  528.  
  529. (define (x-create-window parent rect attrs)
  530.   (apply (function XLIB:CREATE-WINDOW)
  531.      `(:parent ,parent :x ,(xrect-x rect) :y ,(xrect-y rect)
  532.        :width ,(xrect-w rect) :height ,(xrect-h rect)
  533.        ,@(attrs->keywords attrs))))
  534.  
  535. (define-attribute-setter drawable border-width)
  536.  
  537. (define (x-drawable-size drawable)
  538.   (mk-xsize (xlib:drawable-width drawable) (xlib:drawable-height drawable)))
  539.  
  540. (define (x-drawable-resize drawable size)
  541.   (setf (xlib:drawable-width drawable) (xsize-w size))
  542.   (setf (xlib:drawable-height drawable) (xsize-h size)))
  543.  
  544. (define (x-window-pos window)
  545.   (mk-xpoint (xlib:drawable-x window) (xlib:drawable-y window)))
  546.  
  547. (define (x-window-move window point)
  548.   (setf (xlib:drawable-x window) (xpoint-x point))
  549.   (setf (xlib:drawable-y window) (xpoint-y point)))
  550.  
  551. (define-attribute-setter window background)
  552. (define-attribute-setter window backing-pixel)
  553. (define-attribute-setter window backing-planes)
  554. (define-attribute-setter window backing-store)
  555. (define-attribute-setter window bit-gravity)
  556. (define-attribute-setter window border)
  557. (define-attribute-setter window colormap)
  558.  
  559. (define (x-set-window-cursor window cursor)
  560.   (let ((val (if (null? cursor) :none cursor)))
  561.     (setf (xlib:window-cursor window) val)))
  562.  
  563. (define-attribute-setter window do-not-propagate-mask)
  564. (define-attribute-setter window event-mask)
  565. (define-attribute-setter window gravity)
  566. (define-attribute-setter window override-redirect)
  567. (define-attribute-setter window priority)
  568. (define-attribute-setter window save-under)
  569.  
  570. (define (x-query-tree window)
  571.   (multiple-value-bind (children parent root)
  572.                (xlib:query-tree window)
  573.      (make-h-tuple (list->haskell-list/identity children) parent root)))
  574.  
  575. (define (x-reparent-window window parent point)
  576.   (xlib:reparent-window window parent (xpoint-x point) (xpoint-y point)))
  577.  
  578. (define (x-translate-coordinates source point dest)
  579.   (xlib:translate-coordinates source (xpoint-x point) (xpoint-y point) dest))
  580.  
  581. (define (x-create-pixmap size depth drawable)
  582.   (xlib:create-pixmap :width (xsize-w size)
  583.               :height (xsize-h size)
  584.               :depth depth
  585.               :drawable drawable))
  586.  
  587. (define (x-create-gcontext drawable attrs)
  588.   (apply (function XLIB:CREATE-GCONTEXT)
  589.      `(:drawable ,drawable ,@(attrs->keywords attrs))))
  590.  
  591. (define (x-update-gcontext gcontext attrs)
  592.   (do ((keys (attrs->keywords attrs) (cddr keys)))
  593.       ((null? keys))
  594.     (x-update-gcontext-attr gcontext (car keys) (cadr keys))))
  595.  
  596. (define (x-update-gcontext-attr gcontext key attr)
  597.   (case key
  598.     (:arc-mode (setf (xlib:gcontext-arc-mode gcontext) attr))
  599.     (:background (setf (xlib:gcontext-background gcontext) attr))
  600.     (:cap-style (setf (xlib:gcontext-cap-style gcontext) attr))
  601.     (:fill-style (setf (xlib:gcontext-fill-style gcontext) attr))
  602.     (:clip-mask (setf (xlib:gcontext-clip-mask gcontext) attr))
  603.     (:clip-x (setf (xlib:gcontext-clip-x gcontext) attr))
  604.     (:clip-y (setf (xlib:gcontext-clip-y gcontext) attr))
  605.     (:dash-offset (setf (xlib:gcontext-dash-offset gcontext) attr))
  606.     (:dashes (setf (xlib:gcontext-dashes gcontext) attr))
  607.     (:exposures (setf (xlib:gcontext-exposures gcontext) attr))
  608.     (:fill-rule (setf (xlib:gcontext-fill-rule gcontext) attr))
  609.     (:font (setf (xlib:gcontext-font gcontext) attr))
  610.     (:foreground (setf (xlib:gcontext-foreground gcontext) attr))
  611. ;    (:function (setf (xlib:gcontext-function gcontext) attr))
  612.     (:join-style (setf (xlib:gcontext-join-style gcontext) attr))
  613.     (:line-style (setf (xlib:gcontext-line-style gcontext) attr))
  614. ;    (:line-width (setf (xlib:gcontext-line-width gcontext) attr))
  615. ;    (:plane-mask (setf (xlib:gcontext-plane-mask gcontext) attr))
  616. ;    (:stipple (setf (xlib:gcontext-stipple gcontext) attr))
  617.     (:subwindow-mode (setf (xlib:gcontext-subwindow-mode gcontext) attr))
  618. ;    (:tile (setf (xlib:gcontext-tile gcontext) attr))
  619. ;    (:ts-x (setf (xlib:gcontext-ts-x gcontext) attr))
  620. ;    (:ts-y (setf (xlib:gcontext-ts-y gcontext) attr))
  621.     (else (format '#t "Graphics context attribute ~A is not settable.~%"
  622.           key))))
  623.  
  624. (define (x-query-best-stipple dsize drawable)
  625.   (multiple-value-bind (w h) 
  626.         (xlib:query-best-stipple (xsize-w dsize) (xsize-h dsize) drawable)
  627.      (mk-xsize w h)))
  628.  
  629. (define (x-query-best-tile dsize drawable)
  630.   (multiple-value-bind (w h) 
  631.         (xlib:query-best-tile (xsize-w dsize) (xsize-h dsize) drawable)
  632.      (mk-xsize w h)))
  633.  
  634. (define (x-clear-area window rect exposures-p)
  635.   (xlib:clear-area window 
  636.            :x (xrect-x rect)
  637.            :y (xrect-y rect)
  638.            :width (xrect-w rect)
  639.            :height (xrect-h rect)
  640.            :exposures-p exposures-p))
  641.  
  642. (define (x-copy-area src gcontext rect dest point)
  643.   (xlib:copy-area src 
  644.           gcontext 
  645.           (xrect-x rect) (xrect-y rect) 
  646.           (xrect-w rect) (xrect-h rect) 
  647.           dest 
  648.           (xpoint-x point) (xpoint-y point)))
  649.  
  650. (define (x-copy-plane src gcontext plane rect dest point)
  651.   (xlib:copy-plane src 
  652.            gcontext 
  653.            plane 
  654.            (xrect-x rect) (xrect-y rect) 
  655.            (xrect-w rect) (xrect-h rect) 
  656.            dest 
  657.            (xpoint-x point) (xpoint-y point)))
  658.  
  659. (define (x-draw-point drawable gcontext point)
  660.   (xlib:draw-point drawable gcontext (xpoint-x point) (xpoint-y point)))
  661.  
  662. (define (x-draw-points drawable gcontext points)
  663.   (xlib:draw-points drawable gcontext (points->point-seq points)))
  664.  
  665. (define (points->point-seq points)
  666.   (if (null? points)
  667.       '()
  668.       (let ((point (car points)))
  669.     (lisp:list* (xpoint-x point)
  670.             (xpoint-y point)
  671.             (points->point-seq (cdr points))))))
  672.  
  673. (define (segments->point-seq segments)
  674.   (if (null? segments)
  675.       '()
  676.       (let* ((first-pair (car segments))
  677.          (point-1 (force (tuple-select 2 0 first-pair)))
  678.          (point-2 (force (tuple-select 2 1 first-pair))))
  679.     (lisp:list* (xpoint-x point-1)
  680.             (xpoint-y point-1) 
  681.             (xpoint-x point-2)
  682.             (xpoint-y point-2) 
  683.             (segments->point-seq (cdr segments))))))
  684.  
  685. (define (rects->point-seq rects)
  686.   (if (null? rects)
  687.       '()
  688.       (let ((rect (car rects)))
  689.     (lisp:list* (xrect-x rect)
  690.             (xrect-y rect)
  691.             (xrect-w rect)
  692.             (xrect-h rect)
  693.             (rects->point-seq (cdr rects))))))
  694.  
  695. (define (point-seq->rects point-seq)
  696.   (if (null? point-seq)
  697.       '()
  698.       (cons (mk-xrect (car point-seq) (cadr point-seq) 
  699.               (caddr point-seq) (cadddr point-seq))
  700.         (point-seq->rects (cddddr point-seq)))))
  701.  
  702. (define (arcs->point-seq arcs)
  703.   (if (null? arcs)
  704.       '()
  705.       (let ((arc (car arcs)))
  706.     (lisp:list* (xarc-x arc)
  707.             (xarc-y arc)
  708.             (xarc-w arc)
  709.             (xarc-h arc)
  710.             (xarc-a1 arc)
  711.             (xarc-a2 arc)
  712.             (arcs->point-seq (cdr arcs))))))
  713.  
  714. (define (x-draw-line drawable gcontext point-1 point-2)
  715.   (xlib:draw-line drawable gcontext (xpoint-x point-1) (xpoint-y point-1)
  716.           (xpoint-x point-2) (xpoint-y point-2)))
  717.  
  718. (define (x-draw-lines drawable gcontext points fill-p)
  719.   (xlib:draw-lines drawable gcontext 
  720.            (points->point-seq points) :fill-p fill-p))
  721.  
  722. (define (x-draw-segments drawable gcontext segments)
  723.   (xlib:draw-segments drawable gcontext (segments->point-seq segments)))
  724.  
  725. (define (x-draw-rectangle drawable gcontext rect fill-p)
  726.   (xlib:draw-rectangle drawable gcontext
  727.                (xrect-x rect) (xrect-y rect) 
  728.                (xrect-w rect) (xrect-h rect)
  729.                fill-p))
  730.  
  731. (define (x-draw-rectangles drawable gcontext rects fill-p)
  732.   (xlib:draw-rectangles drawable gcontext
  733.             (rects->point-seq rects)
  734.             fill-p))
  735.  
  736. (define (x-draw-arc drawable gcontext arc fill-p)
  737.   (xlib:draw-arc drawable gcontext
  738.          (xarc-x arc) (xarc-y arc) 
  739.          (xarc-w arc) (xarc-h arc)
  740.          (xarc-a1 arc) (xarc-a2 arc)
  741.          fill-p))
  742.  
  743. (define (x-draw-arcs drawable gcontext arcs fill-p)
  744.   (xlib:draw-arcs drawable gcontext
  745.           (arcs->point-seq arcs)
  746.           fill-p))
  747.  
  748. (define (x-draw-glyph drawable gcontext point element)
  749.   (nth-value 1
  750.          (xlib:draw-glyph drawable gcontext (xpoint-x point) 
  751.                   (xpoint-y point) element)))
  752.  
  753. (define (x-draw-glyphs drawable gcontext point element)
  754.   (nth-value 1 (xlib:draw-glyphs drawable gcontext (xpoint-x point) 
  755.                  (xpoint-y point) element)))
  756.  
  757. (define (x-draw-image-glyph drawable gcontext point element)
  758.   (nth-value 1 (xlib:draw-image-glyph drawable gcontext (xpoint-x point) 
  759.                       (xpoint-y point) element)))
  760.  
  761. (define (x-draw-image-glyphs drawable gcontext point element)
  762.   (nth-value 1 (xlib:draw-image-glyphs drawable gcontext (xpoint-x point) 
  763.                        (xpoint-y point) element)))
  764.  
  765. (define (x-image-size image)
  766.   (mk-xsize (xlib:image-width image) (xlib:image-height image)))
  767.  
  768. (define (x-image-name image)
  769.   (let ((lisp-name (xlib:image-name image)))
  770.     (cond ((null? lisp-name) "")
  771.       ((symbol? lisp-name) (symbol->string lisp-name))
  772.       (else lisp-name))))
  773.     
  774. (define-attribute-setter image name)
  775.  
  776. (define (x-image-hot-spot image)
  777.   (mk-xpoint (xlib:image-x-hot image) (xlib:image-y-hot image)))
  778.  
  779. (define (x-set-image-hot-spot image point)
  780.   (setf (xlib:image-x-hot image) (xpoint-x point))
  781.   (setf (xlib:image-y-hot image) (xpoint-y point)))
  782.  
  783. (define-attribute-setter image xy-bitmap-list)
  784. (define-attribute-setter image z-bits-per-pixel)
  785. (define-attribute-setter image z-pixarray)
  786.  
  787. (define (x-create-image attrs)
  788.   (apply (function xlib:create-image) (attrs->keywords attrs)))
  789.  
  790. (define (x-copy-image image rect type)
  791.   (xlib:copy-image image :x (xrect-x rect) :y (xrect-y rect)
  792.            :width (xrect-w rect) :height (xrect-h rect)
  793.            :result-type type))
  794.  
  795. (define (x-get-image drawable rect pmask format type)
  796.   (xlib:get-image drawable :x (xrect-x rect) :y (xrect-y rect)
  797.           :width (xrect-w rect) :height (xrect-h rect)
  798.           :plane-mask pmask :format format :result-type type))
  799.  
  800. (define (x-put-image drawable gcontext image point rect)
  801.   (xlib:put-image drawable gcontext image 
  802.           :src-x (xpoint-x point) :src-y (xpoint-y point)
  803.           :x (xrect-x rect) :y (xrect-y rect)
  804.           :width (xrect-w rect) :height (xrect-h rect)))
  805.  
  806. (define (x-get-raw-image drawable rect pmask format)
  807.   (xlib:get-raw-image drawable 
  808.               :x (xrect-x rect) :y (xrect-y rect) 
  809.               :width (xrect-w rect) :height (xrect-h rect)
  810.               :plane-mask pmask :format format))
  811.  
  812. (define (x-put-raw-image drawable gcontext data depth rect left-pad format)
  813.   (xlib:put-raw-image drawable gcontext data
  814.               :depth depth 
  815.               :x (xrect-x rect) :y (xrect-y rect) 
  816.               :width (xrect-w rect) :height (xrect-h rect)
  817.               :left-pad left-pad :format format))
  818.  
  819. (define (x-font-name font)
  820.   (let ((lisp-name (xlib:font-name font)))
  821.     (cond ((null? lisp-name) "")
  822.       ((symbol? lisp-name) (symbol->string lisp-name))
  823.       (else lisp-name))))
  824.  
  825. (define (x-alloc-color colormap color)
  826.   (multiple-value-bind (pixel screen-color exact-color)
  827.        (xlib:alloc-color colormap color)
  828.      (make-h-tuple pixel screen-color exact-color)))
  829.  
  830. (define (x-alloc-color-cells colormap colors planes contiguous-p)
  831.   (multiple-value-bind (pixels mask)
  832.        (xlib:alloc-color-cells colormap colors :planes planes 
  833.                    :contiguous-p contiguous-p)
  834.      (make-h-tuple (list->haskell-list/identity pixels) (list->haskell-list/identity mask))))
  835.  
  836. (define (x-alloc-color-planes colormap colors reds greens blues contiguous-p)
  837.   (multiple-value-bind (pixels red-mask green-mask blue-mask)
  838.        (xlib:alloc-color-planes colormap colors :reds reds :greens greens
  839.                 :blues blues :contiguous-p contiguous-p)
  840.      (make-h-tuple (list->haskell-list/identity pixels) 
  841.            red-mask
  842.            green-mask
  843.            blue-mask)))
  844.  
  845. (define (x-lookup-color colormap name)
  846.   (multiple-value-bind (screen-color exact-color)
  847.       (xlib:lookup-color colormap name)
  848.     (make-h-tuple screen-color exact-color)))
  849.  
  850. (define (unzip l)
  851.   (if (null? l)
  852.       '()
  853.       (let ((h (car l)))
  854.     (lisp:list* (force (tuple-select 2 0 h))
  855.             (force (tuple-select 2 1 h))
  856.             (unzip (cdr l))))))
  857.  
  858. (define (x-store-colors colormap pixel-colors)
  859.   (xlib:store-colors colormap (unzip pixel-colors)))
  860.  
  861. (define (x-create-cursor source mask point foreground background)
  862.   (apply (function xlib:create-cursor)
  863.      `(:source ,source
  864.        ,@(if mask `(:mask ,mask) '())
  865.        :x ,(xpoint-x point) :y ,(xpoint-y point)
  866.        :foreground ,foreground :background ,background)))
  867.  
  868. (define (x-create-glyph-cursor src mask foreground background)
  869.   (apply (function xlib:create-glyph-cursor)
  870.      `(:source-font ,(force (tuple-select 2 0 src))
  871.        :source-char ,(integer->char (force (tuple-select 2 1 src)))
  872.        ,@(if mask 
  873.          `(:mask-font ,(force (tuple-select 2 0 mask))
  874.          :mask-char ,(integer->char (force (tuple-select 2 1 mask))))
  875.          '())
  876.        :foreground ,foreground :background ,background)))
  877.  
  878. (define (x-query-best-cursor size display)
  879.   (multiple-value-bind (w h)
  880.       (xlib:query-best-cursor (xsize-w size) (xsize-h size) display)
  881.     (mk-xsize w h)))
  882.  
  883. (define (x-change-property window property content)
  884.   (xlib:change-property window property 
  885.             (car content) (cadr content) 
  886.             (caddr content)))
  887.  
  888. (define (x-get-property window property)
  889.   (lisp:multiple-value-bind (data type format) 
  890.                 (xlib:get-property window property)
  891.      (list (sequence->list data) type format)))
  892.  
  893. (define (x-convert-selection selection type requestor property time)
  894.   (apply (function xlib:convert-selection)
  895.      `(,selection ,type ,requestor ,property ,@(if time `(,time) '()))))
  896.  
  897. (define (x-set-selection-owner display selection time owner)
  898.   (if time
  899.       (setf (xlib:selection-owner display selection time) owner)
  900.       (setf (xlib:selection-owner display selection) owner)))
  901.  
  902. (define (sequence->list seq)
  903.   (if (list? seq) seq
  904.       (do ((i (1- (lisp:length seq)) (1- i))
  905.        (res '() (cons (lisp:elt seq i) res)))
  906.       ((< i 0) res))))
  907.  
  908. (define *this-event* '())
  909.  
  910. (define (translate-event lisp:&rest event-slots lisp:&key event-key 
  911.              lisp:&allow-other-keys)
  912.   (setf *this-event* (cons event-key event-slots))
  913.   '#t)
  914.  
  915.  
  916. (define (x-get-event display)
  917.   (xlib:process-event display :handler #'translate-event :force-output-p '#t)
  918.   *this-event*)
  919.  
  920. (define (x-queue-event display event append-p)
  921.   (apply (function xlib:queue-event)
  922.      `(,display ,(car event) ,@(cdr event) :append-p ,append-p)))
  923.  
  924. (define (x-event-listen display)
  925.   (let ((res (xlib:event-listen display)))
  926.     (if (null? res) 0 res)))
  927.  
  928. (define (x-send-event window event mask)
  929.   (apply (function xlib:send-event)
  930.      `(,window ,(car event) ,mask ,@(cdr event))))
  931.  
  932. (define (x-global-pointer-position display)
  933.   (multiple-value-bind (x y) (xlib:global-pointer-position display)
  934.     (mk-xpoint x y)))
  935.  
  936. (define (x-pointer-position window)
  937.   (multiple-value-bind (x y same) (xlib:pointer-position window)
  938.     (if same (mk-xpoint x y) '())))
  939.  
  940. (define (x-motion-events window start stop)
  941.   (do ((npos '() (cons (mk-xpoint (car pos) (cadr pos)) npos))
  942.        (pos (xlib:motion-events window :start start :stop stop) 
  943.         (cdddr pos)))
  944.       ((null? pos) (nreverse npos))))
  945.  
  946. (define (x-warp-pointer dest-win point)
  947.   (xlib:warp-pointer dest-win (xpoint-x point) (xpoint-y point)))
  948.  
  949. (define (x-set-input-focus display focus revert-to time)
  950.   (apply (function xlib:set-input-focus)
  951.      `(,display ,focus ,revert-to ,@(if time `(,time) '()))))
  952.  
  953. (define (x-input-focus display)
  954.   (multiple-value-bind (focus revert-to) (xlib:input-focus display)
  955.     (make-h-tuple focus revert-to)))
  956.  
  957. (define (x-grab-pointer window event-mask attrs time)
  958.   (apply (function xlib:grab-pointer)
  959.      `(,window ,event-mask
  960.            ,@(attrs->keywords attrs)
  961.        ,@(if time `(:time ,time) '()))))
  962.  
  963. (define (x-ungrab-pointer display time)
  964.   (if time
  965.       (xlib:ungrab-pointer display :time time)
  966.       (xlib:ungrab-pointer display)))
  967.       
  968. (define (x-change-active-pointer-grab display event-mask attrs time)
  969.   (apply (function xlib:change-active-pointer-grab)
  970.      `(,display ,event-mask
  971.            ,@(attrs->keywords attrs)
  972.        ,@(if time `(,time) '()))))
  973.  
  974. (define (x-grab-button window button event-mask state-mask attrs)
  975.   (apply (function xlib:grab-button)
  976.      `(,window ,button ,event-mask :modifiers ,state-mask
  977.        ,@(attrs->keywords attrs))))
  978.  
  979. (define (x-ungrab-button window button modifiers)
  980.   (xlib:ungrab-button window button :modifiers modifiers))
  981.  
  982. (define (x-grab-keyboard window attrs time)
  983.   (apply (function xlib:grab-keyboard)
  984.      `(,window ,@(attrs->keywords attrs)
  985.        ,@(if time `(:time ,time) '()))))
  986.  
  987. (define (x-ungrab-keyboard display time)
  988.   (if time
  989.       (xlib:ungrab-keyboard display :time time)
  990.       (xlib:ungrab-keyboard display)))
  991.       
  992. (define (x-grab-key window key state-mask attrs)
  993.   (apply (function xlib:grab-key)
  994.      `(,window ,key :modifiers ,state-mask ,@(attrs->keywords attrs))))
  995.  
  996. (define (x-ungrab-key window key modifiers)
  997.   (xlib:ungrab-button window key :modifiers modifiers))
  998.  
  999. (define (x-set-pointer-acceleration display val)
  1000.   (xlib:change-pointer-control display :acceleration val))
  1001.  
  1002. (define (x-set-pointer-threshold display val)
  1003.   (xlib:change-pointer-control display :threshold val))
  1004.  
  1005. (define (x-pointer-acceleration display)
  1006.   (lisp:coerce (nth-value 0 (xlib:pointer-control display)) 
  1007.            'lisp:single-float))
  1008.  
  1009. (define (x-pointer-threshold display)
  1010.   (lisp:coerce (nth-value 1 (xlib:pointer-control display)) 
  1011.            'lisp:single-float))
  1012.  
  1013. (define-attribute-setter pointer mapping)
  1014.  
  1015. (define (x-set-keyboard-key-click-percent display v)
  1016.   (xlib:change-keyboard-control display :key-click-percent v))
  1017.  
  1018. (define (x-set-keyboard-bell-percent display v)
  1019.   (xlib:change-keyboard-control display :bell-percent v))
  1020.  
  1021. (define (x-set-keyboard-bell-pitch display v)
  1022.   (xlib:change-keyboard-control display :bell-pitch v))
  1023.  
  1024. (define (x-set-keyboard-bell-duration display v)
  1025.   (xlib:change-keyboard-control display :bell-duration v))
  1026.  
  1027.  
  1028. ;;; Yes, leds are really counted from 1 rather than 0.
  1029.  
  1030. (define (x-set-keyboard-led display v)
  1031.   (declare (type integer v))
  1032.   (do ((led 1 (1+ led))
  1033.        (vv v (lisp:ash vv -1)))
  1034.       ((> led 32))
  1035.       (declare (type fixnum led) (type integer vv))
  1036.       (xlib:change-keyboard-control display
  1037.         :led led
  1038.     :led-mode (if (lisp:logand vv 1) :on :off))))
  1039.  
  1040. (define (x-set-keyboard-auto-repeat-mode display v)
  1041.   (do ((key 0 (1+ key)))
  1042.       ((>= key (lisp:length v)))
  1043.       (declare (type fixnum key))
  1044.       (xlib:change-keyboard-control display
  1045.         :key key
  1046.     :auto-repeat-mode (if (eqv? (the fixnum (lisp:aref v key)) 1) :on :off)
  1047.     )))
  1048.  
  1049. (define (x-keyboard-key-click-percent display)
  1050.   (nth-value 0 (xlib:keyboard-control display)))
  1051.  
  1052. (define (x-keyboard-bell-percent display)
  1053.   (nth-value 1 (xlib:keyboard-control display)))
  1054.  
  1055. (define (x-keyboard-bell-pitch display)
  1056.   (nth-value 2 (xlib:keyboard-control display)))
  1057.  
  1058. (define (x-keyboard-bell-duration display)
  1059.   (nth-value 3 (xlib:keyboard-control display)))
  1060.  
  1061. (define (x-keyboard-led display)
  1062.   (nth-value 4 (xlib:keyboard-control display)))
  1063.  
  1064. (define (x-keyboard-auto-repeat-mode display)
  1065.   (nth-value 6 (xlib:keyboard-control display)))
  1066.  
  1067. (define (x-modifier-mapping display)
  1068.   (lisp:multiple-value-list (xlib:modifier-mapping display)))
  1069.  
  1070. (define (x-set-modifier-mapping display l)
  1071.   (let ((l1 (cddddr l)))
  1072.     (xlib:set-modifier-mapping display 
  1073.                    :shift (car l)
  1074.                    :lock (cadr l)
  1075.                    :control (caddr l)
  1076.                    :mod1 (cadddr l)
  1077.                    :mod2 (car l1)
  1078.                    :mod3 (cadr l1)
  1079.                    :mod4 (caddr l1)
  1080.                    :mod5 (cadddr l1))))
  1081.  
  1082. (define (x-keysym-character display keysym state)
  1083.   (let ((res (xlib:keysym->character display keysym state)))
  1084.     (if (char? res) (char->integer res) '())))
  1085.  
  1086. (define (x-keycode-character display keycode state)
  1087.   (let ((res (xlib:keycode->character display keycode state)))
  1088.     (if (char? res) (char->integer res) '())))
  1089.  
  1090. (define-attribute-setter close-down mode)
  1091.  
  1092. (define-attribute-setter access control)
  1093.  
  1094. (define (x-screen-saver display)
  1095.   (lisp:multiple-value-list (xlib:screen-saver display)))
  1096.  
  1097. (define (x-set-screen-saver display ss)
  1098.   (xlib:set-screen-saver display (car ss) (cadr ss) (caddr ss) (cadddr ss)))
  1099.  
  1100. (define (slots->keywords slots)
  1101.   (if (null slots) '()
  1102.       `(,@(slot->keyword (car slots)) ,@(slots->keywords (cdr slots)))))
  1103.  
  1104. (define (slot->keyword slot)
  1105.   (let* ((tag (keyword-key slot))
  1106.      (val (keyword-val slot)))
  1107.     (case tag
  1108.       (:pos `(:x ,(xpoint-x val) :y ,(xpoint-y val)))
  1109.       (:root-pos `(:root-x ,(xpoint-x val) :root-y ,(xpoint-y val)))
  1110.       (:size `(:width ,(xsize-w val) :height ,(xsize-h val)))
  1111.       (:rect `(:x ,(xrect-x val) :y ,(xrect-y val)
  1112.            :width ,(xrect-w val) :height ,(xrect-h val)))
  1113.       (:graph-fun `(:major ,(car val) :minor ,(cdr val)))
  1114.       (:visibility `(:state ,val))
  1115.       (:property-state `(:state ,val))
  1116.       (:message `(:data ,(car val) :type ,(cadr val) :format ,(caddr val)))
  1117.       (else `(,tag ,val)))))
  1118.  
  1119. (define (keywords->slots type keywords event)
  1120.   (let* ((slots (keywords->slots1 type keywords))
  1121.      (has-root-xy (memq type '(:key-press :key-release :button-press 
  1122.                           :button-release :motion-notify 
  1123.                           :enter-notify :leave-notify)))
  1124.      (has-xy (or has-root-xy 
  1125.              (memq type '(:gravity-notify :reparent-notify))))
  1126.      (has-graph-fun (memq type '(:graphics-exposure :no-exposure)))
  1127.      (has-rect (memq type '(:exposure :graphics-exposure 
  1128.                       :configure-notify
  1129.                       :create-notify :configure-request)))
  1130.      (has-size (memq type '(:resize-request)))
  1131.      (has-message (memq type '(:client-message))))
  1132.     (when has-xy
  1133.       (push (make-keyword :pos (x-event-pos event)) slots))
  1134.     (when has-root-xy
  1135.       (push (make-keyword :root-pos (x-event-root-pos event))    slots))
  1136.     (when has-graph-fun
  1137.       (push (make-keyword :graph-fun (x-event-graph-fun event)) slots))
  1138.     (when has-rect
  1139.       (push (make-keyword :rect (x-event-rect event))    slots))
  1140.     (when has-size
  1141.       (push (make-keyword :size (x-event-size event))    slots))
  1142.     (when has-message
  1143.       (push (make-keyword :message (x-event-message event)) slots))
  1144.     slots))
  1145.       
  1146. (define (keywords->slots1 type keywords)
  1147.   (if (null? keywords)
  1148.       '()
  1149.       (if (memq (car keywords) 
  1150.         '(:x :y :width :height :root-x :root-y 
  1151.              :major :minor :type :data :format))
  1152.       (keywords->slots1 type (cddr keywords))
  1153.       (cons (keyword->slot type (car keywords) (cadr keywords))
  1154.         (keywords->slots1 type (cddr keywords))))))
  1155.  
  1156. (define (keyword->slot type slot val)
  1157.   (if (eq? slot :state)
  1158.       (case type
  1159.     (:property-state (make-keyword :property-state val))
  1160.     (:visibility (make-keyword :visibility val))
  1161.     (else (make-keyword :state val)))
  1162.       (make-keyword slot val)))
  1163.          
  1164. (define (attrs->keywords attrs)
  1165.   (if (null attrs)
  1166.       '()
  1167.       (nconc (attr->keyword (car attrs))
  1168.          (attrs->keywords (cdr attrs)))))
  1169.  
  1170. (define (attr->keyword attr)
  1171.   (let* ((tag (keyword-key attr))
  1172.      (val (keyword-val attr)))
  1173.     (case tag
  1174.       (:clip-origin `(:clip-x ,(xpoint-x val) :clip-y ,(xpoint-y val)))
  1175.       (:dashes `(,tag ,(haskell-list->list/identity val)))
  1176.       (:tile-origin `(:ts-x ,(xpoint-x val) :ts-y ,(xpoint-y val)))
  1177.       (:size `(:width ,(xsize-w val) :height ,(xsize-h val)))
  1178.       (:name `(:name ,(haskell-string->string val)))
  1179.       (:hot-spot `(:x-hot ,(xpoint-x val) :y-hot ,(xpoint-y val)))
  1180.       (else `(,tag ,val)))))
  1181.  
  1182. (define (x-mutable-array-create inits)
  1183.   (list->vector inits))
  1184.  
  1185. (define (x-mutable-array-lookup a i)
  1186.   (vector-ref a i))
  1187.  
  1188. (define (x-mutable-array-update a i x)
  1189.   (setf (vector-ref a i) x))
  1190.  
  1191. (define (x-mutable-array-length a)
  1192.   (vector-length a))
  1193.  
  1194. (define (get-time-zone)
  1195.   (nth-value 8 (lisp:get-decoded-time)))
  1196.  
  1197. (define (decode-time time zone)
  1198.   (multiple-value-bind (sec min hour date mon year week ds-p)
  1199.                (if zone
  1200.                (lisp:decode-universal-time time zone)
  1201.                (lisp:decode-universal-time time))   
  1202.     (make-h-tuple
  1203.       (list->haskell-list/identity (list sec min hour date mon year week))
  1204.       ds-p)))
  1205.  
  1206. (define (encode-time time zone)
  1207.   (apply (function lisp:encode-universal-time)
  1208.      (if (null? zone) time (append time (list zone)))))
  1209.  
  1210. (define (get-run-time)
  1211.   (/ (lisp:coerce (lisp:get-internal-run-time) 'lisp:single-float)
  1212.      (lisp:coerce lisp:internal-time-units-per-second 'lisp:single-float)))
  1213.  
  1214. (define (get-elapsed-time)
  1215.   (/ (lisp:coerce (lisp:get-internal-real-time) 'lisp:single-float)
  1216.      (lisp:coerce lisp:internal-time-units-per-second 'lisp:single-float)))
  1217.  
  1218. (define (prim.thenio---1 x fn)
  1219.   (lambda (state)
  1220.     (declare (ignore state))
  1221.     (let ((res (funcall x (box 'state))))
  1222.       (format '#t "~A~%" res)
  1223.       (funcall fn res (box 'state)))))
  1224.  
  1225. (define-attribute-setter wm name)
  1226. (define-attribute-setter wm icon-name)
  1227.