summaryrefslogtreecommitdiff
path: root/plugingui
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2013-05-08 14:56:19 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2013-05-08 14:56:19 +0200
commit895c942289c81ca24346d3bb18d2b922ae469554 (patch)
tree58a5ad2ae9ad311bfa59daaa8114a83b5277c3c5 /plugingui
parent8cacd4e097bb969fe6de20d88e98763deef658e6 (diff)
Remove GlobalContext class. Move all native code from EventHandler class to NativeWindowX11 and NativeWindowWin32 classes.
Diffstat (limited to 'plugingui')
-rw-r--r--plugingui/Makefile.am1
-rw-r--r--plugingui/Makefile.am.plugingui1
-rw-r--r--plugingui/Makefile.mingw321
-rw-r--r--plugingui/colour.cc2
-rw-r--r--plugingui/eventhandler.cc400
-rw-r--r--plugingui/eventhandler.h19
-rw-r--r--plugingui/font.cc2
-rw-r--r--plugingui/font.h10
-rw-r--r--plugingui/globalcontext.cc62
-rw-r--r--plugingui/globalcontext.h67
-rw-r--r--plugingui/nativewindow.h8
-rw-r--r--plugingui/nativewindow_win32.cc300
-rw-r--r--plugingui/nativewindow_win32.h15
-rw-r--r--plugingui/nativewindow_x11.cc163
-rw-r--r--plugingui/nativewindow_x11.h10
-rw-r--r--plugingui/painter.cc2
-rw-r--r--plugingui/plugingui.cc18
-rw-r--r--plugingui/plugingui.h2
-rw-r--r--plugingui/widget.cc1
-rw-r--r--plugingui/window.cc20
-rw-r--r--plugingui/window.h10
21 files changed, 486 insertions, 628 deletions
diff --git a/plugingui/Makefile.am b/plugingui/Makefile.am
index fc91d58..be0ecb6 100644
--- a/plugingui/Makefile.am
+++ b/plugingui/Makefile.am
@@ -26,7 +26,6 @@ EXTRA_DIST = \
directory.h \
eventhandler.h \
font.h \
- globalcontext.h \
guievent.h \
image.h \
label.h \
diff --git a/plugingui/Makefile.am.plugingui b/plugingui/Makefile.am.plugingui
index abdf6d5..f291428 100644
--- a/plugingui/Makefile.am.plugingui
+++ b/plugingui/Makefile.am.plugingui
@@ -4,7 +4,6 @@ PLUGIN_GUI_SOURCES = \
$(top_srcdir)/plugingui/nativewindow_x11.cc \
$(top_srcdir)/plugingui/nativewindow_win32.cc \
$(top_srcdir)/plugingui/plugingui.cc \
- $(top_srcdir)/plugingui/globalcontext.cc \
$(top_srcdir)/plugingui/label.cc \
$(top_srcdir)/plugingui/eventhandler.cc \
$(top_srcdir)/plugingui/font.cc \
diff --git a/plugingui/Makefile.mingw32 b/plugingui/Makefile.mingw32
index 746c066..b8ffe9e 100644
--- a/plugingui/Makefile.mingw32
+++ b/plugingui/Makefile.mingw32
@@ -13,7 +13,6 @@ CXX_SOURCES = \
$(top_srcdir)/plugingui/nativewindow_x11.cc \
$(top_srcdir)/plugingui/nativewindow_win32.cc \
$(top_srcdir)/plugingui/plugingui.cc \
- $(top_srcdir)/plugingui/globalcontext.cc \
$(top_srcdir)/plugingui/label.cc \
$(top_srcdir)/plugingui/eventhandler.cc \
$(top_srcdir)/plugingui/font.cc \
diff --git a/plugingui/colour.cc b/plugingui/colour.cc
index 01c4fc3..943011b 100644
--- a/plugingui/colour.cc
+++ b/plugingui/colour.cc
@@ -26,8 +26,6 @@
*/
#include "colour.h"
-#include "globalcontext.h"
-
GUI::Colour::Colour()
{
red = blue = green = alpha = 1.0;
diff --git a/plugingui/eventhandler.cc b/plugingui/eventhandler.cc
index a7aff12..7eae827 100644
--- a/plugingui/eventhandler.cc
+++ b/plugingui/eventhandler.cc
@@ -26,392 +26,25 @@
*/
#include "eventhandler.h"
-#include "globalcontext.h"
-
-#include <stdio.h>
-
-#ifdef X11
-#include <X11/Xutil.h>
-#endif/*X11*/
+#include "window.h"
-GUI::EventHandler::EventHandler(GlobalContext *gctx)
+GUI::EventHandler::EventHandler(GUI::NativeWindow *n, GUI::Window *w)
{
- this->gctx = gctx;
+ native = n;
+ window = w;
+
last_click = 0;
last_was_dbl_click = false;
-#ifdef WIN32
- this->gctx->eventhandler = this;
- event = NULL;
-#endif/*WIN32*/
}
bool GUI::EventHandler::hasEvent()
{
-#ifdef X11
- return XPending(gctx->display);
-#endif/*X11*/
-
-#ifdef WIN32
- MSG msg;
- return PeekMessage(&msg, NULL, 0, 0, 0) != 0;
-#endif/*WIN32*/
- return false;
+ return native->hasEvent();
}
-#ifdef WIN32
-
-extern GUI::Window *gwindow;
-
-#include "window.h"
-LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
-{
- GUI::EventHandler *handler =
- (GUI::EventHandler *) GetWindowLong(hwnd, GWL_USERDATA);
-
- switch(msg) {
- case WM_SIZE:
- {
- static bool first = true;
- if(!first) {
- GUI::ResizeEvent *e = new GUI::ResizeEvent();
- e->width = LOWORD(lp);
- e->height = HIWORD(lp);
- handler->event = e;
- first = false;
- }
- }
- break;
-
- case WM_MOVE:
- {
-// GUI::MoveEvent *e = new GUI::MoveEvent();
-// e->x = (int)(short) LOWORD(lp);
-// e->y = (int)(short) HIWORD(lp);
-// handler->event = e;
- }
- break;
-
- case WM_CLOSE:
- {
- GUI::CloseEvent *e = new GUI::CloseEvent();
- handler->event = e;
- }
- break;
-// HWND child, old;
-// old = 0;
-
-// numDialogs--;
-
-// while(old != (child = GetNextDlgGroupItem(hwnd, hwnd, false))) {
-// old = child;
-// EndDialog(child, 0);
-// }
-
-// if(numDialogs) EndDialog(hwnd, 0);
-// else PostQuitMessage(0);
-// return 0;
- case WM_MOUSEMOVE:
- {
-
- GUI::MouseMoveEvent *e = new GUI::MouseMoveEvent();
- e->x = (int)(short) LOWORD(lp);
- e->y = (int)(short) HIWORD(lp);
- handler->event = e;
- }
- break;
-
- case WM_MOUSEWHEEL:
- {
- GUI::ScrollEvent *e = new GUI::ScrollEvent();
-
- // NOTE: lp is coordinates in screen space, not client space.
- POINT p;
- p.x = (int)(short) LOWORD(lp);
- p.y = (int)(short) HIWORD(lp);
- ScreenToClient(hwnd, &p);
-
- e->x = p.x;
- e->y = p.y;
- e->delta = -1 * (short)HIWORD(wp) / 60;
- handler->event = e;
- }
- break;
-
- case WM_LBUTTONUP:
- case WM_LBUTTONDBLCLK:
- case WM_LBUTTONDOWN:
- case WM_RBUTTONUP:
- case WM_RBUTTONDBLCLK:
- case WM_RBUTTONDOWN:
- case WM_MBUTTONUP:
- case WM_MBUTTONDBLCLK:
- case WM_MBUTTONDOWN:
- {
- GUI::ButtonEvent *e = new GUI::ButtonEvent();
- e->x = (int)(short) LOWORD(lp);
- e->y = (int)(short) HIWORD(lp);
-
- if(msg == WM_LBUTTONUP ||
- msg == WM_LBUTTONDBLCLK ||
- msg == WM_LBUTTONDOWN) e->button = 0;
-
- if(msg == WM_RBUTTONUP ||
- msg == WM_RBUTTONDBLCLK ||
- msg == WM_RBUTTONDOWN) e->button = 1;
-
- if(msg == WM_MBUTTONUP ||
- msg == WM_MBUTTONDBLCLK ||
- msg == WM_MBUTTONDOWN) e->button = 2;
-
- e->direction = 0;
- if(msg == WM_LBUTTONUP ||
- msg == WM_RBUTTONUP ||
- msg == WM_MBUTTONUP) e->direction = -1;
-
- if(msg == WM_LBUTTONDOWN ||
- msg == WM_RBUTTONDOWN ||
- msg == WM_MBUTTONDOWN) e->direction = 1;
-
- e->doubleclick = (msg == WM_LBUTTONDBLCLK ||
- msg == WM_RBUTTONDBLCLK ||
- msg == WM_MBUTTONDBLCLK);
-
- handler->event = e;
- }
- break;
-
- case WM_KEYDOWN:
- {
- GUI::KeyEvent *e = new GUI::KeyEvent();
- //printf("wp: %d\n", wp);
- switch(wp) {
- case 37: e->keycode = GUI::KeyEvent::KEY_LEFT; break;
- case 39: e->keycode = GUI::KeyEvent::KEY_RIGHT; break;
- case 38: e->keycode = GUI::KeyEvent::KEY_UP; break;
- case 40: e->keycode = GUI::KeyEvent::KEY_DOWN; break;
- case 8: e->keycode = GUI::KeyEvent::KEY_BACKSPACE; break;
- case 46: e->keycode = GUI::KeyEvent::KEY_DELETE; break;
- case 36: e->keycode = GUI::KeyEvent::KEY_HOME; break;
- case 35: e->keycode = GUI::KeyEvent::KEY_END; break;
- case 33: e->keycode = GUI::KeyEvent::KEY_PGUP; break;
- case 34: e->keycode = GUI::KeyEvent::KEY_PGDOWN; break;
- case 13: e->keycode = GUI::KeyEvent::KEY_ENTER; break;
- default: e->keycode = GUI::KeyEvent::KEY_UNKNOWN; break;
- }
- e->text = "";
- e->direction = -1;
- handler->event = e;
- }
- break;
-
- case WM_CHAR:
- {
- //printf("WM_CHAR %d %d\n", (int)lp, (int)wp);
- if(wp >= ' ') { // Filter control chars.
- GUI::KeyEvent *e = new GUI::KeyEvent();
- e->keycode = GUI::KeyEvent::KEY_CHARACTER;
- e->text += (char)wp;
- e->direction = -1;
- handler->event = e;
- }
- }
- break;
-
- case WM_PAINT:
- {
- GUI::RepaintEvent *e = new GUI::RepaintEvent();
- e->x = 0;
- e->y = 0;
- e->width = 100;
- e->height = 100;
- handler->event = e;
-
- // Move to window.h (in class)
- HDC pDC;
- HBITMAP old;
- HBITMAP ourbitmap;
- int * framebuf;
- GUI::PixelBuffer &px = gwindow->wpixbuf;
-
- { // Create bitmap (move to window.cc)
- HDC hDC;
- BITMAPINFO bitmapinfo;
- hDC = CreateCompatibleDC(NULL);
- bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bitmapinfo.bmiHeader.biWidth = px.width;
- bitmapinfo.bmiHeader.biHeight = -px.height; /* top-down */
- bitmapinfo.bmiHeader.biPlanes = 1;
- bitmapinfo.bmiHeader.biBitCount = 32;
- bitmapinfo.bmiHeader.biCompression = BI_RGB;
- bitmapinfo.bmiHeader.biSizeImage = 0;
- bitmapinfo.bmiHeader.biClrUsed = 256;
- bitmapinfo.bmiHeader.biClrImportant = 256;
- ourbitmap=CreateDIBSection(hDC, &bitmapinfo,
- DIB_RGB_COLORS, (void**)&framebuf, 0, 0);
- pDC=CreateCompatibleDC(NULL);
- old = (HBITMAP__*)SelectObject(pDC, ourbitmap);
- DeleteDC(hDC);
- }
-
- { // Copy GUI::PixelBuffer to framebuffer (move to window.cc)
- int i,j,k;
- for (k=0,i=0;i<(int)px.height;i++) {
- for (j=0;j<(int)px.width;j++,k++) {
- *(framebuf+k)=RGB(px.buf[(j + i * px.width) * 3 + 2],
- px.buf[(j + i * px.width) * 3 + 1],
- px.buf[(j + i * px.width) * 3 + 0]);
- }
- }
- }
-
- PAINTSTRUCT ps;
- HDC hdc = BeginPaint(handler->gctx->m_hwnd, &ps);
- BitBlt(hdc,0,0,px.width,px.height,pDC,0,0,SRCCOPY);
- EndPaint(handler->gctx->m_hwnd, &ps);
-
- { // Destroy bitmap (move to window.cc)
- SelectObject(pDC,old);
- DeleteDC(pDC);
- DeleteObject(ourbitmap);
-
- }
- }
- return DefWindowProc(hwnd, msg, wp, lp);
- }
-
- return DefWindowProc(hwnd, msg, wp, lp);
-}
-#endif/*WIN32*/
-
GUI::Event *GUI::EventHandler::getNextEvent()
{
- Event *event = NULL;
-#ifdef X11
- XEvent xe;
- XNextEvent(gctx->display, &xe);
-
- if(xe.type == MotionNotify) {
- while(true) { // Hack to make sure only the last event is played.
- if(!hasEvent()) break;
- XEvent nxe;
- XPeekEvent(gctx->display, &nxe);
- if(nxe.type != MotionNotify) break;
- XNextEvent(gctx->display, &xe);
- }
-
- MouseMoveEvent *e = new MouseMoveEvent();
- e->window_id = xe.xmotion.window;
- e->x = xe.xmotion.x;
- e->y = xe.xmotion.y;
- event = e;
- }
-
- if(xe.type == Expose && xe.xexpose.count == 0) {
- RepaintEvent *e = new RepaintEvent();
- e->window_id = xe.xexpose.window;
- e->x = xe.xexpose.x;
- e->y = xe.xexpose.y;
- e->width = xe.xexpose.width;
- e->height = xe.xexpose.height;
- event = e;
- }
-
- if(xe.type == ConfigureNotify) {
- ResizeEvent *e = new ResizeEvent();
- e->window_id = xe.xconfigure.window;
- // e->x = xe.xconfigure.x;
- // e->y = xe.xconfigure.y;
- e->width = xe.xconfigure.width;
- e->height = xe.xconfigure.height;
- event = e;
- }
-
- if(xe.type == ButtonPress || xe.type == ButtonRelease) {
- if(xe.xbutton.button == 4 || xe.xbutton.button == 5) {
- int scroll = 1;
- while(true) { // Hack to make sure only the last event is played.
- if(!hasEvent()) break;
- XEvent nxe;
- XPeekEvent(gctx->display, &nxe);
- if(nxe.type != ButtonPress && nxe.type != ButtonRelease) break;
- scroll += 1;
- XNextEvent(gctx->display, &xe);
- }
- ScrollEvent *e = new ScrollEvent();
- e->window_id = xe.xbutton.window;
- e->x = xe.xbutton.x;
- e->y = xe.xbutton.y;
- e->delta = scroll * (xe.xbutton.button==4?-1:1);
- event = e;
- } else {
- ButtonEvent *e = new ButtonEvent();
- e->window_id = xe.xbutton.window;
- e->x = xe.xbutton.x;
- e->y = xe.xbutton.y;
- e->button = 0;
- e->direction = xe.type == ButtonPress?1:-1;
- e->doubleclick =
- xe.type == ButtonPress && (xe.xbutton.time - last_click) < 200;
-
- if(xe.type == ButtonPress) last_click = xe.xbutton.time;
- event = e;
- }
- }
-
- if(xe.type == KeyPress || xe.type == KeyRelease) {
- //printf("key: %d\n", xe.xkey.keycode);
- KeyEvent *e = new KeyEvent();
- e->window_id = xe.xkey.window;
-
- switch(xe.xkey.keycode) {
- case 113: e->keycode = KeyEvent::KEY_LEFT; break;
- case 114: e->keycode = KeyEvent::KEY_RIGHT; break;
- case 111: e->keycode = KeyEvent::KEY_UP; break;
- case 116: e->keycode = KeyEvent::KEY_DOWN; break;
- case 119: e->keycode = KeyEvent::KEY_DELETE; break;
- case 22: e->keycode = KeyEvent::KEY_BACKSPACE; break;
- case 110: e->keycode = KeyEvent::KEY_HOME; break;
- case 115: e->keycode = KeyEvent::KEY_END; break;
- case 117: e->keycode = KeyEvent::KEY_PGDOWN; break;
- case 112: e->keycode = KeyEvent::KEY_PGUP; break;
- case 36: e->keycode = KeyEvent::KEY_ENTER; break;
- default: e->keycode = KeyEvent::KEY_UNKNOWN; break;
- }
-
- char buf[1024];
- int sz = XLookupString(&xe.xkey, buf, sizeof(buf), NULL, NULL);
- if(sz && e->keycode == KeyEvent::KEY_UNKNOWN) {
- e->keycode = KeyEvent::KEY_CHARACTER;
- }
- e->text.append(buf, sz);
-
- e->direction = xe.type == KeyPress?1:-1;
- event = e;
- }
-
- if(xe.type == ClientMessage &&
- (unsigned int)xe.xclient.data.l[0] == gctx->wmDeleteMessage) {
- CloseEvent *e = new CloseEvent();
- event = e;
- }
-
-#endif/*X11*/
-
-#ifdef WIN32
- MSG msg;
-
- if(GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- // printf("Got message: %p\n", this->event);
-
- event = this->event;
- this->event = NULL;
-#endif/*WIN32*/
-
- return event;
+ return native->getNextEvent();
}
void GUI::EventHandler::registerCloseHandler(void (*handler)(void *), void *ptr)
@@ -420,7 +53,7 @@ void GUI::EventHandler::registerCloseHandler(void (*handler)(void *), void *ptr)
this->closeHandlerPtr = ptr;
}
-void GUI::EventHandler::processEvents(Window *window)
+void GUI::EventHandler::processEvents()
{
while(hasEvent()) {
Event *event = getNextEvent();
@@ -556,20 +189,3 @@ void GUI::EventHandler::processEvents(Window *window)
delete event;
}
}
-
-#ifdef TEST_EVENTHANDLER
-//Additional dependency files
-//deps:
-//Required cflags (autoconf vars may be used)
-//cflags:
-//Required link options (autoconf vars may be used)
-//libs:
-#include "test.h"
-
-TEST_BEGIN;
-
-// TODO: Put some testcode here (see test.h for usable macros).
-
-TEST_END;
-
-#endif/*TEST_EVENTHANDLER*/
diff --git a/plugingui/eventhandler.h b/plugingui/eventhandler.h
index 69586f4..028418d 100644
--- a/plugingui/eventhandler.h
+++ b/plugingui/eventhandler.h
@@ -28,36 +28,33 @@
#define __DRUMGIZMO_EVENTHANDLER_H__
#include "guievent.h"
-#include "globalcontext.h"
-
-#include "window.h"
+#include "nativewindow.h"
+//#include "window.h"
namespace GUI {
+class Window;
class EventHandler {
public:
- EventHandler(GlobalContext *gctx);
+ EventHandler(NativeWindow *native, Window *window);
- void processEvents(Window *window);
+ void processEvents();
bool hasEvent();
Event *getNextEvent();
void registerCloseHandler(void (*handler)(void *), void *ptr);
-#ifdef WIN32
- Event *event;
-#endif/*WIN32*/
-
- GlobalContext *gctx;
-
private:
+ Window *window;
int last_click;
void (*closeHandler)(void *);
void *closeHandlerPtr;
// Used to ignore mouse button release after a double click.
bool last_was_dbl_click;
+
+ NativeWindow *native;
};
};
diff --git a/plugingui/font.cc b/plugingui/font.cc
index f9c8135..828286c 100644
--- a/plugingui/font.cc
+++ b/plugingui/font.cc
@@ -93,7 +93,7 @@ size_t GUI::Font::textHeight(std::string text)
return img_font.height();
}
-GUI::PixelBufferAlpha *GUI::Font::render(GlobalContext *gctx, std::string text)
+GUI::PixelBufferAlpha *GUI::Font::render(std::string text)
{
int border = 1;
PixelBufferAlpha *pb =
diff --git a/plugingui/font.h b/plugingui/font.h
index c0a65f4..b47fbde 100644
--- a/plugingui/font.h
+++ b/plugingui/font.h
@@ -27,13 +27,12 @@
#ifndef __DRUMGIZMO_FONT_H__
#define __DRUMGIZMO_FONT_H__
-#include "pixelbuffer.h"
+#include <string>
+#include <map>
-#include "globalcontext.h"
+#include "pixelbuffer.h"
#include "image.h"
-#include <string>
-
namespace GUI {
class Font {
@@ -49,12 +48,11 @@ public:
size_t textWidth(std::string text);
size_t textHeight(std::string text = "");
- PixelBufferAlpha *render(GlobalContext *gctx, std::string text);
+ PixelBufferAlpha *render(std::string text);
private:
Image img_font;
- GlobalContext *gctx;
std::map<char, int> character_offset;
std::map<char, size_t> character_width;
std::map<char, int> character_pre_bias;
diff --git a/plugingui/globalcontext.cc b/plugingui/globalcontext.cc
deleted file mode 100644
index 0edcb74..0000000
--- a/plugingui/globalcontext.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/***************************************************************************
- * globalcontext.cc
- *
- * Sun Oct 9 19:16:47 CEST 2011
- * Copyright 2011 Bent Bisballe Nyeng
- * deva@aasimon.org
- ****************************************************************************/
-
-/*
- * This file is part of DrumGizmo.
- *
- * DrumGizmo is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * DrumGizmo is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with DrumGizmo; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-#include "globalcontext.h"
-
-GUI::GlobalContext::GlobalContext()
-{
-#ifdef X11
- display = XOpenDisplay(NULL);
-#endif/*X11*/
-
-#ifdef WIN32
- eventhandler = NULL;
-#endif/*WIN32*/
-}
-
-GUI::GlobalContext::~GlobalContext()
-{
-#ifdef X11
- XCloseDisplay(display);
-#endif/*X11*/
-}
-
-#ifdef TEST_GLOBALCONTEXT
-//Additional dependency files
-//deps:
-//Required cflags (autoconf vars may be used)
-//cflags:
-//Required link options (autoconf vars may be used)
-//libs:
-#include "test.h"
-
-TEST_BEGIN;
-
-// TODO: Put some testcode here (see test.h for usable macros).
-
-TEST_END;
-
-#endif/*TEST_GLOBALCONTEXT*/
diff --git a/plugingui/globalcontext.h b/plugingui/globalcontext.h
deleted file mode 100644
index 77e3c37..0000000
--- a/plugingui/globalcontext.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/***************************************************************************
- * globalcontext.h
- *
- * Sun Oct 9 19:16:47 CEST 2011
- * Copyright 2011 Bent Bisballe Nyeng
- * deva@aasimon.org
- ****************************************************************************/
-
-/*
- * This file is part of DrumGizmo.
- *
- * DrumGizmo is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * DrumGizmo is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with DrumGizmo; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-#ifndef __DRUMGIZMO_GLOBALCONTEXT_H__
-#define __DRUMGIZMO_GLOBALCONTEXT_H__
-
-#ifdef X11
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#endif/*X11*/
-
-#ifdef WIN32
-//#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
-#include <windows.h>
-typedef HWND WNDID;
-namespace GUI { class EventHandler; };
-#endif/*WIN32*/
-
-#include <map>
-
-namespace GUI {
-
-class Widget;
-
-class GlobalContext {
-public:
- GlobalContext();
- ~GlobalContext();
-
-#ifdef X11
- Display *display;
- Atom wmDeleteMessage;
-#endif/*X11*/
-
-#ifdef WIN32
- WNDID m_hwnd;
- char *m_className;
- EventHandler *eventhandler;
-#endif/*WIN32*/
-};
-
-};
-
-#endif/*__DRUMGIZMO_GLOBALCONTEXT_H__*/
diff --git a/plugingui/nativewindow.h b/plugingui/nativewindow.h
index 848a761..f27989f 100644
--- a/plugingui/nativewindow.h
+++ b/plugingui/nativewindow.h
@@ -29,13 +29,13 @@
#include <string>
-#include "globalcontext.h"
+#include "guievent.h"
namespace GUI {
class NativeWindow {
public:
- NativeWindow(GlobalContext *c) : gctx(c) {}
+ NativeWindow() {}
virtual ~NativeWindow() {}
virtual void resize(int width, int height) = 0;
@@ -47,8 +47,8 @@ public:
virtual void redraw() = 0;
virtual void grabMouse(bool grab) = 0;
-protected:
- GlobalContext *gctx;
+ virtual bool hasEvent() = 0;
+ virtual Event *getNextEvent() = 0;
};
};
diff --git a/plugingui/nativewindow_win32.cc b/plugingui/nativewindow_win32.cc
index d3c5a23..935cd04 100644
--- a/plugingui/nativewindow_win32.cc
+++ b/plugingui/nativewindow_win32.cc
@@ -30,20 +30,244 @@
#include "window.h"
+LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
+{
+ GUI::NativeWindowWin32 *native =
+ (GUI::NativeWindowWin32 *)GetWindowLong(hwnd, GWL_USERDATA);
+
+ // NOTE: 'native' is NULL intil the WM_CREATE message has been handled.
+ if(!native) return DefWindowProc(hwnd, msg, wp, lp);
+
+ GUI::Window *window = native->window;
+
+ switch(msg) {
+ case WM_SIZE:
+ {
+ static bool first = true;
+ if(!first) {
+ GUI::ResizeEvent *e = new GUI::ResizeEvent();
+ e->width = LOWORD(lp);
+ e->height = HIWORD(lp);
+ native->event = e;
+ first = false;
+ }
+ }
+ break;
+
+ case WM_MOVE:
+ {
+// GUI::MoveEvent *e = new GUI::MoveEvent();
+// e->x = (int)(short) LOWORD(lp);
+// e->y = (int)(short) HIWORD(lp);
+// native->event = e;
+ }
+ break;
+
+ case WM_CLOSE:
+ {
+ GUI::CloseEvent *e = new GUI::CloseEvent();
+ native->event = e;
+ }
+ break;
+// HWND child, old;
+// old = 0;
+
+// numDialogs--;
+
+// while(old != (child = GetNextDlgGroupItem(hwnd, hwnd, false))) {
+// old = child;
+// EndDialog(child, 0);
+// }
+
+// if(numDialogs) EndDialog(hwnd, 0);
+// else PostQuitMessage(0);
+// return 0;
+ case WM_MOUSEMOVE:
+ {
+
+ GUI::MouseMoveEvent *e = new GUI::MouseMoveEvent();
+ e->x = (int)(short) LOWORD(lp);
+ e->y = (int)(short) HIWORD(lp);
+ native->event = e;
+ }
+ break;
+
+ case WM_MOUSEWHEEL:
+ {
+ GUI::ScrollEvent *e = new GUI::ScrollEvent();
+
+ // NOTE: lp is coordinates in screen space, not client space.
+ POINT p;
+ p.x = (int)(short) LOWORD(lp);
+ p.y = (int)(short) HIWORD(lp);
+ ScreenToClient(hwnd, &p);
+
+ e->x = p.x;
+ e->y = p.y;
+ e->delta = -1 * (short)HIWORD(wp) / 60;
+ native->event = e;
+ }
+ break;
+
+ case WM_LBUTTONUP:
+ case WM_LBUTTONDBLCLK:
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONUP:
+ case WM_RBUTTONDBLCLK:
+ case WM_RBUTTONDOWN:
+ case WM_MBUTTONUP:
+ case WM_MBUTTONDBLCLK:
+ case WM_MBUTTONDOWN:
+ {
+ GUI::ButtonEvent *e = new GUI::ButtonEvent();
+ e->x = (int)(short) LOWORD(lp);
+ e->y = (int)(short) HIWORD(lp);
+
+ if(msg == WM_LBUTTONUP ||
+ msg == WM_LBUTTONDBLCLK ||
+ msg == WM_LBUTTONDOWN) e->button = 0;
+
+ if(msg == WM_RBUTTONUP ||
+ msg == WM_RBUTTONDBLCLK ||
+ msg == WM_RBUTTONDOWN) e->button = 1;
+
+ if(msg == WM_MBUTTONUP ||
+ msg == WM_MBUTTONDBLCLK ||
+ msg == WM_MBUTTONDOWN) e->button = 2;
+
+ e->direction = 0;
+ if(msg == WM_LBUTTONUP ||
+ msg == WM_RBUTTONUP ||
+ msg == WM_MBUTTONUP) e->direction = -1;
+
+ if(msg == WM_LBUTTONDOWN ||
+ msg == WM_RBUTTONDOWN ||
+ msg == WM_MBUTTONDOWN) e->direction = 1;
+
+ e->doubleclick = (msg == WM_LBUTTONDBLCLK ||
+ msg == WM_RBUTTONDBLCLK ||
+ msg == WM_MBUTTONDBLCLK);
+
+ native->event = e;
+ }
+ break;
+
+ case WM_KEYDOWN:
+ {
+ GUI::KeyEvent *e = new GUI::KeyEvent();
+ //printf("wp: %d\n", wp);
+ switch(wp) {
+ case 37: e->keycode = GUI::KeyEvent::KEY_LEFT; break;
+ case 39: e->keycode = GUI::KeyEvent::KEY_RIGHT; break;
+ case 38: e->keycode = GUI::KeyEvent::KEY_UP; break;
+ case 40: e->keycode = GUI::KeyEvent::KEY_DOWN; break;
+ case 8: e->keycode = GUI::KeyEvent::KEY_BACKSPACE; break;
+ case 46: e->keycode = GUI::KeyEvent::KEY_DELETE; break;
+ case 36: e->keycode = GUI::KeyEvent::KEY_HOME; break;
+ case 35: e->keycode = GUI::KeyEvent::KEY_END; break;
+ case 33: e->keycode = GUI::KeyEvent::KEY_PGUP; break;
+ case 34: e->keycode = GUI::KeyEvent::KEY_PGDOWN; break;
+ case 13: e->keycode = GUI::KeyEvent::KEY_ENTER; break;
+ default: e->keycode = GUI::KeyEvent::KEY_UNKNOWN; break;
+ }
+ e->text = "";
+ e->direction = -1;
+ native->event = e;
+ }
+ break;
+
+ case WM_CHAR:
+ {
+ //printf("WM_CHAR %d %d\n", (int)lp, (int)wp);
+ if(wp >= ' ') { // Filter control chars.
+ GUI::KeyEvent *e = new GUI::KeyEvent();
+ e->keycode = GUI::KeyEvent::KEY_CHARACTER;
+ e->text += (char)wp;
+ e->direction = -1;
+ native->event = e;
+ }
+ }
+ break;
+
+ case WM_PAINT:
+ {
+ GUI::RepaintEvent *e = new GUI::RepaintEvent();
+ e->x = 0;
+ e->y = 0;
+ e->width = 100;
+ e->height = 100;
+ native->event = e;
+
+ // Move to window.h (in class)
+ HDC pDC;
+ HBITMAP old;
+ HBITMAP ourbitmap;
+ int * framebuf;
+ GUI::PixelBuffer &px = window->wpixbuf;
+
+ { // Create bitmap (move to window.cc)
+ HDC hDC;
+ BITMAPINFO bitmapinfo;
+ hDC = CreateCompatibleDC(NULL);
+ bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapinfo.bmiHeader.biWidth = px.width;
+ bitmapinfo.bmiHeader.biHeight = -px.height; /* top-down */
+ bitmapinfo.bmiHeader.biPlanes = 1;
+ bitmapinfo.bmiHeader.biBitCount = 32;
+ bitmapinfo.bmiHeader.biCompression = BI_RGB;
+ bitmapinfo.bmiHeader.biSizeImage = 0;
+ bitmapinfo.bmiHeader.biClrUsed = 256;
+ bitmapinfo.bmiHeader.biClrImportant = 256;
+ ourbitmap=CreateDIBSection(hDC, &bitmapinfo,
+ DIB_RGB_COLORS, (void**)&framebuf, 0, 0);
+ pDC=CreateCompatibleDC(NULL);
+ old = (HBITMAP__*)SelectObject(pDC, ourbitmap);
+ DeleteDC(hDC);
+ }
+
+ { // Copy GUI::PixelBuffer to framebuffer (move to window.cc)
+ int i,j,k;
+ for (k=0,i=0;i<(int)px.height;i++) {
+ for (j=0;j<(int)px.width;j++,k++) {
+ *(framebuf+k)=RGB(px.buf[(j + i * px.width) * 3 + 2],
+ px.buf[(j + i * px.width) * 3 + 1],
+ px.buf[(j + i * px.width) * 3 + 0]);
+ }
+ }
+ }
+
+ PAINTSTRUCT ps;
+ HDC hdc = BeginPaint(native->m_hwnd, &ps);
+ BitBlt(hdc, 0, 0, px.width, px.height, pDC, 0, 0, SRCCOPY);
+ EndPaint(native->m_hwnd, &ps);
+
+ { // Destroy bitmap (move to window.cc)
+ SelectObject(pDC,old);
+ DeleteDC(pDC);
+ DeleteObject(ourbitmap);
+
+ }
+ }
+ return DefWindowProc(hwnd, msg, wp, lp);
+ }
+
+ return DefWindowProc(hwnd, msg, wp, lp);
+}
+
// Delared in eventhandler.cc
LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
-GUI::NativeWindowWin32::NativeWindowWin32(GlobalContext *gctx,
- GUI::Window *window)
- : GUI::NativeWindow(gctx)
+GUI::NativeWindowWin32::NativeWindowWin32(GUI::Window *window)
+ : GUI::NativeWindow()
{
this->window = window;
WNDCLASSEX wcex;
WNDID wndId;
- gctx->m_hwnd = 0;
- gctx->m_className = NULL;
+ m_hwnd = 0;
+ m_className = NULL;
+ event = NULL;
memset(&wcex, 0, sizeof(wcex));
@@ -56,7 +280,7 @@ GUI::NativeWindowWin32::NativeWindowWin32(GlobalContext *gctx,
wcex.lpfnWndProc = (WNDPROC)dialogProc;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
// Set data:
- wcex.cbWndExtra = sizeof(EventHandler*); // Size of data.
+ wcex.cbWndExtra = sizeof(NativeWindowWin32*); // Size of data.
wcex.hInstance = GetModuleHandle(NULL);
// if(ex_style && WS_EX_TRANSPARENT == WS_EX_TRANSPARENT) {
@@ -65,7 +289,7 @@ GUI::NativeWindowWin32::NativeWindowWin32(GlobalContext *gctx,
wcex.hbrBackground = NULL;//(HBRUSH) COLOR_BACKGROUND + 1;
// }
- wcex.lpszClassName = gctx->m_className = strdup("DrumGizmoClass");
+ wcex.lpszClassName = m_className = strdup("DrumGizmoClass");
RegisterClassEx(&wcex);
@@ -79,42 +303,42 @@ GUI::NativeWindowWin32::NativeWindowWin32(GlobalContext *gctx,
wndId = 0;
// }
- gctx->m_hwnd = CreateWindowEx(0/*ex_style*/, gctx->m_className,
- "DGBasisWidget",
- (WS_OVERLAPPEDWINDOW | WS_VISIBLE),
- window->x(), window->y(),
- window->width(), window->height(),
- wndId, NULL,
- GetModuleHandle(NULL), NULL);
+ m_hwnd = CreateWindowEx(0/*ex_style*/, m_className,
+ "DGBasisWidget",
+ (WS_OVERLAPPEDWINDOW | WS_VISIBLE),
+ window->x(), window->y(),
+ window->width(), window->height(),
+ wndId, NULL,
+ GetModuleHandle(NULL), NULL);
- SetWindowLongPtr(gctx->m_hwnd, GWL_USERDATA, (LONG_PTR)gctx->eventhandler);
+ SetWindowLongPtr(m_hwnd, GWL_USERDATA, (LONG_PTR)this);
}
GUI::NativeWindowWin32::~NativeWindowWin32()
{
- UnregisterClass(gctx->m_className, GetModuleHandle(NULL));
- free(gctx->m_className);
+ UnregisterClass(m_className, GetModuleHandle(NULL));
+ free(m_className);
}
void GUI::NativeWindowWin32::resize(int width, int height)
{
- SetWindowPos(gctx->m_hwnd, NULL, -1, -1, (int)width, (int)height, SWP_NOMOVE);
+ SetWindowPos(m_hwnd, NULL, -1, -1, (int)width, (int)height, SWP_NOMOVE);
RECT r;
- GetClientRect(gctx->m_hwnd, &r);
+ GetClientRect(m_hwnd, &r);
int w = width - r.right;
int h = height - r.bottom;
- SetWindowPos(gctx->m_hwnd, NULL, -1, -1, width + w, height + h, SWP_NOMOVE);
+ SetWindowPos(m_hwnd, NULL, -1, -1, width + w, height + h, SWP_NOMOVE);
}
void GUI::NativeWindowWin32::move(int x, int y)
{
- SetWindowPos(gctx->m_hwnd, NULL, (int)x, (int)y, -1, -1, SWP_NOSIZE);
+ SetWindowPos(m_hwnd, NULL, (int)x, (int)y, -1, -1, SWP_NOSIZE);
}
void GUI::NativeWindowWin32::show()
{
- ShowWindow(gctx->m_hwnd, SW_SHOW);
+ ShowWindow(m_hwnd, SW_SHOW);
}
void GUI::NativeWindowWin32::handleBuffer()
@@ -123,24 +347,46 @@ void GUI::NativeWindowWin32::handleBuffer()
void GUI::NativeWindowWin32::hide()
{
- ShowWindow(gctx->m_hwnd, SW_HIDE);
+ ShowWindow(m_hwnd, SW_HIDE);
}
void GUI::NativeWindowWin32::redraw()
{
- RedrawWindow(gctx->m_hwnd, NULL, NULL, RDW_ERASE|RDW_INVALIDATE);
- UpdateWindow(gctx->m_hwnd);
+ RedrawWindow(m_hwnd, NULL, NULL, RDW_ERASE|RDW_INVALIDATE);
+ UpdateWindow(m_hwnd);
}
void GUI::NativeWindowWin32::setCaption(const std::string &caption)
{
- SetWindowText(gctx->m_hwnd, caption.c_str());
+ SetWindowText(m_hwnd, caption.c_str());
}
void GUI::NativeWindowWin32::grabMouse(bool grab)
{
- if(grab) SetCapture(gctx->m_hwnd);
+ if(grab) SetCapture(m_hwnd);
else ReleaseCapture();
}
+bool GUI::NativeWindowWin32::hasEvent()
+{
+ MSG msg;
+ return PeekMessage(&msg, NULL, 0, 0, 0) != 0;
+}
+
+GUI::Event *GUI::NativeWindowWin32::getNextEvent()
+{
+ Event *event = NULL;
+
+ MSG msg;
+ if(GetMessage(&msg, NULL, 0, 0)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ event = this->event;
+ this->event = NULL;
+
+ return event;
+}
+
#endif/*WIN32*/
diff --git a/plugingui/nativewindow_win32.h b/plugingui/nativewindow_win32.h
index cceff2f..d8ba7b3 100644
--- a/plugingui/nativewindow_win32.h
+++ b/plugingui/nativewindow_win32.h
@@ -31,12 +31,17 @@
#include "nativewindow.h"
+#include <windows.h>
+typedef HWND WNDID;
+
namespace GUI {
class Window;
+class Event;
+
class NativeWindowWin32 : public NativeWindow {
public:
- NativeWindowWin32(GlobalContext *gctx, GUI::Window *window);
+ NativeWindowWin32(GUI::Window *window);
~NativeWindowWin32();
void resize(int width, int height);
@@ -48,8 +53,14 @@ public:
void redraw();
void grabMouse(bool grab);
-private:
+ bool hasEvent();
+ Event *getNextEvent();
+
+ // Needed by dialogProc
GUI::Window *window;
+ WNDID m_hwnd;
+ char *m_className;
+ Event *event;
};
};
diff --git a/plugingui/nativewindow_x11.cc b/plugingui/nativewindow_x11.cc
index 79349dd..f8511a0 100644
--- a/plugingui/nativewindow_x11.cc
+++ b/plugingui/nativewindow_x11.cc
@@ -32,26 +32,28 @@
#include "window.h"
-GUI::NativeWindowX11::NativeWindowX11(GlobalContext *gctx, GUI::Window *window)
- : GUI::NativeWindow(gctx)
+GUI::NativeWindowX11::NativeWindowX11(GUI::Window *window)
+ : GUI::NativeWindow()
{
+ display = XOpenDisplay(NULL);
+
this->window = window;
buffer = NULL;
// Get some colors
- int blackColor = BlackPixel(gctx->display, DefaultScreen(gctx->display));
+ int blackColor = BlackPixel(display, DefaultScreen(display));
- ::Window w = DefaultRootWindow(gctx->display);
+ ::Window w = DefaultRootWindow(display);
// Create the window
- xwindow = XCreateSimpleWindow(gctx->display,
+ xwindow = XCreateSimpleWindow(display,
w,
window->x(), window->y(),
window->width(), window->height(),
0,
blackColor, blackColor);
- XSelectInput(gctx->display, xwindow,
+ XSelectInput(display, xwindow,
StructureNotifyMask |
PointerMotionMask |
ButtonPressMask |
@@ -63,40 +65,41 @@ GUI::NativeWindowX11::NativeWindowX11(GlobalContext *gctx, GUI::Window *window)
SubstructureNotifyMask);
// register interest in the delete window message
- gctx->wmDeleteMessage = XInternAtom(gctx->display, "WM_DELETE_WINDOW", false);
- XSetWMProtocols(gctx->display, xwindow, &gctx->wmDeleteMessage, 1);
+ wmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", false);
+ XSetWMProtocols(display, xwindow, &wmDeleteMessage, 1);
// "Map" the window (that is, make it appear on the screen)
- XMapWindow(gctx->display, xwindow);
+ XMapWindow(display, xwindow);
// Create a "Graphics Context"
- gc = XCreateGC(gctx->display, xwindow, 0, NULL);
+ gc = XCreateGC(display, xwindow, 0, NULL);
}
GUI::NativeWindowX11::~NativeWindowX11()
{
- XDestroyWindow(gctx->display, xwindow);
- //gctx->widgets.erase(window);
+ XDestroyWindow(display, xwindow);
+ //widgets.erase(window);
+ XCloseDisplay(display);
}
void GUI::NativeWindowX11::resize(int width, int height)
{
- XResizeWindow(gctx->display, xwindow, width, height);
+ XResizeWindow(display, xwindow, width, height);
}
void GUI::NativeWindowX11::move(int x, int y)
{
- XMoveWindow(gctx->display, xwindow, x, y);
+ XMoveWindow(display, xwindow, x, y);
}
void GUI::NativeWindowX11::show()
{
- XMapWindow(gctx->display, xwindow);
+ XMapWindow(display, xwindow);
}
void GUI::NativeWindowX11::hide()
{
- XUnmapWindow(gctx->display, xwindow);
+ XUnmapWindow(display, xwindow);
}
static int get_byte_order (void)
@@ -210,7 +213,7 @@ void GUI::NativeWindowX11::handleBuffer()
{
if(buffer) XDestroyImage(buffer);
buffer =
- create_image_from_buffer(gctx->display, DefaultScreen(gctx->display),
+ create_image_from_buffer(display, DefaultScreen(display),
window->wpixbuf.buf,
window->wpixbuf.width,
window->wpixbuf.height);
@@ -220,14 +223,14 @@ void GUI::NativeWindowX11::redraw()
{
// http://stackoverflow.com/questions/6384987/load-image-onto-a-window-using-xlib
if(buffer == NULL) window->updateBuffer();
- XPutImage(gctx->display, xwindow, gc, buffer, 0, 0, 0, 0,
+ XPutImage(display, xwindow, gc, buffer, 0, 0, 0, 0,
window->width(), window->height());
- XFlush(gctx->display);
+ XFlush(display);
}
void GUI::NativeWindowX11::setCaption(const std::string &caption)
{
- XStoreName(gctx->display, xwindow, caption.c_str());
+ XStoreName(display, xwindow, caption.c_str());
}
void GUI::NativeWindowX11::grabMouse(bool grab)
@@ -236,5 +239,125 @@ void GUI::NativeWindowX11::grabMouse(bool grab)
// Don't need to do anything on this platoform...
}
+bool GUI::NativeWindowX11::hasEvent()
+{
+ return XPending(display);
+}
+
+GUI::Event *GUI::NativeWindowX11::getNextEvent()
+{
+ Event *event = NULL;
+
+ XEvent xe;
+ XNextEvent(display, &xe);
+
+ if(xe.type == MotionNotify) {
+ while(true) { // Hack to make sure only the last event is played.
+ if(!hasEvent()) break;
+ XEvent nxe;
+ XPeekEvent(display, &nxe);
+ if(nxe.type != MotionNotify) break;
+ XNextEvent(display, &xe);
+ }
+
+ MouseMoveEvent *e = new MouseMoveEvent();
+ e->window_id = xe.xmotion.window;
+ e->x = xe.xmotion.x;
+ e->y = xe.xmotion.y;
+ event = e;
+ }
+
+ if(xe.type == Expose && xe.xexpose.count == 0) {
+ RepaintEvent *e = new RepaintEvent();
+ e->window_id = xe.xexpose.window;
+ e->x = xe.xexpose.x;
+ e->y = xe.xexpose.y;
+ e->width = xe.xexpose.width;
+ e->height = xe.xexpose.height;
+ event = e;
+ }
+
+ if(xe.type == ConfigureNotify) {
+ ResizeEvent *e = new ResizeEvent();
+ e->window_id = xe.xconfigure.window;
+ // e->x = xe.xconfigure.x;
+ // e->y = xe.xconfigure.y;
+ e->width = xe.xconfigure.width;
+ e->height = xe.xconfigure.height;
+ event = e;
+ }
+
+ if(xe.type == ButtonPress || xe.type == ButtonRelease) {
+ if(xe.xbutton.button == 4 || xe.xbutton.button == 5) {
+ int scroll = 1;
+ while(true) { // Hack to make sure only the last event is played.
+ if(!hasEvent()) break;
+ XEvent nxe;
+ XPeekEvent(display, &nxe);
+ if(nxe.type != ButtonPress && nxe.type != ButtonRelease) break;
+ scroll += 1;
+ XNextEvent(display, &xe);
+ }
+ ScrollEvent *e = new ScrollEvent();
+ e->window_id = xe.xbutton.window;
+ e->x = xe.xbutton.x;
+ e->y = xe.xbutton.y;
+ e->delta = scroll * (xe.xbutton.button==4?-1:1);
+ event = e;
+ } else {
+ ButtonEvent *e = new ButtonEvent();
+ e->window_id = xe.xbutton.window;
+ e->x = xe.xbutton.x;
+ e->y = xe.xbutton.y;
+ e->button = 0;
+ e->direction = xe.type == ButtonPress?1:-1;
+ e->doubleclick =
+ xe.type == ButtonPress && (xe.xbutton.time - last_click) < 200;
+
+ if(xe.type == ButtonPress) last_click = xe.xbutton.time;
+ event = e;
+ }
+ }
+
+ if(xe.type == KeyPress || xe.type == KeyRelease) {
+ //printf("key: %d\n", xe.xkey.keycode);
+ KeyEvent *e = new KeyEvent();
+ e->window_id = xe.xkey.window;
+
+ switch(xe.xkey.keycode) {
+ case 113: e->keycode = KeyEvent::KEY_LEFT; break;
+ case 114: e->keycode = KeyEvent::KEY_RIGHT; break;
+ case 111: e->keycode = KeyEvent::KEY_UP; break;
+ case 116: e->keycode = KeyEvent::KEY_DOWN; break;
+ case 119: e->keycode = KeyEvent::KEY_DELETE; break;
+ case 22: e->keycode = KeyEvent::KEY_BACKSPACE; break;
+ case 110: e->keycode = KeyEvent::KEY_HOME; break;
+ case 115: e->keycode = KeyEvent::KEY_END; break;
+ case 117: e->keycode = KeyEvent::KEY_PGDOWN; break;
+ case 112: e->keycode = KeyEvent::KEY_PGUP; break;
+ case 36: e->keycode = KeyEvent::KEY_ENTER; break;
+ default: e->keycode = KeyEvent::KEY_UNKNOWN; break;
+ }
+
+ char buf[1024];
+ int sz = XLookupString(&xe.xkey, buf, sizeof(buf), NULL, NULL);
+ if(sz && e->keycode == KeyEvent::KEY_UNKNOWN) {
+ e->keycode = KeyEvent::KEY_CHARACTER;
+ }
+ e->text.append(buf, sz);
+
+ e->direction = xe.type == KeyPress?1:-1;
+ event = e;
+ }
+
+ if(xe.type == ClientMessage &&
+ (unsigned int)xe.xclient.data.l[0] == wmDeleteMessage) {
+ CloseEvent *e = new CloseEvent();
+ event = e;
+ }
+
+ return event;
+}
+
#endif/*X11*/
diff --git a/plugingui/nativewindow_x11.h b/plugingui/nativewindow_x11.h
index 0cd11da..84044de 100644
--- a/plugingui/nativewindow_x11.h
+++ b/plugingui/nativewindow_x11.h
@@ -38,7 +38,7 @@ namespace GUI {
class Window;
class NativeWindowX11 : public NativeWindow {
public:
- NativeWindowX11(GlobalContext *gctx, GUI::Window *window);
+ NativeWindowX11(GUI::Window *window);
~NativeWindowX11();
void resize(int width, int height);
@@ -50,12 +50,20 @@ public:
void redraw();
void grabMouse(bool grab);
+ bool hasEvent();
+ Event *getNextEvent();
+
private:
::Window xwindow;
GC gc;
XImage *buffer;
GUI::Window *window;
+
+ int last_click;
+
+ Display *display;
+ Atom wmDeleteMessage;
};
};
diff --git a/plugingui/painter.cc b/plugingui/painter.cc
index 9e5b052..842ff11 100644
--- a/plugingui/painter.cc
+++ b/plugingui/painter.cc
@@ -176,7 +176,7 @@ void GUI::Painter::clear()
void GUI::Painter::drawText(int x0, int y0, GUI::Font &font, std::string text,
bool nocolour)
{
- PixelBufferAlpha *textbuf = font.render(widget->window()->gctx, text);
+ PixelBufferAlpha *textbuf = font.render(text);
if(nocolour) {
for(size_t x = 0; x < textbuf->width; x++) {
for(size_t y = 0; y < textbuf->height; y++) {
diff --git a/plugingui/plugingui.cc b/plugingui/plugingui.cc
index 3c2cb4c..5b2f2e3 100644
--- a/plugingui/plugingui.cc
+++ b/plugingui/plugingui.cc
@@ -29,7 +29,6 @@
#include <hugin.hpp>
#include <stdio.h>
-#include "globalcontext.h"
#include "knob.h"
#include "verticalline.h"
@@ -184,9 +183,7 @@ PluginGUI::PluginGUI(DrumGizmo *drumgizmo)
this->drumgizmo = drumgizmo;
- gctx = NULL;
window = NULL;
- eventhandler = NULL;
running = true;
closing = false;
@@ -231,7 +228,7 @@ void PluginGUI::thread_main()
if(!running) break;
- eventhandler->processEvents(window);
+ window->eventHandler()->processEvents();
Message *msg;
if((msg = drumgizmo->receiveGUIMessage()) != NULL) {
@@ -301,8 +298,6 @@ void PluginGUI::thread_main()
void PluginGUI::deinit()
{
if(window) delete window;
- if(eventhandler) delete eventhandler;
- if(gctx) delete gctx;
}
void closeEventHandler(void *ptr)
@@ -314,11 +309,10 @@ void closeEventHandler(void *ptr)
void PluginGUI::init()
{
DEBUG(gui, "init");
- gctx = new GUI::GlobalContext();
- eventhandler = new GUI::EventHandler(gctx);
- eventhandler->registerCloseHandler(closeEventHandler, (void*)&closing);
+ window = new GUI::Window();
+ window->eventHandler()->registerCloseHandler(closeEventHandler,
+ (void*)&closing);
- window = new GUI::Window(gctx);
window->resize(370, 330);
window->setCaption("DrumGizmo v"VERSION);
@@ -470,7 +464,7 @@ void PluginGUI::init()
void PluginGUI::show()
{
- if(!gctx) init();
+ if(!window) init();
window->show();
}
@@ -488,7 +482,7 @@ void PluginGUI::processEvents()
}
#ifndef USE_THREAD
- eventhandler->processEvents(window);
+ window->eventHandler()->processEvents(window);
#endif/*USE_THREAD*/
}
diff --git a/plugingui/plugingui.h b/plugingui/plugingui.h
index ac0023b..97e45b8 100644
--- a/plugingui/plugingui.h
+++ b/plugingui/plugingui.h
@@ -29,7 +29,6 @@
#include "window.h"
#include "eventhandler.h"
-#include "globalcontext.h"
#include "label.h"
#include "lineedit.h"
@@ -62,7 +61,6 @@ public:
void setWindowClosedCallback(void (*handler)(void *), void *ptr);
//private:
- GUI::GlobalContext *gctx;
GUI::Window *window;
GUI::EventHandler *eventhandler;
diff --git a/plugingui/widget.cc b/plugingui/widget.cc
index 7d79859..05966aa 100644
--- a/plugingui/widget.cc
+++ b/plugingui/widget.cc
@@ -26,7 +26,6 @@
*/
#include "widget.h"
-#include "globalcontext.h"
#include "painter.h"
#include "window.h"
diff --git a/plugingui/window.cc b/plugingui/window.cc
index 580a3c6..1f98c6f 100644
--- a/plugingui/window.cc
+++ b/plugingui/window.cc
@@ -42,15 +42,9 @@
#include "nativewindow_win32.h"
#endif/*WIN32*/
-GUI::Window *gwindow = NULL;
-
-GUI::Window::Window(GlobalContext *gctx)
+GUI::Window::Window()
: Widget(NULL), wpixbuf(100, 100), back(":bg.png"), logo(":logo.png")
{
- gwindow = this;
-
- this->gctx = gctx;
-
_x = _y = 100;
_width = wpixbuf.width;
_height = wpixbuf.height;
@@ -61,17 +55,25 @@ GUI::Window::Window(GlobalContext *gctx)
_mouseFocus = NULL;
#ifdef X11
- native = new NativeWindowX11(gctx, this);
+ native = new NativeWindowX11(this);
#endif/*X11*/
#ifdef WIN32
- native = new NativeWindowWin32(gctx, this);
+ native = new NativeWindowWin32(this);
#endif/*WIN32*/
+
+ eventhandler = new GUI::EventHandler(native, this);
}
GUI::Window::~Window()
{
delete native;
+ delete eventhandler;
+}
+
+GUI::EventHandler *GUI::Window::eventHandler()
+{
+ return eventhandler;
}
void GUI::Window::setCaption(std::string caption)
diff --git a/plugingui/window.h b/plugingui/window.h
index c9cfe83..2a25d41 100644
--- a/plugingui/window.h
+++ b/plugingui/window.h
@@ -29,17 +29,16 @@
#include "widget.h"
-#include "globalcontext.h"
-
#include "pixelbuffer.h"
#include "nativewindow.h"
#include "image.h"
+#include "eventhandler.h"
namespace GUI {
class Window : public Widget {
public:
- Window(GlobalContext *gctx);
+ Window();
~Window();
void show();
@@ -66,6 +65,8 @@ public:
Window *window();
+ EventHandler *eventHandler();
+
// handlers
virtual void redraw();
void resized(size_t w, size_t h);
@@ -79,8 +80,6 @@ public:
Widget *mouseFocus();
void setMouseFocus(Widget *widget);
- GlobalContext *gctx;
-
PixelBuffer wpixbuf;
void updateBuffer();
@@ -92,6 +91,7 @@ protected:
Widget *_mouseFocus;
NativeWindow *native;
+ EventHandler *eventhandler;
Image back;
Image logo;