diff --git a/moo/kernel/Class.moo b/moo/kernel/Class.moo index 05e1a16..64da4ce 100644 --- a/moo/kernel/Class.moo +++ b/moo/kernel/Class.moo @@ -7,7 +7,7 @@ class(#pointer,#limited) Class(Apex) var spec, selfspec, superclass, subclasses, name, modname. var instvars, classinstvars, classvars, pooldics. var instmthdic, classmthdic, nsup, nsdic. - var trsize, initv, initv_ci. + var trsize, trgc, initv, initv_ci. method(#class) initialize { ^self } diff --git a/moo/kernel/Collect.moo b/moo/kernel/Collect.moo index fded7df..45c0569 100644 --- a/moo/kernel/Collect.moo +++ b/moo/kernel/Collect.moo @@ -451,7 +451,7 @@ class Dictionary(Set) { (* [NOTE] * VM require Dictionary to implement new: and __put_assoc - * for the dictionary expression notation - :{ } + * for the dictionary expression notation - %{ } *) ## TODO: implement Dictionary as a Hashed List/Table or Red-Black Tree @@ -466,7 +466,7 @@ class Dictionary(Set) * to a dictionary with the dictionary/association expression notation * like this: * - * :{ 1 -> 20, #moo -> 999 } + * %{ 1 -> 20, #moo -> 999 } * * it must return self for the way VM works. *) diff --git a/moo/kernel/Mill.moo b/moo/kernel/Mill.moo index d6e0da6..a0cf16c 100644 --- a/moo/kernel/Mill.moo +++ b/moo/kernel/Mill.moo @@ -216,28 +216,24 @@ class MyObject(Object) a :=999. - a := #{ + a := %( 1, 2, a, 4, 1 + 1, - #{ 1, 2, #{a, a := a + 1, a, if (a > 10) { a + 20 } }, 3}, + %( 1, 2, %(a, a := a + 1, a, if (a > 10) { a + 20 } ), 3), 2 + 2, #'a b c' - }. + ). (* Dictionary ??? - a := #{ + a := %{ key -> value , key -> value , key -> value , key -> value - } - - a := :{ - key -> value, - } + ),. *) a do: [ :v | v dump]. @@ -278,7 +274,7 @@ class MyObject(Object) }.*) - a := :{ + a := %{ 'aaa' -> 10, 'bbb' -> 20, 'bbb' -> 30, @@ -368,6 +364,6 @@ a free. (* pooldic XXD { #abc := #(1 2 3). - #def := #{ 1, 3, 4 }. ## syntax error - literal expected where #{ is + #def := %( 1, 3, 4 ). ## syntax error - literal expected where %( is } *) diff --git a/moo/kernel/X11.moo b/moo/kernel/X11.moo index 227347d..875cc6e 100644 --- a/moo/kernel/X11.moo +++ b/moo/kernel/X11.moo @@ -1,14 +1,7 @@ #include 'Moo.moo'. -###var xxxx. ## global variables. - class X11(Object) from 'x11' { - (* The X11 class represents a X11 display *) - - var(#class) default_display. - - var cid. var windows. ## all windows registered var event_loop_sem, event_loop_proc. @@ -19,20 +12,31 @@ class X11(Object) from 'x11' var mouse_event. var mouse_wheel_event. - method(#primitive) _connect. + method(#primitive,#liberal) _connect(name). method(#primitive) _disconnect. + method(#primitive) _get_base. method(#primitive) _get_fd. method(#primitive) _get_event. - - method cid { ^self.cid } - method wid { ^nil } - method display { ^self } + + method server { ^self } + method serverBase { ^self _get_base } + method windowBase { ^nil } } class X11.Exception(System.Exception) { } +class X11.Point(Object) +{ + var(#get,#set) x := 0, y := 0. +} + +class X11.Dimension(Object) +{ + var(#get,#set) width := 0, height := 0. +} + class X11.Rectangle(Object) { var(#get,#set) @@ -40,29 +44,8 @@ class X11.Rectangle(Object) y := 0, width := 0, height := 0. - -(* - method x { ^self.x } - method y { ^self.y } - method width { ^self.width } - method height { ^self.height } - - method x: x { self.x := x } - method y: y { self.y := y } - method width: width { self.width := width } - method height: height { self.height := height } -*) - - method x: x y: y width: width height: height - { - self.x := x. - self.y := y. - self.width := width. - self.height := height. - } } - ## --------------------------------------------------------------------------- ## Event ## --------------------------------------------------------------------------- @@ -100,468 +83,192 @@ pooldic X11.MouseButton class X11.MouseEvent(X11.Event) { - var(#get,#set) + var(#get,#set) x := 0, y := 0, button := 0. ## X11.MouseButton - -(* - method initialize - { - self.x := 0. - self.y := 0. - self.button := 0. - } - - method x { ^self.x } - method y { ^self.y } - method button { ^self.button } ## X11.MouseButton -*) - - method x: x y: y button: button - { - self.x := x. - self.y := y. - self.button := button. - } } class X11.MouseWheelEvent(X11.Event) { - var(#get) + var(#get,#set) x := 0, y := 0, amount := 0. - -(* method x { ^self.x } - method y { ^self.y } - method amount { ^self.amount } -*) - -(* - method initialize - { - self.x := 0. - self.y := 0. - self.amount := 0. - } -*) - - method x: x y: y amount: amount - { - self.x := x. - self.y := y. - self.amount := amount. - } } class X11.ExposeEvent(X11.Event) { - var(#get) + var(#get,#set) x := 0, y := 0, width := 0, height := 0. - -(* - method x { ^self.x } - method y { ^self.y } - method width { ^self.width } - method height { ^self.height } - - method initialize - { - self.x := 0. - self.y := 0. - self.width := 0. - self.height := 0. - }*) - - method x: x y: y width: width height: height - { - self.x := x. - self.y := y. - self.width := width. - self.height := height. - } } + ## --------------------------------------------------------------------------- -## Graphics Context +## Window ## --------------------------------------------------------------------------- -pooldic X11.GCAttr +class X11.Widget(Object) { - (* see xcb/xproto.h *) - GC_FOREGROUND := 4. - GC_BACKGROUND := 8. - GC_LINE_WIDTH := 16. - GC_LINE_STYLE := 32. - GC_FONT := 16384. -} + var(#get,#set) parent. -class X11.GC(Object) from 'x11.gc' -{ - var window, id. - - method(#primitive) _make (display, window). - method(#primitive) _kill. - method(#primitive) _drawLine(x1, y1, x2, y2). - method(#primitive) _drawRect(x, y, width, height). - method(#primitive) _fillRect(x, y, width, height). - method(#primitive) _change(gcattr, value). - - method(#class) new: window + method server { - ^(super new) __open_on: window - } - - method __open_on: window - { - if ((id := self _make(window display cid, window wid)) isError) - { - X11.Exception signal: 'cannot make a graphic context' - }. - - self.window := window. - self.id := id. - } - - method close - { - if (self.id notNil) - { - self _kill. - self.id := nil. - self.window := nil. - } - } - - method foreground: value - { - ^self _change (X11.GCAttr.GC_FOREGROUND, value) - } - - method background: value - { - ^self _change (X11.GCAttr.GC_BACKGROUND, value) - } -} - -## --------------------------------------------------------------------------- -## --------------------------------------------------------------------------- - - -class(#limited) X11.Component(Object) -{ - var parent. - - method parent - { - ^self.parent - } - - method parent: parent - { - self.parent := parent. - } - - method display - { | p pp | p := self. while ((pp := p parent) notNil) { p := pp }. - ^p display. + ^p server. } - method display: display - { - ## do nothing - } + method serverBase { ^self server serverBase } + method windowBase { ^nil} + + + ##method displayOn: gc { } } -class X11.Canvas(Component) +class X11.Window(selfns.Widget) from 'x11.win' { - method paint: gr - { - self subclassResponsibility: #paint - } + var bounds. - method update: gr - { - self subclassResponsibility: #paint - } -} - -class X11.WindowedComponent(Component) from 'x11.win' -{ - var(#class) geom. - var wid, bounds. - - method(#primitive) _get_window_dwatom. - method(#primitive) _get_window_id. - method(#primitive) _make_window (display, x, y, width, height, parent). + method(#primitive) _make_window(server, x, y, width, height, parent). method(#primitive) _kill_window. - method(#primitive) _get_window_geometry (geom). - method(#primitive) _set_window_geometry (geom). - - method wid { ^self.wid } - - method initialize - { - self.bounds := X11.Rectangle new. - } + method(#primitive) _get_base. + method(#primitive) _get_bounds(rect). + method(#primitive) _set_bounds(rect). method(#class) new: parent { - ^(super new) __open_on_window: parent + ^(super new) __open_on: parent. } - method __open_on_window: parent + method initialize { - | id disp | + self.bounds := selfns.Rectangle new. + } - disp := parent display. + method __open_on: parent + { + | server winbase | - wid := self _make_window (disp cid, 5, 5, 300, 300, parent wid). - if (wid isError) { X11.Exception signal: ('cannot make a window - ' & wid asString) }. - - self.wid := wid. - self display: disp. + server := parent server. + winbase := self _make_window (server serverBase, 5, 5, 400, 400, parent windowBase). - if (disp ~= parent) + (* + if (server _make_window (5, 5, 400, 400, parent, self) isError) + { + X11.Exception signal: 'cannot make a window' + }. + *) + + if (server ~= parent) { self.parent := parent. - parent addComponent: self. + self.parent addWidget: self. }. - disp addWindow: self. + server addWindow: self. - self _get_window_geometry (self.bounds). + self _get_bounds(self.bounds). self windowOpened. } - method close + method dispose { - if (self.wid notNil) + if (self windowBase notNil) { self windowClosing. - self display removeWindow: self. - if (self.parent notNil) { self.parent removeComponent: self }. + self server removeWindow: self. + if (self.parent notNil) { self.parent removeWidget: self }. - self _kill_window. + self _dispose_window. self windowClosed. ## you can't make a primitive call any more - self.wid := nil. + ##self.wid := nil. self.parent := nil. } } - method cachedBounds - { - ^self.bounds - } - - method bounds - { - self _get_window_geometry (self.bounds). - ^self.bounds - } - - method bounds: rect - { - self _set_window_geometry (rect). - self _get_window_geometry (self.bounds). ## To update bounds - } - - method windowOpened - { - } - method windowClosing - { - } - method windowClosed - { - } - method windowResized - { - } - - method expose: event - { - - ## ('EXPOSE IN WINDOWS....' & (self.wid asString) & ' ' & (event x asString) & ' ' & (event y asString) & ' ' & (event width asString) & ' ' & (event height asString)) dump. - } - - (* TODO: take the followings out to a seperate mouse listener??? *) - method mouseEntered: event - { - } - method mouseExited: event - { - } - method mouseClicked: event - { - } - method mousePressed: event - { - ('MOUSE PRESSED' & (self.wid asString) & ' ' & (event x asString) & ' ' & (event y asString) & ' ' & (event button asString)) dump. - } - method mouseReleased: event - { - ('MOUSE RELEASED' & (self.wid asString) & ' ' & (event x asString) & ' ' & (event y asString)) dump. - } - method mouseWheelMoved: event - { - ('MOUSE WHEEL MOVED' & (self.wid asString) & ' ' & (event x asString) & ' ' & (event y asString) & ' ' & (event amount asString)) dump. - } + method windowBase { ^self _get_base } } -class X11.Container(WindowedComponent) +class X11.FrameWindow(selfns.Window) { - var components. - - method initialize + method(#class) new: server { - super initialize. - self.components := System.Dictionary new: 128. - } - - method addComponent: component - { - ## TODO: the key is component's wid. it's only supported for WindowedCompoennt. - ## what is a better key to support Component that's not linked to any window? - ^self.components at: (component wid) put: component - } - - method removeComponent: component - { - ^self.components removeKey: (component wid) - } - - method close - { - self.components do: [:c | c close ]. - ^super close + ^super new: server. } } -class X11.FrameWindow(Container) -{ - var display. - - method display { ^self.display } - method display: display { self.display := display } - - method(#class) new - { - super new: X11 defaultDisplay. ## connect if X11 is not connected. - } - - method(#class) new: display - { - ^super new: display. - } - - ##method show: flag - ##{ - ##} - - (* - method windowActivated: event - { - } - method windowDeactivated: event - { - } - method windowIconified: event - { - } - method windowDeiconified: event - { - }*) -} - -class X11.Button(WindowedComponent) -{ -} - +## --------------------------------------------------------------------------- +## X11 server +## --------------------------------------------------------------------------- extend X11 { method(#class) new { - ^(super new) __connect_to_display: nil. + ^(super new) __connect_to_server: nil. } - method __connect_to_display: name + method __connect_to_server: name { - ## TODO: make use of name to connect to a non-default display. - | cid | - cid := self _connect. - if (cid isError) { X11.Exception signal: 'cannot connect to display' }. - self.cid := cid. + | base | + base := self _connect(name). + if (base isError) { X11.Exception signal: 'cannot connect to server' }. + ##self.base := base. } method close { - if (self.cid notNil) + if (self _get_base notNil) { self _disconnect. - self.cid := nil. + ##self.cid := nil. } } - method(#class) defaultDisplay - { - | conn | - if (self.default_display isNil) - { - conn := X11 new. - ##if (conn isError) { X11.Exception signal: 'cannot connect to default display' }. - self.default_display := conn. - }. - - ^self.default_display - } - - method(#class) closeDefaultDisplay - { - if (self.default_display notNil) - { - self.default_display close. - self.default_display := nil. - } - } - - method(#class) enterEventLoop - { - ^self defaultDisplay enterEventLoop - } - method initialize { super initialize. self.windows := System.Dictionary new: 100. - - self.expose_event := X11.ExposeEvent new. - self.key_event := X11.KeyEvent new. - self.mouse_event := X11.MouseEvent new. - self.mouse_wheel_event := X11.MouseWheelEvent new. + 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.ll_event_blocks := System.Dictionary new. self.ll_event_blocks - at: X11.LLEvent.KEY_PRESS put: #__handle_key_event:; - at: X11.LLEvent.KEY_RELEASE put: #__handle_key_event:; - at: X11.LLEvent.BUTTON_PRESS put: #__handle_button_event:; - at: X11.LLEvent.BUTTON_RELEASE put: #__handle_button_event:; - at: X11.LLEvent.MOTION_NOTIFY put: #__handle_notify:; - at: X11.LLEvent.ENTER_NOTIFY put: #__handle_notify:; - at: X11.LLEvent.LEAVE_NOTIFY put: #__handle_notify:; - at: X11.LLEvent.EXPOSE put: #__handle_expose:; - at: X11.LLEvent.DESTROY_NOTIFY put: #__handle_destroy_notify:; - at: X11.LLEvent.CONFIGURE_NOTIFY put: #__handle_configure_notify:; - at: X11.LLEvent.CLIENT_MESSAGE put: #__handle_client_message:. + at: self.LLEvent.KEY_PRESS put: #__handle_key_event:; + at: self.LLEvent.KEY_RELEASE put: #__handle_key_event:; + at: self.LLEvent.BUTTON_PRESS put: #__handle_button_event:; + at: self.LLEvent.BUTTON_RELEASE put: #__handle_button_event:; + at: self.LLEvent.MOTION_NOTIFY put: #__handle_notify:; + at: self.LLEvent.ENTER_NOTIFY put: #__handle_notify:; + at: self.LLEvent.LEAVE_NOTIFY put: #__handle_notify:; + at: self.LLEvent.EXPOSE put: #__handle_expose:; + at: self.LLEvent.DESTROY_NOTIFY put: #__handle_destroy_notify:; + at: self.LLEvent.CONFIGURE_NOTIFY put: #__handle_configure_notify:; + at: self.LLEvent.CLIENT_MESSAGE put: #__handle_client_message:. + *) + self.ll_event_blocks := %{ + self.LLEvent.KEY_PRESS -> #__handle_key_event:, + self.LLEvent.KEY_RELEASE -> #__handle_key_event:, + self.LLEvent.BUTTON_PRESS -> #__handle_button_event:, + self.LLEvent.BUTTON_RELEASE -> #__handle_button_event:, + self.LLEvent.MOTION_NOTIFY -> #__handle_notify:, + self.LLEvent.ENTER_NOTIFY -> #__handle_notify:, + self.LLEvent.LEAVE_NOTIFY -> #__handle_notify:, + self.LLEvent.EXPOSE -> #__handle_expose:, + self.LLEvent.DESTROY_NOTIFY -> #__handle_destroy_notify:, + self.LLEvent.CONFIGURE_NOTIFY -> #__handle_configure_notify:, + self.LLEvent.CLIENT_MESSAGE -> #__handle_client_message: + }. } method connect @@ -570,7 +277,7 @@ extend X11 if (self.windows isNil) { if ((cid := self _connect) isError) { ^cid }. - self.cid := cid. + ##self.cid := cid. self.windows := System.Dictionary new. } } @@ -586,15 +293,15 @@ extend X11 self _disconnect. } } - + method addWindow: window { - ^self.windows at: (window wid) put: window. + ^self.windows at: (window windowBase) put: window. } method removeWindow: window { - ^self.windows removeKey: (window wid) + ^self.windows removeKey: (window windowBase) } method enterEventLoop @@ -603,27 +310,27 @@ extend X11 { self.event_loop_sem := Semaphore new. Processor signal: self.event_loop_sem onInput: (self _get_fd). - self.event_loop_proc := [ - | event ongoing | - + self.event_loop_proc := [ + | event ongoing | + ongoing := true. - while (self.windows size > 0) + while (self.windows size > 0) { ###'Waiting for X11 event...' dump. self.event_loop_sem wait. if (ongoing not) { break }. - while ((event := self _get_event) notNil) + while ((event := self _get_event) notNil) { if (event isError) { - System logNl: ('Error while getting a event from display ' & self.cid asString). + ##System logNl: ('Error while getting a event from server ' & self.cid asString). ongoing := false. break. } - else - { - self __dispatch_event: event. + else + { + self __dispatch_event: event. }. }. }. @@ -635,12 +342,11 @@ extend X11 ] fork. } } - + method exitEventLoop { if (self.event_loop_sem notNil) { - ###self.even_loop_sem ... self.event_loop_proc terminate. self.event_loop_proc := nil. self.event_loop_sem := nil. @@ -655,10 +361,10 @@ extend X11 method __dispatch_event: event { | type mthname | - + ##type := System _getUint8(event, 0). type := event getUint8(0). - + mthname := self.ll_event_blocks at: (type bitAnd: 16r7F). if (mthname isError) { @@ -679,292 +385,43 @@ extend X11 method __handle_expose: event { - (* - typedef struct xcb_expose_event_t { - uint8_t response_type; - uint8_t pad0; - uint16_t sequence; - xcb_window_t window; // uint32_t - uint16_t x; - uint16_t y; - uint16_t width; - uint16_t height; - uint16_t count; - uint8_t pad1[2]; - } xcb_expose_event_t; - *) - - | wid window | - - ##wid := System _getUint32(event, 4). ## window - wid := event getUint32(4). - window := self.windows at: wid. - - if (window notError) - { - (* - self.expose_event - x: System _getUint16(event, 8) ## x - y: System _getUint16(event, 10) ## y - width: System _getUint16(event, 12) ## width - height: System _getUint16(event, 14). ## height - *) - self.expose_event - x: event getUint16(8) ## x - y: event getUint16(10) ## y - width: event getUint16(12) ## width - height: event getUint16(14). ## height - - window expose: self.expose_event. - } - else - { - System logNl: ('Expose event on unknown window - ' & wid asString). - } } method __handle_button_event: event { - (* - typedef uint8_t xcb_button_t; - typedef struct xcb_button_press_event_t { - uint8_t response_type; - xcb_button_t detail; // uint8_t - uint16_t sequence; - xcb_timestamp_t time; // uint32_t - xcb_window_t root; // uint32_t - xcb_window_t event; - xcb_window_t child; - int16_t root_x; - int16_t root_y; - int16_t event_x; - int16_t event_y; - uint16_t state; - uint8_t same_screen; - uint8_t pad0; - } xcb_button_press_event_t; - typedef xcb_button_press_event_t xcb_button_release_event_t; - *) - - | type wid window detail | - type := System _getUint8(event, 0) bitAnd: 16r7F. ## lower 7 bits of response_type - wid := System _getUint32(event, 12). ## event - ##type := event getUint8(0) bitAnd: 16r7F. ## lower 7 bits of response_type - ##wid := event getUint32(12). ## event - - window := self.windows at: wid. - - if (window notError) - { - ##detail := System _getUint8(event, 1). - detail := event getUint8(1). - if (detail >= 1 and: [detail <= 3]) - { - self.mouse_event - x: event getUint16(24) ## event_x - y: event getUint16(26) ## event_y - button: detail. - - if (type == X11.LLEvent.BUTTON_PRESS) - { - window mousePressed: self.mouse_event - } - else - { - window mouseReleased: self.mouse_event - } - } - elsif (detail == 4 or: [detail == 5]) - { - if (type == X11.LLEvent.BUTTON_RELEASE) - { - self.mouse_wheel_event - x: event getUint16(24) ## event_x - y: event getUint16(26) ## event_y - amount: (if (detail == 4) { -1 } else { 1 }). - window mouseWheelMoved: self.mouse_wheel_event - } - } - } - else - { - System logNl: ('Button event on unknown window - ' & wid asString). - } } method __handle_destroy_notify: event { - (* - typedef struct xcb_destroy_notify_event_t { - uint8_t response_type; - uint8_t pad0; - uint16_t sequence; - xcb_window_t event; - xcb_window_t window; - } xcb_destroy_notify_event_t; - *) - - | wid window | - - wid := System _getUint32(event, 4). ## event - window := self.windows at: wid. - - if (window notError) - { - 'WINDOW DESTROYED....................' dump. - } - else - { - System logNl: ('Destroy notify event on unknown window - ' & wid asString). - } } - + method __handle_configure_notify: event { - (* - typedef struct xcb_configure_notify_event_t { - uint8_t response_type; - uint8_t pad0; - uint16_t sequence; - xcb_window_t event; - xcb_window_t window; - xcb_window_t above_sibling; - int16_t x; - int16_t y; - uint16_t width; - uint16_t height; - uint16_t border_width; - uint8_t override_redirect; - uint8_t pad1; - } xcb_configure_notify_event_t; - *) - - | wid window bounds width height | - - ## type := System _getUint8(event, 0) bitAnd: 16r7F. ## lower 7 bits of response_type - wid := System _getUint32(event, 4). ## event - window := self.windows at: wid. - - if (window notError) - { - width := System _getUint16(event, 20). - height := System _getUint16(event, 22). - bounds := window cachedBounds. ## old bounds before resizing. - if (bounds width ~= width or: [bounds height ~= height]) { window windowResized }. - } - else - { - System logNl: ('Configure notify event on unknown window - ' & wid asString). - } } method __handle_client_message: event { - (* - typedef union xcb_client_message_data_t { - uint8_t data8[20]; - uint16_t data16[10]; - uint32_t data32[5]; - } xcb_client_message_data_t; - - typedef struct xcb_client_message_event_t { - uint8_t response_type; - uint8_t format; - uint16_t sequence; - xcb_window_t window; // uint32_t - xcb_atom_t type; // uint32_t - xcb_client_message_data_t data; - } xcb_client_message_event_t; - *) - | type wid window dw | - - ##wid := System _getUint32(event, 4). ## window - wid := event getUint32(4). ## window - window := self.windows at: wid. - - if (window notError) - { - ##dw := System _getUint32(event, 12). ## data.data32[0] - dw := event getUint32(12). ## data.data32[0] - if (dw == window _get_window_dwatom) - { - window close. - } - - ## TODO: handle other client messages - } - else - { - System logNl: ('Client message on unknown window - ' & wid asString). - } } method __handle_key_event: type { - (* - typedef struct xcb_key_press_event_t { - uint8_t response_type; - xcb_keycode_t detail; - uint16_t sequence; - xcb_timestamp_t time; - xcb_window_t root; - xcb_window_t event; - xcb_window_t child; - int16_t root_x; - int16_t root_y; - int16_t event_x; - int16_t event_y; - uint16_t state; - uint8_t same_screen; - uint8_t pad0; - } xcb_key_press_event_t; - typedef xcb_key_press_event_t xcb_key_release_event_t; - *) - - if (type = X11.LLEvent.KEY_PRESS) - { - } - else - { - } } } - -class MyButton(X11.Button) +class MyWidget(Window) { - method windowOpened - { - super windowOpened. - self repaint. - } - - method expose: event - { - super expose: event. - self repaint. - } - - method repaint - { - |gc| - gc := X11.GC new: self. - gc foreground: 16rFF8877. - gc _fillRect(0, 0, 50, 50). - gc close. - } } class MyFrame(X11.FrameWindow) { var gc. - var b1. - var b2. + method windowOpened { super windowOpened. + (* if (self.gc isNil) { self.gc := X11.GC new: self. @@ -974,8 +431,8 @@ self.gc _drawRect(10, 20, 30, 40). self.gc foreground: 20. self.gc _drawRect(100, 100, 200, 200). }. - - self.b1 := MyButton new: self. + + self.b1 := MyWidget new: self.*) self windowResized. } @@ -992,96 +449,50 @@ self.gc _drawRect(100, 100, 200, 200). 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; + self.b1 bounds: rect;*) } method expose: event { super expose: event. - (* - ('EXPOSE....' & (self.id asString) & ' ' & (event x asString) & ' ' & (event y asString) & ' ' & (event width asString) & ' ' & (event height asString)) dump. - -self.gc foreground: 2. -##self.gc drawLine: (10@20) to: (30@40). -self.gc _drawLine(10, 20, 300, 400). -self.gc _drawRect(10, 20, 30, 40). -self.gc foreground: 20. -self.gc _drawRect(100, 100, 200, 200).*) } } - - - class MyObject(Object) -{ - method(#class) abc +{ + + method(#class) main { - ^9234554123489129038123908123908312908 - } - - method(#class) main - { - | f q p disp1 disp2 disp3 | - - f := 20. - (q:=:{ 10 -> 20, 20 -> 30, f + 40 -> self abc, (Association key: 10 value: 49), f -> f })dump. - (q at: 60) dump. - (q at: 10) dump. - - - #( #a:y: #b #c) dump. - f := LinkedList new. - f addLast: 10. - f addLast: 20. - q := f addLast: 30. - f addLast: 40. - f removeLink: q. - f addLastLink: q. - (f findLink: 30) prev value dump. - - f do: [:v | v dump ]. - (f size asString & ' elements in list') dump. + | disp1 disp2 disp3 f q p | disp1 := X11 new. disp2 := X11 new. disp3 := X11 new. - - ##X11 connect. + f := MyFrame new: disp2. q := MyFrame new: disp1. p := MyFrame new: disp3. - - ## MyButton new: q. - ## MyButton new: f. - -(* - f add: X11.Button new: 'click me'. - f width: 200 height: 200. - f show. -*) - disp1 enterEventLoop. ## this is not a blocking call. it spawns another process. disp2 enterEventLoop. disp3 enterEventLoop. - (*while (true) - { - '111' dump. - ##x signal_event_loop_semaphore. - Processor sleepFor: 5. - }.*) - ## [ while (true) { '111' dump. Processor sleepFor: 1. } ] fork. - - ##X11 disconnect. - - ##X11 closeDefaultDisplay. + ##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. } + } diff --git a/moo/kernel/test-001.moo b/moo/kernel/test-001.moo index 8bdc47e..fad1c26 100644 --- a/moo/kernel/test-001.moo +++ b/moo/kernel/test-001.moo @@ -108,7 +108,7 @@ extend MyObject { | tc limit | - tc := #{ + tc := %( ## 0 - 4 [MyObject.Donkey v == 901982], [selfns.MyObject.Donkey v == 901982], @@ -160,7 +160,7 @@ extend MyObject ## 35 - 39 [MyObject.System.System.System KING == #KING] - }. + ). limit := tc size. MyObject.System.System a: XX.AAAA. diff --git a/moo/kernel/test-002.moo b/moo/kernel/test-002.moo index 2803052..1c7d963 100644 --- a/moo/kernel/test-002.moo +++ b/moo/kernel/test-002.moo @@ -21,11 +21,11 @@ class MyObject(Object) { | tc limit | - tc := #{ + tc := %( ## 0 - 4 [ self proc1 == 100 ], [ Processor sleepFor: 2. self proc1 == 200 ] - }. + ). limit := tc size. diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 1ea492a..d46ee80 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -273,14 +273,18 @@ static MOO_INLINE int is_binselchar (moo_ooci_t c) { /* * binary-selector-character := - * '%' | '&' | '*' | '+' | '-' | - * '/' | '<' | '>' | '=' | '?' | - * '@' | '\' | '~' | '|' + * '&' | '*' | '+' | '-' | '/' | + * '<' | '>' | '=' | '?' | '@' | + * '\' | '~' | '|' + * + * - a comma is special in moo and doesn't form a binary selector. + * - a percent sign is special in moo and doesn't form a binary selector. + * - an exclamation mark is excluded intentioinally because i can't tell + * the method symbol #! from the comment introducer #!. */ switch (c) { - case '%': case '&': case '*': case '+': @@ -1652,11 +1656,6 @@ retry: SET_TOKEN_TYPE (moo, MOO_IOTOK_ASSIGN); ADD_TOKEN_CHAR (moo, c); } - else if (c == '{') - { - SET_TOKEN_TYPE (moo, MOO_IOTOK_DICBRACE); - ADD_TOKEN_CHAR (moo, c); - } else { unget_char (moo, &moo->c->lxc); @@ -1708,6 +1707,34 @@ retry: SET_TOKEN_TYPE (moo, MOO_IOTOK_SEMICOLON); goto single_char_token; + case '%': + SET_TOKEN_TYPE (moo, MOO_IOTOK_PERCENT); + ADD_TOKEN_CHAR(moo, c); + GET_CHAR_TO (moo, c); + + /* TODO: byte array expression token -> %[ */ + if (c == '(') + { + /* %( - array expression */ + ADD_TOKEN_CHAR(moo, c); + SET_TOKEN_TYPE (moo, MOO_IOTOK_PERCPAREN); + } + else if (c == '{') + { + /* %{ - dictionary expression */ + ADD_TOKEN_CHAR(moo, c); + SET_TOKEN_TYPE (moo, MOO_IOTOK_PERCBRACE); + } + else + { + /* NOTE the percent sign not followed by ( or } is + * meaningless at this moment. however, i return + * it as a token so that the compiler anyway + * will fail eventually */ + unget_char (moo, &moo->c->lxc); + } + break; + case '#': ADD_TOKEN_CHAR(moo, c); GET_CHAR_TO (moo, c); @@ -1720,19 +1747,14 @@ retry: case '(': /* #( - array literal */ ADD_TOKEN_CHAR(moo, c); - SET_TOKEN_TYPE (moo, MOO_IOTOK_APAREN); + SET_TOKEN_TYPE (moo, MOO_IOTOK_HASHPAREN); break; case '[': /* #[ - byte array literal */ ADD_TOKEN_CHAR(moo, c); - SET_TOKEN_TYPE (moo, MOO_IOTOK_BABRACK); + SET_TOKEN_TYPE (moo, MOO_IOTOK_HASHBRACK); break; - - case '{': - /* #{ - array expression */ - ADD_TOKEN_CHAR(moo, c); - SET_TOKEN_TYPE (moo, MOO_IOTOK_ABRACE); break; case '\'': @@ -1923,7 +1945,7 @@ retry: break; } -MOO_DEBUG2 (moo, "TOKEN: [%.*js]\n", (moo_ooi_t)moo->c->tok.name.len, moo->c->tok.name.ptr); +MOO_DEBUG3 (moo, "TOKEN: [%.*js] %d\n", (moo_ooi_t)moo->c->tok.name.len, moo->c->tok.name.ptr, (int)moo->c->tok.type); return 0; } @@ -4604,7 +4626,7 @@ static int compile_byte_array_literal (moo_t* moo) moo_oow_t index; MOO_ASSERT (moo, moo->c->balit.count == 0); - MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_BABRACK); + MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_HASHBRACK); if (read_byte_array_literal(moo, &lit) <= -1 || add_literal(moo, lit, &index) <= -1 || @@ -4620,7 +4642,7 @@ static int compile_array_literal (moo_t* moo) moo_oow_t index; MOO_ASSERT (moo, moo->c->arlit.count == 0); - MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_APAREN); + MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_HASHPAREN); if (read_array_literal(moo, 0, &lit) <= -1 || add_literal(moo, lit, &index) <= -1 || @@ -4635,7 +4657,7 @@ static int compile_array_expression (moo_t* moo) moo_oow_t maip; moo_ioloc_t aeloc; - MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_ABRACE); + MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_PERCPAREN); maip = moo->c->mth.code.len; if (emit_single_param_instruction(moo, BCODE_MAKE_ARRAY, 0) <= -1) return -1; @@ -4659,7 +4681,7 @@ static int compile_array_expression (moo_t* moo) return -1; } - if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE) break; + if (TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) break; if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA) { @@ -4689,7 +4711,7 @@ static int compile_dictionary_expression (moo_t* moo) { moo_oow_t mdip; - MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_DICBRACE); + MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_PERCBRACE); GET_TOKEN (moo); /* read a token after :{ */ @@ -4931,21 +4953,21 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons GET_TOKEN (moo); break; - case MOO_IOTOK_BABRACK: /* #[ */ + case MOO_IOTOK_HASHBRACK: /* #[ */ /*GET_TOKEN (moo);*/ if (compile_byte_array_literal(moo) <= -1) return -1; break; - case MOO_IOTOK_APAREN: /* #( */ + case MOO_IOTOK_HASHPAREN: /* #( */ /*GET_TOKEN (moo);*/ if (compile_array_literal(moo) <= -1) return -1; break; - case MOO_IOTOK_ABRACE: /* #{ */ + case MOO_IOTOK_PERCPAREN: /* %( */ if (compile_array_expression(moo) <= -1) return -1; break; - case MOO_IOTOK_DICBRACE: /* :{ */ + case MOO_IOTOK_PERCBRACE: /* %{ */ if (compile_dictionary_expression(moo) <= -1) return -1; break; @@ -6939,7 +6961,6 @@ static int make_defined_class (moo_t* moo) if (make_getters_and_setters (moo) <= -1) return -1; - if (just_made) { @@ -7456,6 +7477,7 @@ static int __compile_class_definition (moo_t* moo, int extend) * inherit so that the inherited methods work well when they * access the trailer space */ moo->c->cls.self_oop->trsize = ((moo_oop_class_t)moo->c->cls.self_oop->superclass)->trsize; + moo->c->cls.self_oop->trgc = ((moo_oop_class_t)moo->c->cls.self_oop->superclass)->trgc; } } @@ -7614,10 +7636,9 @@ static moo_oop_t token_to_literal (moo_t* moo, int rdonly) } /* [NOTE] i don't mark RDONLY on a value resolved via an identifier */ - } - case MOO_IOTOK_BABRACK: /* #[ - byte array literal parenthesis */ + case MOO_IOTOK_HASHBRACK: /* #[ - byte array literal parenthesis */ { moo_oop_t lit; if (read_byte_array_literal(moo, &lit) <= -1) return MOO_NULL; @@ -7629,7 +7650,7 @@ static moo_oop_t token_to_literal (moo_t* moo, int rdonly) return lit; } - case MOO_IOTOK_APAREN: /* #( - array literal parenthesis */ + case MOO_IOTOK_HASHPAREN: /* #( - array literal parenthesis */ { moo_oop_t lit; if (read_array_literal(moo, rdonly, &lit) <= -1) return MOO_NULL; diff --git a/moo/lib/err.c b/moo/lib/err.c index bbd0f9d..a8243c4 100644 --- a/moo/lib/err.c +++ b/moo/lib/err.c @@ -47,7 +47,7 @@ static moo_ooch_t errstr_13[] = {'n','o','t',' ','a',' ','d','i','r','e','c','t' static moo_ooch_t errstr_14[] = {'i','n','t','e','r','r','u','p','t','e','d','\0'}; static moo_ooch_t errstr_15[] = {'p','i','p','e',' ','e','r','r','o','r','\0'}; static moo_ooch_t errstr_16[] = {'r','e','s','o','u','r','c','e',' ','t','e','m','p','o','r','a','r','i','l','y',' ','u','n','a','v','a','i','l','a','b','l','e','\0'}; -static moo_ooch_t errstr_17[] = {'d','a','t','a',' ','t','o','o',' ','l','a','r','g','e','\0'}; +static moo_ooch_t errstr_17[] = {'d','a','t','a',' ','n','o','t',' ','a','v','a','i','l','a','b','l','e','\0'}; static moo_ooch_t errstr_18[] = {'m','e','s','s','a','g','e',' ','r','e','c','e','i','v','e','r',' ','e','r','r','o','r','\0'}; static moo_ooch_t errstr_19[] = {'m','e','s','s','a','g','e',' ','s','e','n','d','i','n','g',' ','e','r','r','o','r','\0'}; static moo_ooch_t errstr_20[] = {'w','r','o','n','g',' ','n','u','m','b','e','r',' ','o','f',' ','a','r','g','u','m','e','n','t','s','\0'}; diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 8994c34..b84ded1 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -232,6 +232,18 @@ static int ignite_1 (moo_t* moo) !moo->_small_pointer || !moo->_system) return -1; MOO_OBJ_SET_CLASS (moo->_nil, (moo_oop_t)moo->_undefined_object); + +#if defined(MOO_USE_METHOD_TRAILER) + /* an instance of a method class stores byte codes in the trailer space + * when compiled with MOO_USE_METHOD_TRAILER. unlike other classes with + * trailer size set, the size of the trailer space is not really determined + * by the traailer size set in the class. the compiler determines the + * actual size of the trailer space depending on the byte codes generated. + * i should set the following fields to avoid confusion at the GC phase. */ + moo->_method->trsize = MOO_SMOOI_TO_OOP(0); + moo->_method->trgc = MOO_SMPTR_TO_OOP(0); +#endif + return 0; } @@ -419,7 +431,6 @@ static MOO_INLINE moo_oow_t get_payload_bytes (moo_t* moo, moo_oop_t oop) { moo_oow_t nbytes_aligned; -#if defined(MOO_USE_METHOD_TRAILER) if (MOO_OBJ_GET_FLAGS_TRAILER(oop)) { moo_oow_t nbytes; @@ -446,12 +457,9 @@ static MOO_INLINE moo_oow_t get_payload_bytes (moo_t* moo, moo_oop_t oop) } else { -#endif /* calculate the payload size in bytes */ nbytes_aligned = MOO_ALIGN (MOO_OBJ_BYTESOF(oop), MOO_SIZEOF(moo_oop_t)); -#if defined(MOO_USE_METHOD_TRAILER) } -#endif return nbytes_aligned; } @@ -517,7 +525,6 @@ static moo_uint8_t* scan_new_heap (moo_t* moo, moo_uint8_t* ptr) oop = (moo_oop_t)ptr; - #if defined(MOO_USE_METHOD_TRAILER) if (MOO_OBJ_GET_FLAGS_TRAILER(oop)) { moo_oow_t nbytes; @@ -532,11 +539,8 @@ static moo_uint8_t* scan_new_heap (moo_t* moo, moo_uint8_t* ptr) } else { - #endif nbytes_aligned = MOO_ALIGN (MOO_OBJ_BYTESOF(oop), MOO_SIZEOF(moo_oop_t)); - #if defined(MOO_USE_METHOD_TRAILER) } - #endif MOO_OBJ_SET_CLASS (oop, moo_moveoop(moo, (moo_oop_t)MOO_OBJ_GET_CLASS(oop))); if (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_OOP) @@ -566,6 +570,25 @@ static moo_uint8_t* scan_new_heap (moo_t* moo, moo_uint8_t* ptr) } } + if (MOO_OBJ_GET_FLAGS_TRAILER(oop)) + { + moo_oop_class_t c; + moo_trgc_t trgc; + + /* i use SMPTR(0) to indicate no trailer gc callback. + * i don't use moo->_nil because c->trgc field may not have + * been updated to a new nil address while moo->_nil could + * have been updated in the process of garbage collection. + * this comment will be invalidated when moo->_nil is + * stored in a permanent heap or GC gets changed to + * a non-copying collector. no matter what GC implementation + * i choose, using SMPTR(0) for this purpose is safe. */ + c = MOO_OBJ_GET_CLASS(oop); + MOO_ASSERT(moo, MOO_OOP_IS_SMPTR(c->trgc)); + trgc = MOO_OOP_TO_SMPTR(c->trgc); + if (trgc) trgc (moo, oop); + } + ptr = ptr + MOO_SIZEOF(moo_obj_t) + nbytes_aligned; } diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 426f8c5..aee85eb 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -345,8 +345,9 @@ struct moo_iotok_t MOO_IOTOK_IDENT_DOTTED, MOO_IOTOK_BINSEL, MOO_IOTOK_KEYWORD, - MOO_IOTOK_ASSIGN, - MOO_IOTOK_COLON, + MOO_IOTOK_ASSIGN, /* := */ + MOO_IOTOK_COLON, /* : */ + MOO_IOTOK_PERCENT, /* % */ MOO_IOTOK_RETURN, /* ^ */ MOO_IOTOK_LOCAL_RETURN, /* ^^ */ MOO_IOTOK_LBRACE, @@ -355,10 +356,10 @@ struct moo_iotok_t MOO_IOTOK_RBRACK, MOO_IOTOK_LPAREN, MOO_IOTOK_RPAREN, - MOO_IOTOK_APAREN, /* #( - array literal */ - MOO_IOTOK_BABRACK, /* #[ - byte array literal */ - MOO_IOTOK_ABRACE, /* #{ - array expression */ - MOO_IOTOK_DICBRACE, /* :{ - dictionary expression */ + MOO_IOTOK_HASHPAREN, /* #( - array literal */ + MOO_IOTOK_HASHBRACK, /* #[ - byte array literal */ + MOO_IOTOK_PERCPAREN, /* %{ - array expression */ + MOO_IOTOK_PERCBRACE, /* %{ - dictionary expression */ MOO_IOTOK_PERIOD, MOO_IOTOK_COMMA, MOO_IOTOK_SEMICOLON @@ -1009,14 +1010,12 @@ moo_oop_t moo_allocoopobj ( moo_oow_t size ); -#if defined(MOO_USE_METHOD_TRAILER) moo_oop_t moo_allocoopobjwithtrailer ( moo_t* moo, moo_oow_t size, const moo_oob_t* tptr, moo_oow_t tlen ); -#endif moo_oop_t moo_alloccharobj ( moo_t* moo, diff --git a/moo/lib/moo.c b/moo/lib/moo.c index 91ab0a8..60fa7e4 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -829,23 +829,35 @@ int moo_genpfmethods (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class, const moo_pfbase_t* moo_findpfbase (moo_t* moo, moo_pfinfo_t* pfinfo, moo_oow_t pfcount, const moo_ooch_t* name, moo_oow_t namelen) { - moo_oow_t left, right, mid; int n; /* binary search */ +#if 0 + /* [NOTE] this algorithm is NOT underflow safe with moo_oow_t types */ + int left, right, mid; - left = 0; right = pfcount - 1; - - while (left <= right) + for (left = 0, right = pfcount - 1; left <= right; ) { /*mid = (left + right) / 2;*/ mid = left + ((right - left) / 2); n = moo_compoocharsoocstr (name, namelen, pfinfo[mid].mthname); - if (n < 0) right = mid - 1; + if (n < 0) right = mid - 1; /* this substraction can make right negative. so i can't use moo_oow_t for the variable */ else if (n > 0) left = mid + 1; else return &pfinfo[mid].base; } +#else + /* [NOTE] this algorithm is underflow safe with moo_oow_t types */ + moo_oow_t base, mid, lim; + + for (base = 0, lim = pfcount; lim > 0; lim >>= 1) + { + mid = base + (lim >> 1); + n = moo_compoocharsoocstr (name, namelen, pfinfo[mid].mthname); + if (n == 0) return &pfinfo[mid].base; + if (n > 0) { base = mid + 1; lim--; } + } +#endif moo_seterrnum (moo, MOO_ENOENT); return MOO_NULL; @@ -853,14 +865,14 @@ moo_pfbase_t* moo_findpfbase (moo_t* moo, moo_pfinfo_t* pfinfo, moo_oow_t pfcoun /* -------------------------------------------------------------------------- */ -int moo_setclasstrsize (moo_t* moo, moo_oop_class_t _class, moo_oow_t size) +int moo_setclasstrsize (moo_t* moo, moo_oop_class_t _class, moo_oow_t size, moo_trgc_t trgc) { moo_oop_class_t sc; moo_oow_t spec; MOO_ASSERT (moo, MOO_CLASSOF(moo, _class) == moo->_class); - MOO_ASSERT (moo, size <= MOO_SMOOI_MAX); - + MOO_ASSERT (moo, size <= MOO_SMOOI_MAX); + if (_class == moo->_method) { /* the bytes code emitted by the compiler go to the trailer part @@ -884,12 +896,14 @@ int moo_setclasstrsize (moo_t* moo, moo_oop_class_t _class, moo_oow_t size) if (_class->trsize != moo->_nil) { + MOO_ASSERT (moo, _class->trgc != moo->_nil); MOO_DEBUG3 (moo, "Not allowed to re-set trailer size to %zu on the %.*js class\n", size, MOO_OBJ_GET_SIZE(_class->name), MOO_OBJ_GET_CHAR_SLOT(_class->name)); goto eperm; } + MOO_ASSERT (moo, _class->trgc == moo->_nil); sc = (moo_oop_class_t)_class->superclass; if (MOO_OOP_IS_SMOOI(sc->trsize) && size < MOO_OOP_TO_SMOOI(sc->trsize)) @@ -906,10 +920,13 @@ int moo_setclasstrsize (moo_t* moo, moo_oop_class_t _class, moo_oow_t size) /* you can only set the trailer size once when it's not set yet */ _class->trsize = MOO_SMOOI_TO_OOP(size); - MOO_DEBUG3 (moo, "Set trailer size to %zu on the %.*js class\n", + _class->trgc = MOO_SMPTR_TO_OOP(trgc); /* i don't replace NULL by nil for GC safety. */ + + MOO_DEBUG5 (moo, "Set trailer size to %zu on the %.*js class with gc callback of %p(%p)\n", size, MOO_OBJ_GET_SIZE(_class->name), - MOO_OBJ_GET_CHAR_SLOT(_class->name)); + MOO_OBJ_GET_CHAR_SLOT(_class->name), + MOO_SMPTR_TO_OOP(trgc), trgc); return 0; eperm: diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 7e719a4..721334f 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -64,7 +64,7 @@ enum moo_errnum_t MOO_EPIPE, MOO_EAGAIN, - MOO_ETOOBIG, /**< data too large */ + MOO_ENOAVAIL, /**< data not available*/ MOO_EMSGRCV, /**< mesasge receiver error */ MOO_EMSGSND, /**< message sending error. even doesNotUnderstand: is not found */ MOO_ENUMARGS, /**< wrong number of arguments */ @@ -494,7 +494,7 @@ struct moo_dic_t typedef struct moo_nsdic_t moo_nsdic_t; typedef struct moo_nsdic_t* moo_oop_nsdic_t; -#define MOO_CLASS_NAMED_INSTVARS 17 +#define MOO_CLASS_NAMED_INSTVARS 18 typedef struct moo_class_t moo_class_t; typedef struct moo_class_t* moo_oop_class_t; @@ -538,6 +538,7 @@ struct moo_class_t moo_oop_nsdic_t nsdic; /* dictionary used for namespacing - may be nil when there are no subitems underneath */ moo_oop_t trsize; /* trailer size for new instances */ + moo_oop_t trgc; /* trailer gc callback */ /* [0] - initial values for instance variables of new instances * [1] - initial values for class instance variables */ @@ -980,7 +981,6 @@ struct moo_mod_data_t }; typedef struct moo_mod_data_t moo_mod_data_t; - struct moo_sbuf_t { moo_ooch_t* ptr; @@ -989,6 +989,9 @@ struct moo_sbuf_t }; typedef struct moo_sbuf_t moo_sbuf_t; +/* special callback to be called for trailer */ +typedef void (*moo_trgc_t) (moo_t* moo, moo_oop_t obj); + /* ========================================================================= * MOO VM * ========================================================================= */ @@ -1623,7 +1626,8 @@ MOO_EXPORT moo_oop_t moo_findclass ( MOO_EXPORT int moo_setclasstrsize ( moo_t* moo, moo_oop_class_t _class, - moo_oow_t size + moo_oow_t size, + moo_trgc_t trgc ); MOO_EXPORT void* moo_getobjtrailer ( diff --git a/moo/lib/obj.c b/moo/lib/obj.c index a1eea3a..3b5f13f 100644 --- a/moo/lib/obj.c +++ b/moo/lib/obj.c @@ -78,7 +78,6 @@ moo_oop_t moo_allocoopobj (moo_t* moo, moo_oow_t size) return (moo_oop_t)hdr; } -#if defined(MOO_USE_METHOD_TRAILER) moo_oop_t moo_allocoopobjwithtrailer (moo_t* moo, moo_oow_t size, const moo_oob_t* bptr, moo_oow_t blen) { moo_oop_oop_t hdr; @@ -112,7 +111,6 @@ moo_oop_t moo_allocoopobjwithtrailer (moo_t* moo, moo_oow_t size, const moo_oob_ return (moo_oop_t)hdr; } -#endif static MOO_INLINE moo_oop_t alloc_numeric_array (moo_t* moo, const void* ptr, moo_oow_t len, moo_obj_type_t type, moo_oow_t unit, int extra) { diff --git a/moo/mod/Makefile.am b/moo/mod/Makefile.am index 96e8d6e..04b87d8 100644 --- a/moo/mod/Makefile.am +++ b/moo/mod/Makefile.am @@ -70,8 +70,8 @@ libmoo_stdio_la_LDFLAGS = $(LDFLAGS_COMMON) libmoo_stdio_la_LIBADD = $(LIBADD_COMMON) if ENABLE_MOD_X11 -libmoo_x11_la_SOURCES = x11.c _x11.h +libmoo_x11_la_SOURCES = x11.c x11-win.c _x11.h libmoo_x11_la_CPPFLAGS = $(CPPFLAGS_COMMON) libmoo_x11_la_LDFLAGS = $(LDFLAGS_COMMON) -libmoo_x11_la_LIBADD = $(LIBADD_COMMON) -lxcb +libmoo_x11_la_LIBADD = $(LIBADD_COMMON) -lX11 endif diff --git a/moo/mod/Makefile.in b/moo/mod/Makefile.in index c03bbfe..7859ede 100644 --- a/moo/mod/Makefile.in +++ b/moo/mod/Makefile.in @@ -182,8 +182,9 @@ libmoo_stdio_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ @ENABLE_STATIC_MODULE_TRUE@am_libmoo_stdio_la_rpath = @ENABLE_MOD_X11_TRUE@libmoo_x11_la_DEPENDENCIES = \ @ENABLE_MOD_X11_TRUE@ $(am__DEPENDENCIES_1) -am__libmoo_x11_la_SOURCES_DIST = x11.c _x11.h -@ENABLE_MOD_X11_TRUE@am_libmoo_x11_la_OBJECTS = libmoo_x11_la-x11.lo +am__libmoo_x11_la_SOURCES_DIST = x11.c x11-win.c _x11.h +@ENABLE_MOD_X11_TRUE@am_libmoo_x11_la_OBJECTS = libmoo_x11_la-x11.lo \ +@ENABLE_MOD_X11_TRUE@ libmoo_x11_la-x11-win.lo libmoo_x11_la_OBJECTS = $(am_libmoo_x11_la_OBJECTS) libmoo_x11_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -454,10 +455,10 @@ libmoo_stdio_la_SOURCES = stdio.c _stdio.h libmoo_stdio_la_CPPFLAGS = $(CPPFLAGS_COMMON) libmoo_stdio_la_LDFLAGS = $(LDFLAGS_COMMON) libmoo_stdio_la_LIBADD = $(LIBADD_COMMON) -@ENABLE_MOD_X11_TRUE@libmoo_x11_la_SOURCES = x11.c _x11.h +@ENABLE_MOD_X11_TRUE@libmoo_x11_la_SOURCES = x11.c x11-win.c _x11.h @ENABLE_MOD_X11_TRUE@libmoo_x11_la_CPPFLAGS = $(CPPFLAGS_COMMON) @ENABLE_MOD_X11_TRUE@libmoo_x11_la_LDFLAGS = $(LDFLAGS_COMMON) -@ENABLE_MOD_X11_TRUE@libmoo_x11_la_LIBADD = $(LIBADD_COMMON) -lxcb +@ENABLE_MOD_X11_TRUE@libmoo_x11_la_LIBADD = $(LIBADD_COMMON) -lX11 all: all-am .SUFFIXES: @@ -559,6 +560,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_console_la-console.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_ffi_la-ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_stdio_la-stdio.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_x11_la-x11-win.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_x11_la-x11.Plo@am__quote@ .c.o: @@ -613,6 +615,13 @@ libmoo_x11_la-x11.lo: x11.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_x11_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmoo_x11_la-x11.lo `test -f 'x11.c' || echo '$(srcdir)/'`x11.c +libmoo_x11_la-x11-win.lo: x11-win.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_x11_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmoo_x11_la-x11-win.lo -MD -MP -MF $(DEPDIR)/libmoo_x11_la-x11-win.Tpo -c -o libmoo_x11_la-x11-win.lo `test -f 'x11-win.c' || echo '$(srcdir)/'`x11-win.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmoo_x11_la-x11-win.Tpo $(DEPDIR)/libmoo_x11_la-x11-win.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='x11-win.c' object='libmoo_x11_la-x11-win.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_x11_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmoo_x11_la-x11-win.lo `test -f 'x11-win.c' || echo '$(srcdir)/'`x11-win.c + mostlyclean-libtool: -rm -f *.lo diff --git a/moo/mod/_x11.h b/moo/mod/_x11.h index 9f93e35..acb7579 100644 --- a/moo/mod/_x11.h +++ b/moo/mod/_x11.h @@ -29,6 +29,42 @@ #include + +#include + +/* [NOTE] this header is for internal use only. + * so most of the declarations here don't have the moo_ prefix */ + +#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 +{ + Display* disp; + Window wind; +}; + + +typedef struct x11_t* oop_x11_t; +struct x11_t +{ + Display* disp; +}; + +typedef struct x11_trailer_t x11_trailer_t; +struct x11_trailer_t +{ + XEvent* curevt; +}; + #if defined(__cplusplus) extern "C" { #endif diff --git a/moo/mod/console.c b/moo/mod/console.c index 9f42406..5d50918 100644 --- a/moo/mod/console.c +++ b/moo/mod/console.c @@ -261,7 +261,7 @@ static moo_pfinfo_t pfinfos[] = static int import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) { - if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(console_t)) <= -1) return -1; + if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(console_t), MOO_NULL) <= -1) return -1; return 0; } diff --git a/moo/mod/ffi.c b/moo/mod/ffi.c index 1da0890..a281902 100644 --- a/moo/mod/ffi.c +++ b/moo/mod/ffi.c @@ -541,7 +541,7 @@ static moo_pfinfo_t pfinfos[] = static int import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) { - if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(ffi_t)) <= -1) return -1; + if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(ffi_t), MOO_NULL) <= -1) return -1; return 0; } diff --git a/moo/mod/stdio.c b/moo/mod/stdio.c index 81d037d..81ff27f 100644 --- a/moo/mod/stdio.c +++ b/moo/mod/stdio.c @@ -222,9 +222,8 @@ static moo_pfinfo_t pfinfos[] = /* ------------------------------------------------------------------------ */ static int import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) { - if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(stdio_t)) <= -1) return -1; + if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(stdio_t), MOO_NULL) <= -1) return -1; return 0; - /*return moo_genpfmethods (moo, mod, _class, pfinfos, MOO_COUNTOF(pfinfos));*/ } static moo_pfbase_t* query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name, moo_oow_t namelen) diff --git a/moo/mod/x11.c b/moo/mod/x11.c index 0db2a28..ef51c91 100644 --- a/moo/mod/x11.c +++ b/moo/mod/x11.c @@ -28,26 +28,8 @@ #include #include -#include #include -#define C MOO_METHOD_CLASS -#define I MOO_METHOD_INSTANCE - - -/** - * @brief Bit mask to find event type regardless of event source. - * - * Each event in the X11 protocol contains an 8-bit type code. - * The most-significant bit in this code is set if the event was - * generated from a SendEvent request. This mask can be used to - * determine the type of event regardless of how the event was - * generated. See the X11R6 protocol specification for details. - */ -#define XCB_EVENT_RESPONSE_TYPE_MASK (0x7f) -#define XCB_EVENT_RESPONSE_TYPE(e) (e->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) -#define XCB_EVENT_SENT(e) (e->response_type & ~XCB_EVENT_RESPONSE_TYPE_MASK) - typedef struct x11_modctx_t x11_modctx_t; struct x11_modctx_t @@ -55,159 +37,158 @@ struct x11_modctx_t moo_oop_class_t x11_class; }; -typedef struct x11_t x11_t; -struct x11_t -{ - xcb_connection_t* c; - xcb_screen_t* screen; - xcb_generic_event_t* curevt; /* most recent event received */ -}; - -typedef struct x11_win_t x11_win_t; -struct x11_win_t -{ - xcb_window_t id; - xcb_intern_atom_reply_t* dwar; - xcb_connection_t* c; -}; - -typedef struct x11_gc_t x11_gc_t; -struct x11_gc_t -{ - xcb_gcontext_t id; - xcb_window_t wid; - xcb_connection_t* c; -}; - /* ------------------------------------------------------------------------ */ static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs) { - x11_t* x11; - xcb_connection_t* c; + x11_trailer_t* x11; + Display* disp = MOO_NULL; + XEvent* curevt = MOO_NULL; + char* dispname = MOO_NULL; - x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); + x11 = (x11_trailer_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); -/* TODO: accept display target as a parameter */ - if (x11->c) + if (x11->disp) { - MOO_DEBUG0 (moo, " Unable to connect multiple times\n"); + MOO_DEBUG0 (moo, " Unable to open a display multiple times\n"); MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EEXIST); - return MOO_PF_SUCCESS; + goto oops; } - /* - name = MOO_STACK_GETARG(moo, nargs, 0); - - if (!MOO_OBJ_IS_CHAR_POINTER(name)) + if (nargs >= 1) { - moo_seterrnum (moo, MOO_EINVAL); - goto softfail; + moo_oop_t np; + + np = MOO_STACK_GETARG(moo, nargs, 0); + if (np != moo->_nil) + { + moo_oow_t bl; + + if (!MOO_OBJ_IS_CHAR_POINTER(np)) + { + MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL); + goto oops; + } + + bl = MOO_OBJ_GET_SIZE(np); + dispname = moo_dupootobcstr (moo, MOO_OBJ_GET_CHAR_SLOT(np), &bl); + if (!dispname) + { + MOO_DEBUG2 (moo, " Cannot convert display name %.*js\n", MOO_OBJ_GET_SIZE(np), MOO_OBJ_GET_CHAR_SLOT(np)); + MOO_STACK_SETRETTOERRNUM (moo, nargs); + goto oops; + } + } } - MOO_DEBUG3 (moo, " %.*js => %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, rcv->handle); - */ - - c = xcb_connect (MOO_NULL, MOO_NULL); - if (!c || xcb_connection_has_error(c)) + curevt = moo_allocmem (moo, MOO_SIZEOF(*x11->curevt)); + if (!curevt) { - MOO_DEBUG0 (moo, " Cannot connect to X11 server\n"); + MOO_STACK_SETRETTOERRNUM (moo, nargs); + goto oops; + } + + disp = XOpenDisplay(dispname); + if (!disp) + { + MOO_DEBUG1 (moo, " Cannot connect to X11 server %hs\n", XDisplayName(dispname)); MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ESYSERR); - return MOO_PF_SUCCESS; + goto oops; } - x11->screen = xcb_setup_roots_iterator(xcb_get_setup(c)).data; - x11->c = c; + x11->disp = disp; + x11->curevt = curevt; - MOO_ASSERT (moo, MOO_IN_SMPTR_RANGE(c)); + MOO_ASSERT (moo, MOO_IN_SMPTR_RANGE(disp)); - MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP(c)); + MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP(disp)); + if (dispname) moo_freemem (moo, dispname); + return MOO_PF_SUCCESS; + +oops: + if (disp) XCloseDisplay (disp); + if (curevt) moo_freemem (moo, curevt); + if (dispname) moo_freemem (moo, dispname); return MOO_PF_SUCCESS; } static moo_pfrc_t pf_disconnect (moo_t* moo, moo_ooi_t nargs) { - x11_t* x11; + x11_trailer_t* x11; - x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); + x11 = (x11_trailer_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); if (x11->curevt) { - free (x11->curevt); + moo_freemem (moo, x11->curevt); x11->curevt = MOO_NULL; } - if (x11->c) + + if (x11->disp) { - xcb_disconnect (x11->c); - x11->c = MOO_NULL; + XCloseDisplay (x11->disp); + x11->disp = MOO_NULL; } MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS; } -static moo_pfrc_t pf_get_fd (moo_t* moo, moo_ooi_t nargs) +static moo_pfrc_t pf_get_base (moo_t* moo, moo_ooi_t nargs) { - x11_t* x11; + x11_trailer_t* x11; - x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); + x11 = (x11_trailer_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - if (x11->c) + if (x11->disp) { - int c; - - c = xcb_get_file_descriptor(x11->c); - if (!MOO_IN_SMOOI_RANGE(c)) goto error; - MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(c)); + MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP (x11->disp)); } else { - error: - MOO_STACK_SETRETTOERRNUM (moo, nargs); /* TODO: be more specific about error code */ + MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ENOAVAIL); } return MOO_PF_SUCCESS; } -static moo_pfrc_t pf_getevent (moo_t* moo, moo_ooi_t nargs) +static moo_pfrc_t pf_get_fd (moo_t* moo, moo_ooi_t nargs) { - x11_t* x11; - xcb_generic_event_t* evt; - int e; + x11_trailer_t* x11; - x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); + x11 = (x11_trailer_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - evt = xcb_poll_for_event(x11->c); - if (x11->curevt) free (x11->curevt); - x11->curevt = evt; - - if (evt) + if (x11->disp) { - moo_oop_t llevt; - /*uint8_t evttype; + int c; - evttype = evt->response_type & 0x7F;*/ - x11->curevt = evt; - - /* - llevt = moo_oowtoint (moo, (moo_oow_t)evt); - if (!llevt) + c = ConnectionNumber(x11->disp); + if (!MOO_IN_SMOOI_RANGE(c)) { - llevt = MOO_ERROR_TO_OOP(moo->errnum); - free (evt); - x11->curevt = MOO_NULL; - }*/ - - MOO_ASSERT (moo, MOO_IN_SMPTR_RANGE(evt)); - llevt = MOO_SMPTR_TO_OOP(evt); - - MOO_STACK_SETRET (moo, nargs, llevt); + MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ERANGE); + } + else + { + MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(c)); + } } - else if ((e = xcb_connection_has_error(x11->c))) + else { - /* TODO: to be specific about the error */ - MOO_DEBUG1 (moo, " Error detected while getting an event - %d\n", e); - MOO_STACK_SETRETTOERRNUM (moo, nargs); + 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)) + { + XNextEvent (x11->disp, x11->curevt); + MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP(x11->curevt)); } else { @@ -220,453 +201,19 @@ static moo_pfrc_t pf_getevent (moo_t* moo, moo_ooi_t nargs) /* ------------------------------------------------------------------------ */ -static moo_pfrc_t pf_gc_draw_line (moo_t* moo, moo_ooi_t nargs) -{ - x11_gc_t* gc; - xcb_point_t pt[2]; - moo_oop_t a[4]; - - gc = (x11_gc_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - - a[0] = MOO_STACK_GETARG(moo, nargs, 0); - a[1] = MOO_STACK_GETARG(moo, nargs, 1); - a[2] = MOO_STACK_GETARG(moo, nargs, 2); - a[3] = MOO_STACK_GETARG(moo, nargs, 3); - if (!MOO_OOP_IS_SMOOI(a[0]) || !MOO_OOP_IS_SMOOI(a[1]) || - !MOO_OOP_IS_SMOOI(a[2]) || !MOO_OOP_IS_SMOOI(a[0])) goto reterr; - - pt[0].x = MOO_OOP_TO_SMOOI(a[0]); - pt[0].y = MOO_OOP_TO_SMOOI(a[1]); - pt[1].x = MOO_OOP_TO_SMOOI(a[2]); - pt[1].y = MOO_OOP_TO_SMOOI(a[3]); - - xcb_poly_line (gc->c, XCB_COORD_MODE_ORIGIN, gc->wid, gc->id, 2, pt); - xcb_flush (gc->c); - - MOO_STACK_SETRETTORCV (moo, nargs); - return MOO_PF_SUCCESS; - -reterr: - MOO_STACK_SETRETTOERRNUM (moo, nargs); /* More specific error code*/ - return MOO_PF_SUCCESS; -} - -static moo_pfrc_t pf_gc_draw_rect (moo_t* moo, moo_ooi_t nargs) -{ - x11_gc_t* gc; - xcb_rectangle_t r; - moo_oop_t a[4]; - - gc = (x11_gc_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - - a[0] = MOO_STACK_GETARG(moo, nargs, 0); - a[1] = MOO_STACK_GETARG(moo, nargs, 1); - a[2] = MOO_STACK_GETARG(moo, nargs, 2); - a[3] = MOO_STACK_GETARG(moo, nargs, 3); - if (!MOO_OOP_IS_SMOOI(a[0]) || !MOO_OOP_IS_SMOOI(a[1]) || - !MOO_OOP_IS_SMOOI(a[2]) || !MOO_OOP_IS_SMOOI(a[0])) - { - MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL); - return MOO_PF_SUCCESS; - } - - r.x = MOO_OOP_TO_SMOOI(a[0]); - r.y = MOO_OOP_TO_SMOOI(a[1]); - r.width = MOO_OOP_TO_SMOOI(a[2]); - r.height = MOO_OOP_TO_SMOOI(a[3]); - - xcb_poly_rectangle (gc->c, gc->wid, gc->id, 1, &r); - xcb_flush (gc->c); - - MOO_STACK_SETRETTORCV (moo, nargs); - return MOO_PF_SUCCESS; -} - - -static moo_pfrc_t pf_gc_fill_rect (moo_t* moo, moo_ooi_t nargs) -{ - x11_gc_t* gc; - xcb_rectangle_t r; - moo_oop_t a[4]; - - gc = (x11_gc_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - - a[0] = MOO_STACK_GETARG(moo, nargs, 0); - a[1] = MOO_STACK_GETARG(moo, nargs, 1); - a[2] = MOO_STACK_GETARG(moo, nargs, 2); - a[3] = MOO_STACK_GETARG(moo, nargs, 3); - if (!MOO_OOP_IS_SMOOI(a[0]) || !MOO_OOP_IS_SMOOI(a[1]) || - !MOO_OOP_IS_SMOOI(a[2]) || !MOO_OOP_IS_SMOOI(a[0])) - { - MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL); - return MOO_PF_SUCCESS; - } - - r.x = MOO_OOP_TO_SMOOI(a[0]); - r.y = MOO_OOP_TO_SMOOI(a[1]); - r.width = MOO_OOP_TO_SMOOI(a[2]); - r.height = MOO_OOP_TO_SMOOI(a[3]); - - xcb_poly_fill_rectangle (gc->c, gc->wid, gc->id, 1, &r); - xcb_flush (gc->c); - - MOO_STACK_SETRETTORCV (moo, nargs); - return MOO_PF_SUCCESS; -} - -static moo_pfrc_t pf_gc_change (moo_t* moo, moo_ooi_t nargs) -{ - x11_gc_t* gc; - moo_oop_t t; - moo_oow_t tmpoow; - uint32_t value; - - gc = (x11_gc_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - - t = MOO_STACK_GETARG(moo, nargs, 0); - if (!MOO_OOP_IS_SMOOI(t)) - { - einval: - MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL); - return MOO_PF_SUCCESS; - } - - if (moo_inttooow (moo, MOO_STACK_GETARG(moo, nargs, 1), &tmpoow) <= 0) goto einval; - value = tmpoow; - - /* XCB_GC_FUNCTION, XCB_GC_PLANE_MASK, XCB_GC_FOREGROUND, XCB_GC_BACKGROUND, etc - * this primitive allows only 1 value to be used. you must not specify - * a bitwise-ORed mask of more than 1 XCB_GC_XXX enumerator. */ - xcb_change_gc (gc->c, gc->id, MOO_OOP_TO_SMOOI(t), &value); - xcb_flush (gc->c); - - MOO_STACK_SETRETTORCV (moo, nargs); - return MOO_PF_SUCCESS; -} - -static moo_pfrc_t pf_gc_get_id (moo_t* moo, moo_ooi_t nargs) -{ - x11_gc_t* gc; - moo_oop_t x; - - gc = (x11_gc_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - - x = moo_oowtoint (moo, gc->id); - if (!x) return MOO_PF_HARD_FAILURE; - - MOO_STACK_SETRET (moo, nargs, x); - return MOO_PF_SUCCESS; -} - -static moo_pfrc_t pf_gc_kill (moo_t* moo, moo_ooi_t nargs) -{ - x11_gc_t* gc; - - gc = (x11_gc_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - -/* TODO: check on gc id */ - xcb_free_gc (gc->c, gc->id); - xcb_flush (gc->c); - - MOO_STACK_SETRETTORCV (moo, nargs); - return MOO_PF_SUCCESS; -} - -static moo_pfrc_t pf_gc_make (moo_t* moo, moo_ooi_t nargs) -{ - x11_gc_t* gc; - moo_oop_t t; - moo_oow_t tmpoow; - xcb_connection_t* c; - xcb_window_t wid; - xcb_gcontext_t gcid; - - gc = (x11_gc_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - - t = MOO_STACK_GETARG(moo, nargs, 0); - if (!MOO_OOP_IS_SMPTR(t)) - { - einval: - MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL); - return MOO_PF_SUCCESS; - } - c = MOO_OOP_TO_SMPTR(t); - - t = MOO_STACK_GETARG(moo, nargs, 1); - if (moo_inttooow (moo, t, &tmpoow) <= 0) goto einval; - wid = tmpoow; - - gcid = xcb_generate_id (c); - - t = moo_oowtoint (moo, gcid); - if (!t) - { - MOO_STACK_SETRETTOERRNUM (moo, nargs); - return MOO_PF_SUCCESS; - } - - xcb_create_gc (c, gcid, wid, 0, 0); - -/*TODO: use xcb_request_check() for error handling. xcb_create_gc_checked??? xxx_checked()... */ - xcb_flush (c); - - gc->id = gcid; - gc->wid = wid; - gc->c = c; - - MOO_STACK_SETRET (moo, nargs, t); - return MOO_PF_SUCCESS; -} - -/* ------------------------------------------------------------------------ */ -static moo_pfrc_t pf_win_get_dwatom (moo_t* moo, moo_ooi_t nargs) -{ - x11_win_t* win; - moo_oop_t x; - - win = (x11_win_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - - x = moo_oowtoint (moo, win->dwar->atom); - if (!x) - { - MOO_STACK_SETRETTOERRNUM (moo, nargs); - return MOO_PF_SUCCESS; - } - - MOO_STACK_SETRET (moo, nargs, x); - return MOO_PF_SUCCESS; -} - -static moo_pfrc_t pf_win_get_geometry (moo_t* moo, moo_ooi_t nargs) -{ - x11_win_t* win; - moo_oop_t t; - xcb_get_geometry_cookie_t gc; - xcb_get_geometry_reply_t* geom; - - win = (x11_win_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - t = MOO_STACK_GETARG(moo, nargs, 0); - - /* expecting an object composed of 4 object pointers */ - if (!MOO_OOP_IS_POINTER(t) || MOO_OBJ_GET_FLAGS_TYPE(t) != MOO_OBJ_TYPE_OOP || MOO_OBJ_GET_SIZE(t) != 4) - { - MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL); - return MOO_PF_SUCCESS; - } - - gc = xcb_get_geometry (win->c, win->id); - geom = xcb_get_geometry_reply (win->c, gc, NULL); - - ((moo_oop_oop_t)t)->slot[0] = MOO_SMOOI_TO_OOP(geom->x); - ((moo_oop_oop_t)t)->slot[1] = MOO_SMOOI_TO_OOP(geom->y); - ((moo_oop_oop_t)t)->slot[2] = MOO_SMOOI_TO_OOP(geom->width); - ((moo_oop_oop_t)t)->slot[3] = MOO_SMOOI_TO_OOP(geom->height); - - free (geom); - - MOO_STACK_SETRET (moo, nargs, t); - return MOO_PF_SUCCESS; -} - -static moo_pfrc_t pf_win_set_geometry (moo_t* moo, moo_ooi_t nargs) -{ - x11_win_t* win; - moo_oop_t t; - uint32_t values[4]; - int flags = 0, vcount = 0; - - win = (x11_win_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - t = MOO_STACK_GETARG(moo, nargs, 0); - - /* expecting an object composed of 4 object pointers */ - if (!MOO_OOP_IS_POINTER(t) || MOO_OBJ_GET_FLAGS_TYPE(t) != MOO_OBJ_TYPE_OOP || MOO_OBJ_GET_SIZE(t) != 4) - { - MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL); - return MOO_PF_SUCCESS; - } - - if (MOO_OOP_IS_SMOOI(((moo_oop_oop_t)t)->slot[0])) - { - flags |= XCB_CONFIG_WINDOW_X; - values[vcount++] = MOO_OOP_TO_SMOOI(((moo_oop_oop_t)t)->slot[0]); - } - if (MOO_OOP_IS_SMOOI(((moo_oop_oop_t)t)->slot[1])) - { - flags |= XCB_CONFIG_WINDOW_Y; - values[vcount++] = MOO_OOP_TO_SMOOI(((moo_oop_oop_t)t)->slot[1]); - } - if (MOO_OOP_IS_SMOOI(((moo_oop_oop_t)t)->slot[2])) - { - flags |= XCB_CONFIG_WINDOW_WIDTH; - values[vcount++] = MOO_OOP_TO_SMOOI(((moo_oop_oop_t)t)->slot[2]); - } - if (MOO_OOP_IS_SMOOI(((moo_oop_oop_t)t)->slot[3])) - { - flags |= XCB_CONFIG_WINDOW_HEIGHT; - values[vcount++] = MOO_OOP_TO_SMOOI(((moo_oop_oop_t)t)->slot[3]); - } - - xcb_configure_window (win->c, win->id, flags, values); - - MOO_STACK_SETRETTORCV (moo, nargs); - return MOO_PF_SUCCESS; -} - -static moo_pfrc_t pf_win_get_id (moo_t* moo, moo_ooi_t nargs) -{ - x11_win_t* win; - moo_oop_t x; - - win = (x11_win_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - - x = moo_oowtoint (moo, win->id); - if (!x) - { - MOO_STACK_SETRETTOERRNUM (moo, nargs); - return MOO_PF_SUCCESS; - } - - MOO_STACK_SETRET (moo, nargs, x); - return MOO_PF_SUCCESS; -} - -static moo_pfrc_t pf_win_kill (moo_t* moo, moo_ooi_t nargs) -{ - x11_win_t* win; - - win = (x11_win_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - -/* TODO: check on windows id */ - - xcb_unmap_window (win->c, win->id); /* TODO: check error code */ - xcb_destroy_window (win->c, win->id); - xcb_flush (win->c); - - MOO_STACK_SETRETTORCV (moo, nargs); - return MOO_PF_SUCCESS; -} - -static moo_pfrc_t pf_win_make (moo_t* moo, moo_ooi_t nargs) -{ - x11_win_t* win; - xcb_window_t wid; - - uint32_t mask; - uint32_t values[2]; - xcb_intern_atom_cookie_t cookie; - xcb_intern_atom_reply_t* reply; - - moo_oop_t a0, a1, a2, a3, a4; - - xcb_connection_t* c; - xcb_window_t parent; - xcb_screen_t* screen; - - win = (x11_win_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - - a0 = MOO_STACK_GETARG(moo, nargs, 0); /* connection - SmallPointer (xcb_connection_t*) */ - a1 = MOO_STACK_GETARG(moo, nargs, 1); /* x - SmallInteger */ - 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 */ - - - if (!MOO_OOP_IS_SMPTR(a0) || !MOO_OOP_IS_SMOOI(a1) || - !MOO_OOP_IS_SMOOI(a2) || !MOO_OOP_IS_SMOOI(a3) || !MOO_OOP_IS_SMOOI(a4)) - { - einval: - MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL); - return MOO_PF_SUCCESS; - } - - c = MOO_OOP_TO_SMPTR(a0); - screen = xcb_setup_roots_iterator(xcb_get_setup(c)).data; - - a0 = MOO_STACK_GETARG(moo, nargs, 5); /* parent - Integer (xcb_window_t - uint32_t) */ - if (a0 == moo->_nil) - { - parent = screen->root; - } - else - { - moo_oow_t tmpoow; - if (moo_inttooow(moo, a0, &tmpoow) <= 0) goto einval; - parent = tmpoow; - } - - wid = xcb_generate_id (c); - - a0 = moo_oowtoint (moo, wid); - if (!a0) - { - MOO_STACK_SETRETTOERRNUM (moo, nargs); - return MOO_PF_SUCCESS; - } - - mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; - values[0] = screen->white_pixel; - values[1] = XCB_EVENT_MASK_KEY_RELEASE | - XCB_EVENT_MASK_BUTTON_PRESS | - XCB_EVENT_MASK_BUTTON_RELEASE | - XCB_EVENT_MASK_BUTTON_RELEASE | - /*XCB_EVENT_MASK_BUTTON_MOTION |*/ - XCB_EVENT_MASK_EXPOSURE | - XCB_EVENT_MASK_STRUCTURE_NOTIFY | - /*XCB_EVENT_MASK_POINTER_MOTION |*/ - XCB_EVENT_MASK_ENTER_WINDOW | - XCB_EVENT_MASK_LEAVE_WINDOW/* | - XCB_EVENT_MASK_VISIBILITY_CHANGE */; - xcb_create_window ( - c, - XCB_COPY_FROM_PARENT, /* depth */ - wid, /* wid */ - parent, /* parent */ - MOO_OOP_TO_SMOOI(a1), /* x */ - MOO_OOP_TO_SMOOI(a2), /* y */ - MOO_OOP_TO_SMOOI(a3), /* width */ - MOO_OOP_TO_SMOOI(a4), /* height */ - 1, /* border width */ - XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */ - XCB_COPY_FROM_PARENT, - mask, - values - ); - - 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); - } - - xcb_map_window (c, wid); - xcb_flush (c); - - win->id = wid; - win->c = c; - - MOO_STACK_SETRET (moo, nargs, a0); - return MOO_PF_SUCCESS; -} - -/* ------------------------------------------------------------------------ */ - static moo_pfinfo_t x11_pfinfo[] = { - { I, { '_','c','o','n','n','e','c','t','\0' }, 0, { pf_connect, 0, 0 } }, - { I, { '_','d','i','s','c','o','n','n','e','c','t','\0' }, 0, { pf_disconnect, 0, 0 } }, - { I, { '_','g','e','t','_','e','v','e','n','t','\0'}, 0, { pf_getevent, 0, 0 } }, - { I, { '_','g','e','t','_','f','d','\0' }, 0, { pf_get_fd, 0, 0 } } + + { 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 } }, + { 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 } } }; 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)) <= -1) return -1; - /*return moo_genpfmethods(moo, mod, _class, x11_pfinfo, MOO_COUNTOF(x11_pfinfo));*/ + if (moo_setclasstrsize(moo, _class, MOO_SIZEOF(x11_t), MOO_NULL) <= -1) return -1; return 0; } @@ -681,7 +228,7 @@ static void x11_unload (moo_t* moo, moo_mod_t* mod) moo_freemem (moo, mod->ctx); } -static void x11_gc (moo_t* moo, moo_mod_t* mod) +static void gc_mod_x11 (moo_t* moo, moo_mod_t* mod) { x11_modctx_t* ctx = mod->ctx; @@ -714,7 +261,7 @@ int moo_mod_x11 (moo_t* moo, moo_mod_t* mod) return -1; } - mod->gc = x11_gc; + mod->gc = gc_mod_x11; mod->ctx = ctx; } @@ -727,82 +274,3 @@ int moo_mod_x11 (moo_t* moo, moo_mod_t* mod) /* ------------------------------------------------------------------------ */ -static moo_pfinfo_t x11_gc_pfinfo[] = -{ - { I, { '_','c','h','a','n','g','e','\0' }, 0, { pf_gc_change, 2, 2,} }, - { I, { '_','d','r','a','w','L','i','n','e','\0' }, 0, { pf_gc_draw_line, 4, 4 } }, - { I, { '_','d','r','a','w','R','e','c','t','\0' }, 0, { pf_gc_draw_rect, 4, 4 } }, - { I, { '_','f','i','l','l','R','e','c','t' }, 0, { pf_gc_fill_rect, 4, 4 } }, - { I, { '_','g','e','t','_','i','d','\0' }, 0, { pf_gc_get_id, 0, 0 } }, - { I, { '_','k','i','l','l','\0' }, 0, { pf_gc_kill, 0, 0 } }, - { I, { '_','m','a','k','e','\0' }, 0, { pf_gc_make, 2, 2 } } - -}; - -static int x11_gc_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) -{ - if (moo_setclasstrsize(moo, _class, MOO_SIZEOF(x11_gc_t)) <= -1) return -1; - return 0; -} - -static moo_pfbase_t* x11_gc_query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name, moo_oow_t namelen) -{ - return moo_findpfbase(moo, x11_gc_pfinfo, MOO_COUNTOF(x11_gc_pfinfo), name, namelen); -} - -static void x11_gc_unload (moo_t* moo, moo_mod_t* mod) -{ - /* anything? */ -} - -int moo_mod_x11_gc (moo_t* moo, moo_mod_t* mod) -{ - mod->import = x11_gc_import; - mod->query = x11_gc_query; - mod->unload = x11_gc_unload; - mod->gc = MOO_NULL; - mod->ctx = MOO_NULL; - - return 0; -} - - -/* ------------------------------------------------------------------------ */ - -static moo_pfinfo_t x11_win_pfinfo[] = -{ - { I, { '_','g','e','t','_','w','i','n','d','o','w','_','d','w','a','t','o','m','\0'}, 0, { pf_win_get_dwatom, 0, 0 } }, - { I, { '_','g','e','t','_','w','i','n','d','o','w','_','g','e','o','m','e','t','r','y','\0'}, 0, { pf_win_get_geometry, 1, 1 } }, - { I, { '_','g','e','t','_','w','i','n','d','o','w','_','i','d','\0' }, 0, { pf_win_get_id, 0, 0 } }, - { I, { '_','k','i','l','l','_','w','i','n','d','o','w','\0' }, 0, { pf_win_kill, 0, 0 } }, - { I, { '_','m','a','k','e','_','w','i','n','d','o','w','\0' }, 0, { pf_win_make, 6, 6 } }, - { I, { '_','s','e','t','_','w','i','n','d','o','w','_','g','e','o','m','e','t','r','y','\0'}, 0, { pf_win_set_geometry, 1, 1 } } -}; - -static int x11_win_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) -{ - if (moo_setclasstrsize(moo, _class, MOO_SIZEOF(x11_win_t)) <= -1) return -1; - /*return moo_genpfmethods(moo, mod, _class, x11_win_pfinfo, MOO_COUNTOF(x11_win_pfinfo));*/ - return 0; -} - -static moo_pfbase_t* x11_win_query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name, moo_oow_t namelen) -{ - return moo_findpfbase(moo, x11_win_pfinfo, MOO_COUNTOF(x11_win_pfinfo), name, namelen); -} - -static void x11_win_unload (moo_t* moo, moo_mod_t* mod) -{ - /* anything? */ -} - -int moo_mod_x11_win (moo_t* moo, moo_mod_t* mod) -{ - mod->import = x11_win_import; - mod->query = x11_win_query; - mod->unload = x11_win_unload; - mod->gc = MOO_NULL; - mod->ctx = MOO_NULL; - - return 0; -}