Author: Tim Felgentreff <[email protected]>
Branch:
Changeset: r213:8a4ae64a404c
Date: 2013-03-18 18:16 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/8a4ae64a404c/
Log: add input primitives, using a bad queue for now. this'll go away
once we get the SDL event queue working with this.
diff --git a/spyvm/display.py b/spyvm/display.py
--- a/spyvm/display.py
+++ b/spyvm/display.py
@@ -1,15 +1,54 @@
from rpython.rlib.rarithmetic import r_uint
from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rlib.runicode import unicode_encode_utf_8
from rsdl import RSDL, RSDL_helper
+class SDLEventQueue(object):
+ def __init__(self, default, maxlen=10):
+ assert default
+ self.default = default
+ self.ary = []
+ self.maxlen = 10
+
+ def push(self, event):
+ if len(self.ary) == self.maxlen:
+ self.ary.pop(0)
+ self.ary.append(event)
+
+ def shift(self):
+ if not self.ary:
+ self.ary += self.default
+ return self.ary.pop(0)
+
+ def peek(self):
+ if self.ary:
+ return self.ary[0]
+ else:
+ return self.default[0]
+
+ def size(self):
+ if not self.ary:
+ return len(self.default)
+ else:
+ return len(self.ary)
+
+
class SDLDisplay(object):
- _attrs_ = ["screen", "width", "height", "depth", "surface", "has_surface"]
+ _attrs_ = ["screen", "width", "height", "depth", "surface", "has_surface",
+ "last_mouse_position", "mouse_downs", "mouse_ups", "key_ups",
"key_downs"]
- def __init__(self):
+ def __init__(self, title):
assert RSDL.Init(RSDL.INIT_VIDEO) >= 0
+ RSDL.WM_SetCaption(title, "RSqueakVM")
+ RSDL.EnableUNICODE(1)
self.has_surface = False
+ self.last_mouse_position = [0, 0]
+ self.mouse_downs = SDLEventQueue([0])
+ self.mouse_ups = SDLEventQueue([0])
+ self.key_ups = SDLEventQueue([0])
+ self.key_downs = SDLEventQueue([0])
def set_video_mode(self, w, h, d):
assert w > 0 and h > 0
@@ -39,3 +78,58 @@
def blit(self):
RSDL.BlitSurface(self.surface, lltype.nullptr(RSDL.Rect), self.screen,
lltype.nullptr(RSDL.Rect))
RSDL.Flip(self.screen)
+
+ def get_next_event(self):
+ event = lltype.malloc(RSDL.Event, flavor="raw")
+ ok = 1
+ try:
+ while ok == 1:
+ ok = rffi.cast(lltype.Signed, RSDL.PollEvent(event))
+ if ok == 1:
+ c_type = rffi.getintfield(event, 'c_type')
+ if c_type == RSDL.MOUSEBUTTONDOWN or c_type ==
RSDL.MOUSEBUTTONUP:
+ b = rffi.cast(RSDL.MouseButtonEventPtr, event)
+ btn = rffi.getintfield(b, 'c_button')
+ if btn == RSDL.BUTTON_LEFT:
+ btn = 1
+ elif btn == RSDL.BUTTON_MIDDLE:
+ btn = 2
+ elif btn == RSDL.BUTTON_RIGHT:
+ btn = 4
+
+ if c_type == RSDL.MOUSEBUTTONDOWN:
+ self.mouse_downs.push(btn)
+ else:
+ self.mouse_ups.push(btn)
+ elif c_type == RSDL.MOUSEMOTION:
+ m = rffi.cast(RSDL.MouseMotionEventPtr, event)
+ x = rffi.getintfield(m, "c_x")
+ y = rffi.getintfield(m, "c_y")
+ self.last_mouse_position = [x, y]
+ elif c_type == RSDL.KEYUP or c_type == RSDL.KEYDOWN:
+ p = rffi.cast(RSDL.KeyboardEventPtr, event)
+ char = rffi.getintfield(p.c_keysym, 'c_unicode')
+ if char != 0:
+ for c in unicode_encode_utf_8(unichr(char), 1,
"ignore"):
+ if c_type == RSDL.KEYUP:
+ self.key_ups.push(ord(c))
+ else:
+ self.key_downs.push(ord(c))
+ finally:
+ lltype.free(event, flavor='raw')
+
+ def mouse_point(self):
+ self.get_next_event()
+ return self.last_mouse_position
+
+ def mouse_button(self):
+ self.get_next_event()
+ return self.mouse_ups.shift()
+
+ def next_keycode(self):
+ self.get_next_event()
+ return self.key_downs.shift()
+
+ def peek_keycode(self):
+ self.get_next_event()
+ return self.key_downs.peek()
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -1,5 +1,5 @@
from spyvm import constants, model, shadow, wrapper
-from spyvm.error import UnwrappingError, WrappingError
+from spyvm.error import UnwrappingError, WrappingError, PrimitiveFailedError
from rpython.rlib.objectmodel import instantiate, specialize
from rpython.rlib.rarithmetic import intmask, r_uint, int_between
@@ -270,7 +270,15 @@
assert isinstance(w_array, model.W_PointersObject)
return [w_array.at0(self, i) for i in range(w_array.size())]
-
+
+ def get_display(self):
+ w_display = self.objtable['w_display']
+ if w_display:
+ w_bitmap = w_display.fetch(self, 0)
+ if isinstance(w_bitmap, model.W_DisplayBitmap):
+ return w_bitmap.display
+ raise PrimitiveFailedError()
+
def _freeze_(self):
return True
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -540,6 +540,14 @@
KBD_PEEK = 109
+@expose_primitive(MOUSE_POINT, unwrap_spec=[object])
+def func(interp, s_frame, w_rcvr):
+ x, y = interp.space.get_display().mouse_point()
+ w_point = model.W_PointersObject(interp.space.w_Point, 2)
+ w_point.store(interp.space, 0, interp.space.wrap_int(x))
+ w_point.store(interp.space, 1, interp.space.wrap_int(y))
+ return w_point
+
@expose_primitive(GET_NEXT_EVENT, unwrap_spec=[object])
def func(interp, s_frame, w_rcvr):
raise PrimitiveNotYetWrittenError()
@@ -593,7 +601,7 @@
else:
assert isinstance(w_bitmap, model.W_WordsObject)
if not sdldisplay:
- sdldisplay = display.SDLDisplay()
+ sdldisplay = display.SDLDisplay(interp.image_name)
w_display_bitmap =
model.W_DisplayBitmap(w_bitmap.getclass(interp.space), w_bitmap.size(), depth,
sdldisplay)
for idx, word in enumerate(w_bitmap.words):
w_display_bitmap.setword(idx, word)
@@ -630,7 +638,6 @@
w_rcvr.atput0(interp.space, i0, w_replacement.at0(interp.space, repOff
+ i0))
return w_rcvr
-
@expose_primitive(SCREEN_SIZE, unwrap_spec=[object])
def func(interp, s_frame, w_rcvr):
# XXX get the real screen size
@@ -640,6 +647,20 @@
point.store_y(480)
return w_res
+@expose_primitive(MOUSE_BUTTONS, unwrap_spec=[object])
+def func(interp, s_frame, w_rcvr):
+ btn = interp.space.get_display().mouse_button()
+ return interp.space.wrap_int(btn)
+
+@expose_primitive(KBD_NEXT, unwrap_spec=[object])
+def func(interp, s_frame, w_rcvr):
+ return interp.space.wrap_int(interp.space.get_display().next_keycode())
+
+@expose_primitive(KBD_PEEK, unwrap_spec=[object])
+def func(interp, s_frame, w_rcvr):
+ return interp.space.wrap_int(interp.space.get_display().peek_keycode())
+
+
# ___________________________________________________________________________
# Control Primitives
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit