Author: Lars Wassermann <[email protected]>
Branch: 
Changeset: r281:3d04096604cf
Date: 2013-04-16 11:12 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/3d04096604cf/

Log:    merge with tip

diff --git a/spyvm/display.py b/spyvm/display.py
--- a/spyvm/display.py
+++ b/spyvm/display.py
@@ -6,57 +6,26 @@
 from rsdl import RSDL, RSDL_helper
 
 
-class SDLEventQueue(object):
-    def __init__(self, default, maxlen=10):
-        assert default
-        self.default = default
-        self.contents = []
-        self.maxlen = 10
-
-    def push(self, event):
-        contents = self.contents
-        assert len(contents) <= self.maxlen
-        if len(contents) == self.maxlen:
-            contents.pop(0)
-        contents.append(event)
-
-    def shift(self):
-        contents = self.contents
-        assert len(contents) <= self.maxlen
-        if contents == []:
-            contents = list(self.default)
-        return contents.pop(0)
-
-    def peek(self):
-        contents = self.contents
-        assert len(contents) <= self.maxlen
-        if contents:
-            return contents[0]
-        else:
-            return self.default[0]
-
-    def size(self):
-        if not self.contents:
-            return len(self.default)
-        else:
-            return len(self.contents)
-
+MOUSE_BTN_RIGHT = 1
+MOUSE_BTN_MIDDLE = 2
+MOUSE_BTN_LEFT = 4
+MOD_SHIFT  = 8
+MOD_CONTROL = 16
+MOD_ALT = 64
 
 class SDLDisplay(object):
     _attrs_ = ["screen", "width", "height", "depth", "surface", "has_surface",
-               "last_mouse_position", "last_mouse_buttons", "mouse_downs", 
"mouse_ups", "key_ups", "key_downs"]
+               "mouse_position", "button", "key"]
 
     def __init__(self, title):
         assert RSDL.Init(RSDL.INIT_VIDEO) >= 0
         RSDL.WM_SetCaption(title, "RSqueakVM")
         RSDL.EnableUNICODE(1)
+        SDLCursor.has_display = True
         self.has_surface = False
-        self.last_mouse_position = [0, 0]
-        self.last_mouse_buttons = 0
-        self.mouse_downs = SDLEventQueue([0])
-        self.mouse_ups = SDLEventQueue([0])
-        self.key_ups = SDLEventQueue([0])
-        self.key_downs = SDLEventQueue([0])
+        self.mouse_position = [0, 0]
+        self.button = 0
+        self.key = 0
 
     def set_video_mode(self, w, h, d):
         assert w > 0 and h > 0
@@ -68,7 +37,7 @@
         assert self.screen
 
     def get_pixelbuffer(self):
-        return self.screen.c_pixels
+        return rffi.cast(rffi.ULONGP, self.screen.c_pixels)
 
     def flip(self):
         RSDL.Flip(self.screen)
@@ -85,51 +54,110 @@
                     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:
-                            button = 4
+                        if btn == RSDL.BUTTON_RIGHT:
+                            btn = MOUSE_BTN_RIGHT
                         elif btn == RSDL.BUTTON_MIDDLE:
-                            button = 2
-                        elif btn == RSDL.BUTTON_RIGHT:
-                            button = 1
+                            btn = MOUSE_BTN_MIDDLE
+                        elif btn == RSDL.BUTTON_LEFT:
+                            btn = MOUSE_BTN_LEFT
                         else:
                             assert 0
                             button = 0
                         
                         if c_type == RSDL.MOUSEBUTTONDOWN:
-                            self.mouse_downs.push(button)
+                            self.button |= btn
                             self.last_mouse_buttons |= button
                         else:
-                            self.mouse_ups.push(button)
+                            self.button &= ~btn
                             self.last_mouse_buttons &= ~button
                     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 = list([x, y])
+                        self.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))
+                            chars = unicode_encode_utf_8(unichr(char), 1, 
"ignore")
+                            if len(chars) == 1:
+                                if c_type == RSDL.KEYDOWN:
+                                    self.key = ord(chars[0])
                                 else:
-                                    self.key_downs.push(ord(c))
+                                    pass # XXX: Todo?
+                    elif c_type == RSDL.QUIT:
+                        exit(0)
         finally:
             lltype.free(event, flavor='raw')
 
+    def get_modifier_mask(self):
+        RSDL.PumpEvents()
+        mod = RSDL.GetModState()
+        modifier = 0
+        if mod & RSDL.KMOD_CTRL != 0:
+            modifier |= MOD_CONTROL
+        if mod & RSDL.KMOD_SHIFT != 0:
+            modifier |= MOD_SHIFT
+        if mod & RSDL.KMOD_ALT != 0:
+            modifier |= MOD_ALT
+        return modifier
+
     def mouse_point(self):
         self.get_next_event()
-        return self.last_mouse_position
+        return self.mouse_position
 
     def mouse_button(self):
         self.get_next_event()
-        return self.last_mouse_buttons
+        return self.button | self.get_modifier_mask()
 
     def next_keycode(self):
-        self.get_next_event()
-        return self.key_downs.shift()
+        key = self.key
+        self.key = 0
+        return key
 
     def peek_keycode(self):
         self.get_next_event()
-        return self.key_downs.peek()
+        return self.key
+
+
+class SDLCursorClass(object):
+    _attrs_ = ["cursor", "has_cursor", "has_display"]
+
+    instance = None
+
+    def __init__(self):
+        self.has_cursor = False
+        self.has_display = False
+
+    def set(self, data_words, w, h, x, y, mask_words=None):
+        if not self.has_display:
+            return
+        if self.has_cursor:
+            RSDL.FreeCursor(self.cursor)
+        try:
+            data = self.words_to_bytes(len(data_words) * 4, data_words)
+            try:
+                mask = self.words_to_bytes(len(data_words) * 4, mask_words)
+                self.cursor = RSDL.CreateCursor(data, mask, w * 2, h, x, y)
+                self.has_cursor = True
+                RSDL.SetCursor(self.cursor)
+            finally:
+                lltype.free(mask, flavor="raw")
+        finally:
+            lltype.free(data, flavor="raw")
+
+    def words_to_bytes(self, bytenum, words):
+        bytes = lltype.malloc(RSDL.Uint8P.TO, bytenum, flavor="raw")
+        if words:
+            for pos in range(bytenum / 4):
+                word = words[pos]
+                bytes[pos * 4] = rffi.r_uchar((word >> 24) & 0xff)
+                bytes[pos * 4 + 1] = rffi.r_uchar((word >> 16) & 0xff)
+                bytes[pos * 4 + 2] = rffi.r_uchar((word >> 8) & 0xff)
+                bytes[pos * 4 + 3] = rffi.r_uchar(word & 0xff)
+        else:
+            for idx in range(bytenum):
+                bytes[idx] = rffi.r_uchar(0)
+        return bytes
+
+SDLCursor = SDLCursorClass()
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -36,6 +36,11 @@
         space, as memory representation varies depending on PyPy 
translation."""
         return 0
 
+    def instsize(self, space):
+        """Return the size of the object reserved for instance variables.
+        Only returns something non-zero for W_PointersObjects"""
+        return 0
+
     def varsize(self, space):
         """Return bytesize of variable-sized part.
 
@@ -807,17 +812,15 @@
     @jit.unroll_safe
     def setword(self, n, word):
         self._real_depth_buffer[n] = word
-        pos = n * NATIVE_DEPTH * 4
+        pos = n * NATIVE_DEPTH
         mask = r_uint(1)
         mask <<= 31
         for i in xrange(32):
             bit = mask & word
-            self.pixelbuffer[pos] = rffi.r_uchar(0xff * (bit == 0))
-            self.pixelbuffer[pos + 1] = rffi.r_uchar(0xff * (bit == 0))
-            self.pixelbuffer[pos + 2] = rffi.r_uchar(0xff * (bit == 0))
-            self.pixelbuffer[pos + 3] = rffi.r_uchar(0xff)
+            pixel = r_uint((0x00ffffff * (bit == 0)) | r_uint(0xff000000))
+            self.pixelbuffer[pos] = pixel
             mask >>= 1
-            pos += 4
+            pos += 1
 
 
 # XXX Shouldn't compiledmethod have class reference for subclassed compiled
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -575,9 +575,34 @@
     # in case we return normally, we have to restore the removed w_rcvr
     return w_rcvr
 
-@expose_primitive(BE_CURSOR, unwrap_spec=[object])
-def func(interp, s_frame, w_rcvr):
-    # TODO: Use info from cursor object.
+@expose_primitive(BE_CURSOR)
+def func(interp, s_frame, argcount):
+    if not (0 <= argcount <= 1):
+        raise PrimitiveFailedError()
+    w_rcvr = s_frame.peek(argcount)
+    if argcount == 1:
+        # TODO: use mask
+        w_mask = s_frame.peek(0)
+        if not isinstance(w_mask, model.W_WordsObject):
+            raise PrimitiveFailedError()
+    else:
+        w_mask = None
+    w_bitmap = w_rcvr.fetch(interp.space, 0)
+    if not isinstance(w_bitmap, model.W_WordsObject):
+        raise PrimitiveFailedError()
+    width = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 1))
+    height = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 2))
+    depth = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 3))
+    hotpt = wrapper.PointWrapper(interp.space, w_rcvr.fetch(interp.space, 4))
+    display.SDLCursor.set(
+        w_bitmap.words,
+        width,
+        height,
+        hotpt.x(),
+        hotpt.y(),
+        w_mask.words if w_mask else None
+    )
+
     interp.space.objtable['w_cursor'] = w_rcvr
     return w_rcvr
 
@@ -647,8 +672,8 @@
     # might be different (e.g. Symbol and ByteString)
     if w_rcvr.__class__ is not w_replacement.__class__:
         raise PrimitiveFailedError()
-    if (w_rcvr.size() <= stop
-            or w_replacement.size() < repStart + (stop - start)):
+    if (w_rcvr.size() - w_rcvr.instsize(interp.space) <= stop
+            or w_replacement.size() - w_replacement.instsize(interp.space) <= 
repStart + (stop - start)):
         raise PrimitiveFailedError()
     repOff = repStart - start
     for i0 in range(start, stop + 1):
@@ -1128,7 +1153,7 @@
     if not w_rcvr.getclass(interp.space).is_same_object(
         interp.space.w_Semaphore):
         raise PrimitiveFailedError()
-    s_frame.push(w_rcvr) # w_rcvr is the result in the old frame
+    # s_frame.push(w_rcvr) # w_rcvr is the result in the old frame
     return wrapper.SemaphoreWrapper(interp.space, 
w_rcvr).wait(s_frame.w_self())
 
 @expose_primitive(RESUME, unwrap_spec=[object], result_is_new_frame=True)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to