mirror of https://github.com/mosra/magnum.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
4.6 KiB
139 lines
4.6 KiB
|
14 years ago
|
/*
|
||
|
|
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
|
||
|
|
|
||
|
|
This file is part of Magnum.
|
||
|
|
|
||
|
|
Magnum is free software: you can redistribute it and/or modify
|
||
|
|
it under the terms of the GNU Lesser General Public License version 3
|
||
|
|
only, as published by the Free Software Foundation.
|
||
|
|
|
||
|
|
Magnum 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 Lesser General Public License version 3 for more details.
|
||
|
|
*/
|
||
|
|
|
||
|
14 years ago
|
#include "AbstractXContext.h"
|
||
|
14 years ago
|
|
||
|
14 years ago
|
#define None 0L // redef Xlib nonsense
|
||
|
|
|
||
|
14 years ago
|
/* Mask for X events */
|
||
|
14 years ago
|
#define INPUT_MASK KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|StructureNotifyMask
|
||
|
14 years ago
|
|
||
|
14 years ago
|
using namespace std;
|
||
|
|
|
||
|
|
namespace Magnum { namespace Contexts {
|
||
|
|
|
||
|
14 years ago
|
AbstractXContext::AbstractXContext(AbstractGlInterface<Display*, VisualID, Window>* glInterface, int&, char**, const string& title, const Math::Vector2<GLsizei>& size): glInterface(glInterface), viewportSize(size) {
|
||
|
|
/* Get default X display */
|
||
|
|
display = XOpenDisplay(0);
|
||
|
14 years ago
|
|
||
|
14 years ago
|
/* Get visual ID */
|
||
|
|
VisualID visualId = glInterface->getVisualId(display);
|
||
|
14 years ago
|
|
||
|
14 years ago
|
/* Get visual info */
|
||
|
14 years ago
|
XVisualInfo *visInfo, visTemplate;
|
||
|
|
int visualCount;
|
||
|
|
visTemplate.visualid = visualId;
|
||
|
14 years ago
|
visInfo = XGetVisualInfo(display, VisualIDMask, &visTemplate, &visualCount);
|
||
|
14 years ago
|
if(!visInfo) {
|
||
|
|
Error() << "Cannot get X visual";
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Create X Window */
|
||
|
14 years ago
|
Window root = RootWindow(display, DefaultScreen(display));
|
||
|
14 years ago
|
XSetWindowAttributes attr;
|
||
|
|
attr.background_pixel = 0;
|
||
|
|
attr.border_pixel = 0;
|
||
|
14 years ago
|
attr.colormap = XCreateColormap(display, root, visInfo->visual, AllocNone);
|
||
|
14 years ago
|
attr.event_mask = 0;
|
||
|
14 years ago
|
unsigned long mask = CWBackPixel|CWBorderPixel|CWColormap|CWEventMask;
|
||
|
14 years ago
|
window = XCreateWindow(display, root, 20, 20, size.x(), size.y(), 0, visInfo->depth, InputOutput, visInfo->visual, mask, &attr);
|
||
|
|
XSetStandardProperties(display, window, title.c_str(), 0, None, 0, 0, 0);
|
||
|
14 years ago
|
XFree(visInfo);
|
||
|
|
|
||
|
14 years ago
|
/* Be notified about closing the window */
|
||
|
14 years ago
|
deleteWindow = XInternAtom(display, "WM_DELETE_WINDOW", True);
|
||
|
|
XSetWMProtocols(display, window, &deleteWindow, 1);
|
||
|
|
|
||
|
|
/* Create context */
|
||
|
|
glInterface->createContext(window);
|
||
|
14 years ago
|
|
||
|
14 years ago
|
/* Capture exposure, keyboard and mouse button events */
|
||
|
14 years ago
|
XSelectInput(display, window, INPUT_MASK);
|
||
|
14 years ago
|
|
||
|
14 years ago
|
/* Set OpenGL context as current */
|
||
|
14 years ago
|
glInterface->makeCurrent();
|
||
|
14 years ago
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
/* Init GLEW */
|
||
|
|
GLenum err = glewInit();
|
||
|
|
if(err != GLEW_OK) {
|
||
|
14 years ago
|
Error() << "AbstractXContext: cannot initialize GLEW:" << glewGetErrorString(err);
|
||
|
14 years ago
|
exit(1);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
14 years ago
|
AbstractXContext::~AbstractXContext() {
|
||
|
|
/* Shut down the interface */
|
||
|
|
delete glInterface;
|
||
|
14 years ago
|
|
||
|
|
/* Shut down X */
|
||
|
14 years ago
|
XDestroyWindow(display, window);
|
||
|
|
XCloseDisplay(display);
|
||
|
14 years ago
|
}
|
||
|
|
|
||
|
14 years ago
|
int AbstractXContext::exec() {
|
||
|
14 years ago
|
/* Show window */
|
||
|
14 years ago
|
XMapWindow(display, window);
|
||
|
14 years ago
|
|
||
|
14 years ago
|
/* Call viewportEvent for the first time */
|
||
|
|
viewportEvent(viewportSize);
|
||
|
|
|
||
|
|
while(true) {
|
||
|
14 years ago
|
XEvent event;
|
||
|
14 years ago
|
|
||
|
|
/* Closed window */
|
||
|
14 years ago
|
if(XCheckTypedWindowEvent(display, window, ClientMessage, &event) &&
|
||
|
14 years ago
|
Atom(event.xclient.data.l[0]) == deleteWindow) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
14 years ago
|
while(XCheckWindowEvent(display, window, INPUT_MASK, &event)) {
|
||
|
14 years ago
|
switch(event.type) {
|
||
|
14 years ago
|
/* Window resizing */
|
||
|
|
case ConfigureNotify: {
|
||
|
|
Math::Vector2<int> size(event.xconfigure.width, event.xconfigure.height);
|
||
|
|
if(size != viewportSize) {
|
||
|
|
viewportSize = size;
|
||
|
|
viewportEvent(size);
|
||
|
|
}
|
||
|
|
} break;
|
||
|
|
|
||
|
|
/* Key/mouse events */
|
||
|
14 years ago
|
case KeyPress:
|
||
|
|
keyPressEvent(static_cast<Key>(XLookupKeysym(&event.xkey, 0)), {event.xkey.x, event.xkey.y});
|
||
|
|
break;
|
||
|
|
case KeyRelease:
|
||
|
|
keyReleaseEvent(static_cast<Key>(XLookupKeysym(&event.xkey, 0)), {event.xkey.x, event.xkey.y});
|
||
|
|
break;
|
||
|
|
case ButtonPress:
|
||
|
|
mousePressEvent(static_cast<MouseButton>(event.xbutton.button), {event.xbutton.x, event.xbutton.y});
|
||
|
|
break;
|
||
|
|
case ButtonRelease:
|
||
|
|
mouseReleaseEvent(static_cast<MouseButton>(event.xbutton.button), {event.xbutton.x, event.xbutton.y});
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
14 years ago
|
/** @todo Handle at least window closing and resizing */
|
||
|
|
drawEvent();
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
}}
|