aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/views
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-06-17 13:42:43 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-06-17 13:42:43 +0000
commitacb3d88cf84adf367c173a7a33cd3b0c379291dc (patch)
tree2ba54592fb7e8b35a659cf194daa9920a817e11b /src/views
parentc33b6e542f51e7a81e8ef495624bd30da0388f55 (diff)
use select() so we can wait for XEvents or our timer
poll for xevents using XPending BUG= Review URL: https://codereview.chromium.org/17275003 git-svn-id: http://skia.googlecode.com/svn/trunk@9633 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/views')
-rw-r--r--src/views/unix/SkOSWindow_Unix.cpp196
-rw-r--r--src/views/unix/skia_unix.cpp23
2 files changed, 107 insertions, 112 deletions
diff --git a/src/views/unix/SkOSWindow_Unix.cpp b/src/views/unix/SkOSWindow_Unix.cpp
index a20644556d..591493e57e 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;
}
+
diff --git a/src/views/unix/skia_unix.cpp b/src/views/unix/skia_unix.cpp
index 108e9ac206..d77a8161fb 100644
--- a/src/views/unix/skia_unix.cpp
+++ b/src/views/unix/skia_unix.cpp
@@ -18,14 +18,7 @@
SkOSWindow* gWindow;
-static void catch_alarm(int sig)
-{
- SkEvent::ServiceQueueTimer();
-}
-
int main(int argc, char** argv){
- signal(SIGALRM, catch_alarm);
-
gWindow = create_sk_window(NULL, argc, argv);
// drain any events that occurred before gWindow was assigned.
@@ -43,20 +36,4 @@ int main(int argc, char** argv){
// SkEvent handlers
-void SkEvent::SignalNonEmptyQueue()
-{
- if (gWindow) {
- gWindow->post_linuxevent();
- }
-}
-
-void SkEvent::SignalQueueTimer(SkMSec delay)
-{
- itimerval newTimer;
- newTimer.it_interval.tv_sec = 0;
- newTimer.it_interval.tv_usec = 0;
- newTimer.it_value.tv_sec = 0;
- newTimer.it_value.tv_usec = delay * 1000;
- setitimer(ITIMER_REAL, &newTimer, NULL);
-}