OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 #include <X11/Xatom.h> | 9 #include <X11/Xatom.h> |
10 #include <X11/XKBlib.h> | 10 #include <X11/XKBlib.h> |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 XSelectInput(dsp, win, eventMask); | 319 XSelectInput(dsp, win, eventMask); |
320 | 320 |
321 // Wait until screen is ready. | 321 // Wait until screen is ready. |
322 XEvent evt; | 322 XEvent evt; |
323 do { | 323 do { |
324 XNextEvent(dsp, &evt); | 324 XNextEvent(dsp, &evt); |
325 } while(evt.type != MapNotify); | 325 } while(evt.type != MapNotify); |
326 | 326 |
327 } | 327 } |
328 | 328 |
| 329 //////////////////////////////////////////////// |
| 330 |
| 331 // Some helper code to load the correct version of glXSwapInterval |
| 332 #define GLX_GET_PROC_ADDR(name) glXGetProcAddress(reinterpret_cast<const GLubyte
*>((name))) |
| 333 #define EXT_WRANGLE(name, type, ...) \ |
| 334 if (GLX_GET_PROC_ADDR(#name)) { \ |
| 335 static type k##name; \ |
| 336 if (!k##name) { \ |
| 337 k##name = (type) GLX_GET_PROC_ADDR(#name); \ |
| 338 } \ |
| 339 k##name(__VA_ARGS__); \ |
| 340 SkDebugf("using %s\n", #name); \ |
| 341 return; \ |
| 342 } |
| 343 |
| 344 static void glXSwapInterval(Display* dsp, GLXDrawable drawable, int interval) { |
| 345 EXT_WRANGLE(glXSwapIntervalEXT, PFNGLXSWAPINTERVALEXTPROC, dsp, drawable, in
terval); |
| 346 EXT_WRANGLE(glXSwapIntervalMESA, PFNGLXSWAPINTERVALMESAPROC, interval); |
| 347 EXT_WRANGLE(glXSwapIntervalSGI, PFNGLXSWAPINTERVALSGIPROC, interval); |
| 348 } |
| 349 |
| 350 ///////////////////////////////////////////////////////////////////////// |
| 351 |
329 bool SkOSWindow::attach(SkBackEndTypes, int msaaSampleCount, AttachmentInfo* inf
o) { | 352 bool SkOSWindow::attach(SkBackEndTypes, int msaaSampleCount, AttachmentInfo* inf
o) { |
330 this->initWindow(msaaSampleCount, info); | 353 this->initWindow(msaaSampleCount, info); |
331 | 354 |
332 if (NULL == fUnixWindow.fDisplay) { | 355 if (NULL == fUnixWindow.fDisplay) { |
333 return false; | 356 return false; |
334 } | 357 } |
335 if (NULL == fUnixWindow.fGLContext) { | 358 if (NULL == fUnixWindow.fGLContext) { |
336 SkASSERT(fVi); | 359 SkASSERT(fVi); |
337 | 360 |
338 fUnixWindow.fGLContext = glXCreateContext(fUnixWindow.fDisplay, | 361 fUnixWindow.fGLContext = glXCreateContext(fUnixWindow.fDisplay, |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 | 443 |
421 XPutImage(fUnixWindow.fDisplay, | 444 XPutImage(fUnixWindow.fDisplay, |
422 fUnixWindow.fWin, | 445 fUnixWindow.fWin, |
423 fUnixWindow.fGc, | 446 fUnixWindow.fGc, |
424 &image, | 447 &image, |
425 0, 0, // src x,y | 448 0, 0, // src x,y |
426 0, 0, // dst x,y | 449 0, 0, // dst x,y |
427 width, height); | 450 width, height); |
428 } | 451 } |
429 | 452 |
| 453 enum { |
| 454 _NET_WM_STATE_REMOVE =0, |
| 455 _NET_WM_STATE_ADD = 1, |
| 456 _NET_WM_STATE_TOGGLE =2 |
| 457 }; |
| 458 |
| 459 void SkOSWindow::setFullscreen(bool setFullscreen) { |
| 460 Display* dsp = fUnixWindow.fDisplay; |
| 461 if (NULL == dsp) { |
| 462 return; |
| 463 } |
| 464 Window win = fUnixWindow.fWin; |
| 465 |
| 466 // Full screen |
| 467 Atom wm_state = XInternAtom(dsp, "_NET_WM_STATE", False); |
| 468 Atom fullscreen = XInternAtom(dsp, "_NET_WM_STATE_FULLSCREEN", False); |
| 469 |
| 470 XEvent evt; |
| 471 sk_bzero(&evt, sizeof(evt)); |
| 472 evt.type = ClientMessage; |
| 473 evt.xclient.window = win; |
| 474 evt.xclient.message_type = wm_state; |
| 475 evt.xclient.format = 32; |
| 476 evt.xclient.data.l[0] = setFullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_RE
MOVE; |
| 477 evt.xclient.data.l[1] = fullscreen; |
| 478 evt.xclient.data.l[2] = 0; |
| 479 |
| 480 XSendEvent(dsp, DefaultRootWindow(dsp), False, |
| 481 SubstructureRedirectMask | SubstructureNotifyMask, &evt); |
| 482 } |
| 483 |
| 484 void SkOSWindow::setVsync(bool vsync) { |
| 485 if (fUnixWindow.fDisplay && fUnixWindow.fGLContext && fUnixWindow.fWin) { |
| 486 int swapInterval = vsync ? 1 : 0; |
| 487 glXSwapInterval(fUnixWindow.fDisplay, fUnixWindow.fWin, swapInterval); |
| 488 } |
| 489 } |
| 490 |
430 /////////////////////////////////////////////////////////////////////////////// | 491 /////////////////////////////////////////////////////////////////////////////// |
431 | 492 |
432 void SkEvent::SignalNonEmptyQueue() { | 493 void SkEvent::SignalNonEmptyQueue() { |
433 // nothing to do, since we spin on our event-queue, polling for XPending | 494 // nothing to do, since we spin on our event-queue, polling for XPending |
434 } | 495 } |
435 | 496 |
436 void SkEvent::SignalQueueTimer(SkMSec delay) { | 497 void SkEvent::SignalQueueTimer(SkMSec delay) { |
437 // just need to record the delay time. We handle waking up for it in | 498 // just need to record the delay time. We handle waking up for it in |
438 // MyXNextEventWithDelay() | 499 // MyXNextEventWithDelay() |
439 gTimerDelay = delay; | 500 gTimerDelay = delay; |
440 } | 501 } |
OLD | NEW |