1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo#include <X11/Xlib.h>
9b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo#include <X11/Xatom.h>
1075356a713f0576d5e4f542898267acbcf4d18d88bsalomon@google.com#include <X11/XKBlib.h>
11b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo#include <GL/glx.h>
129df214e836f2b897224178676c03017e9190b7e0Scroggo#include <GL/gl.h>
139df214e836f2b897224178676c03017e9190b7e0Scroggo#include <GL/glu.h>
14b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo
15b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo#include "SkWindow.h"
16b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo
17b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo#include "SkBitmap.h"
1808526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo#include "SkCanvas.h"
19b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo#include "SkColor.h"
20b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo#include "SkEvent.h"
219df214e836f2b897224178676c03017e9190b7e0Scroggo#include "SkKey.h"
229df214e836f2b897224178676c03017e9190b7e0Scroggo#include "SkWindow.h"
239df214e836f2b897224178676c03017e9190b7e0Scroggo#include "XkeysToSkKeys.h"
249df214e836f2b897224178676c03017e9190b7e0Scroggoextern "C" {
259df214e836f2b897224178676c03017e9190b7e0Scroggo    #include "keysym2ucs.h"
269df214e836f2b897224178676c03017e9190b7e0Scroggo}
279df214e836f2b897224178676c03017e9190b7e0Scroggo
28aed68d999bfd307c2cdf1539e4ed4caa9130c7f3Scroggoconst int WIDTH = 500;
29aed68d999bfd307c2cdf1539e4ed4caa9130c7f3Scroggoconst int HEIGHT = 500;
309df214e836f2b897224178676c03017e9190b7e0Scroggo
319df214e836f2b897224178676c03017e9190b7e0Scroggo// Determine which events to listen for.
329df214e836f2b897224178676c03017e9190b7e0Scroggoconst long EVENT_MASK = StructureNotifyMask|ButtonPressMask|ButtonReleaseMask
339df214e836f2b897224178676c03017e9190b7e0Scroggo        |ExposureMask|PointerMotionMask|KeyPressMask|KeyReleaseMask;
34b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo
3593c7ee34dc5c8f6bfad65809f4b39f8d00d7f0d4sugoi@google.comSkOSWindow::SkOSWindow(void*)
364bdfb8c9d6482a56c7212034a6f73046227ed023robertphillips@google.com    : fVi(NULL)
371195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    , fMSAASampleCount(0) {
381195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    fUnixWindow.fDisplay = NULL;
398108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com    fUnixWindow.fGLContext = NULL;
4064cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com    this->initWindow(0, NULL);
419df214e836f2b897224178676c03017e9190b7e0Scroggo    this->resize(WIDTH, HEIGHT);
42b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo}
43b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo
448108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.comSkOSWindow::~SkOSWindow() {
451195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    this->closeWindow();
461195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com}
471195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com
481195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.comvoid SkOSWindow::closeWindow() {
498108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com    if (NULL != fUnixWindow.fDisplay) {
501195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        this->detach();
511195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        SkASSERT(NULL != fUnixWindow.fGc);
528108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com        XFreeGC(fUnixWindow.fDisplay, fUnixWindow.fGc);
531195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        fUnixWindow.fGc = NULL;
549df214e836f2b897224178676c03017e9190b7e0Scroggo        XDestroyWindow(fUnixWindow.fDisplay, fUnixWindow.fWin);
551195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        fVi = NULL;
569df214e836f2b897224178676c03017e9190b7e0Scroggo        XCloseDisplay(fUnixWindow.fDisplay);
571195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        fUnixWindow.fDisplay = NULL;
581195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        fMSAASampleCount = 0;
591195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    }
601195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com}
611195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com
6264cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.comvoid SkOSWindow::initWindow(int requestedMSAASampleCount, AttachmentInfo* info) {
631195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    if (fMSAASampleCount != requestedMSAASampleCount) {
641195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        this->closeWindow();
651195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    }
661195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    // presence of fDisplay means we already have a window
671195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    if (NULL != fUnixWindow.fDisplay) {
6864cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com        if (NULL != info) {
6964cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com            if (NULL != fVi) {
7064cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com                glXGetConfig(fUnixWindow.fDisplay, fVi, GLX_SAMPLES_ARB, &info->fSampleCount);
7164cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com                glXGetConfig(fUnixWindow.fDisplay, fVi, GLX_STENCIL_SIZE, &info->fStencilBits);
7264cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com            } else {
7364cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com                info->fSampleCount = 0;
7464cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com                info->fStencilBits = 0;
7564cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com            }
7664cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com        }
771195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        return;
781195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    }
791195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    fUnixWindow.fDisplay = XOpenDisplay(NULL);
801195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    Display* dsp = fUnixWindow.fDisplay;
811195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    if (NULL == dsp) {
821195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        SkDebugf("Could not open an X Display");
831195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        return;
841195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    }
851195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    // Attempt to create a window that supports GL
861195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    GLint att[] = {
871195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        GLX_RGBA,
881195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        GLX_DEPTH_SIZE, 24,
891195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        GLX_DOUBLEBUFFER,
901195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        GLX_STENCIL_SIZE, 8,
911195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        None
921195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    };
931195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    SkASSERT(NULL == fVi);
941195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    if (requestedMSAASampleCount > 0) {
951195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        static const GLint kAttCount = SK_ARRAY_COUNT(att);
961195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        GLint msaaAtt[kAttCount + 4];
971195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        memcpy(msaaAtt, att, sizeof(att));
981195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        SkASSERT(None == msaaAtt[kAttCount - 1]);
991195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        msaaAtt[kAttCount - 1] = GLX_SAMPLE_BUFFERS_ARB;
1001195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        msaaAtt[kAttCount + 0] = 1;
1011195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        msaaAtt[kAttCount + 1] = GLX_SAMPLES_ARB;
1021195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        msaaAtt[kAttCount + 2] = requestedMSAASampleCount;
1031195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        msaaAtt[kAttCount + 3] = None;
1041195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        fVi = glXChooseVisual(dsp, DefaultScreen(dsp), msaaAtt);
1051195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        fMSAASampleCount = requestedMSAASampleCount;
1061195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    }
1071195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    if (NULL == fVi) {
1081195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        fVi = glXChooseVisual(dsp, DefaultScreen(dsp), att);
1091195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        fMSAASampleCount = 0;
1101195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    }
1111195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com
1121195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    if (fVi) {
11364cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com        if (NULL != info) {
11464cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com            glXGetConfig(dsp, fVi, GLX_SAMPLES_ARB, &info->fSampleCount);
11564cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com            glXGetConfig(dsp, fVi, GLX_STENCIL_SIZE, &info->fStencilBits);
11664cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com        }
1171195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        Colormap colorMap = XCreateColormap(dsp,
1181195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                            RootWindow(dsp, fVi->screen),
1191195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                            fVi->visual,
1201195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                             AllocNone);
1211195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        XSetWindowAttributes swa;
1221195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        swa.colormap = colorMap;
1231195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        swa.event_mask = EVENT_MASK;
1241195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        fUnixWindow.fWin = XCreateWindow(dsp,
1251195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                         RootWindow(dsp, fVi->screen),
1261195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                         0, 0, // x, y
1271195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                         WIDTH, HEIGHT,
1281195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                         0, // border width
1291195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                         fVi->depth,
1301195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                         InputOutput,
1311195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                         fVi->visual,
1321195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                         CWEventMask | CWColormap,
1331195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                         &swa);
1341195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    } else {
13564cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com        if (NULL != info) {
13664cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com            info->fSampleCount = 0;
13764cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com            info->fStencilBits = 0;
13864cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com        }
1391195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        // Create a simple window instead.  We will not be able to show GL
1401195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        fUnixWindow.fWin = XCreateSimpleWindow(dsp,
1411195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                               DefaultRootWindow(dsp),
1421195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                               0, 0,  // x, y
1431195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                               WIDTH, HEIGHT,
1441195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                               0,     // border width
1451195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                               0,     // border value
1461195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                                               0);    // background value
1479df214e836f2b897224178676c03017e9190b7e0Scroggo    }
1481195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    this->mapWindowAndWait();
1491195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    fUnixWindow.fGc = XCreateGC(dsp, fUnixWindow.fWin, 0, NULL);
150b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo}
151b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo
15237924183583cf3fdc59b91de0acc26e1fcf2598dreed@google.comstatic unsigned getModi(const XEvent& evt) {
153e378d833489476f68485a64dc437da325e75ee71reed@google.com    static const struct {
154e378d833489476f68485a64dc437da325e75ee71reed@google.com        unsigned    fXMask;
155e378d833489476f68485a64dc437da325e75ee71reed@google.com        unsigned    fSkMask;
156e378d833489476f68485a64dc437da325e75ee71reed@google.com    } gModi[] = {
157e378d833489476f68485a64dc437da325e75ee71reed@google.com        // X values found by experiment. Is there a better way?
158e378d833489476f68485a64dc437da325e75ee71reed@google.com        { 1,    kShift_SkModifierKey },
159e378d833489476f68485a64dc437da325e75ee71reed@google.com        { 4,    kControl_SkModifierKey },
160e378d833489476f68485a64dc437da325e75ee71reed@google.com        { 8,    kOption_SkModifierKey },
161e378d833489476f68485a64dc437da325e75ee71reed@google.com    };
1624e73aa1566f2ee9a2525942cab4e885cb51b855cskia.committer@gmail.com
163e378d833489476f68485a64dc437da325e75ee71reed@google.com    unsigned modi = 0;
164e378d833489476f68485a64dc437da325e75ee71reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gModi); ++i) {
165e378d833489476f68485a64dc437da325e75ee71reed@google.com        if (evt.xkey.state & gModi[i].fXMask) {
166e378d833489476f68485a64dc437da325e75ee71reed@google.com            modi |= gModi[i].fSkMask;
167e378d833489476f68485a64dc437da325e75ee71reed@google.com        }
168e378d833489476f68485a64dc437da325e75ee71reed@google.com    }
169e378d833489476f68485a64dc437da325e75ee71reed@google.com    return modi;
1704d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com}
1714d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com
172acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.comstatic SkMSec gTimerDelay;
173acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com
174d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.comstatic bool MyXNextEventWithDelay(Display* dsp, XEvent* evt) {
17504018f37af9d1b231111dc557fa281689b8a4616commit-bot@chromium.org    // Check for pending events before entering the select loop. There might
17604018f37af9d1b231111dc557fa281689b8a4616commit-bot@chromium.org    // be events in the in-memory queue but not processed yet.
17704018f37af9d1b231111dc557fa281689b8a4616commit-bot@chromium.org    if (XPending(dsp)) {
17804018f37af9d1b231111dc557fa281689b8a4616commit-bot@chromium.org        XNextEvent(dsp, evt);
17904018f37af9d1b231111dc557fa281689b8a4616commit-bot@chromium.org        return true;
18004018f37af9d1b231111dc557fa281689b8a4616commit-bot@chromium.org    }
18104018f37af9d1b231111dc557fa281689b8a4616commit-bot@chromium.org
182acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com    SkMSec ms = gTimerDelay;
183acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com    if (ms > 0) {
184acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        int x11_fd = ConnectionNumber(dsp);
185acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        fd_set input_fds;
186acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        FD_ZERO(&input_fds);
187acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        FD_SET(x11_fd, &input_fds);
188acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com
189acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        timeval tv;
190acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        tv.tv_sec = ms / 1000;              // seconds
191acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        tv.tv_usec = (ms % 1000) * 1000;    // microseconds
192a48595d8633208b3e0d46f67a8d530ebbc452ad0skia.committer@gmail.com
193d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com        if (!select(x11_fd + 1, &input_fds, NULL, NULL, &tv)) {
194d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com            if (!XPending(dsp)) {
195d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com                return false;
196d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com            }
197d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com        }
198acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com    }
199d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com    XNextEvent(dsp, evt);
200d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com    return true;
201acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com}
202acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com
203acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.comSkOSWindow::NextXEventResult SkOSWindow::nextXEvent() {
204acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com    XEvent evt;
205acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com    Display* dsp = fUnixWindow.fDisplay;
206acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com
207d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com    if (!MyXNextEventWithDelay(fUnixWindow.fDisplay, &evt)) {
208d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com        return kContinue_NextXEventResult;
209d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com    }
210acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com
211acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com    switch (evt.type) {
212acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        case Expose:
213acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            if (0 == evt.xexpose.count) {
214acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com                return kPaintRequest_NextXEventResult;
215acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            }
216acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            break;
217acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        case ConfigureNotify:
218acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            this->resize(evt.xconfigure.width, evt.xconfigure.height);
219acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            break;
220acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        case ButtonPress:
221acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            if (evt.xbutton.button == Button1)
222acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com                this->handleClick(evt.xbutton.x, evt.xbutton.y,
223acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com                            SkView::Click::kDown_State, NULL, getModi(evt));
224acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            break;
225acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        case ButtonRelease:
226acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            if (evt.xbutton.button == Button1)
227acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com                this->handleClick(evt.xbutton.x, evt.xbutton.y,
228acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com                              SkView::Click::kUp_State, NULL, getModi(evt));
229acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            break;
230acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        case MotionNotify:
231acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            this->handleClick(evt.xmotion.x, evt.xmotion.y,
232acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com                           SkView::Click::kMoved_State, NULL, getModi(evt));
233acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            break;
234acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        case KeyPress: {
2355e4fe216892927ae81edd7a22b2b00521920f2f3bungeman@google.com            int shiftLevel = (evt.xkey.state & ShiftMask) ? 1 : 0;
236acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            KeySym keysym = XkbKeycodeToKeysym(dsp, evt.xkey.keycode,
237acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com                                               0, shiftLevel);
238acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            if (keysym == XK_Escape) {
239acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com                return kQuitRequest_NextXEventResult;
240acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            }
241acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            this->handleKey(XKeyToSkKey(keysym));
242acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            long uni = keysym2ucs(keysym);
243acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            if (uni != -1) {
244acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com                this->handleChar((SkUnichar) uni);
245acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            }
246acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            break;
247acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        }
248acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        case KeyRelease:
249acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            this->handleKeyUp(XKeyToSkKey(XkbKeycodeToKeysym(dsp, evt.xkey.keycode, 0, 0)));
250acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            break;
251acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        default:
252acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            // Do nothing for other events
253acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            break;
254acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com    }
255acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com    return kContinue_NextXEventResult;
256acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com}
257acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com
2588108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.comvoid SkOSWindow::loop() {
2599df214e836f2b897224178676c03017e9190b7e0Scroggo    Display* dsp = fUnixWindow.fDisplay;
2601195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    if (NULL == dsp) {
2611195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        return;
2621195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    }
263d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com    Window win = fUnixWindow.fWin;
264d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com
265d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com    XSelectInput(dsp, win, EVENT_MASK);
2669df214e836f2b897224178676c03017e9190b7e0Scroggo
267d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com    bool sentExposeEvent = false;
268acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com
269acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com    for (;;) {
270d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com        SkEvent::ServiceQueueTimer();
271d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com
272d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com        bool moreToDo = SkEvent::ProcessEvent();
273d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com
274d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com        if (this->isDirty() && !sentExposeEvent) {
275d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com            sentExposeEvent = true;
276d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com
277d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com            XEvent evt;
278d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com            sk_bzero(&evt, sizeof(evt));
279d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com            evt.type = Expose;
280d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com            evt.xexpose.display = dsp;
281d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com            XSendEvent(dsp, win, false, ExposureMask, &evt);
282acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        }
283d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com
284acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com        if (XPending(dsp) || !moreToDo) {
285acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com            switch (this->nextXEvent()) {
286acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com                case kContinue_NextXEventResult:
2879df214e836f2b897224178676c03017e9190b7e0Scroggo                    break;
288acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com                case kPaintRequest_NextXEventResult:
289d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com                    sentExposeEvent = false;
290d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com                    if (this->isDirty()) {
291d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com                        this->update(NULL);
292d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com                    }
293d1f1b67f5eab110fa0c47c082776d9da1c5fba86reed@google.com                    this->doPaint();
294acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com                    break;
295acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com                case kQuitRequest_NextXEventResult:
296acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com                    return;
2979df214e836f2b897224178676c03017e9190b7e0Scroggo            }
2989df214e836f2b897224178676c03017e9190b7e0Scroggo        }
2999df214e836f2b897224178676c03017e9190b7e0Scroggo    }
3009df214e836f2b897224178676c03017e9190b7e0Scroggo}
3019df214e836f2b897224178676c03017e9190b7e0Scroggo
3028108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.comvoid SkOSWindow::mapWindowAndWait() {
3031195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    SkASSERT(NULL != fUnixWindow.fDisplay);
3049df214e836f2b897224178676c03017e9190b7e0Scroggo    Display* dsp = fUnixWindow.fDisplay;
3059df214e836f2b897224178676c03017e9190b7e0Scroggo    Window win = fUnixWindow.fWin;
3069df214e836f2b897224178676c03017e9190b7e0Scroggo    XMapWindow(dsp, win);
3079df214e836f2b897224178676c03017e9190b7e0Scroggo
3089df214e836f2b897224178676c03017e9190b7e0Scroggo    long eventMask = StructureNotifyMask;
3099df214e836f2b897224178676c03017e9190b7e0Scroggo    XSelectInput(dsp, win, eventMask);
3109df214e836f2b897224178676c03017e9190b7e0Scroggo
3119df214e836f2b897224178676c03017e9190b7e0Scroggo    // Wait until screen is ready.
3129df214e836f2b897224178676c03017e9190b7e0Scroggo    XEvent evt;
3139df214e836f2b897224178676c03017e9190b7e0Scroggo    do {
3149df214e836f2b897224178676c03017e9190b7e0Scroggo        XNextEvent(dsp, &evt);
3159df214e836f2b897224178676c03017e9190b7e0Scroggo    } while(evt.type != MapNotify);
3169df214e836f2b897224178676c03017e9190b7e0Scroggo
317b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo}
318b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo
31964cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.combool SkOSWindow::attach(SkBackEndTypes, int msaaSampleCount, AttachmentInfo* info) {
32064cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com    this->initWindow(msaaSampleCount, info);
32164cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com
3221195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    if (NULL == fUnixWindow.fDisplay) {
3231195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        return false;
324d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
3258108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com    if (NULL == fUnixWindow.fGLContext) {
3261195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        SkASSERT(NULL != fVi);
3279df214e836f2b897224178676c03017e9190b7e0Scroggo
3288108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com        fUnixWindow.fGLContext = glXCreateContext(fUnixWindow.fDisplay,
3298108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com                                                  fVi,
3308108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com                                                  NULL,
3318108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com                                                  GL_TRUE);
3328108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com        if (NULL == fUnixWindow.fGLContext) {
3338108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com            return false;
3348108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com        }
3359df214e836f2b897224178676c03017e9190b7e0Scroggo    }
3368108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com    glXMakeCurrent(fUnixWindow.fDisplay,
3378108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com                   fUnixWindow.fWin,
3388108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com                   fUnixWindow.fGLContext);
3398108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com    glViewport(0, 0,
340e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com               SkScalarRoundToInt(this->width()),
341e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com               SkScalarRoundToInt(this->height()));
3428108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com    glClearColor(0, 0, 0, 0);
3438108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com    glClearStencil(0);
3448108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3459df214e836f2b897224178676c03017e9190b7e0Scroggo    return true;
346b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo}
347b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo
3488108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.comvoid SkOSWindow::detach() {
3498108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com    if (NULL == fUnixWindow.fDisplay || NULL == fUnixWindow.fGLContext) {
3508108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com        return;
3518108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com    }
3529df214e836f2b897224178676c03017e9190b7e0Scroggo    glXMakeCurrent(fUnixWindow.fDisplay, None, NULL);
3538108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com    glXDestroyContext(fUnixWindow.fDisplay, fUnixWindow.fGLContext);
3548108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com    fUnixWindow.fGLContext = NULL;
355b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo}
356b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo
3578108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.comvoid SkOSWindow::present() {
3588108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com    if (NULL != fUnixWindow.fDisplay && NULL != fUnixWindow.fGLContext) {
3599df214e836f2b897224178676c03017e9190b7e0Scroggo        glXSwapBuffers(fUnixWindow.fDisplay, fUnixWindow.fWin);
3609df214e836f2b897224178676c03017e9190b7e0Scroggo    }
361b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo}
362b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo
3638108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.comvoid SkOSWindow::onSetTitle(const char title[]) {
3641195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    if (NULL == fUnixWindow.fDisplay) {
3658108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com        return;
3668108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.com    }
367b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo    XTextProperty textProp;
368b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo    textProp.value = (unsigned char*)title;
369b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo    textProp.format = 8;
370b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo    textProp.nitems = strlen((char*)textProp.value);
371b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo    textProp.encoding = XA_STRING;
372b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo    XSetWMName(fUnixWindow.fDisplay, fUnixWindow.fWin, &textProp);
373b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo}
374b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo
3758108c47b50d13cf55b0265b97d729f354e7a697ebsalomon@google.comstatic bool convertBitmapToXImage(XImage& image, const SkBitmap& bitmap) {
376b66365f5dd8cba718e1657ee3c85b4406e55f17dscroggo    sk_bzero(&image, sizeof(image));
377b66365f5dd8cba718e1657ee3c85b4406e55f17dscroggo
378b66365f5dd8cba718e1657ee3c85b4406e55f17dscroggo    int bitsPerPixel = bitmap.bytesPerPixel() * 8;
379b66365f5dd8cba718e1657ee3c85b4406e55f17dscroggo    image.width = bitmap.width();
380b66365f5dd8cba718e1657ee3c85b4406e55f17dscroggo    image.height = bitmap.height();
381b66365f5dd8cba718e1657ee3c85b4406e55f17dscroggo    image.format = ZPixmap;
382b66365f5dd8cba718e1657ee3c85b4406e55f17dscroggo    image.data = (char*) bitmap.getPixels();
383b66365f5dd8cba718e1657ee3c85b4406e55f17dscroggo    image.byte_order = LSBFirst;
384b66365f5dd8cba718e1657ee3c85b4406e55f17dscroggo    image.bitmap_unit = bitsPerPixel;
385b66365f5dd8cba718e1657ee3c85b4406e55f17dscroggo    image.bitmap_bit_order = LSBFirst;
386b66365f5dd8cba718e1657ee3c85b4406e55f17dscroggo    image.bitmap_pad = bitsPerPixel;
387b66365f5dd8cba718e1657ee3c85b4406e55f17dscroggo    image.depth = 24;
388acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com    image.bytes_per_line = bitmap.rowBytes() - bitmap.width() * 4;
389b66365f5dd8cba718e1657ee3c85b4406e55f17dscroggo    image.bits_per_pixel = bitsPerPixel;
39008526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo    return XInitImage(&image);
39108526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo}
39208526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo
39308526c07f4f530e56b70d4b22f5a4af35d9ebccascroggovoid SkOSWindow::doPaint() {
3941195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    if (NULL == fUnixWindow.fDisplay) {
3951195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        return;
3961195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    }
3977fa22f33290e3a1777c781eb059c97d5b674b27acommit-bot@chromium.org    // If we are drawing with GL, we don't need XPutImage.
3987fa22f33290e3a1777c781eb059c97d5b674b27acommit-bot@chromium.org    if (NULL != fUnixWindow.fGLContext) {
3997fa22f33290e3a1777c781eb059c97d5b674b27acommit-bot@chromium.org        return;
4007fa22f33290e3a1777c781eb059c97d5b674b27acommit-bot@chromium.org    }
40108526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo    // Draw the bitmap to the screen.
40208526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo    const SkBitmap& bitmap = getBitmap();
40308526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo    int width = bitmap.width();
40408526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo    int height = bitmap.height();
40508526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo
4060f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    XImage image;
4071195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    if (!convertBitmapToXImage(image, bitmap)) {
4081195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        return;
4091195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    }
41008526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo
4111195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    XPutImage(fUnixWindow.fDisplay,
4121195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com              fUnixWindow.fWin,
4131195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com              fUnixWindow.fGc,
4141195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com              &image,
4151195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com              0, 0,     // src x,y
4161195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com              0, 0,     // dst x,y
4171195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com              width, height);
418b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo}
419b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo
420acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com///////////////////////////////////////////////////////////////////////////////
421b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo
422acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.comvoid SkEvent::SignalNonEmptyQueue() {
423acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com    // nothing to do, since we spin on our event-queue, polling for XPending
424b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo}
425b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo
426acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.comvoid SkEvent::SignalQueueTimer(SkMSec delay) {
427acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com    // just need to record the delay time. We handle waking up for it in
428acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com    // MyXNextEventWithDelay()
429acb3d88cf84adf367c173a7a33cd3b0c379291dcreed@google.com    gTimerDelay = delay;
430b7e9aee1acf27fc98cb37ed69c05da71b4c3c69bscroggo}
431