ongoing x11 experiment
This commit is contained in:
parent
d311c7cb6e
commit
16ff846013
@ -2,6 +2,9 @@
|
||||
|
||||
class X11(Object) from 'x11'
|
||||
{
|
||||
var display_base := nil.
|
||||
var shell_container := nil.
|
||||
|
||||
var windows. ## all windows registered
|
||||
|
||||
var event_loop_sem, event_loop_proc.
|
||||
@ -12,15 +15,13 @@ class X11(Object) from 'x11'
|
||||
var mouse_event.
|
||||
var mouse_wheel_event.
|
||||
|
||||
method(#primitive,#liberal) _connect(name).
|
||||
method(#primitive) _disconnect.
|
||||
method(#primitive) _get_base.
|
||||
method(#primitive) _get_fd.
|
||||
method(#primitive) _get_event.
|
||||
method(#class,#primitive,#liberal) _open_display(name).
|
||||
method(#class,#primitive) _close_display(display).
|
||||
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 server { ^self }
|
||||
method serverBase { ^self _get_base }
|
||||
method windowBase { ^nil }
|
||||
method(#primitive) _get_evtbuf.
|
||||
}
|
||||
|
||||
class X11.Exception(System.Exception)
|
||||
@ -107,99 +108,147 @@ class X11.ExposeEvent(X11.Event)
|
||||
}
|
||||
|
||||
|
||||
|
||||
## ---------------------------------------------------------------------------
|
||||
## Window
|
||||
## X11 Widgets
|
||||
## ---------------------------------------------------------------------------
|
||||
|
||||
class X11.Widget(Object)
|
||||
{
|
||||
var(#get,#set) parent.
|
||||
var(#get,#set)
|
||||
parent := nil,
|
||||
x := 0,
|
||||
y := 0,
|
||||
width := 0,
|
||||
height := 0,
|
||||
fgcolor := 0,
|
||||
bgcolor := 0,
|
||||
realized := false.
|
||||
|
||||
method server
|
||||
method displayOn: grctx
|
||||
{
|
||||
| p pp |
|
||||
p := self.
|
||||
while ((pp := p parent) notNil) { p := pp }.
|
||||
^p server.
|
||||
}
|
||||
|
||||
method serverBase { ^self server serverBase }
|
||||
method windowBase { ^nil}
|
||||
|
||||
|
||||
##method displayOn: gc { }
|
||||
method displayBase
|
||||
{
|
||||
if (self.parent isNil) { ^nil }.
|
||||
^self.parent displayBase.
|
||||
}
|
||||
|
||||
class X11.Window(selfns.Widget) from 'x11.win'
|
||||
method realize
|
||||
{
|
||||
var bounds.
|
||||
|
||||
method(#primitive) _make_window(server, x, y, width, height, parent).
|
||||
method(#primitive) _kill_window.
|
||||
method(#primitive) _get_base.
|
||||
method(#primitive) _get_bounds(rect).
|
||||
method(#primitive) _set_bounds(rect).
|
||||
|
||||
method(#class) new: parent
|
||||
{
|
||||
^(super new) __open_on: parent.
|
||||
}
|
||||
|
||||
method initialize
|
||||
{
|
||||
self.bounds := selfns.Rectangle new.
|
||||
}
|
||||
|
||||
method __open_on: parent
|
||||
{
|
||||
| server winbase |
|
||||
|
||||
server := parent server.
|
||||
winbase := self _make_window (server serverBase, 5, 5, 400, 400, parent windowBase).
|
||||
|
||||
(*
|
||||
if (server _make_window (5, 5, 400, 400, parent, self) isError)
|
||||
{
|
||||
X11.Exception signal: 'cannot make a window'
|
||||
}.
|
||||
*)
|
||||
|
||||
if (server ~= parent)
|
||||
{
|
||||
self.parent := parent.
|
||||
self.parent addWidget: self.
|
||||
}.
|
||||
|
||||
server addWindow: self.
|
||||
|
||||
self _get_bounds(self.bounds).
|
||||
self windowOpened.
|
||||
}
|
||||
|
||||
method dispose
|
||||
{
|
||||
if (self windowBase notNil)
|
||||
{
|
||||
self windowClosing.
|
||||
|
||||
self server removeWindow: self.
|
||||
if (self.parent notNil) { self.parent removeWidget: self }.
|
||||
|
||||
self _dispose_window.
|
||||
self windowClosed. ## you can't make a primitive call any more
|
||||
|
||||
##self.wid := nil.
|
||||
self.parent := nil.
|
||||
}
|
||||
}
|
||||
|
||||
method windowBase { ^self _get_base }
|
||||
class X11.Label(X11.Widget)
|
||||
{
|
||||
var(#get) text := ''.
|
||||
|
||||
method text: text
|
||||
{
|
||||
self.text := text.
|
||||
self displayOn: nil.
|
||||
}
|
||||
|
||||
class X11.FrameWindow(selfns.Window)
|
||||
method displayOn: grctx
|
||||
{
|
||||
method(#class) new: server
|
||||
## grctx _fillRectangle ().
|
||||
## grctx _drawText (...).
|
||||
## TODO Draw Text...
|
||||
}
|
||||
|
||||
method realize
|
||||
{
|
||||
^super new: server.
|
||||
## if i want to use a window to represent it, it must create window here.
|
||||
## otherwise, do other works in displayOn???
|
||||
}
|
||||
|
||||
method dispose
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class X11.Composite(X11.Widget)
|
||||
{
|
||||
var children.
|
||||
|
||||
method initialize
|
||||
{
|
||||
self.children := LinkedList new.
|
||||
}
|
||||
|
||||
method add: widget
|
||||
{
|
||||
if (widget parent notNil)
|
||||
{
|
||||
selfns.Exception signal: 'Cannot add an already added widget'.
|
||||
}.
|
||||
|
||||
self.children addLast: widget.
|
||||
widget parent: self.
|
||||
}
|
||||
|
||||
method remove: widget
|
||||
{
|
||||
| link |
|
||||
if (widget parent =~ self)
|
||||
{
|
||||
selfns.Exception sinal: 'Cannot remove a foreign widget'
|
||||
}.
|
||||
|
||||
## TODO: unmap and destroy...
|
||||
link := self.children findLink: widget.
|
||||
self.children removeLink: link.
|
||||
widget parent: nil.
|
||||
}
|
||||
|
||||
method childrenCount
|
||||
{
|
||||
^self.children size
|
||||
}
|
||||
|
||||
method dispose
|
||||
{
|
||||
self.children do: [:child | child dispose ]
|
||||
}
|
||||
}
|
||||
|
||||
class X11.Shell(X11.Composite)
|
||||
{
|
||||
var(#get) title.
|
||||
var(#get,#set) displayBase.
|
||||
|
||||
method new: title
|
||||
{
|
||||
self.title := title.
|
||||
}
|
||||
|
||||
method title: title
|
||||
{
|
||||
self.title := title.
|
||||
if (self.realized)
|
||||
{
|
||||
## set window title of this window.
|
||||
}
|
||||
}
|
||||
|
||||
method realize
|
||||
{
|
||||
| wind |
|
||||
if (self.realized) { ^self }.
|
||||
|
||||
wind := X11 _create_window(self.displayBase, nil, self.x, self.y, self.width, self.height, self.fgcolor, self.bgcolor).
|
||||
if (wind isError)
|
||||
{
|
||||
self.Exception signal: ('Cannot create shell ' & self.title).
|
||||
}.
|
||||
|
||||
self.children do: [:child | child realize ].
|
||||
self.realized := true.
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,30 +259,46 @@ extend X11
|
||||
{
|
||||
method(#class) new
|
||||
{
|
||||
^(super new) __connect_to_server: nil.
|
||||
^(super new) __connect_to: nil.
|
||||
}
|
||||
|
||||
method __connect_to_server: name
|
||||
method __connect_to: name
|
||||
{
|
||||
| base |
|
||||
base := self _connect(name).
|
||||
if (base isError) { X11.Exception signal: 'cannot connect to server' }.
|
||||
##self.base := base.
|
||||
base := X11 _open_display(name).
|
||||
if (base isError) { self.Exception signal: 'cannot open display' }.
|
||||
self.display_base := base.
|
||||
}
|
||||
|
||||
method close
|
||||
method dispose
|
||||
{
|
||||
if (self _get_base notNil)
|
||||
if (self.display_event notNil)
|
||||
{
|
||||
self _disconnect.
|
||||
##self.cid := nil.
|
||||
}
|
||||
X11 _free_event.
|
||||
self.display_event := nil.
|
||||
}.
|
||||
|
||||
if (self.shell_container notNil)
|
||||
{
|
||||
self.shell_container dispose.
|
||||
self.shell_container := nil.
|
||||
}.
|
||||
|
||||
if (self.display_base notNil)
|
||||
{
|
||||
|
||||
X11 _close_display (self.display_base).
|
||||
self.display_base := nil.
|
||||
}l
|
||||
}
|
||||
|
||||
method initialize
|
||||
{
|
||||
super initialize.
|
||||
|
||||
self.shell_container := self.Composite new.
|
||||
self.display_event := self _alloc_event.
|
||||
|
||||
self.windows := System.Dictionary new: 100.
|
||||
|
||||
self.expose_event := self.ExposeEvent new.
|
||||
@ -271,30 +336,25 @@ extend X11
|
||||
}.
|
||||
}
|
||||
|
||||
method connect
|
||||
method addShell: shell
|
||||
{
|
||||
| cid |
|
||||
if (self.windows isNil)
|
||||
if (shell displayBase isNil)
|
||||
{
|
||||
if ((cid := self _connect) isError) { ^cid }.
|
||||
##self.cid := cid.
|
||||
self.windows := System.Dictionary new.
|
||||
self.shell_container add: shell.
|
||||
shell displayBase: self.display_base.
|
||||
}
|
||||
}
|
||||
|
||||
method disconnect
|
||||
method removeShell: shell
|
||||
{
|
||||
if (self.windows notNil)
|
||||
if (shell displayBase notNil)
|
||||
{
|
||||
self.windows do: [ :frame |
|
||||
frame close.
|
||||
].
|
||||
self.windows := nil.
|
||||
self _disconnect.
|
||||
self.shell_container remove: shell.
|
||||
shell displayBase: nil.
|
||||
}
|
||||
}
|
||||
|
||||
method addWindow: window
|
||||
method registerWindow: window
|
||||
{
|
||||
^self.windows at: (window windowBase) put: window.
|
||||
}
|
||||
@ -309,18 +369,18 @@ extend X11
|
||||
if (self.event_loop_sem isNil)
|
||||
{
|
||||
self.event_loop_sem := Semaphore new.
|
||||
Processor signal: self.event_loop_sem onInput: (self _get_fd).
|
||||
Processor signal: self.event_loop_sem onInput: (X11 _get_fd(self.display_base)).
|
||||
self.event_loop_proc := [
|
||||
| event ongoing |
|
||||
|
||||
ongoing := true.
|
||||
while (self.windows size > 0)
|
||||
while (self.shell_container childrenCount > 0)
|
||||
{
|
||||
###'Waiting for X11 event...' dump.
|
||||
self.event_loop_sem wait.
|
||||
if (ongoing not) { break }.
|
||||
|
||||
while ((event := self _get_event) notNil)
|
||||
while (self _get_event(self.display_base, self.display_event))
|
||||
{
|
||||
if (event isError)
|
||||
{
|
||||
@ -338,7 +398,8 @@ extend X11
|
||||
Processor unsignal: self.event_loop_sem.
|
||||
self.event_loop_sem := nil.
|
||||
|
||||
self disconnect.
|
||||
self dispose.
|
||||
'CLOSING X11 EVENT LOOP' dump.
|
||||
] fork.
|
||||
}
|
||||
}
|
||||
@ -408,91 +469,36 @@ extend X11
|
||||
}
|
||||
}
|
||||
|
||||
class MyWidget(Window)
|
||||
{
|
||||
}
|
||||
|
||||
class MyFrame(X11.FrameWindow)
|
||||
{
|
||||
var gc.
|
||||
|
||||
|
||||
method windowOpened
|
||||
{
|
||||
super windowOpened.
|
||||
|
||||
(*
|
||||
if (self.gc isNil)
|
||||
{
|
||||
self.gc := X11.GC new: self.
|
||||
self.gc foreground: 10.
|
||||
self.gc _drawLine(10, 20, 30, 40).
|
||||
self.gc _drawRect(10, 20, 30, 40).
|
||||
self.gc foreground: 20.
|
||||
self.gc _drawRect(100, 100, 200, 200).
|
||||
}.
|
||||
|
||||
self.b1 := MyWidget new: self.*)
|
||||
|
||||
self windowResized.
|
||||
}
|
||||
|
||||
method windowClosing
|
||||
{
|
||||
super windowClosing.
|
||||
(*if (self.gc notNil)
|
||||
{
|
||||
self.gc close.
|
||||
self.gc := nil.
|
||||
}*)
|
||||
}
|
||||
|
||||
method windowResized
|
||||
{
|
||||
(*
|
||||
| rect |
|
||||
|
||||
super windowResized.
|
||||
|
||||
rect := self bounds.
|
||||
rect x: 0; y: 0; height: ((rect height) quo: 2); width: ((rect width) - 2).
|
||||
self.b1 bounds: rect;*)
|
||||
}
|
||||
|
||||
method expose: event
|
||||
{
|
||||
super expose: event.
|
||||
}
|
||||
}
|
||||
|
||||
class MyObject(Object)
|
||||
{
|
||||
var disp1, shell1, shell2.
|
||||
|
||||
method main1
|
||||
{
|
||||
self.disp1 := X11 new.
|
||||
|
||||
shell1 := (X11.Shell new title: 'Shell 1').
|
||||
shell2 := (X11.Shell new title: 'Shell 2').
|
||||
|
||||
shell1 x: 10; y: 20; width: 100; height: 100.
|
||||
shell2 x: 200; y: 200; width: 200; height: 200.
|
||||
|
||||
self.disp1 addShell: shell1.
|
||||
self.disp1 addShell: shell2.
|
||||
|
||||
self.shell1 add: (X11.Label new text: 'xxxxxxxx').
|
||||
self.shell1 realize.
|
||||
self.shell2 realize.
|
||||
|
||||
self.disp1 enterEventLoop. ## this is not a blocking call. it spawns another process.
|
||||
}
|
||||
|
||||
method(#class) main
|
||||
{
|
||||
| disp1 disp2 disp3 f q p |
|
||||
|
||||
disp1 := X11 new.
|
||||
disp2 := X11 new.
|
||||
disp3 := X11 new.
|
||||
|
||||
f := MyFrame new: disp2.
|
||||
q := MyFrame new: disp1.
|
||||
p := MyFrame new: disp3.
|
||||
|
||||
disp1 enterEventLoop. ## this is not a blocking call. it spawns another process.
|
||||
disp2 enterEventLoop.
|
||||
disp3 enterEventLoop.
|
||||
|
||||
##disp1 := X11 new.
|
||||
##f := MyFrame new.
|
||||
##f add: Button new.
|
||||
##f add: Button new.
|
||||
##g := MyFrame new.
|
||||
##g add: (b := Button new).
|
||||
##disp1 add: f.
|
||||
##disp1 add: g.
|
||||
##disp1 enterEventLoop.
|
||||
^self new main1
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,13 +38,6 @@
|
||||
#define MC MOO_METHOD_CLASS
|
||||
#define MI MOO_METHOD_INSTANCE
|
||||
|
||||
typedef struct x11_t x11_t;
|
||||
struct x11_t
|
||||
{
|
||||
Display* disp;
|
||||
XEvent* curevt;
|
||||
};
|
||||
|
||||
typedef struct x11_win_t x11_win_t;
|
||||
struct x11_win_t
|
||||
{
|
||||
|
276
moo/mod/x11.c
276
moo/mod/x11.c
@ -39,21 +39,36 @@ struct x11_modctx_t
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs)
|
||||
#if 0
|
||||
static moo_pfrc_t pf_get_base (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
x11_trailer_t* x11;
|
||||
Display* disp = MOO_NULL;
|
||||
XEvent* curevt = MOO_NULL;
|
||||
char* dispname = MOO_NULL;
|
||||
|
||||
x11 = (x11_trailer_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
|
||||
|
||||
if (x11->disp)
|
||||
{
|
||||
MOO_DEBUG0 (moo, "<x11.connect> Unable to open a display multiple times\n");
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EEXIST);
|
||||
goto oops;
|
||||
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)
|
||||
{
|
||||
x11_trailer_t* x11;
|
||||
Display* disp = MOO_NULL;
|
||||
XEvent* curevt = MOO_NULL;
|
||||
char* dispname = MOO_NULL;
|
||||
|
||||
if (nargs >= 1)
|
||||
{
|
||||
@ -96,9 +111,6 @@ static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs)
|
||||
goto oops;
|
||||
}
|
||||
|
||||
x11->disp = disp;
|
||||
x11->curevt = curevt;
|
||||
|
||||
MOO_ASSERT (moo, MOO_IN_SMPTR_RANGE(disp));
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP(disp));
|
||||
@ -112,57 +124,40 @@ oops:
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_disconnect (moo_t* moo, moo_ooi_t nargs)
|
||||
static moo_pfrc_t pf_close_display (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
x11_trailer_t* x11;
|
||||
moo_oop_t a0;
|
||||
|
||||
x11 = (x11_trailer_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
|
||||
a0 = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
|
||||
if (x11->curevt)
|
||||
if (!MOO_OOP_IS_SMPTR(a0))
|
||||
{
|
||||
moo_freemem (moo, x11->curevt);
|
||||
x11->curevt = MOO_NULL;
|
||||
}
|
||||
|
||||
if (x11->disp)
|
||||
{
|
||||
XCloseDisplay (x11->disp);
|
||||
x11->disp = MOO_NULL;
|
||||
}
|
||||
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
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));
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ENOAVAIL);
|
||||
XCloseDisplay (MOO_OOP_TO_SMPTR(a0));
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
}
|
||||
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static moo_pfrc_t pf_get_fd (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
x11_trailer_t* x11;
|
||||
moo_oop_t a0;
|
||||
|
||||
x11 = (x11_trailer_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
|
||||
a0 = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
|
||||
if (x11->disp)
|
||||
if (!MOO_OOP_IS_SMPTR(a0))
|
||||
{
|
||||
int c;
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
moo_ooi_t c;
|
||||
c = ConnectionNumber(MOO_OOP_TO_SMPTR(a0));
|
||||
|
||||
c = ConnectionNumber(x11->disp);
|
||||
if (!MOO_IN_SMOOI_RANGE(c))
|
||||
{
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ERANGE);
|
||||
@ -172,48 +167,210 @@ static moo_pfrc_t pf_get_fd (moo_t* moo, moo_ooi_t nargs)
|
||||
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(c));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ENOAVAIL);
|
||||
}
|
||||
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_get_event (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 (XPending(x11->disp))
|
||||
moo_oop_t a0, a1;
|
||||
|
||||
a0 = MOO_STACK_GETARG(moo, nargs, 0); /* display - SmallPointer (Display*) */
|
||||
a1 = MOO_STACK_GETARG(moo, nargs, 1); /* event to return - SmallPointer (XEvent*) */
|
||||
|
||||
|
||||
if (!MOO_OOP_IS_SMPTR(a0) || !MOO_OOP_IS_SMPTR(a1))
|
||||
{
|
||||
XNextEvent (x11->disp, x11->curevt);
|
||||
MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP(x11->curevt));
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
Display* disp;
|
||||
XEvent* event;
|
||||
|
||||
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->_nil);
|
||||
MOO_STACK_SETRET (moo, nargs, moo->_false);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Window wind; /* Window -> XID, unsigned long */
|
||||
|
||||
Display* disp;
|
||||
int scrn;
|
||||
Window parent;
|
||||
XSetWindowAttributes attrs;
|
||||
|
||||
moo_oop_t a0, a1, a2, a3, a4, a5, a6, a7;
|
||||
|
||||
a0 = MOO_STACK_GETARG(moo, nargs, 0); /* display - SmallPointer (Display*) */
|
||||
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) ||
|
||||
!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) || !MOO_OOP_IS_SMOOI(a7))
|
||||
{
|
||||
einval:
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||
goto done;
|
||||
}
|
||||
|
||||
disp = MOO_OOP_TO_SMPTR(a0);
|
||||
|
||||
if (a1 == moo->_nil)
|
||||
{
|
||||
scrn = DefaultScreen (disp);
|
||||
parent = RootWindow (disp, scrn);
|
||||
}
|
||||
else
|
||||
{
|
||||
moo_oow_t tmpoow;
|
||||
XWindowAttributes wa;
|
||||
if (moo_inttooow(moo, a1, &tmpoow) <= 0) goto einval;
|
||||
|
||||
parent = tmpoow;
|
||||
XGetWindowAttributes (disp, parent, &wa);
|
||||
MOO_ASSERT (moo, XRootWindowOfScreen(wa.screen) == parent);
|
||||
scrn = XScreenNumberOfScreen(wa.screen);
|
||||
}
|
||||
|
||||
attrs.event_mask = ExposureMask; /* TODO: accept it as a parameter??? */
|
||||
attrs.border_pixel = BlackPixel (disp, scrn); /* TODO: use a6 */
|
||||
attrs.background_pixel = WhitePixel (disp, scrn);/* TODO: use a7 */
|
||||
|
||||
wind = XCreateWindow (
|
||||
disp,
|
||||
parent,
|
||||
MOO_OOP_TO_SMOOI(a2), /* x */
|
||||
MOO_OOP_TO_SMOOI(a3), /* y */
|
||||
MOO_OOP_TO_SMOOI(a4), /* width */
|
||||
MOO_OOP_TO_SMOOI(a5), /* height */
|
||||
1, /* border width */
|
||||
CopyFromParent, /* depth */
|
||||
InputOutput, /* class */
|
||||
CopyFromParent, /* visual */
|
||||
CWEventMask | CWBackPixel | CWBorderPixel, &attrs);
|
||||
if (!wind)
|
||||
{
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ESYSERR);
|
||||
goto done;
|
||||
}
|
||||
|
||||
a0 = moo_oowtoint (moo, wind);
|
||||
if (!a0)
|
||||
{
|
||||
MOO_STACK_SETRETTOERRNUM (moo, nargs);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* TODO: remvoe this */
|
||||
XMapWindow (disp, wind);
|
||||
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);
|
||||
done:
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_destroy_window (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t a0, a1;
|
||||
|
||||
|
||||
a0 = MOO_STACK_GETARG(moo, nargs, 0); /* display - SmallPointer (Display*) */
|
||||
a1 = MOO_STACK_GETARG(moo, nargs, 1); /* window - Integer (Window) */
|
||||
|
||||
if (!MOO_OOP_IS_SMPTR(a0))
|
||||
|
||||
{
|
||||
einval:
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
Display* disp;
|
||||
moo_oow_t wind;
|
||||
|
||||
disp = MOO_OOP_TO_SMPTR(a0);
|
||||
if (moo_inttooow(moo, a1, &wind) <= 0) goto einval;
|
||||
|
||||
XUnmapWindow (disp, (Window)wind);
|
||||
XDestroyWindow (disp, (Window)wind);
|
||||
XFlush (disp);
|
||||
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
}
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
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 } },
|
||||
{ MC, { '_','c','r','e','a','t','e','_','w','i','n','d','o','w','\0' }, 0, { pf_create_window, 8, 8 } },
|
||||
{ MC, { '_','d','e','s','t','r','o','y','_','w','i','n','d','o','w','\0' }, 0, { pf_destroy_window, 2, 2 } },
|
||||
{ MC, { '_','g','e','t','_','e','v','e','n','t','\0'}, 0, { pf_get_event, 2, 2 } },
|
||||
{ MI, { '_','g','e','t','_','e','v','t','b','u','f','\0'}, 0, { pf_get_evtbuf, 0, 0 } },
|
||||
{ MC, { '_','g','e','t','_','f','d','\0' }, 0, { pf_get_fd, 1, 1 } },
|
||||
{ MC, { '_','o','p','e','n','_','d','i','s','p','l','a','y','\0' }, 0, { pf_open_display, 0, 1 } }
|
||||
|
||||
{ MI, { '_','c','o','n','n','e','c','t','\0' }, 0, { pf_connect, 0, 1 } },
|
||||
{ MI, { '_','d','i','s','c','o','n','n','e','c','t','\0' }, 0, { pf_disconnect, 0, 0 } },
|
||||
|
||||
#if 0
|
||||
{ MI, { '_','g','e','t','_','b','a','s','e','\0' }, 0, { pf_get_base, 0, 0 } },
|
||||
{ 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 } }
|
||||
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
static int x11_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class)
|
||||
{
|
||||
if (moo_setclasstrsize(moo, _class, MOO_SIZEOF(x11_t), MOO_NULL) <= -1) return -1;
|
||||
if (moo_setclasstrsize(moo, _class, MOO_SIZEOF(x11_trailer_t), MOO_NULL) <= -1) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -273,4 +430,3 @@ int moo_mod_x11 (moo_t* moo, moo_mod_t* mod)
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user