interim commit of ongoing X11 works
This commit is contained in:
parent
16ff846013
commit
246662220f
@ -2,26 +2,49 @@
|
|||||||
|
|
||||||
class X11(Object) from 'x11'
|
class X11(Object) from 'x11'
|
||||||
{
|
{
|
||||||
|
## =====================================================================
|
||||||
|
## this part of the class must match the internal
|
||||||
|
## definition struct x11_t defined in _x11.h
|
||||||
|
## ---------------------------------------------------------------------
|
||||||
var display_base := nil.
|
var display_base := nil.
|
||||||
var shell_container := nil.
|
var llevent.
|
||||||
|
|
||||||
var windows. ## all windows registered
|
|
||||||
|
|
||||||
var event_loop_sem, event_loop_proc.
|
|
||||||
var ll_event_blocks.
|
|
||||||
|
|
||||||
var expose_event.
|
var expose_event.
|
||||||
var key_event.
|
var key_event.
|
||||||
var mouse_event.
|
var mouse_event.
|
||||||
var mouse_wheel_event.
|
var mouse_wheel_event.
|
||||||
|
## =====================================================================
|
||||||
|
|
||||||
method(#class,#primitive,#liberal) _open_display(name).
|
var shell_container := nil.
|
||||||
method(#class,#primitive) _close_display(display).
|
var window_registrar. ## all windows registered
|
||||||
method(#class,#primitive) _get_fd(display).
|
|
||||||
method(#class,#primitive) _get_event(display, event).
|
|
||||||
method(#class,#primitive) _create_window(display, window, x, y, width, height, fgcolor, bgcolor).
|
|
||||||
|
|
||||||
method(#primitive) _get_evtbuf.
|
var event_loop_sem, event_loop_proc.
|
||||||
|
var llevent_blocks.
|
||||||
|
|
||||||
|
method(#primitive,#liberal) _open_display(name).
|
||||||
|
method(#primitive) _close_display.
|
||||||
|
method(#primitive) _get_fd.
|
||||||
|
method(#primitive) _get_event.
|
||||||
|
|
||||||
|
method(#primitive) _create_window(parent_window, x, y, width, height, fgcolor, bgcolor).
|
||||||
|
method(#primitive) _destroy_window(window).
|
||||||
|
|
||||||
|
##method(#primitive) _fill_rectangle(window, gc, x, y, width, height).
|
||||||
|
method(#primitive) _draw_rectangle(window, gc, x, y, width, height).
|
||||||
|
|
||||||
|
method __create_window(parent_window, x, y, width, height, fgcolor, bgcolor, owner)
|
||||||
|
{
|
||||||
|
| w |
|
||||||
|
w := self _create_window(parent_window, x, y, width, height, fgcolor, bgcolor).
|
||||||
|
if (w notError) { self.window_registrar at: w put: owner }.
|
||||||
|
^w
|
||||||
|
}
|
||||||
|
|
||||||
|
method __close_window(window_handle)
|
||||||
|
{
|
||||||
|
| w |
|
||||||
|
w := self _destroy_window(window_handle).
|
||||||
|
if (w notError) { self.window_registrar removeKey: window_handle }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class X11.Exception(System.Exception)
|
class X11.Exception(System.Exception)
|
||||||
@ -50,7 +73,7 @@ class X11.Rectangle(Object)
|
|||||||
## ---------------------------------------------------------------------------
|
## ---------------------------------------------------------------------------
|
||||||
## Event
|
## Event
|
||||||
## ---------------------------------------------------------------------------
|
## ---------------------------------------------------------------------------
|
||||||
pooldic X11.LLEvent
|
pooldic X11.LLEventType
|
||||||
{
|
{
|
||||||
KEY_PRESS := 2.
|
KEY_PRESS := 2.
|
||||||
KEY_RELEASE := 3.
|
KEY_RELEASE := 3.
|
||||||
@ -66,6 +89,11 @@ pooldic X11.LLEvent
|
|||||||
CLIENT_MESSAGE := 33.
|
CLIENT_MESSAGE := 33.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class X11.LLEvent(Object)
|
||||||
|
{
|
||||||
|
var(#get) type := 0, window := 0, x := 0, y := 0, width := 0, height := 0.
|
||||||
|
}
|
||||||
|
|
||||||
class X11.Event(Object)
|
class X11.Event(Object)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -109,6 +137,45 @@ class X11.ExposeEvent(X11.Event)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## ---------------------------------------------------------------------------
|
||||||
|
## X11 Context
|
||||||
|
## ---------------------------------------------------------------------------
|
||||||
|
class X11.GraphicsContext(Object)
|
||||||
|
{
|
||||||
|
var(#get) widget := nil, gcHandle := nil.
|
||||||
|
|
||||||
|
var(#get,#set)
|
||||||
|
foreground := 0,
|
||||||
|
background := 0,
|
||||||
|
lineWidth := 1,
|
||||||
|
lineStyle := 0,
|
||||||
|
fillStyle := 0.
|
||||||
|
|
||||||
|
method(#class) new: widget
|
||||||
|
{
|
||||||
|
^(super new) __make_gc_on: widget
|
||||||
|
}
|
||||||
|
|
||||||
|
method __make_gc_on: widget
|
||||||
|
{
|
||||||
|
| gc |
|
||||||
|
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 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)
|
||||||
|
{
|
||||||
|
^self.widget displayServer _draw_rectangle (self.widget windowHandle, self.gcHandle, x, y, width, height).
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
## ---------------------------------------------------------------------------
|
## ---------------------------------------------------------------------------
|
||||||
## X11 Widgets
|
## X11 Widgets
|
||||||
## ---------------------------------------------------------------------------
|
## ---------------------------------------------------------------------------
|
||||||
@ -125,23 +192,41 @@ class X11.Widget(Object)
|
|||||||
bgcolor := 0,
|
bgcolor := 0,
|
||||||
realized := false.
|
realized := false.
|
||||||
|
|
||||||
method displayOn: grctx
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
method displayBase
|
method displayServer
|
||||||
{
|
{
|
||||||
if (self.parent isNil) { ^nil }.
|
if (self.parent isNil) { ^nil }.
|
||||||
^self.parent displayBase.
|
^self.parent displayServer.
|
||||||
|
}
|
||||||
|
|
||||||
|
method windowHandle
|
||||||
|
{
|
||||||
|
(* 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 paint: paint_event
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
method realize
|
method realize
|
||||||
{
|
{
|
||||||
|
## super realize chaining required???
|
||||||
}
|
}
|
||||||
|
|
||||||
method dispose
|
method dispose
|
||||||
{
|
{
|
||||||
}
|
## what should be done first? remvoe from container? should dispose be called?
|
||||||
|
## super dispose chaining required?
|
||||||
|
##if (self.parent notNil)
|
||||||
|
##{
|
||||||
|
## self.parent remove: self.
|
||||||
|
##}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class X11.Label(X11.Widget)
|
class X11.Label(X11.Widget)
|
||||||
@ -151,24 +236,28 @@ class X11.Label(X11.Widget)
|
|||||||
method text: text
|
method text: text
|
||||||
{
|
{
|
||||||
self.text := text.
|
self.text := text.
|
||||||
self displayOn: nil.
|
if (self windowHandle notNil) { self paint: nil }
|
||||||
}
|
}
|
||||||
|
|
||||||
method displayOn: grctx
|
method paint: paint_event
|
||||||
{
|
{
|
||||||
## grctx _fillRectangle ().
|
| gc |
|
||||||
## grctx _drawText (...).
|
System logNl: 'LABEL GC.......'.
|
||||||
## TODO Draw Text...
|
gc := selfns.GraphicsContext new: self.
|
||||||
|
gc foreground: 100.
|
||||||
|
gc drawRectangle (self.x, self.y, self.width, self.height).
|
||||||
|
###gc.drawText (self.title)
|
||||||
}
|
}
|
||||||
|
|
||||||
method realize
|
method realize
|
||||||
{
|
{
|
||||||
## if i want to use a window to represent it, it must create window here.
|
## if i want to use a window to represent it, it must create window here.
|
||||||
## otherwise, do other works in displayOn???
|
## otherwise, do other works in paint:???
|
||||||
}
|
}
|
||||||
|
|
||||||
method dispose
|
method dispose
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +286,7 @@ class X11.Composite(X11.Widget)
|
|||||||
| link |
|
| link |
|
||||||
if (widget parent =~ self)
|
if (widget parent =~ self)
|
||||||
{
|
{
|
||||||
selfns.Exception sinal: 'Cannot remove a foreign widget'
|
selfns.Exception sinal: 'Cannot remove an unknown widget'
|
||||||
}.
|
}.
|
||||||
|
|
||||||
## TODO: unmap and destroy...
|
## TODO: unmap and destroy...
|
||||||
@ -213,14 +302,15 @@ class X11.Composite(X11.Widget)
|
|||||||
|
|
||||||
method dispose
|
method dispose
|
||||||
{
|
{
|
||||||
self.children do: [:child | child dispose ]
|
self.children do: [:child | child dispose ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class X11.Shell(X11.Composite)
|
class X11.Shell(X11.Composite)
|
||||||
{
|
{
|
||||||
var(#get) title.
|
var(#get) title := ''.
|
||||||
var(#get,#set) displayBase.
|
var(#get,#set) displayServer := nil.
|
||||||
|
var(#get) windowHandle := nil.
|
||||||
|
|
||||||
method new: title
|
method new: title
|
||||||
{
|
{
|
||||||
@ -230,7 +320,7 @@ class X11.Shell(X11.Composite)
|
|||||||
method title: title
|
method title: title
|
||||||
{
|
{
|
||||||
self.title := title.
|
self.title := title.
|
||||||
if (self.realized)
|
if (self.windowHandle notNil)
|
||||||
{
|
{
|
||||||
## set window title of this window.
|
## set window title of this window.
|
||||||
}
|
}
|
||||||
@ -239,16 +329,36 @@ class X11.Shell(X11.Composite)
|
|||||||
method realize
|
method realize
|
||||||
{
|
{
|
||||||
| wind |
|
| wind |
|
||||||
if (self.realized) { ^self }.
|
if (self.windowHandle notNil) { ^self }.
|
||||||
|
|
||||||
wind := X11 _create_window(self.displayBase, nil, self.x, self.y, self.width, self.height, self.fgcolor, self.bgcolor).
|
wind := self.displayServer __create_window(nil, self.x, self.y, self.width, self.height, self.fgcolor, self.bgcolor, self).
|
||||||
if (wind isError)
|
if (wind isError)
|
||||||
{
|
{
|
||||||
self.Exception signal: ('Cannot create shell ' & self.title).
|
self.Exception signal: ('Cannot create shell ' & self.title).
|
||||||
}.
|
}.
|
||||||
|
|
||||||
self.children do: [:child | child realize ].
|
self.windowHandle := wind.
|
||||||
self.realized := true.
|
|
||||||
|
[
|
||||||
|
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 paint: nil.
|
||||||
|
}
|
||||||
|
|
||||||
|
method dispose
|
||||||
|
{
|
||||||
|
super dispose.
|
||||||
|
if (self.windowHandle notNil)
|
||||||
|
{
|
||||||
|
self.displayServer _destroy_window (self.windowHandle).
|
||||||
|
self.windowHandle := nil.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,20 +374,16 @@ extend X11
|
|||||||
|
|
||||||
method __connect_to: name
|
method __connect_to: name
|
||||||
{
|
{
|
||||||
| base |
|
if (self _open_display(name) isError)
|
||||||
base := X11 _open_display(name).
|
{
|
||||||
if (base isError) { self.Exception signal: 'cannot open display' }.
|
self.Exception signal: 'cannot open display'
|
||||||
self.display_base := base.
|
}
|
||||||
|
.
|
||||||
|
self.display_base dump.
|
||||||
}
|
}
|
||||||
|
|
||||||
method dispose
|
method dispose
|
||||||
{
|
{
|
||||||
if (self.display_event notNil)
|
|
||||||
{
|
|
||||||
X11 _free_event.
|
|
||||||
self.display_event := nil.
|
|
||||||
}.
|
|
||||||
|
|
||||||
if (self.shell_container notNil)
|
if (self.shell_container notNil)
|
||||||
{
|
{
|
||||||
self.shell_container dispose.
|
self.shell_container dispose.
|
||||||
@ -286,101 +392,95 @@ extend X11
|
|||||||
|
|
||||||
if (self.display_base notNil)
|
if (self.display_base notNil)
|
||||||
{
|
{
|
||||||
|
self _close_display.
|
||||||
|
##self.display_base := nil.
|
||||||
|
}.
|
||||||
|
|
||||||
X11 _close_display (self.display_base).
|
## TODO: check if _fini_trailer is not called for some exception throwing...
|
||||||
self.display_base := nil.
|
##self _fini_trailer.
|
||||||
}l
|
|
||||||
}
|
}
|
||||||
|
|
||||||
method initialize
|
method initialize
|
||||||
{
|
{
|
||||||
super initialize.
|
super initialize.
|
||||||
|
|
||||||
self.shell_container := self.Composite new.
|
self.llevent := self.LLEvent new.
|
||||||
self.display_event := self _alloc_event.
|
|
||||||
|
|
||||||
self.windows := System.Dictionary new: 100.
|
|
||||||
|
|
||||||
self.expose_event := self.ExposeEvent new.
|
self.expose_event := self.ExposeEvent new.
|
||||||
self.key_event := self.KeyEvent new.
|
self.key_event := self.KeyEvent new.
|
||||||
self.mouse_event := self.MouseEvent new.
|
self.mouse_event := self.MouseEvent new.
|
||||||
self.mouse_wheel_event := self.MouseWheelEvent new.
|
self.mouse_wheel_event := self.MouseWheelEvent new.
|
||||||
|
|
||||||
|
self.shell_container := self.Composite new.
|
||||||
|
self.window_registrar := System.Dictionary new: 100.
|
||||||
|
|
||||||
(*
|
(*
|
||||||
self.ll_event_blocks := System.Dictionary new.
|
|
||||||
self.ll_event_blocks
|
self.llevent_blocks := System.Dictionary new.
|
||||||
at: self.LLEvent.KEY_PRESS put: #__handle_key_event:;
|
self.llevent_blocks
|
||||||
at: self.LLEvent.KEY_RELEASE put: #__handle_key_event:;
|
at: self.LLEventType.KEY_PRESS put: #__handle_key_event:;
|
||||||
at: self.LLEvent.BUTTON_PRESS put: #__handle_button_event:;
|
at: self.LLEventType.KEY_RELEASE put: #__handle_key_event:;
|
||||||
at: self.LLEvent.BUTTON_RELEASE put: #__handle_button_event:;
|
at: self.LLEventType.BUTTON_PRESS put: #__handle_button_event:;
|
||||||
at: self.LLEvent.MOTION_NOTIFY put: #__handle_notify:;
|
at: self.LLEventType.BUTTON_RELEASE put: #__handle_button_event:;
|
||||||
at: self.LLEvent.ENTER_NOTIFY put: #__handle_notify:;
|
at: self.LLEventType.MOTION_NOTIFY put: #__handle_notify:;
|
||||||
at: self.LLEvent.LEAVE_NOTIFY put: #__handle_notify:;
|
at: self.LLEventType.ENTER_NOTIFY put: #__handle_notify:;
|
||||||
at: self.LLEvent.EXPOSE put: #__handle_expose:;
|
at: self.LLEventType.LEAVE_NOTIFY put: #__handle_notify:;
|
||||||
at: self.LLEvent.DESTROY_NOTIFY put: #__handle_destroy_notify:;
|
at: self.LLEventType.EXPOSE put: #__handle_expose:;
|
||||||
at: self.LLEvent.CONFIGURE_NOTIFY put: #__handle_configure_notify:;
|
at: self.LLEventType.DESTROY_NOTIFY put: #__handle_destroy_notify:;
|
||||||
at: self.LLEvent.CLIENT_MESSAGE put: #__handle_client_message:.
|
at: self.LLEventType.CONFIGURE_NOTIFY put: #__handle_configure_notify:;
|
||||||
|
at: self.LLEventType.CLIENT_MESSAGE put: #__handle_client_message:.
|
||||||
*)
|
*)
|
||||||
self.ll_event_blocks := %{
|
self.llevent_blocks := %{
|
||||||
self.LLEvent.KEY_PRESS -> #__handle_key_event:,
|
self.LLEventType.KEY_PRESS -> #__handle_key_event:,
|
||||||
self.LLEvent.KEY_RELEASE -> #__handle_key_event:,
|
self.LLEventType.KEY_RELEASE -> #__handle_key_event:,
|
||||||
self.LLEvent.BUTTON_PRESS -> #__handle_button_event:,
|
self.LLEventType.BUTTON_PRESS -> #__handle_button_event:,
|
||||||
self.LLEvent.BUTTON_RELEASE -> #__handle_button_event:,
|
self.LLEventType.BUTTON_RELEASE -> #__handle_button_event:,
|
||||||
self.LLEvent.MOTION_NOTIFY -> #__handle_notify:,
|
self.LLEventType.MOTION_NOTIFY -> #__handle_notify:,
|
||||||
self.LLEvent.ENTER_NOTIFY -> #__handle_notify:,
|
self.LLEventType.ENTER_NOTIFY -> #__handle_notify:,
|
||||||
self.LLEvent.LEAVE_NOTIFY -> #__handle_notify:,
|
self.LLEventType.LEAVE_NOTIFY -> #__handle_notify:,
|
||||||
self.LLEvent.EXPOSE -> #__handle_expose:,
|
self.LLEventType.EXPOSE -> #__handle_expose:,
|
||||||
self.LLEvent.DESTROY_NOTIFY -> #__handle_destroy_notify:,
|
self.LLEventType.DESTROY_NOTIFY -> #__handle_destroy_notify:,
|
||||||
self.LLEvent.CONFIGURE_NOTIFY -> #__handle_configure_notify:,
|
self.LLEventType.CONFIGURE_NOTIFY -> #__handle_configure_notify:,
|
||||||
self.LLEvent.CLIENT_MESSAGE -> #__handle_client_message:
|
self.LLEventType.CLIENT_MESSAGE -> #__handle_client_message:
|
||||||
}.
|
}.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
method addShell: shell
|
method addShell: shell
|
||||||
{
|
{
|
||||||
if (shell displayBase isNil)
|
if (shell displayServer isNil)
|
||||||
{
|
{
|
||||||
self.shell_container add: shell.
|
self.shell_container add: shell.
|
||||||
shell displayBase: self.display_base.
|
shell displayServer: self.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
method removeShell: shell
|
method removeShell: shell
|
||||||
{
|
{
|
||||||
if (shell displayBase notNil)
|
if (shell displayServer notNil)
|
||||||
{
|
{
|
||||||
self.shell_container remove: shell.
|
self.shell_container remove: shell.
|
||||||
shell displayBase: nil.
|
shell displayServer: nil.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
method registerWindow: window
|
|
||||||
{
|
|
||||||
^self.windows at: (window windowBase) put: window.
|
|
||||||
}
|
|
||||||
|
|
||||||
method removeWindow: window
|
|
||||||
{
|
|
||||||
^self.windows removeKey: (window windowBase)
|
|
||||||
}
|
|
||||||
|
|
||||||
method enterEventLoop
|
method enterEventLoop
|
||||||
{
|
{
|
||||||
if (self.event_loop_sem isNil)
|
if (self.event_loop_sem isNil)
|
||||||
{
|
{
|
||||||
self.event_loop_sem := Semaphore new.
|
self.event_loop_sem := Semaphore new.
|
||||||
Processor signal: self.event_loop_sem onInput: (X11 _get_fd(self.display_base)).
|
Processor signal: self.event_loop_sem onInput: (self _get_fd).
|
||||||
self.event_loop_proc := [
|
self.event_loop_proc := [
|
||||||
| event ongoing |
|
| evtbuf event ongoing |
|
||||||
|
|
||||||
ongoing := true.
|
ongoing := true.
|
||||||
while (self.shell_container childrenCount > 0)
|
while (self.shell_container childrenCount > 0)
|
||||||
{
|
{
|
||||||
###'Waiting for X11 event...' dump.
|
'Waiting for X11 event...' dump.
|
||||||
self.event_loop_sem wait.
|
self.event_loop_sem wait.
|
||||||
if (ongoing not) { break }.
|
if (ongoing not) { break }.
|
||||||
|
|
||||||
while (self _get_event(self.display_base, self.display_event))
|
while ((event := self _get_event) notNil)
|
||||||
{
|
{
|
||||||
if (event isError)
|
if (event isError)
|
||||||
{
|
{
|
||||||
@ -421,15 +521,16 @@ extend X11
|
|||||||
|
|
||||||
method __dispatch_event: event
|
method __dispatch_event: event
|
||||||
{
|
{
|
||||||
|
(*
|
||||||
| type mthname |
|
| type mthname |
|
||||||
|
|
||||||
|
|
||||||
##type := System _getUint8(event, 0).
|
##type := System _getUint8(event, 0).
|
||||||
type := event getUint8(0).
|
type := event getUint8(0).
|
||||||
|
|
||||||
mthname := self.ll_event_blocks at: (type bitAnd: 16r7F).
|
mthname := self.llevent_blocks at: (type bitAnd: 16r7F).
|
||||||
if (mthname isError)
|
if (mthname isError)
|
||||||
{
|
{
|
||||||
(* unknown event. ignore it *)
|
|
||||||
('IGNORING UNKNOWN LL-EVENT TYPE ' & type asString) dump.
|
('IGNORING UNKNOWN LL-EVENT TYPE ' & type asString) dump.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -437,6 +538,7 @@ extend X11
|
|||||||
^self perform (mthname, event).
|
^self perform (mthname, event).
|
||||||
##^self perform: mthname with: event.
|
##^self perform: mthname with: event.
|
||||||
}
|
}
|
||||||
|
*)
|
||||||
}
|
}
|
||||||
|
|
||||||
method __handle_notify: type
|
method __handle_notify: type
|
||||||
|
@ -166,28 +166,30 @@ typedef struct xtn_t xtn_t;
|
|||||||
struct xtn_t
|
struct xtn_t
|
||||||
{
|
{
|
||||||
const char* source_path; /* main source file */
|
const char* source_path; /* main source file */
|
||||||
|
int vm_running;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
HANDLE waitable_timer;
|
HANDLE waitable_timer;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if defined(USE_DEVPOLL) || defined(USE_EPOLL)
|
#if defined(USE_DEVPOLL) || defined(USE_EPOLL)
|
||||||
int ep; /* /dev/poll or epoll */
|
int ep; /* /dev/poll or epoll */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_DEVPOLL) || defined(USE_POLL)
|
#if defined(USE_DEVPOLL) || defined(USE_POLL)
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
moo_oow_t capa;
|
moo_oow_t capa;
|
||||||
moo_ooi_t* ptr;
|
moo_ooi_t* ptr;
|
||||||
} epd;
|
} epd;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_THREAD)
|
#if defined(USE_THREAD)
|
||||||
int p[2]; /* pipe for signaling */
|
int p[2]; /* pipe for signaling */
|
||||||
pthread_t iothr;
|
pthread_t iothr;
|
||||||
int iothr_up;
|
int iothr_up;
|
||||||
int iothr_abort;
|
int iothr_abort;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -210,14 +212,12 @@ struct xtn_t
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
moo_oow_t len;
|
moo_oow_t len;
|
||||||
#if defined(USE_THREAD)
|
#if defined(USE_THREAD)
|
||||||
pthread_mutex_t mtx;
|
pthread_mutex_t mtx;
|
||||||
pthread_cond_t cnd;
|
pthread_cond_t cnd;
|
||||||
pthread_cond_t cnd2;
|
pthread_cond_t cnd2;
|
||||||
#endif
|
#endif
|
||||||
} ev;
|
} ev;
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -749,7 +749,6 @@ static void log_write (moo_t* moo, moo_oow_t mask, const moo_ooch_t* msg, moo_oo
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
#if defined(USE_DEVPOLL) || defined(USE_POLL)
|
#if defined(USE_DEVPOLL) || defined(USE_POLL)
|
||||||
static int secure_poll_data_space (moo_t* moo, int fd)
|
static int secure_poll_data_space (moo_t* moo, int fd)
|
||||||
@ -1005,7 +1004,8 @@ static void* iothr_main (void* arg)
|
|||||||
if (n <= -1)
|
if (n <= -1)
|
||||||
{
|
{
|
||||||
/* TODO: don't use MOO_DEBUG2. it's not thread safe... */
|
/* TODO: don't use MOO_DEBUG2. it's not thread safe... */
|
||||||
MOO_DEBUG2 (moo, "Warning: epoll_wait failure - %d, %hs\n", errno, strerror(errno));
|
/* the following call has a race-condition issue when called in this separate thread */
|
||||||
|
/*MOO_DEBUG2 (moo, "Warning: epoll_wait failure - %d, %hs\n", errno, strerror(errno));*/
|
||||||
}
|
}
|
||||||
else if (n > 0)
|
else if (n > 0)
|
||||||
{
|
{
|
||||||
@ -1094,18 +1094,19 @@ static int vm_startup (moo_t* moo)
|
|||||||
}
|
}
|
||||||
pcount = 2;
|
pcount = 2;
|
||||||
|
|
||||||
#if defined(O_CLOEXEC)
|
#if defined(O_CLOEXEC)
|
||||||
flag = fcntl (xtn->p[0], F_GETFD);
|
flag = fcntl (xtn->p[0], F_GETFD);
|
||||||
if (flag >= 0) fcntl (xtn->p[0], F_SETFD, flag | FD_CLOEXEC);
|
if (flag >= 0) fcntl (xtn->p[0], F_SETFD, flag | FD_CLOEXEC);
|
||||||
flag = fcntl (xtn->p[1], F_GETFD);
|
flag = fcntl (xtn->p[1], F_GETFD);
|
||||||
if (flag >= 0) fcntl (xtn->p[1], F_SETFD, flag | FD_CLOEXEC);
|
if (flag >= 0) fcntl (xtn->p[1], F_SETFD, flag | FD_CLOEXEC);
|
||||||
#endif
|
#endif
|
||||||
#if defined(O_NONBLOCK)
|
|
||||||
|
#if defined(O_NONBLOCK)
|
||||||
flag = fcntl (xtn->p[0], F_GETFL);
|
flag = fcntl (xtn->p[0], F_GETFL);
|
||||||
if (flag >= 0) fcntl (xtn->p[0], F_SETFL, flag | O_NONBLOCK);
|
if (flag >= 0) fcntl (xtn->p[0], F_SETFL, flag | O_NONBLOCK);
|
||||||
flag = fcntl (xtn->p[1], F_GETFL);
|
flag = fcntl (xtn->p[1], F_GETFL);
|
||||||
if (flag >= 0) fcntl (xtn->p[1], F_SETFL, flag | O_NONBLOCK);
|
if (flag >= 0) fcntl (xtn->p[1], F_SETFL, flag | O_NONBLOCK);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (_add_poll_fd (moo, xtn->p[0], XPOLLIN, MOO_TYPE_MAX(moo_oow_t)) <= -1) goto oops;
|
if (_add_poll_fd (moo, xtn->p[0], XPOLLIN, MOO_TYPE_MAX(moo_oow_t)) <= -1) goto oops;
|
||||||
|
|
||||||
@ -1116,8 +1117,11 @@ static int vm_startup (moo_t* moo)
|
|||||||
xtn->iothr_abort = 0;
|
xtn->iothr_abort = 0;
|
||||||
xtn->iothr_up = 0;
|
xtn->iothr_up = 0;
|
||||||
/*pthread_create (&xtn->iothr, MOO_NULL, iothr_main, moo);*/
|
/*pthread_create (&xtn->iothr, MOO_NULL, iothr_main, moo);*/
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* USE_THREAD */
|
||||||
|
|
||||||
|
xtn->vm_running = 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
@ -1155,6 +1159,7 @@ static void vm_cleanup (moo_t* moo)
|
|||||||
#else
|
#else
|
||||||
xtn_t* xtn = (xtn_t*)moo_getxtn(moo);
|
xtn_t* xtn = (xtn_t*)moo_getxtn(moo);
|
||||||
|
|
||||||
|
xtn->vm_running = 0;
|
||||||
|
|
||||||
#if defined(USE_THREAD)
|
#if defined(USE_THREAD)
|
||||||
if (xtn->iothr_up)
|
if (xtn->iothr_up)
|
||||||
@ -1690,7 +1695,7 @@ static void handle_term (int sig)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_term (void)
|
static void setup_sigterm (void)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
SetConsoleCtrlHandler (handle_term, TRUE);
|
SetConsoleCtrlHandler (handle_term, TRUE);
|
||||||
@ -1707,7 +1712,7 @@ static void setup_term (void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_term (void)
|
static void clear_sigterm (void)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
SetConsoleCtrlHandler (handle_term, FALSE);
|
SetConsoleCtrlHandler (handle_term, FALSE);
|
||||||
@ -1778,8 +1783,6 @@ int main (int argc, char* argv[])
|
|||||||
moo_setoption (moo, MOO_SYSDIC_SIZE, &tab_size);
|
moo_setoption (moo, MOO_SYSDIC_SIZE, &tab_size);
|
||||||
tab_size = 600;
|
tab_size = 600;
|
||||||
moo_setoption (moo, MOO_PROCSTK_SIZE, &tab_size);
|
moo_setoption (moo, MOO_PROCSTK_SIZE, &tab_size);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1796,7 +1799,7 @@ int main (int argc, char* argv[])
|
|||||||
|
|
||||||
if (moo_ignite(moo) <= -1)
|
if (moo_ignite(moo) <= -1)
|
||||||
{
|
{
|
||||||
moo_logbfmt (moo, MOO_LOG_ERROR, "cannot ignite moo - [%d] %js\n", moo_geterrnum(moo), moo_geterrstr(moo));
|
moo_logbfmt (moo, MOO_LOG_ERROR, "ERROR: cannot ignite moo - [%d] %js\n", moo_geterrnum(moo), moo_geterrstr(moo));
|
||||||
moo_close (moo);
|
moo_close (moo);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1872,6 +1875,7 @@ int main (int argc, char* argv[])
|
|||||||
|
|
||||||
}
|
}
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
|
fflush (stdout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1889,7 +1893,7 @@ int main (int argc, char* argv[])
|
|||||||
xret = 0;
|
xret = 0;
|
||||||
g_moo = moo;
|
g_moo = moo;
|
||||||
setup_tick ();
|
setup_tick ();
|
||||||
setup_term ();
|
setup_sigterm ();
|
||||||
|
|
||||||
objname.ptr = str_my_object;
|
objname.ptr = str_my_object;
|
||||||
objname.len = 8;
|
objname.len = 8;
|
||||||
@ -1902,7 +1906,7 @@ int main (int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
cancel_tick ();
|
cancel_tick ();
|
||||||
clear_term ();
|
clear_sigterm ();
|
||||||
g_moo = MOO_NULL;
|
g_moo = MOO_NULL;
|
||||||
|
|
||||||
/*moo_dumpsymtab(moo);
|
/*moo_dumpsymtab(moo);
|
||||||
|
@ -45,19 +45,38 @@ struct x11_win_t
|
|||||||
Window wind;
|
Window wind;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct x11_llevent_t* oop_x11_llevent_t;
|
||||||
|
struct x11_llevent_t
|
||||||
|
{
|
||||||
|
MOO_OBJ_HEADER;
|
||||||
|
moo_oop_t type;
|
||||||
|
moo_oop_t window;
|
||||||
|
moo_oop_t x, y, width, height;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct x11_t* oop_x11_t;
|
typedef struct x11_t* oop_x11_t;
|
||||||
struct x11_t
|
struct x11_t
|
||||||
{
|
{
|
||||||
Display* disp;
|
MOO_OBJ_HEADER;
|
||||||
|
|
||||||
|
moo_oop_t display; /* SMPTR of Display */
|
||||||
|
oop_x11_llevent_t llevent;
|
||||||
|
moo_oop_t key_event;
|
||||||
|
moo_oop_t mouse_event;
|
||||||
|
|
||||||
|
/* in fact, there are more fields */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct x11_trailer_t x11_trailer_t;
|
typedef struct x11_trailer_t x11_trailer_t;
|
||||||
struct x11_trailer_t
|
struct x11_trailer_t
|
||||||
{
|
{
|
||||||
XEvent* curevt;
|
XEvent* event;
|
||||||
|
moo_ooi_t connection_number;
|
||||||
|
Atom wm_delete_window;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
402
moo/mod/x11.c
402
moo/mod/x11.c
@ -38,37 +38,17 @@ struct x11_modctx_t
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
#if 0
|
|
||||||
static moo_pfrc_t pf_get_base (moo_t* moo, moo_ooi_t nargs)
|
|
||||||
{
|
|
||||||
x11_trailer_t* x11;
|
|
||||||
|
|
||||||
x11 = (x11_trailer_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
|
|
||||||
|
|
||||||
if (x11->disp)
|
|
||||||
{
|
|
||||||
MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP (x11->disp));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ENOAVAIL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return MOO_PF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
static moo_pfrc_t pf_open_display (moo_t* moo, moo_ooi_t nargs)
|
static moo_pfrc_t pf_open_display (moo_t* moo, moo_ooi_t nargs)
|
||||||
{
|
{
|
||||||
x11_trailer_t* x11;
|
oop_x11_t x11;
|
||||||
|
x11_trailer_t* tr;
|
||||||
|
|
||||||
Display* disp = MOO_NULL;
|
Display* disp = MOO_NULL;
|
||||||
XEvent* curevt = MOO_NULL;
|
XEvent* event = MOO_NULL;
|
||||||
char* dispname = MOO_NULL;
|
char* dispname = MOO_NULL;
|
||||||
|
moo_ooi_t connno;
|
||||||
|
|
||||||
|
// TODO: CHECK if the receiver is an X11 object
|
||||||
|
|
||||||
if (nargs >= 1)
|
if (nargs >= 1)
|
||||||
{
|
{
|
||||||
@ -96,8 +76,8 @@ static moo_pfrc_t pf_open_display (moo_t* moo, moo_ooi_t nargs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
curevt = moo_allocmem (moo, MOO_SIZEOF(*x11->curevt));
|
event = moo_allocmem (moo, MOO_SIZEOF(*event));
|
||||||
if (!curevt)
|
if (!event)
|
||||||
{
|
{
|
||||||
MOO_STACK_SETRETTOERRNUM (moo, nargs);
|
MOO_STACK_SETRETTOERRNUM (moo, nargs);
|
||||||
goto oops;
|
goto oops;
|
||||||
@ -106,149 +86,173 @@ static moo_pfrc_t pf_open_display (moo_t* moo, moo_ooi_t nargs)
|
|||||||
disp = XOpenDisplay(dispname);
|
disp = XOpenDisplay(dispname);
|
||||||
if (!disp)
|
if (!disp)
|
||||||
{
|
{
|
||||||
MOO_DEBUG1 (moo, "<x11.connect> Cannot connect to X11 server %hs\n", XDisplayName(dispname));
|
MOO_DEBUG1 (moo, "<x11.open_display> Cannot connect to X11 server %hs\n", XDisplayName(dispname));
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ESYSERR);
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ESYSERR);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOO_ASSERT (moo, MOO_IN_SMPTR_RANGE(disp));
|
if (!MOO_IN_SMPTR_RANGE(disp))
|
||||||
|
{
|
||||||
|
MOO_DEBUG1 (moo, "<x11.open_display> Display pointer to %hs not in small pointer range\n", XDisplayName(dispname));
|
||||||
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ERANGE);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
connno = ConnectionNumber(disp);
|
||||||
|
if (!MOO_IN_SMOOI_RANGE(connno))
|
||||||
|
{
|
||||||
|
MOO_DEBUG1 (moo, "<x11.open_display> Connection number to %hs out of small integer range\n", XDisplayName(dispname));
|
||||||
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ERANGE);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
||||||
|
|
||||||
|
tr = (x11_trailer_t*)moo_getobjtrailer (moo, (moo_oop_t)x11, MOO_NULL);
|
||||||
|
tr->event = event;
|
||||||
|
tr->connection_number = connno;
|
||||||
|
tr->wm_delete_window = XInternAtom (disp, "WM_DELETE_WINDOW", False);
|
||||||
|
|
||||||
|
MOO_ASSERT (moo, MOO_IN_SMPTR_RANGE(disp));
|
||||||
|
x11->display = MOO_SMPTR_TO_OOP(disp);
|
||||||
|
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||||
|
|
||||||
MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP(disp));
|
|
||||||
if (dispname) moo_freemem (moo, dispname);
|
if (dispname) moo_freemem (moo, dispname);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
if (disp) XCloseDisplay (disp);
|
if (disp) XCloseDisplay (disp);
|
||||||
if (curevt) moo_freemem (moo, curevt);
|
if (event) moo_freemem (moo, event);
|
||||||
if (dispname) moo_freemem (moo, dispname);
|
if (dispname) moo_freemem (moo, dispname);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static moo_pfrc_t pf_close_display (moo_t* moo, moo_ooi_t nargs)
|
static moo_pfrc_t pf_close_display (moo_t* moo, moo_ooi_t nargs)
|
||||||
{
|
{
|
||||||
moo_oop_t a0;
|
oop_x11_t x11;
|
||||||
|
|
||||||
a0 = MOO_STACK_GETARG(moo, nargs, 0);
|
// TODO: CHECK if the receiver is an X11 object
|
||||||
|
|
||||||
if (!MOO_OOP_IS_SMPTR(a0))
|
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
||||||
|
if (x11->display != moo->_nil)
|
||||||
{
|
{
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
MOO_ASSERT (moo, MOO_OOP_IS_SMPTR(x11->display));
|
||||||
}
|
XCloseDisplay (MOO_OOP_TO_SMPTR(x11->display));
|
||||||
else
|
x11->display = moo->_nil;
|
||||||
{
|
|
||||||
XCloseDisplay (MOO_OOP_TO_SMPTR(a0));
|
|
||||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static moo_pfrc_t pf_get_fd (moo_t* moo, moo_ooi_t nargs)
|
static moo_pfrc_t pf_get_fd (moo_t* moo, moo_ooi_t nargs)
|
||||||
{
|
{
|
||||||
moo_oop_t a0;
|
x11_trailer_t* tr;
|
||||||
|
// TODO: CHECK if the receiver is an X11 object
|
||||||
a0 = MOO_STACK_GETARG(moo, nargs, 0);
|
tr = moo_getobjtrailer (moo, MOO_STACK_GETRCV(moo,nargs), MOO_NULL);
|
||||||
|
MOO_STACK_SETRET(moo, nargs, MOO_SMOOI_TO_OOP(tr->connection_number));
|
||||||
if (!MOO_OOP_IS_SMPTR(a0))
|
|
||||||
{
|
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
moo_ooi_t c;
|
|
||||||
c = ConnectionNumber(MOO_OOP_TO_SMPTR(a0));
|
|
||||||
|
|
||||||
if (!MOO_IN_SMOOI_RANGE(c))
|
|
||||||
{
|
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ERANGE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(c));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static moo_pfrc_t pf_get_event (moo_t* moo, moo_ooi_t nargs)
|
static moo_pfrc_t pf_get_event (moo_t* moo, moo_ooi_t nargs)
|
||||||
{
|
{
|
||||||
|
oop_x11_t x11;
|
||||||
|
x11_trailer_t* tr;
|
||||||
|
|
||||||
moo_oop_t a0, a1;
|
Display* disp;
|
||||||
|
XEvent* event;
|
||||||
|
|
||||||
a0 = MOO_STACK_GETARG(moo, nargs, 0); /* display - SmallPointer (Display*) */
|
// TODO: CHECK if the receiver is an X11 object
|
||||||
a1 = MOO_STACK_GETARG(moo, nargs, 1); /* event to return - SmallPointer (XEvent*) */
|
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
||||||
|
//MOO_ASSERT (moo, MOO_CLASSOF(moo,x11) == modctx->x11_class);
|
||||||
|
tr = moo_getobjtrailer (moo, (moo_oop_t)x11, MOO_NULL);
|
||||||
|
|
||||||
|
disp = MOO_OOP_TO_SMPTR(x11->display);
|
||||||
if (!MOO_OOP_IS_SMPTR(a0) || !MOO_OOP_IS_SMPTR(a1))
|
event = tr->event;
|
||||||
|
if (XPending(disp))
|
||||||
{
|
{
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
oop_x11_llevent_t e;
|
||||||
|
|
||||||
|
XNextEvent (disp, event);
|
||||||
|
|
||||||
|
e = x11->llevent;
|
||||||
|
e->type = MOO_SMOOI_TO_OOP(event->type);
|
||||||
|
e->window = MOO_SMOOI_TO_OOP(0);
|
||||||
|
|
||||||
|
/* [NOTE] When creating the low-level event object, ensure not to
|
||||||
|
* trigger GC directly or indirectly as the GC might be a
|
||||||
|
* copying collector which move objects around during collection */
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case ClientMessage:
|
||||||
|
if (event->xclient.data.l[0] == tr->wm_delete_window)
|
||||||
|
{
|
||||||
|
e->window = MOO_SMOOI_TO_OOP(event->xclient.window);
|
||||||
|
/* WINDOW CLSOE EVENT */
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Expose:
|
||||||
|
{
|
||||||
|
e->window = MOO_SMOOI_TO_OOP(event->xexpose.window);
|
||||||
|
e->x = MOO_SMOOI_TO_OOP(event->xexpose.x);
|
||||||
|
e->y = MOO_SMOOI_TO_OOP(event->xexpose.y);
|
||||||
|
e->width = MOO_SMOOI_TO_OOP(event->xexpose.width);
|
||||||
|
e->height = MOO_SMOOI_TO_OOP(event->xexpose.height);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MOO_STACK_SETRET (moo, nargs, (moo_oop_t)e);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Display* disp;
|
/* nil if there is no event */
|
||||||
XEvent* event;
|
MOO_STACK_SETRET (moo, nargs, moo->_nil);
|
||||||
|
|
||||||
disp = MOO_OOP_TO_SMPTR(a0);
|
|
||||||
event = MOO_OOP_TO_SMPTR(a1);
|
|
||||||
if (XPending(disp))
|
|
||||||
{
|
|
||||||
XNextEvent (disp, event);
|
|
||||||
MOO_STACK_SETRET (moo, nargs, moo->_true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* nil if there is no event */
|
|
||||||
MOO_STACK_SETRET (moo, nargs, moo->_false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static moo_pfrc_t pf_get_evtbuf (moo_t* moo, moo_ooi_t nargs)
|
|
||||||
{
|
|
||||||
x11_trailer_t* tr;
|
|
||||||
|
|
||||||
tr = moo_getobjtrailer (moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
|
|
||||||
|
|
||||||
|
|
||||||
return MOO_PF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static moo_pfrc_t pf_create_window (moo_t* moo, moo_ooi_t nargs)
|
static moo_pfrc_t pf_create_window (moo_t* moo, moo_ooi_t nargs)
|
||||||
{
|
{
|
||||||
Window wind; /* Window -> XID, unsigned long */
|
|
||||||
|
|
||||||
Display* disp;
|
Display* disp;
|
||||||
|
Window wind; /* Window -> XID, unsigned long */
|
||||||
int scrn;
|
int scrn;
|
||||||
Window parent;
|
Window parent;
|
||||||
XSetWindowAttributes attrs;
|
XSetWindowAttributes attrs;
|
||||||
|
|
||||||
moo_oop_t a0, a1, a2, a3, a4, a5, a6, a7;
|
oop_x11_t x11;
|
||||||
|
x11_trailer_t* tr;
|
||||||
|
moo_oop_t a0, a1, a2, a3, a4, a5, a6;
|
||||||
|
|
||||||
a0 = MOO_STACK_GETARG(moo, nargs, 0); /* display - SmallPointer (Display*) */
|
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
||||||
a1 = MOO_STACK_GETARG(moo, nargs, 1); /* parent window - Integer or nil (Window) */
|
|
||||||
a2 = MOO_STACK_GETARG(moo, nargs, 2); /* x - SmallInteger */
|
|
||||||
a3 = MOO_STACK_GETARG(moo, nargs, 3); /* y - SmallInteger */
|
|
||||||
a4 = MOO_STACK_GETARG(moo, nargs, 4); /* width - SmallInteger */
|
|
||||||
a5 = MOO_STACK_GETARG(moo, nargs, 5); /* height - SmallInteger */
|
|
||||||
a6 = MOO_STACK_GETARG(moo, nargs, 6); /* fgcolor - SmallInteger */
|
|
||||||
a7 = MOO_STACK_GETARG(moo, nargs, 7); /* bgcolor - SmallInteger */
|
|
||||||
|
|
||||||
if (!MOO_OOP_IS_SMPTR(a0) ||
|
a0 = MOO_STACK_GETARG(moo, nargs, 0); /* parent window - Integer or nil (Window) */
|
||||||
!MOO_OOP_IS_SMOOI(a2) || !MOO_OOP_IS_SMOOI(a3) || !MOO_OOP_IS_SMOOI(a4) ||
|
a1 = MOO_STACK_GETARG(moo, nargs, 1); /* x - SmallInteger */
|
||||||
!MOO_OOP_IS_SMOOI(a5) || !MOO_OOP_IS_SMOOI(a6) || !MOO_OOP_IS_SMOOI(a7))
|
a2 = MOO_STACK_GETARG(moo, nargs, 2); /* y - SmallInteger */
|
||||||
|
a3 = MOO_STACK_GETARG(moo, nargs, 3); /* width - SmallInteger */
|
||||||
|
a4 = MOO_STACK_GETARG(moo, nargs, 4); /* height - SmallInteger */
|
||||||
|
a5 = MOO_STACK_GETARG(moo, nargs, 5); /* fgcolor - SmallInteger */
|
||||||
|
a6 = MOO_STACK_GETARG(moo, nargs, 6); /* bgcolor - SmallInteger */
|
||||||
|
|
||||||
|
if (!MOO_OOP_IS_SMOOI(a1) || !MOO_OOP_IS_SMOOI(a2) || !MOO_OOP_IS_SMOOI(a3) ||
|
||||||
|
!MOO_OOP_IS_SMOOI(a4) || !MOO_OOP_IS_SMOOI(a5) || !MOO_OOP_IS_SMOOI(a6))
|
||||||
{
|
{
|
||||||
einval:
|
einval:
|
||||||
|
MOO_DEBUG0 (moo, "<x11.create_window> Invalid parameters\n");
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
disp = MOO_OOP_TO_SMPTR(a0);
|
tr = moo_getobjtrailer (moo, (moo_oop_t)x11, MOO_NULL);
|
||||||
|
disp = MOO_OOP_TO_SMPTR(x11->display);
|
||||||
|
|
||||||
if (a1 == moo->_nil)
|
/* ScreenCount (disp); -> the number of screens available in this display server */
|
||||||
|
|
||||||
|
if (a0 == moo->_nil)
|
||||||
{
|
{
|
||||||
scrn = DefaultScreen (disp);
|
scrn = DefaultScreen (disp);
|
||||||
parent = RootWindow (disp, scrn);
|
parent = RootWindow (disp, scrn);
|
||||||
@ -257,7 +261,7 @@ static moo_pfrc_t pf_create_window (moo_t* moo, moo_ooi_t nargs)
|
|||||||
{
|
{
|
||||||
moo_oow_t tmpoow;
|
moo_oow_t tmpoow;
|
||||||
XWindowAttributes wa;
|
XWindowAttributes wa;
|
||||||
if (moo_inttooow(moo, a1, &tmpoow) <= 0) goto einval;
|
if (moo_inttooow(moo, a0, &tmpoow) <= 0) goto einval;
|
||||||
|
|
||||||
parent = tmpoow;
|
parent = tmpoow;
|
||||||
XGetWindowAttributes (disp, parent, &wa);
|
XGetWindowAttributes (disp, parent, &wa);
|
||||||
@ -265,18 +269,18 @@ static moo_pfrc_t pf_create_window (moo_t* moo, moo_ooi_t nargs)
|
|||||||
scrn = XScreenNumberOfScreen(wa.screen);
|
scrn = XScreenNumberOfScreen(wa.screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
attrs.event_mask = ExposureMask; /* TODO: accept it as a parameter??? */
|
attrs.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask; /* TODO: accept it as a parameter??? */
|
||||||
attrs.border_pixel = BlackPixel (disp, scrn); /* TODO: use a6 */
|
attrs.border_pixel = BlackPixel (disp, scrn); /* TODO: use a6 */
|
||||||
attrs.background_pixel = WhitePixel (disp, scrn);/* TODO: use a7 */
|
attrs.background_pixel = WhitePixel (disp, scrn);/* TODO: use a7 */
|
||||||
|
|
||||||
wind = XCreateWindow (
|
wind = XCreateWindow (
|
||||||
disp,
|
disp,
|
||||||
parent,
|
parent,
|
||||||
MOO_OOP_TO_SMOOI(a2), /* x */
|
MOO_OOP_TO_SMOOI(a1), /* x */
|
||||||
MOO_OOP_TO_SMOOI(a3), /* y */
|
MOO_OOP_TO_SMOOI(a2), /* y */
|
||||||
MOO_OOP_TO_SMOOI(a4), /* width */
|
MOO_OOP_TO_SMOOI(a3), /* width */
|
||||||
MOO_OOP_TO_SMOOI(a5), /* height */
|
MOO_OOP_TO_SMOOI(a4), /* height */
|
||||||
1, /* border width */
|
0, /* border width */
|
||||||
CopyFromParent, /* depth */
|
CopyFromParent, /* depth */
|
||||||
InputOutput, /* class */
|
InputOutput, /* class */
|
||||||
CopyFromParent, /* visual */
|
CopyFromParent, /* visual */
|
||||||
@ -287,6 +291,11 @@ static moo_pfrc_t pf_create_window (moo_t* moo, moo_ooi_t nargs)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parent == RootWindow(disp, scrn))
|
||||||
|
{
|
||||||
|
XSetWMProtocols (disp, wind, &tr->wm_delete_window, 1);
|
||||||
|
}
|
||||||
|
|
||||||
a0 = moo_oowtoint (moo, wind);
|
a0 = moo_oowtoint (moo, wind);
|
||||||
if (!a0)
|
if (!a0)
|
||||||
{
|
{
|
||||||
@ -298,19 +307,6 @@ static moo_pfrc_t pf_create_window (moo_t* moo, moo_ooi_t nargs)
|
|||||||
XMapWindow (disp, wind);
|
XMapWindow (disp, wind);
|
||||||
XFlush (disp);
|
XFlush (disp);
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (parent == screen->root)
|
|
||||||
{
|
|
||||||
cookie = xcb_intern_atom(c, 1, 12, "WM_PROTOCOLS");
|
|
||||||
reply = xcb_intern_atom_reply(c, cookie, 0);
|
|
||||||
|
|
||||||
cookie = xcb_intern_atom(c, 0, 16, "WM_DELETE_WINDOW");
|
|
||||||
win->dwar = xcb_intern_atom_reply(c, cookie, 0);
|
|
||||||
|
|
||||||
xcb_change_property(c, XCB_PROP_MODE_REPLACE, wid, reply->atom, 4, 32, 1, &win->dwar->atom);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MOO_STACK_SETRET (moo, nargs, a0);
|
MOO_STACK_SETRET (moo, nargs, a0);
|
||||||
done:
|
done:
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
@ -318,54 +314,144 @@ done:
|
|||||||
|
|
||||||
static moo_pfrc_t pf_destroy_window (moo_t* moo, moo_ooi_t nargs)
|
static moo_pfrc_t pf_destroy_window (moo_t* moo, moo_ooi_t nargs)
|
||||||
{
|
{
|
||||||
moo_oop_t a0, a1;
|
oop_x11_t x11;
|
||||||
|
moo_oop_t a0;
|
||||||
|
|
||||||
|
moo_oow_t wind;
|
||||||
|
|
||||||
a0 = MOO_STACK_GETARG(moo, nargs, 0); /* display - SmallPointer (Display*) */
|
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
||||||
a1 = MOO_STACK_GETARG(moo, nargs, 1); /* window - Integer (Window) */
|
a0 = MOO_STACK_GETARG(moo, nargs, 1); /* window - Integer (Window) */
|
||||||
|
|
||||||
if (!MOO_OOP_IS_SMPTR(a0))
|
|
||||||
|
|
||||||
|
if (moo_inttooow(moo, a0, &wind) <= 0)
|
||||||
{
|
{
|
||||||
einval:
|
MOO_DEBUG0 (moo, "<x11.destroy_window> Invalid parameters\n");
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Display* disp;
|
Display* disp;
|
||||||
moo_oow_t wind;
|
|
||||||
|
|
||||||
disp = MOO_OOP_TO_SMPTR(a0);
|
|
||||||
if (moo_inttooow(moo, a1, &wind) <= 0) goto einval;
|
|
||||||
|
|
||||||
|
disp = MOO_OOP_TO_SMPTR(x11->display);
|
||||||
XUnmapWindow (disp, (Window)wind);
|
XUnmapWindow (disp, (Window)wind);
|
||||||
XDestroyWindow (disp, (Window)wind);
|
XDestroyWindow (disp, (Window)wind);
|
||||||
XFlush (disp);
|
XFlush (disp); /* TODO: is XFlush() needed here? */
|
||||||
|
|
||||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||||
}
|
}
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static moo_pfrc_t pf_create_gc (moo_t* moo, moo_ooi_t nargs)
|
||||||
|
{
|
||||||
|
Display* disp;
|
||||||
|
moo_oow_t wind;
|
||||||
|
|
||||||
|
oop_x11_t x11;
|
||||||
|
moo_oop_t a0;
|
||||||
|
|
||||||
|
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
||||||
|
disp = MOO_OOP_TO_SMPTR(x11);
|
||||||
|
|
||||||
|
a0 = MOO_STACK_GETARG(moo, nargs, 0); /* parent window - Integer or nil (Window) */
|
||||||
|
|
||||||
|
if (moo_inttooow(moo, a0, &wind) <= 0)
|
||||||
|
{
|
||||||
|
MOO_DEBUG0 (moo, "<x11.create_gc> Invalid parameters\n");
|
||||||
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GC gc;
|
||||||
|
|
||||||
|
/* TODO: copy from default GC(DefaultGC...) explicitly??? */
|
||||||
|
gc = XCreateGC (disp, wind, 0, MOO_NULL);
|
||||||
|
if (!MOO_IN_SMPTR_RANGE(gc))
|
||||||
|
{
|
||||||
|
MOO_DEBUG0 (moo, "<x11.create_gc> GC pointer not in small pointer range\n");
|
||||||
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ERANGE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP(gc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return MOO_PF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static moo_pfrc_t pf_destroy_gc (moo_t* moo, moo_ooi_t nargs)
|
||||||
|
{
|
||||||
|
oop_x11_t x11;
|
||||||
|
moo_oop_t a0;
|
||||||
|
|
||||||
|
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
||||||
|
a0 = MOO_STACK_GETARG(moo, nargs, 1); /* GC */
|
||||||
|
|
||||||
|
if (!MOO_OOP_IS_SMPTR(a0))
|
||||||
|
{
|
||||||
|
MOO_DEBUG0 (moo, "<x11.destroy_gc> Invalid parameters\n");
|
||||||
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Display* disp;
|
||||||
|
GC gc;
|
||||||
|
|
||||||
|
disp = MOO_OOP_TO_SMPTR(x11->display);
|
||||||
|
gc = MOO_OOP_TO_SMPTR(a0);
|
||||||
|
|
||||||
|
XFreeGC (disp, gc);
|
||||||
|
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||||
|
}
|
||||||
|
return MOO_PF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static moo_pfrc_t pf_draw_rectangle (moo_t* moo, moo_ooi_t nargs)
|
||||||
|
{
|
||||||
|
Display* disp;
|
||||||
|
moo_oow_t wind, gc;
|
||||||
|
moo_oop_t a0, a1, a2, a3, a4, a5;
|
||||||
|
|
||||||
|
a0 = MOO_STACK_GETARG(moo, nargs, 0); /* Window */
|
||||||
|
a1 = MOO_STACK_GETARG(moo, nargs, 1); /* GC */
|
||||||
|
a2 = MOO_STACK_GETARG(moo, nargs, 2); /* x - SmallInteger */
|
||||||
|
a3 = MOO_STACK_GETARG(moo, nargs, 3); /* y - SmallInteger */
|
||||||
|
a4 = MOO_STACK_GETARG(moo, nargs, 4); /* width - SmallInteger */
|
||||||
|
a5 = MOO_STACK_GETARG(moo, nargs, 5); /* height - SmallInteger */
|
||||||
|
|
||||||
|
if (!MOO_OOP_IS_SMOOI(a2) || !MOO_OOP_IS_SMOOI(a3) ||
|
||||||
|
!MOO_OOP_IS_SMOOI(a4) || !MOO_OOP_IS_SMOOI(a5) ||
|
||||||
|
moo_inttooow(moo, a0, &wind) <= 0 ||
|
||||||
|
moo_inttooow(moo, a1, &gc) <= 0)
|
||||||
|
{
|
||||||
|
MOO_DEBUG0 (moo, "<x11.draw_rectangle> Invalid parameters\n");
|
||||||
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||||
|
return MOO_PF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
disp = MOO_OOP_TO_SMPTR(MOO_STACK_GETRCV(moo,nargs));
|
||||||
|
XDrawRectangle (disp, (Window)wind, (GC)gc,
|
||||||
|
MOO_OOP_TO_SMOOI(a2), MOO_OOP_TO_SMOOI(a3),
|
||||||
|
MOO_OOP_TO_SMOOI(a4), MOO_OOP_TO_SMOOI(a5));
|
||||||
|
|
||||||
|
return MOO_PF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
static moo_pfinfo_t x11_pfinfo[] =
|
static moo_pfinfo_t x11_pfinfo[] =
|
||||||
{
|
{
|
||||||
{ MC, { '_','c','l','o','s','e','_','d','i','s','p','l','a','y','\0' }, 0, { pf_close_display, 1, 1 } },
|
{ MI, { '_','c','l','o','s','e','_','d','i','s','p','l','a','y','\0' }, 0, { pf_close_display, 0, 0 } },
|
||||||
{ MC, { '_','c','r','e','a','t','e','_','w','i','n','d','o','w','\0' }, 0, { pf_create_window, 8, 8 } },
|
{ MI, { '_','c','r','e','a','t','e','_','g','c','\0' }, 0, { pf_create_gc, 1, 1 } },
|
||||||
{ MC, { '_','d','e','s','t','r','o','y','_','w','i','n','d','o','w','\0' }, 0, { pf_destroy_window, 2, 2 } },
|
{ MI, { '_','c','r','e','a','t','e','_','w','i','n','d','o','w','\0' }, 0, { pf_create_window, 7, 7 } },
|
||||||
{ MC, { '_','g','e','t','_','e','v','e','n','t','\0'}, 0, { pf_get_event, 2, 2 } },
|
{ MI, { '_','d','e','s','t','r','o','y','_','g','c','\0' }, 0, { pf_destroy_gc, 1, 1 } },
|
||||||
{ MI, { '_','g','e','t','_','e','v','t','b','u','f','\0'}, 0, { pf_get_evtbuf, 0, 0 } },
|
{ MI, { '_','d','e','s','t','r','o','y','_','w','i','n','d','o','w','\0' }, 0, { pf_destroy_window, 1, 1 } },
|
||||||
{ MC, { '_','g','e','t','_','f','d','\0' }, 0, { pf_get_fd, 1, 1 } },
|
{ MI, { '_','d','r','a','w','_','r','e','c','t','a','n','g','l','e','\0' }, 0, { pf_draw_rectangle, 6, 6 } },
|
||||||
{ MC, { '_','o','p','e','n','_','d','i','s','p','l','a','y','\0' }, 0, { pf_open_display, 0, 1 } }
|
//{ MI, { '_','f','i','l','l','_','r','e','c','t','a','n','g','l','e','\0' }, 0, { pf_fill_rectangle, 6, 6 } },
|
||||||
|
{ MI, { '_','g','e','t','_','e','v','e','n','t','\0'}, 0, { pf_get_event, 0, 0 } },
|
||||||
|
{ MI, { '_','g','e','t','_','f','d','\0' }, 0, { pf_get_fd, 0, 0 } },
|
||||||
|
{ MI, { '_','o','p','e','n','_','d','i','s','p','l','a','y','\0' }, 0, { pf_open_display, 0, 1 } }
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
{ MI, { '_','g','e','t','_','b','a','s','e','\0' }, 0, { pf_get_base, 0, 0 } },
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int x11_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class)
|
static int x11_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class)
|
||||||
|
Loading…
Reference in New Issue
Block a user