11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include <X11/Xlib.h> 935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include <X11/Xatom.h> 1035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include <X11/keysym.h> 1135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include <GL/glx.h> 1235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include <GL/gl.h> 1335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include <GL/glu.h> 1435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 1535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include "SkWindow.h" 1635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 1735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include "SkBitmap.h" 1835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include "SkCanvas.h" 1935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include "SkColor.h" 2035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include "SkEvent.h" 2135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include "SkKey.h" 2235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include "SkWindow.h" 2335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include "XkeysToSkKeys.h" 2435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerextern "C" { 2535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger #include "keysym2ucs.h" 2635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 2735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 280199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerconst int WIDTH = 500; 290199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerconst int HEIGHT = 500; 3035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 3135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger// Determine which events to listen for. 3235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerconst long EVENT_MASK = StructureNotifyMask|ButtonPressMask|ButtonReleaseMask 3335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger |ExposureMask|PointerMotionMask|KeyPressMask|KeyReleaseMask; 3435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 351cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkOSWindow::SkOSWindow(void* unused) : INHERITED(), fGLAttached(false), fVi(0) 3635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{ 3735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fUnixWindow.fDisplay = XOpenDisplay(NULL); 3835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger Display* dsp = fUnixWindow.fDisplay; 3935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (dsp) { 4035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // Attempt to create a window that supports GL 4135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, 4235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger GLX_STENCIL_SIZE, 8, None }; 430199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger fVi = glXChooseVisual(dsp, DefaultScreen(dsp), att); 4435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (fVi) { 450199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger Colormap colorMap = XCreateColormap(dsp, RootWindow(dsp, fVi->screen), 460199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger fVi->visual, AllocNone); 4735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XSetWindowAttributes swa; 480199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger swa.colormap = colorMap; 4935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger swa.event_mask = EVENT_MASK; 500199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger fUnixWindow.fWin = XCreateWindow(dsp, RootWindow(dsp, fVi->screen), 5135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 0, 0, WIDTH, HEIGHT, 0, fVi->depth, 520199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger InputOutput, fVi->visual, CWEventMask | CWColormap, &swa); 5335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 5435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } else { 5535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // Create a simple window instead. We will not be able to 5635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // show GL 5735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fUnixWindow.fWin = XCreateSimpleWindow(dsp, DefaultRootWindow(dsp), 5835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 0, 0, WIDTH, HEIGHT, 0, 0, 0); 5935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 6035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger mapWindowAndWait(); 6135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fUnixWindow.fGc = XCreateGC(dsp, fUnixWindow.fWin, 0, NULL); 6235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 6335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger this->resize(WIDTH, HEIGHT); 6435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fUnixWindow.fGLCreated = false; 6535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 6635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 6735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek SollenbergerSkOSWindow::~SkOSWindow() 6835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{ 6935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (fUnixWindow.fDisplay) { 7035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (fGLAttached) 7135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger glXMakeCurrent(fUnixWindow.fDisplay, None, NULL); 7235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XFreeGC(fUnixWindow.fDisplay, fUnixWindow.fGc); 7335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (fUnixWindow.fGLCreated) 7435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger glXDestroyContext(fUnixWindow.fDisplay, fUnixWindow.fGLContext); 7535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XDestroyWindow(fUnixWindow.fDisplay, fUnixWindow.fWin); 7635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XCloseDisplay(fUnixWindow.fDisplay); 7735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fUnixWindow.fDisplay = 0; 7835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 7935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 8035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 8135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkOSWindow::post_linuxevent() 8235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{ 8335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // Put an event in the X queue to fire an SkEvent. 8435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (!fUnixWindow.fDisplay) return; 8535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger long event_mask = NoEventMask; 8635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XClientMessageEvent event; 8735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger event.type = ClientMessage; 880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger Atom myAtom(0); 8935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger event.message_type = myAtom; 9035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger event.format = 32; 9135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger event.data.l[0] = 0; 9235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XSendEvent(fUnixWindow.fDisplay, fUnixWindow.fWin, false, 0, 9335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger (XEvent*) &event); 941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger XFlush(fUnixWindow.fDisplay); 9535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 9635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 9735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkOSWindow::loop() 9835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{ 9935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger Display* dsp = fUnixWindow.fDisplay; 10035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XSelectInput(dsp, fUnixWindow.fWin, EVENT_MASK); 10135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 10235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger bool loop = true; 10335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XEvent evt; 10435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger while (loop) { 10535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XNextEvent(dsp, &evt); 10635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger switch (evt.type) { 10735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger case Expose: 10835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (evt.xexpose.count == 0) 10935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger this->inval(NULL); 11035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger break; 11135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger case ConfigureNotify: 11235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger this->resize(evt.xconfigure.width, evt.xconfigure.height); 11335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger break; 11435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger case ButtonPress: 11535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (evt.xbutton.button == Button1) 11635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger this->handleClick(evt.xbutton.x, evt.xbutton.y, SkView::Click::kDown_State); 11735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger break; 11835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger case ButtonRelease: 11935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (evt.xbutton.button == Button1) 12035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger this->handleClick(evt.xbutton.x, evt.xbutton.y, SkView::Click::kUp_State); 12135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger break; 12235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger case MotionNotify: 12335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger this->handleClick(evt.xmotion.x, evt.xmotion.y, SkView::Click::kMoved_State); 12435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger break; 12535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger case KeyPress: 12635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger { 12735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger KeySym keysym = XKeycodeToKeysym(dsp, evt.xkey.keycode, 0); 12835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger //SkDebugf("pressed key %i!\n\tKeySym:%i\n", evt.xkey.keycode, XKeycodeToKeysym(dsp, evt.xkey.keycode, 0)); 12935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (keysym == XK_Escape) { 13035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger loop = false; 13135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger break; 13235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 13335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger this->handleKey(XKeyToSkKey(keysym)); 13435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger long uni = keysym2ucs(keysym); 13535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (uni != -1) { 13635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger this->handleChar((SkUnichar) uni); 13735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 13835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger break; 13935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 14035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger case KeyRelease: 14135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger //SkDebugf("released key %i\n", evt.xkey.keycode); 14235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger this->handleKeyUp(XKeyToSkKey(XKeycodeToKeysym(dsp, evt.xkey.keycode, 0))); 14335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger break; 14435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger case ClientMessage: 14535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (SkEvent::ProcessEvent()) { 14635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger this->post_linuxevent(); 14735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 14835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger break; 14935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger default: 15035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // Do nothing for other events 15135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger break; 15235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 15335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 15435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 15535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 15635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkOSWindow::mapWindowAndWait() 15735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{ 15835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger Display* dsp = fUnixWindow.fDisplay; 15935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger Window win = fUnixWindow.fWin; 16035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XMapWindow(dsp, win); 16135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 16235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger long eventMask = StructureNotifyMask; 16335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XSelectInput(dsp, win, eventMask); 16435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 16535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // Wait until screen is ready. 16635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XEvent evt; 16735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger do { 16835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XNextEvent(dsp, &evt); 16935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } while(evt.type != MapNotify); 17035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 17135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 17235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 17335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerbool SkOSWindow::attachGL() 17435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{ 17535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (fGLAttached) return true; 17635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger Display* dsp = fUnixWindow.fDisplay; 17735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (!dsp || !fVi) return false; 17835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 17935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (!fUnixWindow.fGLCreated) { 18035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fUnixWindow.fGLContext = glXCreateContext(dsp, fVi, NULL, GL_TRUE); 18135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fUnixWindow.fGLCreated = true; 18235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger glXMakeCurrent(dsp, fUnixWindow.fWin, fUnixWindow.fGLContext); 18335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger glViewport(0, 0, SkScalarRound(this->width()), SkScalarRound(this->height())); 18435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger glClearColor(0, 0, 0, 0); 18535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger glClearStencil(0); 18635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger glStencilMask(0xffffffff); 18735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger glDisable(GL_SCISSOR_TEST); 18835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 18935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 19035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger else 19135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger glXMakeCurrent(dsp, fUnixWindow.fWin, fUnixWindow.fGLContext); 19235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fGLAttached = true; 19335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 19435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return true; 19535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 19635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 19735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkOSWindow::detachGL() 19835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{ 19935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (!fUnixWindow.fDisplay || !fGLAttached) return; 20035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fGLAttached = false; 20135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // Returns back to normal drawing. 20235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger glXMakeCurrent(fUnixWindow.fDisplay, None, NULL); 20335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // Ensure that we redraw when switching back to raster. 20435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger this->inval(NULL); 20535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 20635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 20735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkOSWindow::presentGL() 20835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{ 20935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (fUnixWindow.fDisplay && fGLAttached) { 21035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger glXSwapBuffers(fUnixWindow.fDisplay, fUnixWindow.fWin); 21135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 21235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 21335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 21435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkOSWindow::onSetTitle(const char title[]) 21535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{ 21635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (!fUnixWindow.fDisplay) return; 21735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XTextProperty textProp; 21835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger textProp.value = (unsigned char*)title; 21935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger textProp.format = 8; 22035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger textProp.nitems = strlen((char*)textProp.value); 22135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger textProp.encoding = XA_STRING; 22235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XSetWMName(fUnixWindow.fDisplay, fUnixWindow.fWin, &textProp); 22335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 22435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkOSWindow::onHandleInval(const SkIRect&) { 2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (new SkEvent("inval-imageview", this->getSinkID()))->post(); 22735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 22835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 22935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerbool SkOSWindow::onEvent(const SkEvent& evt) 23035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{ 23135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (evt.isType("inval-imageview")) { 23235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger update(NULL); 23335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (!fGLAttached) 23435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger doPaint(); 23535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return true; 23635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 23735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return INHERITED::onEvent(evt); 23835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 23935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 24035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerstatic bool convertBitmapToXImage(XImage& image, const SkBitmap& bitmap) 24135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{ 24235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger sk_bzero(&image, sizeof(image)); 24335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 24435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger int bitsPerPixel = bitmap.bytesPerPixel() * 8; 24535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger image.width = bitmap.width(); 24635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger image.height = bitmap.height(); 24735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger image.format = ZPixmap; 24835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger image.data = (char*) bitmap.getPixels(); 24935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger image.byte_order = LSBFirst; 25035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger image.bitmap_unit = bitsPerPixel; 25135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger image.bitmap_bit_order = LSBFirst; 25235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger image.bitmap_pad = bitsPerPixel; 25335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger image.depth = 24; 25435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger image.bytes_per_line = bitmap.rowBytes() - bitmap.width() * bitmap.bytesPerPixel(); 25535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger image.bits_per_pixel = bitsPerPixel; 25635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return XInitImage(&image); 25735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 25835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 25935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkOSWindow::doPaint() { 26035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (!fUnixWindow.fDisplay) return; 26135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // Draw the bitmap to the screen. 26235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger const SkBitmap& bitmap = getBitmap(); 26335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger int width = bitmap.width(); 26435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger int height = bitmap.height(); 26535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 26635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XImage image; 26735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (!convertBitmapToXImage(image, bitmap)) return; 26835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 26935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger XPutImage(fUnixWindow.fDisplay, fUnixWindow.fWin, fUnixWindow.fGc, &image, 0, 0, 0, 0, width, height); 27035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 27135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 27235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerbool SkOSWindow::onHandleChar(SkUnichar) 27335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{ 27435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return false; 27535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 27635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 27735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerbool SkOSWindow::onHandleKey(SkKey key) 27835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{ 27935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return false; 28035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 28135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 28235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerbool SkOSWindow::onHandleKeyUp(SkKey key) 28335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{ 28435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return false; 28535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 286