Thu, 15 Jan 2015 21:03:48 +0100
Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)
michael@0 | 1 | |
michael@0 | 2 | /* |
michael@0 | 3 | * Copyright 2011 Google Inc. |
michael@0 | 4 | * |
michael@0 | 5 | * Use of this source code is governed by a BSD-style license that can be |
michael@0 | 6 | * found in the LICENSE file. |
michael@0 | 7 | */ |
michael@0 | 8 | #include <X11/Xlib.h> |
michael@0 | 9 | #include <X11/Xatom.h> |
michael@0 | 10 | #include <X11/XKBlib.h> |
michael@0 | 11 | #include <GL/glx.h> |
michael@0 | 12 | #include <GL/gl.h> |
michael@0 | 13 | #include <GL/glu.h> |
michael@0 | 14 | |
michael@0 | 15 | #include "SkWindow.h" |
michael@0 | 16 | |
michael@0 | 17 | #include "SkBitmap.h" |
michael@0 | 18 | #include "SkCanvas.h" |
michael@0 | 19 | #include "SkColor.h" |
michael@0 | 20 | #include "SkEvent.h" |
michael@0 | 21 | #include "SkKey.h" |
michael@0 | 22 | #include "SkWindow.h" |
michael@0 | 23 | #include "XkeysToSkKeys.h" |
michael@0 | 24 | extern "C" { |
michael@0 | 25 | #include "keysym2ucs.h" |
michael@0 | 26 | } |
michael@0 | 27 | |
michael@0 | 28 | const int WIDTH = 500; |
michael@0 | 29 | const int HEIGHT = 500; |
michael@0 | 30 | |
michael@0 | 31 | // Determine which events to listen for. |
michael@0 | 32 | const long EVENT_MASK = StructureNotifyMask|ButtonPressMask|ButtonReleaseMask |
michael@0 | 33 | |ExposureMask|PointerMotionMask|KeyPressMask|KeyReleaseMask; |
michael@0 | 34 | |
michael@0 | 35 | SkOSWindow::SkOSWindow(void*) |
michael@0 | 36 | : fVi(NULL) |
michael@0 | 37 | , fMSAASampleCount(0) { |
michael@0 | 38 | fUnixWindow.fDisplay = NULL; |
michael@0 | 39 | fUnixWindow.fGLContext = NULL; |
michael@0 | 40 | this->initWindow(0, NULL); |
michael@0 | 41 | this->resize(WIDTH, HEIGHT); |
michael@0 | 42 | } |
michael@0 | 43 | |
michael@0 | 44 | SkOSWindow::~SkOSWindow() { |
michael@0 | 45 | this->closeWindow(); |
michael@0 | 46 | } |
michael@0 | 47 | |
michael@0 | 48 | void SkOSWindow::closeWindow() { |
michael@0 | 49 | if (NULL != fUnixWindow.fDisplay) { |
michael@0 | 50 | this->detach(); |
michael@0 | 51 | SkASSERT(NULL != fUnixWindow.fGc); |
michael@0 | 52 | XFreeGC(fUnixWindow.fDisplay, fUnixWindow.fGc); |
michael@0 | 53 | fUnixWindow.fGc = NULL; |
michael@0 | 54 | XDestroyWindow(fUnixWindow.fDisplay, fUnixWindow.fWin); |
michael@0 | 55 | fVi = NULL; |
michael@0 | 56 | XCloseDisplay(fUnixWindow.fDisplay); |
michael@0 | 57 | fUnixWindow.fDisplay = NULL; |
michael@0 | 58 | fMSAASampleCount = 0; |
michael@0 | 59 | } |
michael@0 | 60 | } |
michael@0 | 61 | |
michael@0 | 62 | void SkOSWindow::initWindow(int requestedMSAASampleCount, AttachmentInfo* info) { |
michael@0 | 63 | if (fMSAASampleCount != requestedMSAASampleCount) { |
michael@0 | 64 | this->closeWindow(); |
michael@0 | 65 | } |
michael@0 | 66 | // presence of fDisplay means we already have a window |
michael@0 | 67 | if (NULL != fUnixWindow.fDisplay) { |
michael@0 | 68 | if (NULL != info) { |
michael@0 | 69 | if (NULL != fVi) { |
michael@0 | 70 | glXGetConfig(fUnixWindow.fDisplay, fVi, GLX_SAMPLES_ARB, &info->fSampleCount); |
michael@0 | 71 | glXGetConfig(fUnixWindow.fDisplay, fVi, GLX_STENCIL_SIZE, &info->fStencilBits); |
michael@0 | 72 | } else { |
michael@0 | 73 | info->fSampleCount = 0; |
michael@0 | 74 | info->fStencilBits = 0; |
michael@0 | 75 | } |
michael@0 | 76 | } |
michael@0 | 77 | return; |
michael@0 | 78 | } |
michael@0 | 79 | fUnixWindow.fDisplay = XOpenDisplay(NULL); |
michael@0 | 80 | Display* dsp = fUnixWindow.fDisplay; |
michael@0 | 81 | if (NULL == dsp) { |
michael@0 | 82 | SkDebugf("Could not open an X Display"); |
michael@0 | 83 | return; |
michael@0 | 84 | } |
michael@0 | 85 | // Attempt to create a window that supports GL |
michael@0 | 86 | GLint att[] = { |
michael@0 | 87 | GLX_RGBA, |
michael@0 | 88 | GLX_DEPTH_SIZE, 24, |
michael@0 | 89 | GLX_DOUBLEBUFFER, |
michael@0 | 90 | GLX_STENCIL_SIZE, 8, |
michael@0 | 91 | None |
michael@0 | 92 | }; |
michael@0 | 93 | SkASSERT(NULL == fVi); |
michael@0 | 94 | if (requestedMSAASampleCount > 0) { |
michael@0 | 95 | static const GLint kAttCount = SK_ARRAY_COUNT(att); |
michael@0 | 96 | GLint msaaAtt[kAttCount + 4]; |
michael@0 | 97 | memcpy(msaaAtt, att, sizeof(att)); |
michael@0 | 98 | SkASSERT(None == msaaAtt[kAttCount - 1]); |
michael@0 | 99 | msaaAtt[kAttCount - 1] = GLX_SAMPLE_BUFFERS_ARB; |
michael@0 | 100 | msaaAtt[kAttCount + 0] = 1; |
michael@0 | 101 | msaaAtt[kAttCount + 1] = GLX_SAMPLES_ARB; |
michael@0 | 102 | msaaAtt[kAttCount + 2] = requestedMSAASampleCount; |
michael@0 | 103 | msaaAtt[kAttCount + 3] = None; |
michael@0 | 104 | fVi = glXChooseVisual(dsp, DefaultScreen(dsp), msaaAtt); |
michael@0 | 105 | fMSAASampleCount = requestedMSAASampleCount; |
michael@0 | 106 | } |
michael@0 | 107 | if (NULL == fVi) { |
michael@0 | 108 | fVi = glXChooseVisual(dsp, DefaultScreen(dsp), att); |
michael@0 | 109 | fMSAASampleCount = 0; |
michael@0 | 110 | } |
michael@0 | 111 | |
michael@0 | 112 | if (fVi) { |
michael@0 | 113 | if (NULL != info) { |
michael@0 | 114 | glXGetConfig(dsp, fVi, GLX_SAMPLES_ARB, &info->fSampleCount); |
michael@0 | 115 | glXGetConfig(dsp, fVi, GLX_STENCIL_SIZE, &info->fStencilBits); |
michael@0 | 116 | } |
michael@0 | 117 | Colormap colorMap = XCreateColormap(dsp, |
michael@0 | 118 | RootWindow(dsp, fVi->screen), |
michael@0 | 119 | fVi->visual, |
michael@0 | 120 | AllocNone); |
michael@0 | 121 | XSetWindowAttributes swa; |
michael@0 | 122 | swa.colormap = colorMap; |
michael@0 | 123 | swa.event_mask = EVENT_MASK; |
michael@0 | 124 | fUnixWindow.fWin = XCreateWindow(dsp, |
michael@0 | 125 | RootWindow(dsp, fVi->screen), |
michael@0 | 126 | 0, 0, // x, y |
michael@0 | 127 | WIDTH, HEIGHT, |
michael@0 | 128 | 0, // border width |
michael@0 | 129 | fVi->depth, |
michael@0 | 130 | InputOutput, |
michael@0 | 131 | fVi->visual, |
michael@0 | 132 | CWEventMask | CWColormap, |
michael@0 | 133 | &swa); |
michael@0 | 134 | } else { |
michael@0 | 135 | if (NULL != info) { |
michael@0 | 136 | info->fSampleCount = 0; |
michael@0 | 137 | info->fStencilBits = 0; |
michael@0 | 138 | } |
michael@0 | 139 | // Create a simple window instead. We will not be able to show GL |
michael@0 | 140 | fUnixWindow.fWin = XCreateSimpleWindow(dsp, |
michael@0 | 141 | DefaultRootWindow(dsp), |
michael@0 | 142 | 0, 0, // x, y |
michael@0 | 143 | WIDTH, HEIGHT, |
michael@0 | 144 | 0, // border width |
michael@0 | 145 | 0, // border value |
michael@0 | 146 | 0); // background value |
michael@0 | 147 | } |
michael@0 | 148 | this->mapWindowAndWait(); |
michael@0 | 149 | fUnixWindow.fGc = XCreateGC(dsp, fUnixWindow.fWin, 0, NULL); |
michael@0 | 150 | } |
michael@0 | 151 | |
michael@0 | 152 | static unsigned getModi(const XEvent& evt) { |
michael@0 | 153 | static const struct { |
michael@0 | 154 | unsigned fXMask; |
michael@0 | 155 | unsigned fSkMask; |
michael@0 | 156 | } gModi[] = { |
michael@0 | 157 | // X values found by experiment. Is there a better way? |
michael@0 | 158 | { 1, kShift_SkModifierKey }, |
michael@0 | 159 | { 4, kControl_SkModifierKey }, |
michael@0 | 160 | { 8, kOption_SkModifierKey }, |
michael@0 | 161 | }; |
michael@0 | 162 | |
michael@0 | 163 | unsigned modi = 0; |
michael@0 | 164 | for (size_t i = 0; i < SK_ARRAY_COUNT(gModi); ++i) { |
michael@0 | 165 | if (evt.xkey.state & gModi[i].fXMask) { |
michael@0 | 166 | modi |= gModi[i].fSkMask; |
michael@0 | 167 | } |
michael@0 | 168 | } |
michael@0 | 169 | return modi; |
michael@0 | 170 | } |
michael@0 | 171 | |
michael@0 | 172 | static SkMSec gTimerDelay; |
michael@0 | 173 | |
michael@0 | 174 | static bool MyXNextEventWithDelay(Display* dsp, XEvent* evt) { |
michael@0 | 175 | // Check for pending events before entering the select loop. There might |
michael@0 | 176 | // be events in the in-memory queue but not processed yet. |
michael@0 | 177 | if (XPending(dsp)) { |
michael@0 | 178 | XNextEvent(dsp, evt); |
michael@0 | 179 | return true; |
michael@0 | 180 | } |
michael@0 | 181 | |
michael@0 | 182 | SkMSec ms = gTimerDelay; |
michael@0 | 183 | if (ms > 0) { |
michael@0 | 184 | int x11_fd = ConnectionNumber(dsp); |
michael@0 | 185 | fd_set input_fds; |
michael@0 | 186 | FD_ZERO(&input_fds); |
michael@0 | 187 | FD_SET(x11_fd, &input_fds); |
michael@0 | 188 | |
michael@0 | 189 | timeval tv; |
michael@0 | 190 | tv.tv_sec = ms / 1000; // seconds |
michael@0 | 191 | tv.tv_usec = (ms % 1000) * 1000; // microseconds |
michael@0 | 192 | |
michael@0 | 193 | if (!select(x11_fd + 1, &input_fds, NULL, NULL, &tv)) { |
michael@0 | 194 | if (!XPending(dsp)) { |
michael@0 | 195 | return false; |
michael@0 | 196 | } |
michael@0 | 197 | } |
michael@0 | 198 | } |
michael@0 | 199 | XNextEvent(dsp, evt); |
michael@0 | 200 | return true; |
michael@0 | 201 | } |
michael@0 | 202 | |
michael@0 | 203 | SkOSWindow::NextXEventResult SkOSWindow::nextXEvent() { |
michael@0 | 204 | XEvent evt; |
michael@0 | 205 | Display* dsp = fUnixWindow.fDisplay; |
michael@0 | 206 | |
michael@0 | 207 | if (!MyXNextEventWithDelay(fUnixWindow.fDisplay, &evt)) { |
michael@0 | 208 | return kContinue_NextXEventResult; |
michael@0 | 209 | } |
michael@0 | 210 | |
michael@0 | 211 | switch (evt.type) { |
michael@0 | 212 | case Expose: |
michael@0 | 213 | if (0 == evt.xexpose.count) { |
michael@0 | 214 | return kPaintRequest_NextXEventResult; |
michael@0 | 215 | } |
michael@0 | 216 | break; |
michael@0 | 217 | case ConfigureNotify: |
michael@0 | 218 | this->resize(evt.xconfigure.width, evt.xconfigure.height); |
michael@0 | 219 | break; |
michael@0 | 220 | case ButtonPress: |
michael@0 | 221 | if (evt.xbutton.button == Button1) |
michael@0 | 222 | this->handleClick(evt.xbutton.x, evt.xbutton.y, |
michael@0 | 223 | SkView::Click::kDown_State, NULL, getModi(evt)); |
michael@0 | 224 | break; |
michael@0 | 225 | case ButtonRelease: |
michael@0 | 226 | if (evt.xbutton.button == Button1) |
michael@0 | 227 | this->handleClick(evt.xbutton.x, evt.xbutton.y, |
michael@0 | 228 | SkView::Click::kUp_State, NULL, getModi(evt)); |
michael@0 | 229 | break; |
michael@0 | 230 | case MotionNotify: |
michael@0 | 231 | this->handleClick(evt.xmotion.x, evt.xmotion.y, |
michael@0 | 232 | SkView::Click::kMoved_State, NULL, getModi(evt)); |
michael@0 | 233 | break; |
michael@0 | 234 | case KeyPress: { |
michael@0 | 235 | int shiftLevel = (evt.xkey.state & ShiftMask) ? 1 : 0; |
michael@0 | 236 | KeySym keysym = XkbKeycodeToKeysym(dsp, evt.xkey.keycode, |
michael@0 | 237 | 0, shiftLevel); |
michael@0 | 238 | if (keysym == XK_Escape) { |
michael@0 | 239 | return kQuitRequest_NextXEventResult; |
michael@0 | 240 | } |
michael@0 | 241 | this->handleKey(XKeyToSkKey(keysym)); |
michael@0 | 242 | long uni = keysym2ucs(keysym); |
michael@0 | 243 | if (uni != -1) { |
michael@0 | 244 | this->handleChar((SkUnichar) uni); |
michael@0 | 245 | } |
michael@0 | 246 | break; |
michael@0 | 247 | } |
michael@0 | 248 | case KeyRelease: |
michael@0 | 249 | this->handleKeyUp(XKeyToSkKey(XkbKeycodeToKeysym(dsp, evt.xkey.keycode, 0, 0))); |
michael@0 | 250 | break; |
michael@0 | 251 | default: |
michael@0 | 252 | // Do nothing for other events |
michael@0 | 253 | break; |
michael@0 | 254 | } |
michael@0 | 255 | return kContinue_NextXEventResult; |
michael@0 | 256 | } |
michael@0 | 257 | |
michael@0 | 258 | void SkOSWindow::loop() { |
michael@0 | 259 | Display* dsp = fUnixWindow.fDisplay; |
michael@0 | 260 | if (NULL == dsp) { |
michael@0 | 261 | return; |
michael@0 | 262 | } |
michael@0 | 263 | Window win = fUnixWindow.fWin; |
michael@0 | 264 | |
michael@0 | 265 | XSelectInput(dsp, win, EVENT_MASK); |
michael@0 | 266 | |
michael@0 | 267 | bool sentExposeEvent = false; |
michael@0 | 268 | |
michael@0 | 269 | for (;;) { |
michael@0 | 270 | SkEvent::ServiceQueueTimer(); |
michael@0 | 271 | |
michael@0 | 272 | bool moreToDo = SkEvent::ProcessEvent(); |
michael@0 | 273 | |
michael@0 | 274 | if (this->isDirty() && !sentExposeEvent) { |
michael@0 | 275 | sentExposeEvent = true; |
michael@0 | 276 | |
michael@0 | 277 | XEvent evt; |
michael@0 | 278 | sk_bzero(&evt, sizeof(evt)); |
michael@0 | 279 | evt.type = Expose; |
michael@0 | 280 | evt.xexpose.display = dsp; |
michael@0 | 281 | XSendEvent(dsp, win, false, ExposureMask, &evt); |
michael@0 | 282 | } |
michael@0 | 283 | |
michael@0 | 284 | if (XPending(dsp) || !moreToDo) { |
michael@0 | 285 | switch (this->nextXEvent()) { |
michael@0 | 286 | case kContinue_NextXEventResult: |
michael@0 | 287 | break; |
michael@0 | 288 | case kPaintRequest_NextXEventResult: |
michael@0 | 289 | sentExposeEvent = false; |
michael@0 | 290 | if (this->isDirty()) { |
michael@0 | 291 | this->update(NULL); |
michael@0 | 292 | } |
michael@0 | 293 | this->doPaint(); |
michael@0 | 294 | break; |
michael@0 | 295 | case kQuitRequest_NextXEventResult: |
michael@0 | 296 | return; |
michael@0 | 297 | } |
michael@0 | 298 | } |
michael@0 | 299 | } |
michael@0 | 300 | } |
michael@0 | 301 | |
michael@0 | 302 | void SkOSWindow::mapWindowAndWait() { |
michael@0 | 303 | SkASSERT(NULL != fUnixWindow.fDisplay); |
michael@0 | 304 | Display* dsp = fUnixWindow.fDisplay; |
michael@0 | 305 | Window win = fUnixWindow.fWin; |
michael@0 | 306 | XMapWindow(dsp, win); |
michael@0 | 307 | |
michael@0 | 308 | long eventMask = StructureNotifyMask; |
michael@0 | 309 | XSelectInput(dsp, win, eventMask); |
michael@0 | 310 | |
michael@0 | 311 | // Wait until screen is ready. |
michael@0 | 312 | XEvent evt; |
michael@0 | 313 | do { |
michael@0 | 314 | XNextEvent(dsp, &evt); |
michael@0 | 315 | } while(evt.type != MapNotify); |
michael@0 | 316 | |
michael@0 | 317 | } |
michael@0 | 318 | |
michael@0 | 319 | bool SkOSWindow::attach(SkBackEndTypes, int msaaSampleCount, AttachmentInfo* info) { |
michael@0 | 320 | this->initWindow(msaaSampleCount, info); |
michael@0 | 321 | |
michael@0 | 322 | if (NULL == fUnixWindow.fDisplay) { |
michael@0 | 323 | return false; |
michael@0 | 324 | } |
michael@0 | 325 | if (NULL == fUnixWindow.fGLContext) { |
michael@0 | 326 | SkASSERT(NULL != fVi); |
michael@0 | 327 | |
michael@0 | 328 | fUnixWindow.fGLContext = glXCreateContext(fUnixWindow.fDisplay, |
michael@0 | 329 | fVi, |
michael@0 | 330 | NULL, |
michael@0 | 331 | GL_TRUE); |
michael@0 | 332 | if (NULL == fUnixWindow.fGLContext) { |
michael@0 | 333 | return false; |
michael@0 | 334 | } |
michael@0 | 335 | } |
michael@0 | 336 | glXMakeCurrent(fUnixWindow.fDisplay, |
michael@0 | 337 | fUnixWindow.fWin, |
michael@0 | 338 | fUnixWindow.fGLContext); |
michael@0 | 339 | glViewport(0, 0, |
michael@0 | 340 | SkScalarRoundToInt(this->width()), |
michael@0 | 341 | SkScalarRoundToInt(this->height())); |
michael@0 | 342 | glClearColor(0, 0, 0, 0); |
michael@0 | 343 | glClearStencil(0); |
michael@0 | 344 | glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
michael@0 | 345 | return true; |
michael@0 | 346 | } |
michael@0 | 347 | |
michael@0 | 348 | void SkOSWindow::detach() { |
michael@0 | 349 | if (NULL == fUnixWindow.fDisplay || NULL == fUnixWindow.fGLContext) { |
michael@0 | 350 | return; |
michael@0 | 351 | } |
michael@0 | 352 | glXMakeCurrent(fUnixWindow.fDisplay, None, NULL); |
michael@0 | 353 | glXDestroyContext(fUnixWindow.fDisplay, fUnixWindow.fGLContext); |
michael@0 | 354 | fUnixWindow.fGLContext = NULL; |
michael@0 | 355 | } |
michael@0 | 356 | |
michael@0 | 357 | void SkOSWindow::present() { |
michael@0 | 358 | if (NULL != fUnixWindow.fDisplay && NULL != fUnixWindow.fGLContext) { |
michael@0 | 359 | glXSwapBuffers(fUnixWindow.fDisplay, fUnixWindow.fWin); |
michael@0 | 360 | } |
michael@0 | 361 | } |
michael@0 | 362 | |
michael@0 | 363 | void SkOSWindow::onSetTitle(const char title[]) { |
michael@0 | 364 | if (NULL == fUnixWindow.fDisplay) { |
michael@0 | 365 | return; |
michael@0 | 366 | } |
michael@0 | 367 | XTextProperty textProp; |
michael@0 | 368 | textProp.value = (unsigned char*)title; |
michael@0 | 369 | textProp.format = 8; |
michael@0 | 370 | textProp.nitems = strlen((char*)textProp.value); |
michael@0 | 371 | textProp.encoding = XA_STRING; |
michael@0 | 372 | XSetWMName(fUnixWindow.fDisplay, fUnixWindow.fWin, &textProp); |
michael@0 | 373 | } |
michael@0 | 374 | |
michael@0 | 375 | static bool convertBitmapToXImage(XImage& image, const SkBitmap& bitmap) { |
michael@0 | 376 | sk_bzero(&image, sizeof(image)); |
michael@0 | 377 | |
michael@0 | 378 | int bitsPerPixel = bitmap.bytesPerPixel() * 8; |
michael@0 | 379 | image.width = bitmap.width(); |
michael@0 | 380 | image.height = bitmap.height(); |
michael@0 | 381 | image.format = ZPixmap; |
michael@0 | 382 | image.data = (char*) bitmap.getPixels(); |
michael@0 | 383 | image.byte_order = LSBFirst; |
michael@0 | 384 | image.bitmap_unit = bitsPerPixel; |
michael@0 | 385 | image.bitmap_bit_order = LSBFirst; |
michael@0 | 386 | image.bitmap_pad = bitsPerPixel; |
michael@0 | 387 | image.depth = 24; |
michael@0 | 388 | image.bytes_per_line = bitmap.rowBytes() - bitmap.width() * 4; |
michael@0 | 389 | image.bits_per_pixel = bitsPerPixel; |
michael@0 | 390 | return XInitImage(&image); |
michael@0 | 391 | } |
michael@0 | 392 | |
michael@0 | 393 | void SkOSWindow::doPaint() { |
michael@0 | 394 | if (NULL == fUnixWindow.fDisplay) { |
michael@0 | 395 | return; |
michael@0 | 396 | } |
michael@0 | 397 | // If we are drawing with GL, we don't need XPutImage. |
michael@0 | 398 | if (NULL != fUnixWindow.fGLContext) { |
michael@0 | 399 | return; |
michael@0 | 400 | } |
michael@0 | 401 | // Draw the bitmap to the screen. |
michael@0 | 402 | const SkBitmap& bitmap = getBitmap(); |
michael@0 | 403 | int width = bitmap.width(); |
michael@0 | 404 | int height = bitmap.height(); |
michael@0 | 405 | |
michael@0 | 406 | XImage image; |
michael@0 | 407 | if (!convertBitmapToXImage(image, bitmap)) { |
michael@0 | 408 | return; |
michael@0 | 409 | } |
michael@0 | 410 | |
michael@0 | 411 | XPutImage(fUnixWindow.fDisplay, |
michael@0 | 412 | fUnixWindow.fWin, |
michael@0 | 413 | fUnixWindow.fGc, |
michael@0 | 414 | &image, |
michael@0 | 415 | 0, 0, // src x,y |
michael@0 | 416 | 0, 0, // dst x,y |
michael@0 | 417 | width, height); |
michael@0 | 418 | } |
michael@0 | 419 | |
michael@0 | 420 | /////////////////////////////////////////////////////////////////////////////// |
michael@0 | 421 | |
michael@0 | 422 | void SkEvent::SignalNonEmptyQueue() { |
michael@0 | 423 | // nothing to do, since we spin on our event-queue, polling for XPending |
michael@0 | 424 | } |
michael@0 | 425 | |
michael@0 | 426 | void SkEvent::SignalQueueTimer(SkMSec delay) { |
michael@0 | 427 | // just need to record the delay time. We handle waking up for it in |
michael@0 | 428 | // MyXNextEventWithDelay() |
michael@0 | 429 | gTimerDelay = delay; |
michael@0 | 430 | } |