Author: Tim Felgentreff <[email protected]>
Branch: rbitblt
Changeset: r558:c8495a907803
Date: 2014-01-09 11:34 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/c8495a907803/
Log: implement GET_NEXT_EVENT, DEFER_UPDATES, and FORCE_DISPLAY_UPDATE
diff --git a/spyvm/display.py b/spyvm/display.py
--- a/spyvm/display.py
+++ b/spyvm/display.py
@@ -6,16 +6,40 @@
from rsdl import RSDL, RSDL_helper
-MOUSE_BTN_RIGHT = 1
-MOUSE_BTN_MIDDLE = 2
-MOUSE_BTN_LEFT = 4
-MOD_SHIFT = 1
-MOD_CONTROL = 2
-MOD_ALT_CMD = 16 | 8
+# EventSensorConstants
+RedButtonBit = 4
+BlueButtonBit = 2
+YellowButtonBit = 1
+
+ShiftKeyBit = 1
+CtrlKeyBit = 2
+OptionKeyBit = 4
+CommandKeyBit = 8
+
+EventTypeNone = 0
+EventTypeMouse = 1
+EventTypeKeyboard = 2
+EventTypeDragDropFiles = 3
+EventTypeMenu = 4
+EventTypeWindow = 5
+EventTypeComplex = 6
+
+EventKeyChar = 0
+EventKeyDown = 1
+EventKeyUp = 2
+
+WindowEventMetricChange = 1
+WindowEventClose = 2
+WindowEventIconise = 3
+WindowEventActivated = 4
+WindowEventPaint = 5
+WindowEventStinks = 6
+
class SDLDisplay(object):
_attrs_ = ["screen", "width", "height", "depth", "surface", "has_surface",
- "mouse_position", "button", "key", "interrupt_key"]
+ "mouse_position", "button", "key", "interrupt_key",
"_defer_updates",
+ "_deferred_event"]
def __init__(self, title):
assert RSDL.Init(RSDL.INIT_VIDEO) >= 0
@@ -27,6 +51,8 @@
self.interrupt_key = 15 << 8 # pushing all four meta keys, of which we
support three...
self.button = 0
self.key = 0
+ self._deferred_event = None
+ self._defer_updates = False
def set_video_mode(self, w, h, d):
assert w > 0 and h > 0
@@ -47,8 +73,12 @@
def get_pixelbuffer(self):
return rffi.cast(rffi.ULONGP, self.screen.c_pixels)
- def flip(self):
- RSDL.Flip(self.screen)
+ def defer_updates(self, flag):
+ self._defer_updates = flag
+
+ def flip(self, force=False):
+ if (not self._defer_updates) or force:
+ RSDL.Flip(self.screen)
def set_squeak_colormap(self, screen):
# TODO: fix this up from the image
@@ -72,11 +102,11 @@
b = rffi.cast(RSDL.MouseButtonEventPtr, event)
btn = rffi.getintfield(b, 'c_button')
if btn == RSDL.BUTTON_RIGHT:
- btn = MOUSE_BTN_RIGHT
+ btn = YellowButtonBit
elif btn == RSDL.BUTTON_MIDDLE:
- btn = MOUSE_BTN_MIDDLE
+ btn = BlueButtonBit
elif btn == RSDL.BUTTON_LEFT:
- btn = MOUSE_BTN_LEFT
+ btn = RedButtonBit
if c_type == RSDL.MOUSEBUTTONDOWN:
self.button |= btn
@@ -114,7 +144,75 @@
if (interrupt & 0xFF == self.key and interrupt >> 8 ==
self.get_modifier_mask(0)):
raise KeyboardInterrupt
- def get_next_event(self):
+ def get_next_mouse_event(self, time):
+ mods = self.get_modifier_mask(3)
+ btn = self.button
+ if btn == RedButtonBit:
+ if mods & CtrlKeyBit:
+ btn = BlueButtonBit
+ elif mods & CommandKeyBit:
+ btn = YellowButtonBit
+ return [EventTypeMouse,
+ time,
+ int(self.mouse_position[0]),
+ int(self.mouse_position[1]),
+ btn,
+ mods,
+ 0,
+ 0]
+
+ def get_next_key_event(self, t, time):
+ mods = self.get_modifier_mask(3)
+ btn = self.button
+ return [EventTypeKeyboard,
+ time,
+ self.key,
+ t,
+ mods,
+ self.key,
+ 0,
+ 0]
+
+ def get_next_event(self, time=0):
+ if self._deferred_event:
+ deferred = self._deferred_event
+ self._deferred_event = None
+ return deferred
+
+ event = lltype.malloc(RSDL.Event, flavor="raw")
+ try:
+ if rffi.cast(lltype.Signed, RSDL.PollEvent(event)) == 1:
+ c_type = rffi.getintfield(event, 'c_type')
+ if c_type in [RSDL.MOUSEBUTTONDOWN, RSDL.MOUSEBUTTONUP]:
+ self.handle_mouse_button(c_type, event)
+ return self.get_next_mouse_event(time)
+ elif c_type == RSDL.MOUSEMOTION:
+ self.handle_mouse_move(c_type, event)
+ return self.get_next_mouse_event(time)
+ elif c_type == RSDL.KEYDOWN:
+ self.handle_keypress(c_type, event)
+ return self.get_next_key_event(EventKeyDown, time)
+ elif c_type == RSDL.KEYUP:
+ self._deferred_event = self.get_next_key_event(EventKeyUp,
time)
+ return self.get_next_key_event(EventKeyChar, time)
+ elif c_type == RSDL.VIDEORESIZE:
+ self.screen = RSDL.GetVideoSurface()
+ self._deferred_event = [EventTypeWindow, time,
WindowEventPaint,
+ 0, 0, int(self.screen.c_w),
int(self.screen.c_h), 0]
+ return [EventTypeWindow, time, WindowEventMetricChange,
+ 0, 0, int(self.screen.c_w), int(self.screen.c_h),
0]
+ elif c_type == RSDL.VIDEOEXPOSE:
+ self._deferred_event = [EventTypeWindow, time,
WindowEventPaint,
+ 0, 0, int(self.screen.c_w),
int(self.screen.c_h), 0]
+ return [EventTypeWindow, time, WindowEventActivated, 0, 0,
0, 0, 0]
+ elif c_type == RSDL.QUIT:
+ return [EventTypeWindow, time, WindowEventClose, 0, 0, 0,
0, 0]
+ finally:
+ lltype.free(event, flavor='raw')
+ return [EventTypeNone, 0, 0, 0, 0, 0, 0, 0]
+
+ # Old style event handling
+ def pump_events(self):
event = lltype.malloc(RSDL.Event, flavor="raw")
try:
if rffi.cast(lltype.Signed, RSDL.PollEvent(event)) == 1:
@@ -127,8 +225,6 @@
elif c_type == RSDL.KEYDOWN:
self.handle_keypress(c_type, event)
return
- elif c_type == RSDL.VIDEORESIZE:
- pass # TODO
elif c_type == RSDL.QUIT:
from spyvm.error import Exit
raise Exit("Window closed..")
@@ -140,19 +236,19 @@
mod = RSDL.GetModState()
modifier = 0
if mod & RSDL.KMOD_CTRL != 0:
- modifier |= MOD_CONTROL
+ modifier |= CtrlKeyBit
if mod & RSDL.KMOD_SHIFT != 0:
- modifier |= MOD_SHIFT
+ modifier |= ShiftKeyBit
if mod & RSDL.KMOD_ALT != 0:
- modifier |= MOD_ALT_CMD
+ modifier |= (OptionKeyBit | CommandKeyBit)
return modifier << shift
def mouse_point(self):
- self.get_next_event()
+ self.pump_events()
return self.mouse_position
def mouse_button(self):
- self.get_next_event()
+ self.pump_events()
mod = self.get_modifier_mask(3)
return self.button | mod
@@ -162,7 +258,7 @@
return key | self.get_modifier_mask(8)
def peek_keycode(self):
- self.get_next_event()
+ self.pump_events()
self.key |= self.get_modifier_mask(8)
return self.key
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -137,6 +137,8 @@
args += (interp.space.unwrap_array(w_arg), )
elif spec is char:
args += (unwrap_char(w_arg), )
+ elif spec is bool:
+ args += (interp.space.w_true is w_arg, )
else:
raise NotImplementedError(
"unknown unwrap_spec %s" % (spec, ))
@@ -625,9 +627,18 @@
w_point.store(interp.space, 1, interp.space.wrap_int(y))
return w_point
[email protected]_safe
[email protected]_inside
@expose_primitive(GET_NEXT_EVENT, unwrap_spec=[object, object])
def func(interp, s_frame, w_rcvr, w_into):
- raise PrimitiveNotYetWrittenError()
+ ary = interp.space.get_display().get_next_event(time=interp.time_now())
+ for i in range(8):
+ w_into.store(interp.space, i, interp.space.wrap_int(ary[i]))
+ # XXX - hack
+ if ary[0] == display.WindowEventMetricChange and ary[4] > 0 and ary[5] > 0:
+ if interp.image:
+ interp.image.lastWindowSize = ((ary[4] & 0xffff) << 16) | (ary[5]
& 0xffff)
+ return w_rcvr
@expose_primitive(BITBLT_COPY_BITS, clean_stack=False, no_result=True,
compiled_method=True)
def func(interp, s_frame, argcount, s_method):
@@ -908,9 +919,11 @@
# dont know when the space runs out
return w_reciver
-@expose_primitive(DEFER_UPDATES, unwrap_spec=[object, object])
-def func(interp, s_frame, w_receiver, w_bool):
- raise PrimitiveNotYetWrittenError()
+@expose_primitive(DEFER_UPDATES, unwrap_spec=[object, bool])
+def func(interp, s_frame, w_receiver, flag):
+ sdldisplay = interp.space.get_display()
+ sdldisplay.defer_updates(flag)
+ return w_receiver
@expose_primitive(DRAW_RECTANGLE, unwrap_spec=[object, int, int, int, int])
def func(interp, s_frame, w_rcvr, left, right, top, bottom):
@@ -1461,7 +1474,7 @@
@expose_primitive(FORCE_DISPLAY_UPDATE, unwrap_spec=[object])
def func(interp, s_frame, w_rcvr):
- interp.space.get_display().flip()
+ interp.space.get_display().flip(force=True)
return w_rcvr
# ___________________________________________________________________________
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit