summaryrefslogtreecommitdiff
path: root/plugingui/nativewindow_x11.cc
diff options
context:
space:
mode:
Diffstat (limited to 'plugingui/nativewindow_x11.cc')
-rw-r--r--plugingui/nativewindow_x11.cc233
1 files changed, 233 insertions, 0 deletions
diff --git a/plugingui/nativewindow_x11.cc b/plugingui/nativewindow_x11.cc
new file mode 100644
index 0000000..91d7ed6
--- /dev/null
+++ b/plugingui/nativewindow_x11.cc
@@ -0,0 +1,233 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * nativewindow_x11.cc
+ *
+ * Fri Dec 28 18:45:57 CET 2012
+ * Copyright 2012 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 "nativewindow_x11.h"
+
+#ifdef X11
+#include <X11/Xutil.h>
+#include <stdlib.h>
+
+#include "window.h"
+
+GUI::NativeWindowX11::NativeWindowX11(GlobalContext *gctx, GUI::Window *window)
+ : GUI::NativeWindow(gctx)
+{
+ this->window = window;
+ buffer = NULL;
+
+ // Get some colors
+ int blackColor = BlackPixel(gctx->display, DefaultScreen(gctx->display));
+
+ ::Window w = DefaultRootWindow(gctx->display);
+
+ // Create the window
+ xwindow = XCreateSimpleWindow(gctx->display,
+ w,
+ window->x(), window->y(),
+ window->width(), window->height(),
+ 0,
+ blackColor, blackColor);
+
+ XSelectInput(gctx->display, xwindow,
+ StructureNotifyMask |
+ PointerMotionMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ KeyPressMask |
+ KeyReleaseMask|
+ ExposureMask |
+ StructureNotifyMask |
+ SubstructureNotifyMask);
+
+ // register interest in the delete window message
+ gctx->wmDeleteMessage = XInternAtom(gctx->display, "WM_DELETE_WINDOW", false);
+ XSetWMProtocols(gctx->display, xwindow, &gctx->wmDeleteMessage, 1);
+
+ // "Map" the window (that is, make it appear on the screen)
+ XMapWindow(gctx->display, xwindow);
+
+ // Create a "Graphics Context"
+ gc = XCreateGC(gctx->display, xwindow, 0, NULL);
+}
+
+GUI::NativeWindowX11::~NativeWindowX11()
+{
+ XDestroyWindow(gctx->display, xwindow);
+ //gctx->widgets.erase(window);
+}
+
+void GUI::NativeWindowX11::resize(int width, int height)
+{
+ XResizeWindow(gctx->display, xwindow, width, height);
+}
+
+void GUI::NativeWindowX11::move(int x, int y)
+{
+ XMoveWindow(gctx->display, xwindow, x, y);
+}
+
+void GUI::NativeWindowX11::show()
+{
+ XMapWindow(gctx->display, xwindow);
+}
+
+void GUI::NativeWindowX11::hide()
+{
+ XUnmapWindow(gctx->display, xwindow);
+}
+
+static int get_byte_order (void)
+{
+ union {
+ char c[sizeof(short)];
+ short s;
+ } order;
+
+ order.s = 1;
+ if ((1 == order.c[0])) {
+ return LSBFirst;
+ } else {
+ return MSBFirst;
+ }
+}
+
+static XImage *create_image_from_buffer(Display *dis, int screen,
+ unsigned char *buf,
+ int width, int height)
+{
+ int depth;
+ XImage *img = NULL;
+ Visual *vis;
+ double rRatio;
+ double gRatio;
+ double bRatio;
+ int outIndex = 0;
+ int i;
+ int numBufBytes = (3 * (width * height));
+
+ depth = DefaultDepth(dis, screen);
+ vis = DefaultVisual(dis, screen);
+
+ rRatio = vis->red_mask / 255.0;
+ gRatio = vis->green_mask / 255.0;
+ bRatio = vis->blue_mask / 255.0;
+
+ if (depth >= 24) {
+ size_t numNewBufBytes = (4 * (width * height));
+ u_int32_t *newBuf = (u_int32_t *)malloc (numNewBufBytes);
+
+ for (i = 0; i < numBufBytes; ++i) {
+ unsigned int r, g, b;
+ r = (buf[i] * rRatio);
+ ++i;
+ g = (buf[i] * gRatio);
+ ++i;
+ b = (buf[i] * bRatio);
+
+ r &= vis->red_mask;
+ g &= vis->green_mask;
+ b &= vis->blue_mask;
+
+ newBuf[outIndex] = r | g | b;
+ ++outIndex;
+ }
+
+ img = XCreateImage (dis,
+ CopyFromParent, depth,
+ ZPixmap, 0,
+ (char *) newBuf,
+ width, height,
+ 32, 0
+ );
+
+ } else if (depth >= 15) {
+ size_t numNewBufBytes = (2 * (width * height));
+ u_int16_t *newBuf = (u_int16_t *)malloc (numNewBufBytes);
+
+ for (i = 0; i < numBufBytes; ++i) {
+ unsigned int r, g, b;
+
+ r = (buf[i] * rRatio);
+ ++i;
+ g = (buf[i] * gRatio);
+ ++i;
+ b = (buf[i] * bRatio);
+
+ r &= vis->red_mask;
+ g &= vis->green_mask;
+ b &= vis->blue_mask;
+
+ newBuf[outIndex] = r | g | b;
+ ++outIndex;
+ }
+
+ img = XCreateImage(dis, CopyFromParent, depth, ZPixmap, 0, (char *) newBuf,
+ width, height, 16, 0);
+ } else {
+ //fprintf (stderr, "This program does not support displays with a depth less than 15.");
+ return NULL;
+ }
+
+ XInitImage (img);
+ /*Set the client's byte order, so that XPutImage knows what to do with the data.*/
+ /*The default in a new X image is the server's format, which may not be what we want.*/
+ if ((LSBFirst == get_byte_order ())) {
+ img->byte_order = LSBFirst;
+ } else {
+ img->byte_order = MSBFirst;
+ }
+
+ /*The bitmap_bit_order doesn't matter with ZPixmap images.*/
+ img->bitmap_bit_order = MSBFirst;
+
+ return img;
+}
+
+void GUI::NativeWindowX11::handleBuffer()
+{
+ if(buffer) XDestroyImage(buffer);
+ buffer =
+ create_image_from_buffer(gctx->display, DefaultScreen(gctx->display),
+ window->wpixbuf.buf,
+ window->wpixbuf.width,
+ window->wpixbuf.height);
+}
+
+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,
+ window->width(), window->height());
+ XFlush(gctx->display);
+}
+
+void GUI::NativeWindowX11::setCaption(const std::string &caption)
+{
+}
+
+#endif/*X11*/
+