added more X11 code related to GC handling

This commit is contained in:
hyunghwan.chung
2017-06-29 15:04:35 +00:00
parent a2877ac905
commit d0b38926d4
5 changed files with 518 additions and 174 deletions

View File

@ -7,10 +7,6 @@ class X11(Object) from 'x11'
## definition struct x11_t defined in _x11.h
## ---------------------------------------------------------------------
var display_base := nil.
var expose_event.
var key_event.
var mouse_event.
var mouse_wheel_event.
## =====================================================================
var shell_container := nil.
@ -24,16 +20,21 @@ class X11(Object) from 'x11'
method(#primitive) _get_fd.
method(#primitive) _get_llevent(llevent).
method(#primitive) _create_window(parent_window, x, y, width, height, fgcolor, bgcolor).
method(#primitive) _destroy_window(window).
method(#primitive) _create_window(parent_window_handle, x, y, width, height, fgcolor, bgcolor).
method(#primitive) _destroy_window(window_handle).
##method(#primitive) _fill_rectangle(window, gc, x, y, width, height).
method(#primitive) _draw_rectangle(window, gc, x, y, width, height).
method(#primitive) _create_gc (window_handle).
method(#primitive) _destroy_gc (gc). ## note this one accepts a GC object.
method(#primitive) _apply_gc (gc). ## note this one accepts a GC object, not a GC handle.
method __create_window(parent_window, x, y, width, height, fgcolor, bgcolor, owner)
method(#primitive) _draw_rectangle(window_handle, gc_handle, x, y, width, height).
method(#primitive) _fill_rectangle(window_handle, gc_handle, x, y, width, height).
method(#primitive) _draw_string(gc, x, y, string).
method __create_window(parent_window_handle, x, y, width, height, fgcolor, bgcolor, owner)
{
| w |
w := self _create_window(parent_window, x, y, width, height, fgcolor, bgcolor).
w := self _create_window(parent_window_handle, x, y, width, height, fgcolor, bgcolor).
if (w notError) { self.window_registrar at: w put: owner }.
^w
}
@ -141,16 +142,41 @@ class X11.ExposeEvent(X11.Event)
## ---------------------------------------------------------------------------
## X11 Context
## ---------------------------------------------------------------------------
class X11.GraphicsContext(Object)
pooldic X11.GCLineStyle
{
SOLID := 0.
ON_OFF_DASH := 1.
DOUBLE_DASH := 2.
}
pooldic X11.GCFillStyle
{
SOLID := 0.
TILED := 1.
STIPPLED := 2.
OPAQUE_STIPPLED := 3.
}
class X11.GC(Object)
{
## note these fields must match the x11_gc_t structure defined in _x11.h
var(#get) widget := nil, gcHandle := nil.
var(#get,#set)
foreground := 0,
background := 0,
background := 1,
lineWidth := 1,
lineStyle := 0,
fillStyle := 0.
lineStyle := X11.GCLineStyle.SOLID,
fillStyle := X11.GCFillStyle.SOLID,
fontName := nil.
var fontPtr := nil.
method(#class) new
{
self messageProhibited: #new.
}
method(#class) new: widget
{
@ -160,20 +186,47 @@ class X11.GraphicsContext(Object)
method __make_gc_on: widget
{
| gc |
widget displayServer dump.
widget windowHandle dump.
gc := widget displayServer _create_gc (widget windowHandle).
if (gc isError) { selfns.Exception signal: 'Cannot create a graphics context' }.
self.gcHandle := gc.
self.widget := widget.
}
method drawRectangle(x, y, width, height)
{
^self.widget displayServer _draw_rectangle (self.widget windowHandle, self.gcHandle, x, y, width, height).
}
method fillRectangle(x, y, width, height)
{
^self.widget displayServer _fill_rectangle (self.widget windowHandle, self.gcHandle, x, y, width, height).
}
method drawRectangle(x, y, width, height)
method drawString(x, y, string)
{
^self.widget displayServer _draw_rectangle (self.widget windowHandle, self.gcHandle, x, y, width, height).
^self.widget displayServer _draw_string (self, x, y, string).
}
method dispose
{
if (self.gcHandle notNil)
{
self.widget displayServer _destroy_gc (self).
self.gcHandle := nil
}
}
method apply
{
if (self.gcHandle notNil)
{
if (self.widget displayServer _apply_gc (self) isError)
{
X11.Exception signal: 'Cannot apply GC settings'
}
}
}
}
@ -183,44 +236,71 @@ class X11.GraphicsContext(Object)
class X11.Widget(Object)
{
var(#get) windowHandle := nil.
var(#get,#set)
parent := nil,
x := 0,
y := 0,
width := 0,
height := 0,
fgcolor := 0,
fgcolor := 16r1188FF,
bgcolor := 0,
realized := false.
method displayServer
{
if (self.parent isNil) { ^nil }.
^self.parent displayServer.
}
method windowHandle
method parentWindowHandle
{
(* i assume that a widget doesn't' with a low-level window by default.
* if a widget maps to a window, the widget class must implement the
* windowHandle method to return the low-level window handle.
* if it doesn't map to a window, it piggybacks on the parent's window *)
if (self.parent isNil) { ^nil }.
^self.parent windowHandle.
}
method realize { }
method dispose
method realize
{
'Widget dispose XXXXXXXXXXXXXX' dump.
| disp wind |
if (self.windowHandle notNil) { ^self }.
disp := self displayServer.
if (disp isNil)
{
X11.Exception signal: 'Cannot realize a widget not added to a display server'
}.
wind := disp __create_window(self parentWindowHandle, self.x, self.y, self.width, self.height, self.fgcolor, self.bgcolor, self).
if (wind isError)
{
self.Exception signal: 'Cannot create widget window'.
}.
self.windowHandle := wind.
}
method dispose
{
| disp |
'Widget dispose XXXXXXXXXXXXXX' dump.
disp := self displayServer.
if (disp notNil)
{
if (self.windowHandle notNil)
{
disp __destroy_window (self.windowHandle).
self.windowHandle := nil.
}.
}
}
method onPaintEvent: paint_event
{
System logNl: 'Widget...... onPaintEvent YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY.'.
}
method onButtonEvent: event
@ -232,6 +312,7 @@ class X11.Widget(Object)
}
}
class X11.Label(X11.Widget)
{
var(#get) text := ''.
@ -242,20 +323,9 @@ class X11.Label(X11.Widget)
if (self windowHandle notNil) { self onPaintEvent: nil }
}
method onPaintEvent: paint_event
{
| gc |
System logNl: 'LABEL GC.......'.
gc := selfns.GraphicsContext new: self.
gc foreground: 100.
gc drawRectangle (self.x, self.y, self.width, self.height).
###gc.drawText (self.title)
}
method realize
{
## if i want to use a window to represent it, it must create window here.
## otherwise, do other works in onPaintEvent:???
super realize.
}
method dispose
@ -263,6 +333,25 @@ System logNl: 'LABEL GC.......'.
'Label dispose XXXXXXXXXXXXXX' dump.
super dispose.
}
method onPaintEvent: paint_event
{
| gc |
System logNl: 'LABEL GC...... onPaintEvent YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY.'.
gc := selfns.GC new: self.
[
gc foreground: self.fgcolor;
fontName: '-misc-fixed-medium-r-normal-ko-18-120-100-100-c-180-iso10646-1';
apply.
gc drawRectangle (0, 0, self.width - 1, self.height - 1).
##gc fillRectangle (0, 0, self.width, self.height).
##gc drawLine (0, y, CTRLWIDE, y).
##gc drawLine (0, y + CHIGH + 4, CTRLWIDE, Y+CHIGH+4).
gc drawString(10, 10, self.text).
] ensure: [ gc dispose ]
}
}
class X11.Composite(X11.Widget)
@ -303,13 +392,33 @@ class X11.Composite(X11.Widget)
^self.children size
}
method realize
{
super realize.
[
self.children do: [:child | child realize ].
] on: System.Exception do: [:ex |
self dispose.
ex pass
].
}
method dispose
{
'Composite dispose XXXXXXXXXXXXXX' dump.
super dispose.
self.children do: [:child |
child dispose.
self remove: child.
].
super dispose
}
method onPaintEvent: event
{
super onPaintEvent: event.
self.children do: [:child |
## TODO: adjust event relative to each child...
child onPaintEvent: event.
]
}
}
@ -318,13 +427,16 @@ class X11.Shell(X11.Composite)
{
var(#get) title := ''.
var(#get,#set) displayServer := nil.
var(#get) windowHandle := nil.
method new: title
{
self.title := title.
}
#### TODO:
#### redefine x:, y:, width:, height: to return actual geometry values...
####
method title: title
{
self.title := title.
@ -336,50 +448,15 @@ class X11.Shell(X11.Composite)
method realize
{
| wind |
if (self.windowHandle notNil) { ^self }.
if (self.displayServer isNil)
{
## not added to a display server.
X11.Exception signal: 'Cannot realize a shell not added to a display server'
}.
wind := self.displayServer __create_window(nil, self.x, self.y, self.width, self.height, self.fgcolor, self.bgcolor, self).
if (wind isError)
{
self.Exception signal: ('Cannot create shell ' & self.title).
}.
self.windowHandle := wind.
[
self.children do: [:child | child realize ].
] on: System.Exception do: [:ex |
self.displayServer __destroy_window(wind).
self.windowHandle := nil.
ex pass
].
### call displayOn: from the exposure handler...
self onPaintEvent: nil.
'SHELL REALIZE XXXXXXXXXXX' dump.
super realize.
}
method dispose
{
'Shell dispose XXXXXXXXXXXXXX' dump.
if (self.displayServer notNil)
{
if (self.windowHandle notNil)
{
super dispose.
self.displayServer __destroy_window (self.windowHandle).
self.windowHandle := nil.
}.
self.displayServer removeShell: self.
}
super dispose.
self.displayServer removeShell: self.
}
method onCloseEvent
@ -404,8 +481,7 @@ extend X11
if (self _open_display(name) isError)
{
self.Exception signal: 'cannot open display'
}
.
}.
self.display_base dump.
}
@ -420,7 +496,7 @@ extend X11
if (self.display_base notNil)
{
self _close_display.
##self.display_base := nil.
self.display_base := nil.
}.
}
@ -428,11 +504,6 @@ extend X11
{
super initialize.
self.expose_event := self.ExposeEvent new.
self.key_event := self.KeyEvent new.
self.mouse_event := self.MouseEvent new.
self.mouse_wheel_event := self.MouseWheelEvent new.
self.shell_container := self.Composite new.
self.window_registrar := System.Dictionary new: 100.
@ -519,11 +590,13 @@ extend X11
}.
}.
'CLOSING X11 EVENT LOOP' dump.
Processor unsignal: self.event_loop_sem.
self.event_loop_sem := nil.
self dispose.
'CLOSING X11 EVENT LOOP' dump.
] fork.
}
}
@ -561,7 +634,6 @@ extend X11
^nil
}.
(llevent window asString) dump.
^self perform (mthname, llevent, widget).
}
@ -571,6 +643,7 @@ extend X11
method __handle_expose: llevent on: widget
{
widget onPaintEvent: llevent
}
method __handle_button_event: event on: widget
@ -583,6 +656,7 @@ extend X11
method __handle_configure_notify: event on: widget
{
widget onPaintEvent: event.
}
method __handle_client_message: event on: widget
@ -609,6 +683,7 @@ class MyObject(Object)
method main1
{
| comp1 |
self.disp1 := X11 new.
self.disp2 := X11 new.
@ -617,7 +692,7 @@ class MyObject(Object)
shell3 := (X11.Shell new title: 'Shell 3').
shell1 x: 10; y: 20; width: 100; height: 100.
shell1 x: 10; y: 20; width: 500; height: 500.
shell2 x: 200; y: 200; width: 200; height: 200.
shell3 x: 500; y: 200; width: 200; height: 200.
@ -625,7 +700,16 @@ class MyObject(Object)
self.disp1 addShell: shell2.
self.disp2 addShell: shell3.
self.shell1 add: (X11.Label new text: 'xxxxxxxx').
comp1 := X11.Composite new x: 10; y: 10; width: 400; height: 500.
self.shell1 add: comp1.
comp1 add: (X11.Label new text: '간다'; width: 100; height: 100).
comp1 add: (X11.Label new text: 'crayon'; x: 90; y: 90; width: 100; height: 100).
## self.shell1 add: (X11.Label new text: 'xxxxxxxx'; width: 100; height: 100).
self.shell1 add: (X11.Label new text: 'crayon'; x: 90; y: 90; width: 100; height: 100).
self.shell2 add: (X11.Label new text: 'crayon'; x: 90; y: 90; width: 100; height: 100).
self.shell3 add: (X11.Label new text: 'crayon'; x: 90; y: 90; width: 100; height: 100).
self.shell1 realize.
self.shell2 realize.
self.shell3 realize.