/* $Id$
This file is part of libmspgbase
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
#include <msp/strings/lexicalcast.h>
#include "display.h"
#include "window.h"
+#include "display_priv.h"
using namespace std;
namespace Msp {
namespace Graphics {
-Display::Display(const string &disp_name)
+Display::Display(const string &disp_name):
+ priv(new Private)
{
#ifdef WIN32
(void)disp_name;
}
#else
if(disp_name.empty())
- display=XOpenDisplay(0);
+ priv->display=XOpenDisplay(0);
else
- display=XOpenDisplay(disp_name.c_str());
- if(!display)
+ priv->display=XOpenDisplay(disp_name.c_str());
+ if(!priv->display)
throw Exception("Couldn't open X display");
XSetErrorHandler(x_error_handler);
- int screen=DefaultScreen(display);
+ int screen=DefaultScreen(priv->display);
int nmodes;
XF86VidModeModeInfo **infos;
- XF86VidModeGetAllModeLines(display, screen, &nmodes, &infos);
+ XF86VidModeGetAllModeLines(priv->display, screen, &nmodes, &infos);
for(int i=0; i<nmodes; ++i)
{
XF86VidModeModeInfo &info=*infos[i];
XF86VidModeModeLine modeline;
int dotclock;
- XF86VidModeGetModeLine(display, screen, &dotclock, &modeline);
+ XF86VidModeGetModeLine(priv->display, screen, &dotclock, &modeline);
orig_mode=VideoMode(modeline.hdisplay, modeline.vdisplay);
if(modeline.htotal && modeline.vtotal)
orig_mode.rate=dotclock/(modeline.htotal*modeline.vtotal);
Display::~Display()
{
#ifndef WIN32
- XCloseDisplay(display);
- display=0;
+ XCloseDisplay(priv->display);
+ delete priv;
#endif
}
-void Display::add_window(Window *wnd)
+void Display::add_window(Window &wnd)
{
- windows[wnd->get_handle()]=wnd;
+ priv->windows[wnd.get_private().window]=&wnd;
}
-void Display::remove_window(Window *wnd)
+void Display::remove_window(Window &wnd)
{
- windows.erase(wnd->get_handle());
+ priv->windows.erase(wnd.get_private().window);
}
void Display::set_mode(const VideoMode &mode)
ChangeDisplaySettings(&info, CDS_FULLSCREEN);
#else
- int screen=DefaultScreen(display);
+ int screen=DefaultScreen(priv->display);
int nmodes;
XF86VidModeModeInfo **infos;
- XF86VidModeGetAllModeLines(display, screen, &nmodes, &infos);
+ XF86VidModeGetAllModeLines(priv->display, screen, &nmodes, &infos);
for(int i=0; i<nmodes; ++i)
{
XF86VidModeModeInfo &info=*infos[i];
rate=info.dotclock/(info.htotal*info.vtotal);
if(info.hdisplay==mode.width && info.vdisplay==mode.height && (mode.rate==0 || rate==mode.rate))
{
- XF86VidModeSwitchToMode(display, screen, &info);
- XF86VidModeSetViewPort(display, screen, 0, 0);
+ XF86VidModeSwitchToMode(priv->display, screen, &info);
+ XF86VidModeSetViewPort(priv->display, screen, 0, 0);
return;
}
}
else
break;
#else
- int pending=XPending(display);
+ int pending=XPending(priv->display);
if(pending==0)
break;
for(int i=0; i<pending; ++i)
{
- XEvent event;
- XNextEvent(display, &event);
+ Window::Event event;
+ XNextEvent(priv->display, &event.xevent);
check_error();
- map<WindowHandle, Window *>::iterator j=windows.find(event.xany.window);
- if(j!=windows.end())
+ map<WindowHandle, Window *>::iterator j=priv->windows.find(event.xevent.xany.window);
+ if(j!=priv->windows.end())
+ {
j->second->event(event);
+ }
}
#endif
}
/* $Id$
This file is part of libmspgbase
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
#include <list>
#include <map>
#include <string>
-#include "types.h"
namespace Msp {
namespace Graphics {
class Display
{
+public:
+ struct Private;
+
private:
-#ifndef WIN32
- ::Display *display;
-#endif
std::list<VideoMode> modes;
VideoMode orig_mode;
- std::map<WindowHandle, Window *> windows;
+ Private *priv;
public:
Display(const std::string &disp_name=std::string());
~Display();
-#ifndef WIN32
- ::Display *get_display() const { return display; }
-#endif
+ const Private &get_private() const { return *priv; }
- void add_window(Window *);
- void remove_window(Window *);
+ void add_window(Window &);
+ void remove_window(Window &);
const std::list<VideoMode> &get_modes() const { return modes; }
void set_mode(const VideoMode &);
--- /dev/null
+/* $Id$
+
+This file is part of libmspgbase
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GBASE_DISPLAY_PRIV_H_
+#define MSP_GBASE_DISPLAY_PRIV_H_
+
+#include "window_priv.h"
+
+namespace Msp {
+namespace Graphics {
+
+struct Display::Private
+{
+#ifndef WIN32
+ ::Display *display;
+#endif
+ std::map<WindowHandle, Window *> windows;
+};
+
+} // namespace Graphics
+} // namespace Msp
+
+#endif
/* $Id$
This file is part of libmspgbase
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
#ifndef WIN32
#include <sys/ipc.h>
#include <sys/shm.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
#include <X11/Xutil.h>
#endif
#include <msp/core/except.h>
#include "display.h"
#include "drawcontext.h"
#include "window.h"
+#include "display_priv.h"
namespace Msp {
namespace Graphics {
+struct DrawContext::Private
+{
+#ifndef WIN32
+ XImage *image;
+ bool use_shm;
+ XShmSegmentInfo shminfo;
+#endif
+};
+
DrawContext::DrawContext(Window &w):
display(w.get_display()),
window(w)
{
-#ifndef WIN32
- ::Display *dpy=display.get_display();
+#ifdef WIN32
+ throw Exception("DrawContext not supported on win32 yet");
+#else
+ priv=new Private;
- use_shm=XShmQueryExtension(dpy);
+ ::Display *dpy=display.get_private().display;
+
+ priv->use_shm=XShmQueryExtension(dpy);
XWindowAttributes wa;
- XGetWindowAttributes(dpy, window.get_handle(), &wa);
+ XGetWindowAttributes(dpy, window.get_private().window, &wa);
- if(use_shm)
+ if(priv->use_shm)
{
- image=XShmCreateImage(dpy, wa.visual, wa.depth, ZPixmap, 0, &shminfo, wa.width, wa.height);
- if(!image)
+ priv->image=XShmCreateImage(dpy, wa.visual, wa.depth, ZPixmap, 0, &priv->shminfo, wa.width, wa.height);
+ if(!priv->image)
throw Exception("Could not create shared memory XImage");
- shminfo.shmid=shmget(IPC_PRIVATE, image->bytes_per_line*image->height, IPC_CREAT|0666);
- shminfo.shmaddr=image->data=reinterpret_cast<char *>(shmat(shminfo.shmid, 0, 0));
- shminfo.readOnly=false;
+ priv->shminfo.shmid=shmget(IPC_PRIVATE, priv->image->bytes_per_line*priv->image->height, IPC_CREAT|0666);
+ priv->shminfo.shmaddr=priv->image->data=reinterpret_cast<char *>(shmat(priv->shminfo.shmid, 0, 0));
+ priv->shminfo.readOnly=false;
- XShmAttach(dpy, &shminfo);
+ XShmAttach(dpy, &priv->shminfo);
XSync(dpy, false);
display.check_error();
}
else
{
- image=XCreateImage(dpy, wa.visual, wa.depth, ZPixmap, 0, 0, wa.width, wa.height, 8, 0);
- if(!image)
+ priv->image=XCreateImage(dpy, wa.visual, wa.depth, ZPixmap, 0, 0, wa.width, wa.height, 8, 0);
+ if(!priv->image)
throw Exception("Could not create XImage");
- image->data=new char[image->bytes_per_line*image->height];
+ priv->image->data=new char[priv->image->bytes_per_line*priv->image->height];
}
#endif
}
DrawContext::~DrawContext()
{
#ifndef WIN32
- if(use_shm)
+ if(priv->use_shm)
{
- XShmDetach(display.get_display(), &shminfo);
- shmdt(shminfo.shmaddr);
- shmctl(shminfo.shmid, IPC_RMID, 0);
+ XShmDetach(display.get_private().display, &priv->shminfo);
+ shmdt(priv->shminfo.shmaddr);
+ shmctl(priv->shminfo.shmid, IPC_RMID, 0);
}
- XDestroyImage(image);
+ XDestroyImage(priv->image);
#endif
+
+ delete priv;
}
unsigned DrawContext::get_depth() const
#ifdef WIN32
return 0;
#else
- return image->bits_per_pixel;
+ return priv->image->bits_per_pixel;
#endif
}
#ifdef WIN32
return 0;
#else
- return reinterpret_cast<unsigned char *>(image->data);
+ return reinterpret_cast<unsigned char *>(priv->image->data);
#endif
}
void DrawContext::update()
{
#ifndef WIN32
- ::Display *dpy=display.get_display();
+ ::Display *dpy=display.get_private().display;
+ WindowHandle wnd=window.get_private().window;
- GC gc=XCreateGC(dpy, window.get_handle(), 0, 0);
+ GC gc=XCreateGC(dpy, wnd, 0, 0);
- if(use_shm)
- XShmPutImage(dpy, window.get_handle(), gc, image, 0, 0, 0, 0, image->width, image->height, false);
+ if(priv->use_shm)
+ XShmPutImage(dpy, wnd, gc, priv->image, 0, 0, 0, 0, priv->image->width, priv->image->height, false);
else
- XPutImage(dpy, window.get_handle(), gc, image, 0, 0, 0, 0, image->width, image->height);
+ XPutImage(dpy, wnd, gc, priv->image, 0, 0, 0, 0, priv->image->width, priv->image->height);
XFreeGC(dpy, gc);
#endif
/* $Id$
This file is part of libmspgbase
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
#ifndef MSP_GBASE_DRAWCONTEXT_H_
#define MSP_GBASE_DRAWCONTEXT_H_
-#ifndef WIN32
-#include <X11/Xlib.h>
-#include <X11/extensions/XShm.h>
-#endif
-
namespace Msp {
namespace Graphics {
class DrawContext
{
private:
+ struct Private;
+
Display &display;
Window &window;
-#ifndef WIN32
- XImage *image;
- bool use_shm;
- XShmSegmentInfo shminfo;
-#endif
+ Private *priv;
public:
DrawContext(Window &);
#include <msp/core/except.h>
#include "display.h"
#include "glcontext.h"
-#include "types.h"
#include "window.h"
+#include "display_priv.h"
namespace Msp {
namespace Graphics {
priv=new Private;
#ifdef WIN32
- HDC dc=GetDC(window.get_handle());
+ HDC dc=GetDC(window.get_private().window);
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
priv->context=wglCreateContext(dc);
wglMakeCurrent(dc, priv->context);
- ReleaseDC(window.get_handle(), dc);
+ ReleaseDC(window.get_private().window, dc);
#else
std::vector<int> attribs;
attribs.push_back(0);
- ::Display *dpy=display.get_display();
+ ::Display *dpy=display.get_private().display;
XVisualInfo *vi=glXChooseVisual(dpy, DefaultScreen(dpy), &attribs.front());
if(!vi)
XSetWindowAttributes attr;
attr.colormap=XCreateColormap(dpy, DefaultRootWindow(dpy), vi->visual, AllocNone);
- priv->subwnd=XCreateWindow(dpy, window.get_handle(), 0, 0, window.get_width(), window.get_height(), 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr);
- XMapWindow(display.get_display(), priv->subwnd);
+ priv->subwnd=XCreateWindow(dpy, window.get_private().window, 0, 0, window.get_width(), window.get_height(), 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr);
+ XMapWindow(dpy, priv->subwnd);
XFree(vi);
wglMakeCurrent(0, 0);
wglDeleteContext(priv->context);
#else
- ::Display *dpy=display.get_display();
+ ::Display *dpy=display.get_private().display;
glXMakeCurrent(dpy, 0, 0);
glXDestroyContext(dpy, priv->context);
{
#ifdef WITH_OPENGL
#ifdef WIN32
- HDC dc=GetDC(window.get_handle());
+ HDC dc=GetDC(window.get_private().window);
SwapBuffers(dc);
- ReleaseDC(window.get_handle(), dc);
+ ReleaseDC(window.get_private().window, dc);
#else
- glXSwapBuffers(display.get_display(), priv->subwnd);
+ glXSwapBuffers(display.get_private().display, priv->subwnd);
#endif
#endif
}
{
#ifdef WITH_OPENGL
#ifndef WIN32
- XMoveResizeWindow(display.get_display(), priv->subwnd, 0, 0, w, h);
+ XMoveResizeWindow(display.get_private().display, priv->subwnd, 0, 0, w, h);
#endif
glViewport(0, 0, w, h);
#else
+++ /dev/null
-/* $Id$
-
-This file is part of libmspgbase
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
-Distributed under the LGPL
-*/
-
-#ifndef MSP_GBASE_TYPES_H_
-#define MSP_GBASE_TYPES_H_
-
-#ifdef WIN32
-#include <windows.h>
-#else
-#include <X11/Xlib.h>
-#endif
-
-namespace Msp {
-namespace Graphics {
-
-#ifdef WIN32
-typedef HWND WindowHandle;
-#else
-typedef ::Window WindowHandle;
-#endif
-
-} // namespace Graphics
-} // namespace Msp
-
-#endif
/* $Id$
This file is part of libmspgbase
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
#include <msp/core/except.h>
#include "display.h"
#include "window.h"
+#include "display_priv.h"
using namespace std;
+namespace {
+
+#ifdef WIN32
+LRESULT CALLBACK wndproc_(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ if(msg==WM_CREATE)
+ {
+ CREATESTRUCT *cs=reinterpret_cast<CREATESTRUCT *>(lparam);
+ SetWindowLong(hwnd, 0, reinterpret_cast<LONG>(cs->lpCreateParams));
+ }
+ else
+ {
+ Msp::Graphics::Window *wnd=reinterpret_cast<Msp::Graphics::Window *>(GetWindowLong(hwnd, 0));
+ Msp::Graphics::Window::Event ev;
+ ev.msg=msg;
+ ev.wparam=wparam;
+ ev.lparam=lparam;
+ if(wnd && wnd->event(ev))
+ return 0;
+ }
+
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+}
+#endif
+
+}
+
namespace Msp {
namespace Graphics {
Window::~Window()
{
- if(window)
+ if(priv->window)
#ifdef WIN32
- CloseWindow(window);
+ CloseWindow(priv->window);
#else
- XDestroyWindow(display.get_display(), window);
+ XDestroyWindow(display.get_private().display, priv->window);
- if(invisible_cursor)
- XFreeCursor(display.get_display(), invisible_cursor);
+ if(priv->invisible_cursor)
+ XFreeCursor(display.get_private().display, priv->invisible_cursor);
#endif
- display.remove_window(this);
+ display.remove_window(*this);
if(options.fullscreen)
display.restore_mode();
void Window::set_title(const string &title)
{
#ifdef WIN32
- SetWindowText(window, title.c_str());
+ SetWindowText(priv->window, title.c_str());
#else
vector<unsigned char> buf(title.begin(), title.end());
XTextProperty prop;
prop.encoding=XA_STRING;
prop.format=8;
prop.nitems=title.size();
- XSetWMName(display.get_display(), window, &prop);
+ XSetWMName(display.get_private().display, priv->window, &prop);
display.check_error();
#endif
}
if(fullscreen_changed)
{
hide();
- SetWindowLong(window, GWL_EXSTYLE, exstyle);
- SetWindowLong(window, GWL_STYLE, style);
+ SetWindowLong(priv->window, GWL_EXSTYLE, exstyle);
+ SetWindowLong(priv->window, GWL_STYLE, style);
show();
}
if(options.fullscreen)
- SetWindowPos(window, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOZORDER);
+ SetWindowPos(priv->window, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOZORDER);
else
- SetWindowPos(window, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOMOVE|SWP_NOZORDER);
-
- (void)fullscreen_changed;
+ SetWindowPos(priv->window, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOMOVE|SWP_NOZORDER);
#else
- ::Display *dpy=display.get_display();
+ ::Display *dpy=display.get_private().display;
if(fullscreen_changed)
{
hide();
XSetWindowAttributes attr;
attr.override_redirect=options.fullscreen;
- XChangeWindowAttributes(dpy, window, CWOverrideRedirect, &attr);
+ XChangeWindowAttributes(dpy, priv->window, CWOverrideRedirect, &attr);
show();
}
hints.min_width=hints.max_width=options.width;
hints.min_height=hints.max_height=options.height;
}
- XSetWMNormalHints(dpy, window, &hints);
+ XSetWMNormalHints(dpy, priv->window, &hints);
if(options.fullscreen)
- XMoveResizeWindow(dpy, window, 0, 0, options.width, options.height);
+ XMoveResizeWindow(dpy, priv->window, 0, 0, options.width, options.height);
else
- XResizeWindow(dpy, window, options.width, options.height);
+ XResizeWindow(dpy, priv->window, options.width, options.height);
#endif
if(options.fullscreen)
#ifdef WIN32
ShowCursor(s);
#else
- ::Display *dpy=display.get_display();
+ ::Display *dpy=display.get_private().display;
if(s)
- XUndefineCursor(dpy, window);
+ XUndefineCursor(dpy, priv->window);
else
{
- if(!invisible_cursor)
+ if(!priv->invisible_cursor)
{
int screen=DefaultScreen(dpy);
char data=0;
XImage *img=XCreateImage(dpy, DefaultVisual(dpy, screen), 1, XYBitmap, 0, &data, 1, 1, 8, 1);
- Pixmap pm=XCreatePixmap(dpy, window, 1, 1, 1);
+ Pixmap pm=XCreatePixmap(dpy, priv->window, 1, 1, 1);
GC gc=XCreateGC(dpy, pm, 0, 0);
XPutImage(dpy, pm, gc, img, 0, 0, 0, 0, 1, 1);
black.pixel=BlackPixel(dpy, screen);
XQueryColor(dpy, DefaultColormap(dpy, screen), &black);
- invisible_cursor=XCreatePixmapCursor(dpy, pm, pm, &black, &black, 0, 0);
+ priv->invisible_cursor=XCreatePixmapCursor(dpy, pm, pm, &black, &black, 0, 0);
XFreeGC(dpy, gc);
XFreePixmap(dpy, pm);
img->data=0;
XDestroyImage(img);
}
- XDefineCursor(dpy, window, invisible_cursor);
+ XDefineCursor(dpy, priv->window, priv->invisible_cursor);
}
#endif
}
void Window::show()
{
#ifdef WIN32
- ShowWindow(window, SW_SHOWNORMAL);
+ ShowWindow(priv->window, SW_SHOWNORMAL);
#else
- XMapRaised(display.get_display(), window);
+ XMapRaised(display.get_private().display, priv->window);
display.check_error();
#endif
}
void Window::hide()
{
#ifdef WIN32
- ShowWindow(window, SW_HIDE);
+ ShowWindow(priv->window, SW_HIDE);
#else
- XUnmapWindow(display.get_display(), window);
+ XUnmapWindow(display.get_private().display, priv->window);
display.check_error();
#endif
}
void Window::init()
{
+ priv=new Private;
+
#ifdef WIN32
static bool wndclass_created=false;
int exstyle=(options.fullscreen ? WS_EX_APPWINDOW : WS_EX_OVERLAPPEDWINDOW);
AdjustWindowRectEx(&rect, style, false, exstyle);
- window=CreateWindowEx(exstyle,
+ priv->window=CreateWindowEx(exstyle,
"mspgbase",
"Window",
style,
0,
reinterpret_cast<HINSTANCE>(Application::get_data()),
this);
- if(!window)
+ if(!priv->window)
throw Exception("CreateWindowEx failed");
if(options.fullscreen)
display.set_mode(VideoMode(options.width, options.height));
#else
- ::Display *dpy=display.get_display();
+ ::Display *dpy=display.get_private().display;
- wm_delete_window=XInternAtom(dpy, "WM_DELETE_WINDOW", true);
- invisible_cursor=0;
+ priv->wm_delete_window=XInternAtom(dpy, "WM_DELETE_WINDOW", true);
+ priv->invisible_cursor=0;
XSetWindowAttributes attr;
attr.override_redirect=options.fullscreen;
attr.event_mask=ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask|EnterWindowMask;
- window=XCreateWindow(dpy,
+ priv->window=XCreateWindow(dpy,
DefaultRootWindow(dpy),
0, 0,
options.width, options.height,
CopyFromParent,
CWOverrideRedirect|CWEventMask, &attr);
- XSetWMProtocols(dpy, window, &wm_delete_window, 1);
+ XSetWMProtocols(dpy, priv->window, &priv->wm_delete_window, 1);
if(!options.resizable)
{
hints.flags=PMinSize|PMaxSize;
hints.min_width=hints.max_width=options.width;
hints.min_height=hints.max_height=options.height;
- XSetWMNormalHints(dpy, window, &hints);
+ XSetWMNormalHints(dpy, priv->window, &hints);
}
if(options.fullscreen)
{
display.set_mode(VideoMode(options.width, options.height));
- XWarpPointer(dpy, None, window, 0, 0, 0, 0, options.width/2, options.height/2);
+ XWarpPointer(dpy, None, priv->window, 0, 0, 0, 0, options.width/2, options.height/2);
}
#endif
- display.add_window(this);
+ display.add_window(*this);
display.check_error();
}
-#ifndef WIN32
-void Window::event(const XEvent &ev)
+bool Window::event(const Event &evnt)
{
- switch(ev.type)
- {
- case ButtonPress:
- signal_button_press.emit(ev.xbutton.x, ev.xbutton.y, ev.xbutton.button, ev.xbutton.state);
- break;
- case ButtonRelease:
- signal_button_release.emit(ev.xbutton.x, ev.xbutton.y, ev.xbutton.button, ev.xbutton.state);
- break;
- case MotionNotify:
- signal_pointer_motion.emit(ev.xmotion.x, ev.xmotion.y);
- break;
- case KeyPress:
- {
- char buf[16];
- XLookupString(const_cast<XKeyEvent *>(&ev.xkey), buf, sizeof(buf), 0, 0);
- // XXX Handle the result according to locale
- signal_key_press.emit(XKeycodeToKeysym(display.get_display(), ev.xkey.keycode, 0), ev.xkey.state, buf[0]);
- }
- break;
- case KeyRelease:
- signal_key_release.emit(XKeycodeToKeysym(display.get_display(), ev.xkey.keycode, 0), ev.xkey.state);
- break;
- case ConfigureNotify:
- options.width=ev.xconfigure.width;
- options.height=ev.xconfigure.height;
- signal_resize.emit(options.width, options.height);
- break;
- case ClientMessage:
- if(ev.xclient.data.l[0]==static_cast<long>(wm_delete_window))
- signal_close.emit();
- break;
- case EnterNotify:
- XSetInputFocus(display.get_display(), window, RevertToParent, CurrentTime);
- break;
- case MapNotify:
- if(options.fullscreen)
- XGrabPointer(display.get_display(), window, true, None, GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
- break;
- default:;
- }
-}
-#endif
-
#ifdef WIN32
-int Window::wndproc(UINT msg, WPARAM wp, LPARAM lp)
-{
- switch(msg)
+ WPARAM wp=evnt.wparam;
+ LPARAM lp=evnt.lparam;
+ switch(evnt.msg)
{
case WM_KEYDOWN:
signal_key_press.emit(wp, 0, wp);
signal_close.emit();
break;
default:
- return 0;
- }
-
- return 1;
-}
-
-LRESULT CALLBACK Window::wndproc_(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
-{
- if(msg==WM_CREATE)
- {
- CREATESTRUCT *cs=reinterpret_cast<CREATESTRUCT *>(lparam);
- SetWindowLong(hwnd, 0, reinterpret_cast<LONG>(cs->lpCreateParams));
+ return false;
}
- else
+#else
+ const XEvent &ev=evnt.xevent;
+ switch(ev.type)
{
- Window *wnd=reinterpret_cast<Window *>(GetWindowLong(hwnd, 0));
- if(wnd && wnd->wndproc(msg, wparam, lparam))
- return 0;
+ case ButtonPress:
+ signal_button_press.emit(ev.xbutton.x, ev.xbutton.y, ev.xbutton.button, ev.xbutton.state);
+ break;
+ case ButtonRelease:
+ signal_button_release.emit(ev.xbutton.x, ev.xbutton.y, ev.xbutton.button, ev.xbutton.state);
+ break;
+ case MotionNotify:
+ signal_pointer_motion.emit(ev.xmotion.x, ev.xmotion.y);
+ break;
+ case KeyPress:
+ {
+ char buf[16];
+ XLookupString(const_cast<XKeyEvent *>(&ev.xkey), buf, sizeof(buf), 0, 0);
+ // XXX Handle the result according to locale
+ signal_key_press.emit(XKeycodeToKeysym(display.get_private().display, ev.xkey.keycode, 0), ev.xkey.state, buf[0]);
+ }
+ break;
+ case KeyRelease:
+ signal_key_release.emit(XKeycodeToKeysym(display.get_private().display, ev.xkey.keycode, 0), ev.xkey.state);
+ break;
+ case ConfigureNotify:
+ options.width=ev.xconfigure.width;
+ options.height=ev.xconfigure.height;
+ signal_resize.emit(options.width, options.height);
+ break;
+ case ClientMessage:
+ if(ev.xclient.data.l[0]==static_cast<long>(priv->wm_delete_window))
+ signal_close.emit();
+ break;
+ case EnterNotify:
+ XSetInputFocus(display.get_private().display, priv->window, RevertToParent, CurrentTime);
+ break;
+ case MapNotify:
+ if(options.fullscreen)
+ XGrabPointer(display.get_private().display, priv->window, true, None, GrabModeAsync, GrabModeAsync, priv->window, None, CurrentTime);
+ break;
+ default:
+ return false;
}
-
- return DefWindowProc(hwnd, msg, wparam, lparam);
-}
#endif
+ return true;
+}
} // namespace Graphics
} // namespace Msp
/* $Id$
This file is part of libmspgbase
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
#include <string>
#include <sigc++/signal.h>
-#include "types.h"
namespace Msp {
namespace Graphics {
class Window
{
public:
+ struct Private;
+ struct Event;
+
sigc::signal<void, int, int, unsigned, unsigned> signal_button_press;
sigc::signal<void, int, int, unsigned, unsigned> signal_button_release;
sigc::signal<void, int, int> signal_pointer_motion;
protected:
Display &display;
WindowOptions options;
- WindowHandle window;
-#ifndef WIN32
- Atom wm_delete_window;
- Cursor invisible_cursor;
-#endif
+ Private *priv;
public:
Window(Display &, unsigned w, unsigned h, bool fs=false);
const WindowOptions &get_options() const { return options; }
unsigned get_width() const { return options.width; }
unsigned get_height() const { return options.height; }
- WindowHandle get_handle() const { return window; }
+ const Private &get_private() const { return *priv; }
void show();
void hide();
-#ifndef WIN32
- void event(const XEvent &ev);
-#endif
+ bool event(const Event &evnt);
protected:
void init();
-#ifdef WIN32
- int wndproc(UINT, WPARAM, LPARAM);
- static LRESULT CALLBACK wndproc_(HWND, UINT, WPARAM, LPARAM);
-#endif
};
} // namespace Graphics
--- /dev/null
+/* $Id$
+
+This file is part of libmspgbase
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GBASE_WINDOW_PRIV_H_
+#define MSP_GBASE_WINDOW_PRIV_H_
+
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <X11/Xlib.h>
+#endif
+
+namespace Msp {
+namespace Graphics {
+
+#ifdef WIN32
+typedef HWND WindowHandle;
+#else
+typedef ::Window WindowHandle;
+#endif
+
+struct Window::Private
+{
+ WindowHandle window;
+#ifndef WIN32
+ Atom wm_delete_window;
+ Cursor invisible_cursor;
+#endif
+};
+
+struct Window::Event
+{
+#ifdef WIN32
+ UINT msg;
+ WPARAM wparam;
+ LPARAM lparam;
+#else
+ XEvent xevent;
+#endif
+};
+
+} // namespace Graphics
+} // namespace Msp
+
+#endif
/* $Id$
This file is part of libmspgbase
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <X11/Xlib.h>
+#endif
#include <msp/strings/formatter.h>
#include "../gbase/display.h"
#include "keyboard.h"