File: Xeus.l

package info (click to toggle)
euslisp 9.31%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 55,448 kB
  • sloc: ansic: 41,610; lisp: 3,339; makefile: 286; sh: 238; asm: 138; python: 53
file content (782 lines) | stat: -rw-r--r-- 26,598 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
;;;;
;;;; Xwindow interface for euslisp
;;;;	
;;;;	Copyright(c) Toshihiro MATSUI, ETL, 1988
;;;;

(require :geoclasses "geo/geoclasses.l")
(require :xdecl   "Xdecl.l")

(in-package "X")

(defvar *save-under* t)
(export '(*save-under*))



(defcstruct SetWindowAttributes
  (pixmap		:long)
  (background_pixel	:long)
  (border_pixmap	:long)
  (border_pixel		:long)
  (bit_gravity		:integer)
  (win_gravity		:integer)
  (backing_store	:integer)
  (backing_planes	:long)
  (backing_pixel	:long)
  (save_under		:integer)
  (event_mask		:long)
  (do_not_propagate_mask :long)
  (override_redirect	:integer)
  (colormap		:long)
  (cursor		:long))

(defcstruct WindowAttributes
  (x			:integer)	;x position
  (y			:integer)	;y position
  (width		:integer)
  (height		:integer)
  (border_width		:integer)
  (depth		:integer)
  (visual		:long)		;pointer to a VISUAL structure
  (root			:long)		;root window
  (class		:integer)	;InputOnly, OutputOnly
  (bit_gravity		:integer)
  (win_gravity		:integer)
  (backing_store	:integer)
  (backing_planes	:long)
  (backing_pixel	:long)
  (save_under		:integer)
  (colormap		:long)
  (map_installed	:integer)
  (map_state		:integer)
  (all_event_masks	:long)
  (your_event_mask	:long)
  (do_not_propagate_mask :long)
  (override_redirect	:integer)
  (screen		:long))

(defvar swa (instantiate SetWindowAttributes))
(defvar wa  (instantiate windowattributes))



;;
;; Xdrawable  --  Xpixmap -- Xwindow
;;

(defmethod Xdrawable
 (:init (id &optional w h gc)
    (setq gcon
	  (cond (gc gc)
		(id (instance gcontext :create :drawable id))
		(t (instance gcontext :create))))
    (setq drawable id)
    (if w (setq width w))
    (if h (setq height h))
    (setf (gethash drawable *xwindows-hash-tab*) self)
    self)
 (:drawable () drawable)
 (:flush () (Flush *display*))
 (:geometry ()
    (let ((root (instantiate c-long))
	  (x (instantiate c-int))
	  (y (instantiate c-int))
	  (width (instantiate c-int))
	  (height (instantiate c-int))
	  (border_width (instantiate c-int))
	  (depth (instantiate c-int)))
      (GetGeometry *display* drawable root x y width height
		   border_width depth)
      (list (c-long root) (c-int x) (c-int y) (c-int width) (c-int height)
	    (c-int border_width) (c-int depth))))
 (:height () (elt (send self :geometry) 4))
 (:width () (elt (send self :geometry) 3))
 (:pos () (GetWindowAttributes *display* drawable wa)
    (integer-vector (send wa :get 'x) (send wa :get 'y)))
 (:x ()
    (GetWindowAttributes *display* drawable wa)
    (send wa :get 'x))
 (:y ()
    (GetWindowAttributes *display* drawable wa)
    (send wa :get 'y))
 (:gc (&rest newgc)
    (cond ((null newgc)  gcon)
	  ((derivedp (car newgc) gcontext)
	   (setq gcon (car newgc)))
	  (t (send* gcon newgc)))) 
 (:gcid () (send gcon :gc))
 )

(defmethod Xdrawable
 (:line-width (&optional dots) (send gcon :line-width dots))
 (:line-style (&optional dash) (send gcon :line-style dash))
 (:color (&optional color)
    (cond ((or (numberp color) (stringp color) (symbolp color))
		(send gcon :foreground color) gcon)
	  ((derivedp color gcontext) (setq gcon color))
	  (t gcon) ))
 )

(defmethod Xdrawable
 (:copy-from (dw &key (width) (height) (source-x 0) (source-y 0) (x 0) (y 0))
    (unless (or width height)
        (let ((g (send self :geometry)))
           (setq width (elt g 3) height (elt g 4))))
    (CopyArea *display* (send dw :drawable) drawable (gcontext-gcid gcon)
                source-x source-y width height x y))
 (:shift (x &optional (y 0))
    (if (floatp x)
	(setq x (* (send self :width) x)))
    (if (floatp y)
	(setq y (* (send self :height) y)))
    (CopyArea *display* drawable drawable (gcontext-gcid gcon)
                0 0 (send self :width) (send self :height) x y)
    )
 (:point (x y &optional (gc gcon) )
    (DrawPoint *display* drawable (gcontext-gcid gc) x y))
 (:line (x1 y1 x2 y2 &optional (gc gcon))
    (DrawLine *display* drawable (gcontext-gcid gc) x1 y1 x2 y2))
 (:rectangle (x y width height &optional (gc gcon))
    (DrawRectangle *display* drawable (gcontext-gcid gc) x y width height))
 (:arc (x y width &optional (height width) (angle1 0.0) (angle2 2pi) (gc gcon))
    (DrawArc *display* drawable (gcontext-gcid gc)
			x y width height 
			(round (* 64 (rad2deg angle1)))
			(round (* 64 (rad2deg angle2)))))
 (:fill-rectangle (x y width height &optional (gc gcon))
    (FillRectangle *display* drawable (gcontext-gcid gc)
		 (round x) (round y)  (round width) (round height)))
 (:fill-arc (x y width &optional (height width) (angle1 0.0) (angle2 2pi) (gc gcon))
    (FillArc *display* drawable (gcontext-gcid gc)
			x y width height 
			(round (* 64 (rad2deg angle1)))
			(round (* 64 (rad2deg angle2)))))
 (:string (x y str &optional (start 0) (end (length str)) (gc gcon))
    (DrawString *display* drawable (gcontext-gcid gc) x y
		(+ (sys:address str) (* lisp::sizeof-* 2)  start)
		(- end start)))
 (:image-string (x y str &optional (start 0) (end (length str)) (gc gcon))
    (DrawImageString *display* drawable (gcontext-gcid gc) x y
		(+ (sys:address str) (* lisp::sizeof-* 2) start)
		(- end start)))
;; XImage can be regarded as a copy of pixmap at client side.
;; a pixmap in the server can be copied to ximage in the client,
;; and vice versa.
;; :getimage returns an address of ximage structure which holds
;; width, height, format, depth, and a pointer to image data, and so on.
;; you can apply x:getpixel, x:putpixel, and x:getsubimage in order to
;; access each pixel or subimage in the image.
 (:GetImage (&key (xy nil) (x 0) (y 0)
		  (width (- (send self :width) x))
		  (height (- (send self :height) y))
#-(or :alpha :irix6 :word-size=64)
		  (mask #xffffffff)
#+(or :alpha :irix6 :word-size=64)
		  (mask #xfffffffffffffff)
		  (format 2))
	;; #define XYBitmap      0       /* depth 1, XYFormat */
	;; #define XYPixmap      1       /* depth == drawable depth */
	;; #define ZPixmap       2       /* depth == drawable depth */
    (if xy (setq x (aref xy 0) y (aref xy 1)))
    (let* ((ximg (getimage *display* drawable x y width height mask format)) 
#-(or :alpha :irix6 :word-size=64)
	   (pixsize (/ (sys:peek (+ ximg #x2c) :integer) 8))
#+(or :alpha :irix6 :word-size=64)
	   (pixsize (/ (sys:peek (+ ximg #x30) :integer) 8))
#-(or :alpha :irix6 :word-size=64)
	   (rowsize (sys:peek (+ ximg #x28) :integer))
#+(or :alpha :irix6 :word-size=64)
	   (rowsize (sys:peek (+ ximg #x2c) :integer))
	   (xoffset (sys:peek (+ ximg 8) :integer))
	   (ximgdata (sys:peek (+ ximg #x10) :long))
	   (imgbuf (make-string (* width height pixsize))))
	;; (print xoffset)
	(dotimes (h height)
	   (replace imgbuf
		(make-foreign-string (+ ximgdata (* h rowsize pixsize)) width)
		:start1 (* h width pixsize)
		:end1 (* (1+ h) width pixsize)) )
       (DestroyImage ximg)
       imgbuf))
 (:putimage (image &key (src nil) (src-x 0) (src-y 0)
			(dst nil) (dst-x 0) (dst-y 0)
			(width) (height)
			((:gc g) gcon)
			(visual (send self :visual))
			(depth (visual-depth visual))
			(bitunit depth)
			; (case depth (8 8) (15 16) (16 16) (24 32) (32 32))
			(ximage *default-ximage*))
    (if src (setq src-x (aref src 0) src-y (aref src 1)))
    (if dst (setq dst-x (aref dst 0) dst-y (aref dst 1)))
    (cond ((derivedp image image::image-2d)
	        (unless width (setq width (send image :width)))
	        (unless height (setq height (send image :height)))
		(setq image (array-entity image)))
	  (t 	(unless width (setq width (- (send self :width) dst-x)))
		(unless height (setq height (- (send self :height) dst-y))) )
	)
    (set-ximage ximage image width height visual depth bitunit)
    (PutImage *display* drawable (gcontext-gcid g)
		ximage src-x src-y dst-x dst-y width height))
 (:putimage8to24 (image &key (src nil) (src-x 0) (src-y 0)
                        (dst nil) (dst-x 0) (dst-y 0)
                        (width (- (send self :width) dst-x))
                        (height (- (send self :height) dst-y))
                        ((:gc g) gcon) 
			&aux image32 pixel8)
    (if src (setq src-x (aref src 0) src-y (aref src 1)))
    (if dst (setq dst-x (aref dst 0) dst-y (aref dst 1)))
    ;; (setq ximage (create-ximage "" 0 0 8))  ;depth=8
    ;; (set-ximage ximage image width height)
    (setq image32 (make-array (* width height) :element-type :integer))
    (dotimes (I (* width height))
        (setq pixel8 (aref image i))
        (setf (aref image32 i) (logior pixel8 (ash pixel8 8) (ash pixel8 16))))
    (PutImage *display* drawable (gcontext-gcid g)
               image32 src-x src-y dst-x dst-y width height))
;;;
 (:draw-point (p &optional (gc gcon))
    (send self :point (round (elt p 0)) (round (elt p 1))  gc))
 (:draw-line (from to &optional (gc gcon))
    (send self :line (round (aref from 0)) (round (aref from 1))
		     (round (aref to 0))   (round (aref to 1))	gc ))
 (:draw-string (point str &optional (start 0) (end (length str)) (gc gcon))	; ?font?
    (send self :string (round (elt point 0)) (round (elt point 1)) str
		start end gc))
 (:draw-image-string (point str &optional (start 0) (end (length str))
				(gc gcon))	; ?font?
    (send self :image-string (round (elt point 0)) (round (elt point 1))
		str start end gc))
 (:draw-rectangle (point width height &optional (gc gcon))
    (send self :rectangle (round (elt point 0)) (round (elt point 1))
		(round width) (round height) gc))
 (:draw-fill-rectangle (point width height &optional (gc gcon))
    (unless (derivedp gc gcontext)
	(send gcon :foreground gc) (setq gc gcon))
    (send self :fill-rectangle (round (elt point 0)) (round (elt point 1))
		(round width) (round height) gc))
 (:draw-arc (point width
		&optional (height width) (angle1 0.0) (angle2 2pi) (gc gcon))
    (send self :arc
	(round (elt point 0)) (round (elt point 1))
	(round width) (round height) angle1 angle2 gc))
 (:draw-fill-arc (point width
		&optional (height width) (angle1 0.0) (angle2 2pi) (gc gcon))
    (send self :fill-arc
	(round (elt point 0)) (round (elt point 1))
	(round width) (round height) angle1 angle2 gc))
 (:drawline-primitive (x1 y1 x2 y2)
    (send self :line (round x1) (round y1) (round x2) (round y2)))
;;
 (:set-show-mode () (send gcon :function :copy))
 (:set-erase-mode () (send gcon  :function :clear))
 (:set-xor-mode () (send gcon :function :Xor)) ;GXxor ;extention.
 (:clear-area (&key (x 0) (y 0)
		(width (send self :width))
		(height (send self :height))
		((:gc g) gcon))
    ;; this method is only for pixmaps, which does not cleared by ClearArea.
    (send g :function :clear)	; this doesn't fill with the background color.
    (FillRectangle *display* drawable (gcontext-gcid g)  x y width height)
    (send g :function :copy))
 (:clear () (send self :clear-area)))

(defmethod Xdrawable
 (:graph (values &key (color) (max) (min) (gc gcon) (clear nil)	(step))
    (let* ((len (length values))
	   (scale)
	   v
	   (x 0) (x2 0) (y ) (y2)
	   (yinc)
	  )
     (if clear (send self :clear))
     (unless max 
	(unless (consp values) (setq values (coerce values cons)))
	(setq max (apply #'max values)))
     (unless min
	(unless (consp values) (setq values (coerce values cons)))
	(setq min (apply #'min values)))
     (setq max (float max) min (float min))
     (if color (send self :foreground color))
     (setq yinc (/ (float height) (- max min)))
     (unless step (setq step (/ (float width) (1- len))))
     ;;
     (flet ((yval (v)
		(round (- height (* yinc (- v min)))))
	    )
	(setq y (yval (elt values 0)))
        (dotimes (i (1- len))
	   (setq x2 (round (* (1+ i) step)))
	   (setq y2 (yval (elt values (1+ i))))
	   (send self :line x y x2 y2 gc)
	   (setq x x2 y y2)
	   )
        )
     ) )
 )

(defmethod Xdrawable
 (:3d-fill-rectangle (x y w h b lightedge darkedge surface
			topleft-edge	&optional (state :flat))
    (let ((org-pixel (send gcon :foreground)) color1 color2)
      (case state
	   (:up (setq color1 lightedge color2 darkedge))
	   (:down (setq color1 darkedge color2 lightedge))
	   (t  (setq color1 surface color2 surface)))
      (send gcon :foreground color2)
      (send self :fill-rectangle x y w h)
      (send gcon :foreground surface)
      (send self :fill-rectangle (+ x b) (+ y b) (- w b b) (- h b b))
      (send gcon :foreground color1)
      (send self :fill-polygon topleft-edge 1 1)
      (send gcon :foreground org-pixel)
      )
  )
)


;;
;; class XPixMap
;;


(defmethod Xpixmap 
  (:create (&key (size 256) (width size) (height width)
	         (depth (DefaultDepth *display* 0))
		 (gc *defaultgc*)
		&allow-other-keys)
     (setq drawable (CreatePixmap *display* (DefaultRootWindow *display*)
				width height depth))
     (send self :init drawable width height gc)	; send-super?
     self)
  (:create-from-bitmap-file (fname)
     (send-super :init 0)
     (let ((width (instantiate c-int))
	   (height (instantiate c-int))
	   (pixmap (instantiate c-long))
	   (x_hot (instantiate c-int))
	   (y_hot (instantiate c-int)))
        (ReadBitmapFile *display* (DefaultRootWindow *display*)
		 fname width height pixmap x_hot y_hot)
	(Flush *display*)
        (setq drawable (c-long pixmap))
	self))
  (:write-to-bitmap-file (fname)
     (WriteBitmapFile *display* fname drawable
			(send self :width) (send self :height)
			0 0)
     (Flush *display*))
  (:destroy ()
     (FreePixmap *display* drawable)
     (setq drawable nil))
;; use xdrawable's :create method to make a new instance
 ; (:init (id &optional w h)
 ;    (setq drawable id)
 ;    (send-super :init id w h)
 ;    self)
)

;; make series of pixmaps

(defun make-pixmaps (n &key (size 500) (width size) (height width)
			    (gc *blackgc*))
   (let ((maps))
     (dotimes (i n)
	(push (instance Xpixmap :create :width width :height height
					:gc gc) maps)
	(send (car maps) :gc gc))
     maps))

;; make dithered gray pixmap

(defun make-gray-pixmap (gray
		 &key (foreground *fg-pixel*)
			(background *bg-pixel*)
			(depth (defaultdepth *display* 0)))
  (let ((index (floor (* gray 32)))
	(bitmap (instantiate bit-vector 32)) pixmap)
     (dotimes (i index)
	(setf (aref bitmap (elt '( 18 22 0 4 2 6 16 20
				   9 13 27 31 25 29 11 15
				   8 12 26 30 24 28 10 14
				   1 5 19 23 17 21 3 7)
				i)) 1))
     (setq pixmap (instance xpixmap :create :width 8 :height 4))
     (setq bitmap (CreatePixmapFromBitmapData *display* (send *root* :drawable)
			bitmap 8 4 foreground background depth))
     (setf (xpixmap-drawable pixmap) bitmap)
     pixmap))


(defun make-gray-gc (gray
		 &key (foreground *fg-pixel*)
			(background *bg-pixel*)
			(depth (defaultdepth *display* 0)))
  (let ((index (floor (* gray 32)))
	(bitmap (instantiate bit-vector 32)) gray-pixmap gc)
     (setq gc (instance gcontext :create))
     (send gc :change-attributes :fill-style 1)
     (setq gray-pixmap
		(make-gray-pixmap gray :foreground foreground 
			:background background :depth depth))
     (send gc :tile gray-pixmap)
     gc))

(defun make-cleared-pixmap (width &optional (height width)
				 (pixel *bg-pixel*))
   (let ((pmap (instance xpixmap :create
			:width width :height height))
	 (fg-save))
      (setq fg-save (send pmap :gc :foreground))
      (send pmap :gc :foreground pixel)
      (send pmap :fill-rectangle 0 0 width height (send pmap :gc))
      (send pmap :gc :foreground fg-save)
      pmap))


;;
;; class Xwindow
;;

(defun eventmask-to-value (events)
   (cond ((numberp events) events)
         (t
	   (let ((mask 0) m)
	     (dolist (e events)
	        (setq m (cadr (assoc e 
		 '((:keypress 1) (:keyrelease 2) 
		   (:key 3) 
		   (:button #xc)
		   (:buttonPress 4) (:buttonRelease 8)
		   (:enterLeave #x30)
		   (:enterwindow #x10) (:leaveWindow #x20)
		   (:pointermotion #x40)
		   (:pointermotionhint #x80)
		   (:buttonMotion #x2000)
		   (:motion #x2000)
		   (:keymapstate #x4000)
		   (:exposure #x8000)
		   (:visibilityChange #x10000)
		   (:configure #x20000)
		   (:structureNotify #x20000)
		   (:resizeRedirect #x40000)
		   (:substructureNotify #x80000)
		   (:substructureRedirect #x100000)
		   (:FocusChange #x200000)
		   (:propertyChage #x400000)
		   (:colormapChage #x800000)
		   (:ownerGrabButton #x1000000)))))
	          (if m
		     (setq mask (logior mask m))
		     (warn "unknown event-mask keyword ~s~%" e)))
	          mask)) ))

(defun gravity-to-value (g)
    (if (symbolp g)
	(setq g (cdr (assoc g
		'((:forget . 0) (:northwest . 1) (:north . 2)
		  (:northeast . 3) (:west . 4) (:center . 5)
		  (:east . 6) (:southwest . 7) (:south . 8)
		  (:southeast . 9) (:static . 10))))) )
    (unless (integerp g) (error "invalid gravity name" g))
    g)


(defmethod Xwindow	;creation
 (:create (&key ((:parent par) *root*)
		(x 0) (y 0) (size 256) (width size) (height width)
		(border-width 2)
		(border *fg-pixel*)
		(save-under NIL)
		(backing-store :always)
		((:backing-pixmap backingpixmap) nil)
		(foreground)
		(background)
		(title (string (gensym  "WINDOW")))
		(event-mask #x2200f)	;button, key, motion, configure-win
		((:gc xgc)) 
		(font)
		(name)		
		(map t)
		((:visual vi) *visual*)
		(depth (visual-depth vi))
		(color-map)
		(override-redirect nil)
		(gravity :northwest)
		&allow-other-keys)
    (unless par (setq par *root*))
    (setq parent par)
    (setq visual vi)
; Sun's xserver X.V11R2 does not support backing store and save unders.
; but X.V11R3 or upper Xsun does support backing store!
    (setq save-under
         (cond  ((numberp save-under) save-under)
		((eq save-under T) 1)
		(*save-under* 1)
		(T 0)))
    (setq backing-store
	  (cond ((numberp backing-store) backing-store)
		((null *save-under*) 0)
		(t (cadr (assoc backing-store 
			'((:notUseful 0) (:whenMapped 1) (:always 2)))))))
    (setf event-mask (eventmask-to-value event-mask))
    (if (= save-under 0)
	(setq event-mask (logior event-mask 
				(eventmask-to-value 
					'(:exposure :visibilityChange)))))
    (setf (SetWindowAttributes-save_under swa)  save-under)
    (setf (SetWindowAttributes-backing_store swa)  backing-store)
    (setf (SetWindowAttributes-border_pixel swa)   border)
    (setf (SetWindowAttributes-backing_planes swa) -1)
    (setf (SetWindowAttributes-backing_pixel swa) 0)
    (setf (SetWindowAttributes-event_mask swa) event-mask)
    (setf (SetWindowAttributes-win_gravity swa)	(gravity-to-value gravity))
    (unless color-map
	(cond ((= vi *visual*)		;use parent's colormap for the default
		(setq color-map  (send parent :colormap)))
	      (t					;make private cmap
		(setq color-map (instance colormap :create :visual vi))
	        (send color-map :copy-colors *color-map* 0 32)) ))
    (setf (SetWindowAttributes-colormap swa) (send color-map :id))
    (setf (SetWindowAttributes-override_redirect swa)
	  (if override-redirect 1 0)	)
;; create
    (setq drawable
	  (CreateWindow *display*
		(send parent :drawable)
		 x y width height border-width depth 0 vi  #x2fe8 swa))
    (StoreName *display* drawable title)
    (send self :init drawable width height xgc)
    ;; gcontext is created and set to gcon.
    (let ((bgname background))
       (unless background
	   (setq background
		(if (and parent (not (eql parent *root*)))
		    (send parent :gc :background nil color-map)
		    *bg-pixel*)))	;assume we are using the default colormap
       (setq background (send color-map :get-pixel background))
       ; (format t "win=~s bg=~s cmap=~s~%" self background color-map)
       (unless (numberp background) 
          (warn "cannot :get-pixel for ~a~%" bgname)
	  (setq background *bg-pixel*)))
    (send gcon :foreground
	(cond (foreground)
	      (parent (send parent :foreground))
	      (t  *fg-pixel*))
	color-map)
    (setq bg-color background)	;bg-color must be a pixel number
    (SetWindowBackGround *display* drawable bg-color)
    (if backingpixmap
	(setq backing-pixmap
	      (instance Xpixmap :create :width width :height height)))
    (ClearWindow *display* drawable)
    (if map (MapWindow   *display* drawable))
    (if parent (send parent :associate self))
    (push self *xwindows*)
    (cond (font (send gcon :font font))
	  (parent (send gcon :font (send parent :gc :font)))
	  )
    (if name
	(send self :name name)
	(send self :name title))
    (send gcon :background bg-color color-map)
    (flush *display*)
    self)
  )

(defmethod xwindow	;relations
 (:subwindows (&optional n)   (if n (nth n subwindows) subwindows))
 (:map () 
    (send-all subwindows :map)
    (MapWindow *display* drawable))
 (:unmap ()
     (send-all subwindows :unmap)
     (UnmapWindow *display* drawable))
 (:remap ()
     (send self :unmap) (flush *display*)
     (send self :map) (flush *display*))
 (:parent () parent)
 (:associate (child)
    (pushnew child subwindows))
 (:dissociate (child)
    (setq subwindows (delete child subwindows)))
 (:reparent (par &optional (x 0) (y 0))
    (unless (integerp par) (setq par (send par :drawable)))
    (ReparentWindow *display* drawable par x y)
    (setq parent par))
 (:destroy ()
    (send-all subwindows :destroy)
    (if drawable
	(DestroyWindow *display* (prog1 drawable (setq drawable nil))))
    (when parent (send parent :dissociate self) (setq parent nil))
    (setq *xwindows* (delete self *xwindows*))
    (remhash drawable *xwindows-hash-tab*))
 )

(defmethod xwindow	;attributes
 (:attributes (&aux attr)
    (setq attr (instantiate WindowAttributes))
    (GetWindowAttributes *display* drawable attr)
    attr)
 (:event-mask () (send (send self :attributes) :get 'your_event_mask))
 (:selectinput (event-mask)
    (selectinput *display* drawable (eventmask-to-value event-mask)))
 (:visual ()
    (if visual visual (send (send self :attributes) :get 'visual)))
 (:location (&aux (attr (send self :attributes)))
    (integer-vector (send attr :get 'x) (send attr :get 'y)))
 (:size (&aux (attr (send self :attributes)))
    (integer-vector (send attr :get 'width) (send attr :get 'height)))
 (:depth () (send (send self :attributes) :get 'depth))
 (:screen () (send (send self :attributes) :get 'screen))
 (:ColorMap () (let ((color-map (gethash (send (send self :attributes) :get 'colormap)
			*xwindows-hash-tab*)))
		(unless (derivedp color-map colormap)
		    (warning-message 2 "~s's parent ~s does not have cmap; root cmap is used.~%"
				self parent)
		    (setq color-map *color-map*))
		color-map))
 (:root () (send (send self :attributes) :get 'root))	;drawable id of the root
 (:title (title)
    ;(send self :unmap)
    (StoreName *display* drawable title)
    ;(send self :map)
    (Flush *display*))
 (:background (&optional color)
    (when color
       (SetWindowBackGround *display* drawable color)
       (setq bg-color color)
       (send self :clear))
    bg-color)
 (:background-pixmap (pixmap)
    ;; (if (numberp pixmap) (setq pixmap (make-gray-pixmap pixmap)))
    (SetWindowBackGroundPixmap *display* drawable (send pixmap :drawable))
    ;; need to :clear to get  the effect to appear on the window
    (send self :clear)    )
 (:border (pixel) (SetWindowBorder *display* drawable pixel)) 
 )

(defmethod xwindow
 (:save () (send backing-pixmap :copy-from self) (flush *display*))
 (:refresh ()
   (send-super :copy-from backing-pixmap) (flush *display*))
 (:move (newx newy) (MoveWindow *display* drawable newx newy))
 (:resize (w h)
    (ResizeWindow *display* drawable w h)
    (setq width w height h))
 (:raise () (RaiseWindow *display* drawable))
 (:lower () (LowerWindow *display* drawable))
 (:write-to-bitmap-file (fname)
    (send backing-pixmap :write-to-bitmap-file fname))
 (:clear ()
    (ClearWindow *display* drawable))
 (:clear-area (&key (x 0) (y 0)	(width 0) (height 0))
    (ClearArea *display* drawable x y width height 0))
 (:set-colormap (cmap)
    (SetWindowColormap *display* drawable (cmap . cmapid)) )
 (:copy (&rest args)
    (let ((copy (instance* class :create :width (send self :width)
				:height (send self :height)
				args)))
	(send copy :copy-from self)
	copy))
 )


(defun geo::default-viewsurface (&rest args)
   (send* (instantiate xwindow)  :create args))

(defmethod Xdrawable
 (:draw-lines (points &optional (mode 0) (gc gcon))
   (let* ((n (length points)) (xp (instantiate string (* n 4))))
      (send xp :set points 0 :short)
      (DrawLines *display* drawable (gcontext-gcid gc) xp n mode)  ) )
 (:draw-polygon (points &optional (gc gcon)) 
      (send self :draw-lines (append points (list (car points))) 0 gc) )
 (:fill-polygon (points &optional(shape 0) (CoordMode 0) (gc gcon))
#| CoordMode	
    #define CoordModeOrigin     0       /* relative to the origin */
    #define CoordModePrevious   1   /* relative to previous point */
|#
     (let* (n xp) 
       (cond ((vectorp points)
		(setq xp points
		      n (/ (length points) 4)))
	     (t (setq n (length points)
		      xp (instantiate string (* 4 n)))
	        (send xp :set points 0 :short)) )
       (FillPolygon *display* drawable (gcontext-gcid gc) xp n shape
			CoordMode))
  )
 )
#|
        XFillPolyigon(display, drawable, gc, points, npoints, shape, mode)
                Display *display;
                Drawable drawable;
                GC gc;
                Xpoints *points;
                int npoints;
                int shape;
                int mode;

shape: Complex(0), Nonconvex(1), Convex(2)
mode:CoordModeOrigin(0), CoordModePrevious(1)

typedef struct {
        short x,y;
} XPint;
|#


;;;;;;; Hara Extension
(defmethod xwindow
  (:override_redirect (&optional (val 1))
	(setf (SetWindowAttributes-override_redirect swa) val)
	(changewindowAttributes *display* drawable (ash 1 9) swa)
  )
  (:save_under (&optional (val 1))
	(setf (SetWindowAttributes-save_under swa) val)
	(ChangeWindowAttributes *display* drawable (ash 1 10) swa)
  )
 (:settransientforhint ()
	(SetTransientForHint *display* drawable (send parent :drawable))
 )
 (:querypointer ()
   (let ((root (instantiate c-long))
	 (child (instantiate c-long))
	 (root_x (instantiate c-int))
	 (root_y (instantiate c-int))
	 (win_x (instantiate c-int))
	 (win_y (instantiate c-int))
	 (mask (instantiate c-int)))
     (QueryPointer *display* drawable root child root_x root_y win_x win_y
		   mask)
     (list (c-long root) (c-long child) (c-int root_x) (c-int root_y)
	   (c-int win_x) (c-int win_y) (c-int mask))
    )
 )
 (:global-pos ()
   (let ((tmp (send self :querypointer)))
      (integer-vector (- (elt tmp 2) (elt tmp 4)) (- (elt tmp 3) (elt tmp 5)))
   )
 )
)

;;;;;;;;;;;;;;;;;;
;; Handy window creation

(defun make-xwindow (&rest args)
  (send* (instantiate xwindow) :create args))

(defun find-xwindow (subname)
  (mapcan #'(lambda (w)
		(if (substringp subname (string (send w :name)))
		    (list w)))
	  *xwindows*))
	

;;;;;
(provide :Xeus "@(#)$Id$")