small fixes to X11
[k8lst.git] / modules / x11 / base / x11base.st
blob08609595b073035e8553870111a02b1bf562eadb
1 Package [
2   X11
6 class: X11BaseWindow [
7   | wid gc font fcolor fdraw ablock visible bgcolor title parent dead |
9   ^new [
10     ^self error: 'X11BaseWindow instances must be created with special methods'.
11   ]
13   ^newWithId: wid [
14     | obj |
15     obj := self basicNew.
16     self in: obj at: 1 put: wid.
17     self in: obj var: #dead put: false.
18     obj internalInit.
19     ^obj
20   ]
22   ^new: aParent at: xy size: sz bgColor: clr [
23     | wid obj |
24     wid := X11Singleton XCreateSimpleWindow: (aParent ifNotNil: [ aParent wid ])
25       x: xy x y: xy y
26       width: sz x height: sz y
27       bgcolor: clr color.
28     obj := self newWithId: wid.
29     obj; bgColor: clr; backgroundColor: clr.
30     self in: obj var: #bgcolor put: clr.
31     self in: obj var: #parent put: aParent.
32     aParent ifNotNil: [ aParent isGroup ifTrue: [ aParent add: obj ]].
33     ^obj
34   ]
36   isGroup [
37     ^false
38   ]
40   loveKbdFocus [
41     ^false
42   ]
44   parent [
45     ^parent
46   ]
48   internalInit [
49     gc := X11GC new: wid.
50     font := X11Font new.
51     fcolor := X11FontColor new: 1.0 g: 1.0 b: 1.0.
52     fdraw := X11FontDraw new: wid.
53     X11Singleton XSelectInput: wid interestFlag: 1.
54     visible := false.
55     title := ''.
56     self addToBeFinalized.
57     self init.
58   ]
60   init [
61   ]
63   deinit [
64     dead ifFalse: [
65       self hide.
66       dead := true.
67       fdraw ifNotNil: [ fdraw free ].
68       fcolor ifNotNil: [ fcolor free ].
69       font ifNotNil: [ font free ].
70       bgcolor ifNotNil: [ bgcolor free ].
71       gc ifNotNil: [ gc free ].
72       title := parent := nil.
73       self markAsDead.
74       X11Singleton XDestroyWindow: wid.
75     ]
76   ]
78   finalize [
79     self close.
80     fdraw := fcolor := font := gc := wid := bgcolor := title := parent := nil.
81   ]
83   dead [
84     ^dead
85   ]
87   close [
88     dead ifFalse: [ self deinit ].
89   ]
91   wid [
92     ^wid
93   ]
95   gc [
96     ^gc
97   ]
99   title [
100     ^title
101   ]
103   title: aTitle [
104     dead ifTrue: [ ^self ].
105     title := aTitle ifNil: [ '' ].
106     X11Singleton XSetTitle: wid title: title.
107   ]
109   'show/hide'
110   visible [
111     ^visible
112   ]
114   visible: aVis [
115     aVis ifTrue: [ ^self show ].
116     ^self hide
117   ]
119   show [
120     visible ifFalse: [
121       dead ifFalse: [ X11Singleton XMapWindow: wid ].
122     ]
123   ]
125   hide [
126     visible ifTrue: [
127       dead ifFalse: [ X11Singleton XUnmapWindow: wid ].
128     ]
129   ]
131   isActive [
132     ^dead not and: [ visible ].
133   ]
135   'colors'
136   backgroundColor: clr [
137     "window background; not GC"
138     dead ifTrue: [ ^self ].
139     bgcolor := clr.
140     X11Singleton XSetWindowBackground: wid color: clr color
141   ]
143   fgColor: aClr [
144     dead ifTrue: [ ^self ].
145     gc fgColor: aClr.
146   ]
148   bgColor: aClr [
149     dead ifTrue: [ ^self ].
150     gc bgColor: aClr.
151   ]
153   fgColor: r g: g b: b [
154     self fgColor: (X11Color new: r g: g b: b)
155   ]
157   bgColor: r g: g b: b [
158     self bgColor: (X11Color new: r g: g b: b)
159   ]
161   'event handling'
162   sameWid: aWid [
163     aWid ifNil: [ ^false ].
164     (aWid isKindOf: X11BaseWindow) ifTrue: [ aWid := aWid wid ].
165     ^(X11Singleton sameWids: wid and: aWid)
166   ]
168   = aWid [
169     ^self sameWid: aWid
170   ]
172   passEvent: aWid event: evt [
173     "return true if event handler found"
174     (X11Singleton sameWids: wid and: aWid) ifTrue: [
175       (evt at: 1) == #KeyPress ifTrue: [ ^self keyPressEvent: evt ].
176       self onEvent: evt.
177       ^true
178     ].
179     ^false
180   ]
182   onEvent: evt [
183     | mt |
184     (mt := self class findMethodInAll: ('onX11' + (evt at: 1) asString + ':') asSymbol ifAbsent: [nil]) ifNotNil: [
185       "'perform: ' print. mt name printNl."
186       ^self perform: mt withArgument: evt
187     ].
188   ]
190   focusMe [
191     self isActive ifTrue: [
192       self focused ifFalse: [ X11Singleton XSetInputFocus: wid ].
193     ].
194   ]
196   focused [
197     dead ifTrue: [ ^false ].
198     visible ifFalse: [ ^false ].
199     ^self sameWid: (X11Singleton XGetInputFocus)
200   ]
202   keyPressEvent: evt [
203     ^true  "eat all keys"
204   ]
206   action: aBlock [
207     ablock := aBlock
208   ]
210   action [
211     ^ablock
212   ]
214   doAction [
215     ablock ifNotNil: [ ablock value: self ]
216   ]
218   'geometry'
219   move: aPoint [
220     dead ifTrue: [ ^self ].
221     X11Singleton XMoveWindow: wid x: aPoint x y: aPoint y
222   ]
224   resize: aPoint [
225     dead ifTrue: [ ^self ].
226     X11Singleton XResizeWindow: wid width: aPoint x height: aPoint y
227   ]
229   move: aPoint resize: aSize [
230     dead ifTrue: [ ^self ].
231     X11Singleton XMoveResizeWindow: wid x: aPoint x y: aPoint y width: aSize x height: aSize y
232   ]
234   position [
235     | x y |
236     dead ifTrue: [ ^0 @ 0 ].
237     x := X11Singleton XGetGeometry: wid item: 1.
238     y := X11Singleton XGetGeometry: wid item: 2.
239     ^x @ y
240   ]
242   dimensions [
243     | w h |
244     dead ifTrue: [ ^0 @ 0 ].
245     w := X11Singleton XGetGeometry: wid item: 3.
246     h := X11Singleton XGetGeometry: wid item: 4.
247     ^w @ h
248   ]
250   maxXY [
251     | w h |
252     dead ifTrue: [ ^0 @ 0 ].
253     w := X11Singleton XGetGeometry: wid item: 3.
254     h := X11Singleton XGetGeometry: wid item: 4.
255     ^(w-1) @ (h-1)
256   ]
258   width [
259     dead ifTrue: [ ^0 ].
260     ^X11Singleton XGetGeometry: wid item: 3.
261   ]
263   height [
264     dead ifTrue: [ ^0 ].
265     ^X11Singleton XGetGeometry: wid item: 4.
266   ]
268   clientSizeRect [
269     ^Rectangle newFrom: 0 @ 0 size: self dimensions
270   ]
272   clientRect [
273     ^Rectangle newFrom: 0 @ 0 size: self maxXY
274   ]
276   'drawing'
277   clear [
278     dead ifTrue: [ ^self ].
279     X11Singleton XClearWindow: wid
280   ]
282   drawPoint: p0 [
283     dead ifTrue: [ ^self ].
284     X11Singleton XDrawPoint: wid gc: gc gc x: p0 x y: p0 y.
285   ]
287   drawLine: p0 to: p1 [
288     dead ifTrue: [ ^self ].
289     X11Singleton XDrawLine: wid gc: gc gc x0: p0 x y0: p0 y x1: p1 x y1: p1 y.
290   ]
292   drawRect: aRect [
293     dead ifTrue: [ ^self ].
294     X11Singleton XDrawRect: wid gc: gc gc x: aRect x y: aRect y width: aRect width height: aRect height.
295   ]
297   fillRect: aRect [
298     dead ifTrue: [ ^self ].
299     X11Singleton XFillRect: wid gc: gc gc x: aRect x y: aRect y width: aRect width height: aRect height.
300   ]
302   'text'
303   font [
304     ^font
305   ]
307   font: aName [
308     dead ifTrue: [ ^self ].
309     font := X11Font new: aName
310   ]
312   fontColor: aClr [
313     dead ifTrue: [ ^self ].
314     fcolor := aClr
315   ]
317   fontColor: r g: g b: b [
318     dead ifTrue: [ ^self ].
319     fcolor := X11FontColor new: r g: g b: b.
320   ]
322   putTextAt: p0 text: text [
323     dead ifTrue: [ ^self ].
324     X11Singleton XftFontDraw: fdraw draw
325       color: fcolor color
326       font: font font
327       x: p0 x y: p0 y
328       text: text.
329   ]
331   drawTextAt: p0 text: text [
332     | gx gy |
333     dead ifTrue: [ ^self ].
334     gx := font textX: text. gy := font textY: text.
335     X11Singleton XftFontDraw: fdraw draw
336       color: fcolor color
337       font: font font
338       x: p0 x + gx y: p0 y + gy
339       text: text.
340   ]
342   markAsDead [
343     "'-' print. self print. ' ' print. dead printNl.
344     dead ifFalse: [ 'died: ' print. (X11Singleton wid2str: wid) printNl ]."
345     dead ifFalse: [ self deinit. dead := true ]
346   ]
348   childVisibility: aChild vis: aVisFlag [
349   ]
351   childFocusing: aChild focused: aFFlag [
352   ]
354   selected [
355     ^false
356   ]
357   selected: aFlag [
358   ]
360   'drawing'
361   draw: aFull [
362     aFull ifTrue: [ self redraw ].
363   ]
365   redraw [
366   ]
368   'keyboard focus'
369   fixKbdFocus [
370   ]
372   'X11 event handling'
373   onX11MotionNotify: evt [
374   ]
376   onX11ButtonPress: evt [
377   ]
379   onX11ButtonRelease: evt [
380   ]
382   onX11EnterNotify: evt [
383   ]
385   onX11LeaveNotify: evt [
386   ]
388   onX11Expose: evt [
389     self fixKbdFocus.
390     self draw: (evt at: 7) = 0
391   ]
393   onX11FocusIn: evt [
394     parent ifNil: [ ^self selected: true ].
395     parent childFocusing: self focused: true.
396   ]
398   onX11FocusOut: evt [
399     parent ifNil: [ ^self selected: false ].
400     parent childFocusing: self focused: false.
401   ]
403   onX11KeymapNotify: evt [
404   ]
406   onX11KeyPress: evt [
407   ]
409   onX11KeyRelease: evt [
410   ]
412   onX11MapNotify: evt [
413     visible := true.
414     parent ifNotNil: [
415       parent childVisibility: self vis: true.
416       parent fixKbdFocus.
417     ].
418   ]
420   onX11UnmapNotify: evt [
421     visible := false.
422     parent ifNotNil: [
423       parent childVisibility: self vis: true.
424       parent fixKbdFocus.
425     ].
426   ]
428   onX11DestroyNotify: evt [
429     "'dying: ' print. (X11Singleton wid2str: wid) printNl."
430     self markAsDead.
431   ]
433   onX11WMCloseRequest: evt [
434     self close
435   ]