Index: src/views/unix/SkOSWindow_Unix.cpp |
diff --git a/src/views/unix/SkOSWindow_Unix.cpp b/src/views/unix/SkOSWindow_Unix.cpp |
index a20644556dc8e18509ae1fc5f47f1991ec6d1792..591493e57eee9987e3ec36ae25b71d28a940f837 100644 |
--- a/src/views/unix/SkOSWindow_Unix.cpp |
+++ b/src/views/unix/SkOSWindow_Unix.cpp |
@@ -149,23 +149,6 @@ void SkOSWindow::initWindow(int requestedMSAASampleCount, AttachmentInfo* info) |
fUnixWindow.fGc = XCreateGC(dsp, fUnixWindow.fWin, 0, NULL); |
} |
- |
-void SkOSWindow::post_linuxevent() { |
- // Put an event in the X queue to fire an SkEvent. |
- if (NULL == fUnixWindow.fDisplay) { |
- return; |
- } |
- XClientMessageEvent event; |
- event.type = ClientMessage; |
- Atom myAtom(0); |
- event.message_type = myAtom; |
- event.format = 32; |
- event.data.l[0] = 0; |
- XSendEvent(fUnixWindow.fDisplay, fUnixWindow.fWin, false, 0, |
- (XEvent*) &event); |
- XFlush(fUnixWindow.fDisplay); |
-} |
- |
static unsigned getModi(const XEvent& evt) { |
static const struct { |
unsigned fXMask; |
@@ -186,6 +169,81 @@ static unsigned getModi(const XEvent& evt) { |
return modi; |
} |
+static SkMSec gTimerDelay; |
+ |
+static void MyXNextEventWithDelay(Display* dsp, XEvent* evt) { |
+ SkMSec ms = gTimerDelay; |
+ if (ms > 0) { |
+ int x11_fd = ConnectionNumber(dsp); |
+ fd_set input_fds; |
+ FD_ZERO(&input_fds); |
+ FD_SET(x11_fd, &input_fds); |
+ |
+ timeval tv; |
+ tv.tv_sec = ms / 1000; // seconds |
+ tv.tv_usec = (ms % 1000) * 1000; // microseconds |
+ |
+ (void)select(x11_fd + 1, &input_fds, NULL, NULL, &tv); |
+ } |
+ |
+ if (XPending(dsp)) { |
+ XNextEvent(dsp, evt); |
+ } |
+} |
+ |
+SkOSWindow::NextXEventResult SkOSWindow::nextXEvent() { |
+ XEvent evt; |
+ Display* dsp = fUnixWindow.fDisplay; |
+ |
+ MyXNextEventWithDelay(fUnixWindow.fDisplay, &evt); |
+ |
+ switch (evt.type) { |
+ case Expose: |
+ if (0 == evt.xexpose.count) { |
+ return kPaintRequest_NextXEventResult; |
+ } |
+ break; |
+ case ConfigureNotify: |
+ this->resize(evt.xconfigure.width, evt.xconfigure.height); |
+ break; |
+ case ButtonPress: |
+ if (evt.xbutton.button == Button1) |
+ this->handleClick(evt.xbutton.x, evt.xbutton.y, |
+ SkView::Click::kDown_State, NULL, getModi(evt)); |
+ break; |
+ case ButtonRelease: |
+ if (evt.xbutton.button == Button1) |
+ this->handleClick(evt.xbutton.x, evt.xbutton.y, |
+ SkView::Click::kUp_State, NULL, getModi(evt)); |
+ break; |
+ case MotionNotify: |
+ this->handleClick(evt.xmotion.x, evt.xmotion.y, |
+ SkView::Click::kMoved_State, NULL, getModi(evt)); |
+ break; |
+ case KeyPress: { |
+ int shiftLevel = (evt.xkey.keycode & ShiftMask) ? 1 : 0; |
+ KeySym keysym = XkbKeycodeToKeysym(dsp, evt.xkey.keycode, |
+ 0, shiftLevel); |
+ if (keysym == XK_Escape) { |
+ return kQuitRequest_NextXEventResult; |
+ } |
+ this->handleKey(XKeyToSkKey(keysym)); |
+ long uni = keysym2ucs(keysym); |
+ if (uni != -1) { |
+ this->handleChar((SkUnichar) uni); |
+ } |
+ break; |
+ } |
+ case KeyRelease: |
+ this->handleKeyUp(XKeyToSkKey(XkbKeycodeToKeysym(dsp, evt.xkey.keycode, 0, 0))); |
+ break; |
+ default: |
+ // Do nothing for other events |
+ break; |
+ } |
+ return kContinue_NextXEventResult; |
+} |
+ |
void SkOSWindow::loop() { |
Display* dsp = fUnixWindow.fDisplay; |
if (NULL == dsp) { |
@@ -193,58 +251,31 @@ void SkOSWindow::loop() { |
} |
XSelectInput(dsp, fUnixWindow.fWin, EVENT_MASK); |
- bool loop = true; |
- XEvent evt; |
- while (loop) { |
- XNextEvent(dsp, &evt); |
- switch (evt.type) { |
- case Expose: |
- if (evt.xexpose.count == 0) |
- this->inval(NULL); |
- break; |
- case ConfigureNotify: |
- this->resize(evt.xconfigure.width, evt.xconfigure.height); |
- break; |
- case ButtonPress: |
- if (evt.xbutton.button == Button1) |
- this->handleClick(evt.xbutton.x, evt.xbutton.y, |
- SkView::Click::kDown_State, NULL, getModi(evt)); |
- break; |
- case ButtonRelease: |
- if (evt.xbutton.button == Button1) |
- this->handleClick(evt.xbutton.x, evt.xbutton.y, |
- SkView::Click::kUp_State, NULL, getModi(evt)); |
- break; |
- case MotionNotify: |
- this->handleClick(evt.xmotion.x, evt.xmotion.y, |
- SkView::Click::kMoved_State, NULL, getModi(evt)); |
- break; |
- case KeyPress: { |
- KeySym keysym = XkbKeycodeToKeysym(dsp, evt.xkey.keycode, 0, 0); |
- //SkDebugf("pressed key %i!\n\tKeySym:%i\n", evt.xkey.keycode, XKeycodeToKeysym(dsp, evt.xkey.keycode, 0)); |
- if (keysym == XK_Escape) { |
- loop = false; |
+ bool needPaint = false; |
+ |
+ for (;;) { |
+ if (this->isDirty()) { |
+ this->update(NULL); |
+ needPaint = true; |
+ } |
+ if (needPaint) { |
+ this->doPaint(); |
+ needPaint = false; |
+ } |
+ if (gTimerDelay) { |
+ SkEvent::ServiceQueueTimer(); |
+ } |
+ bool moreToDo = SkEvent::ProcessEvent() || needPaint || this->isDirty(); |
+ if (XPending(dsp) || !moreToDo) { |
+ switch (this->nextXEvent()) { |
+ case kContinue_NextXEventResult: |
break; |
- } |
- this->handleKey(XKeyToSkKey(keysym)); |
- long uni = keysym2ucs(keysym); |
- if (uni != -1) { |
- this->handleChar((SkUnichar) uni); |
- } |
- break; |
+ case kPaintRequest_NextXEventResult: |
+ needPaint = true; |
+ break; |
+ case kQuitRequest_NextXEventResult: |
+ return; |
} |
- case KeyRelease: |
- //SkDebugf("released key %i\n", evt.xkey.keycode); |
- this->handleKeyUp(XKeyToSkKey(XkbKeycodeToKeysym(dsp, evt.xkey.keycode, 0, 0))); |
- break; |
- case ClientMessage: |
- if (SkEvent::ProcessEvent()) { |
- this->post_linuxevent(); |
- } |
- break; |
- default: |
- // Do nothing for other events |
- break; |
} |
} |
} |
@@ -321,20 +352,6 @@ void SkOSWindow::onSetTitle(const char title[]) { |
XSetWMName(fUnixWindow.fDisplay, fUnixWindow.fWin, &textProp); |
} |
-void SkOSWindow::onHandleInval(const SkIRect&) { |
- (new SkEvent("inval-imageview", this->getSinkID()))->post(); |
-} |
- |
-bool SkOSWindow::onEvent(const SkEvent& evt) { |
- if (evt.isType("inval-imageview")) { |
- update(NULL); |
- if (NULL == fUnixWindow.fGLContext) |
- this->doPaint(); |
- return true; |
- } |
- return INHERITED::onEvent(evt); |
-} |
- |
static bool convertBitmapToXImage(XImage& image, const SkBitmap& bitmap) { |
sk_bzero(&image, sizeof(image)); |
@@ -348,7 +365,7 @@ static bool convertBitmapToXImage(XImage& image, const SkBitmap& bitmap) { |
image.bitmap_bit_order = LSBFirst; |
image.bitmap_pad = bitsPerPixel; |
image.depth = 24; |
- image.bytes_per_line = bitmap.rowBytes() - bitmap.width() * bitmap.bytesPerPixel(); |
+ image.bytes_per_line = bitmap.rowBytes() - bitmap.width() * 4; |
image.bits_per_pixel = bitsPerPixel; |
return XInitImage(&image); |
} |
@@ -376,14 +393,15 @@ void SkOSWindow::doPaint() { |
width, height); |
} |
-bool SkOSWindow::onHandleChar(SkUnichar) { |
- return false; |
-} |
+/////////////////////////////////////////////////////////////////////////////// |
-bool SkOSWindow::onHandleKey(SkKey) { |
- return false; |
+void SkEvent::SignalNonEmptyQueue() { |
+ // nothing to do, since we spin on our event-queue, polling for XPending |
} |
-bool SkOSWindow::onHandleKeyUp(SkKey) { |
- return false; |
+void SkEvent::SignalQueueTimer(SkMSec delay) { |
+ // just need to record the delay time. We handle waking up for it in |
+ // MyXNextEventWithDelay() |
+ gTimerDelay = delay; |
} |
+ |