using namespace std;
-#include <iostream>
-
namespace Msp {
namespace Graphics {
CloseWindow(window);
#else
XDestroyWindow(display.get_display(), window);
+
+ if(invisible_cursor)
+ XFreeCursor(display.get_display(), invisible_cursor);
#endif
display.remove_window(this);
options=opts;
#ifdef WIN32
- // XXX Preserve position
- MoveWindow(window, 0, 0, options.width, options.height, false);
+ RECT rect;
+ SetRect(&rect, 0, 0, options.width, options.height);
+
+ int style=(options.fullscreen ? WS_POPUP : WS_OVERLAPPEDWINDOW);
+ if(!options.resizable)
+ style&=~WS_THICKFRAME;
+ int exstyle=(options.fullscreen ? WS_EX_APPWINDOW : WS_EX_OVERLAPPEDWINDOW);
+ AdjustWindowRectEx(&rect, style, false, exstyle);
+
+ if(fullscreen_changed)
+ {
+ hide();
+ SetWindowLong(window, GWL_EXSTYLE, exstyle);
+ SetWindowLong(window, GWL_STYLE, style);
+ show();
+ }
+
+ if(options.fullscreen)
+ SetWindowPos(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;
#else
::Display *dpy=display.get_display();
- XMoveResizeWindow(dpy, window, 0, 0, options.width, options.height);
-
if(fullscreen_changed)
{
hide();
show();
}
+ XSizeHints hints;
+ if(options.resizable)
+ hints.flags=0;
+ else
+ {
+ hints.flags=PMinSize|PMaxSize;
+ hints.min_width=hints.max_width=options.width;
+ hints.min_height=hints.max_height=options.height;
+ }
+ XSetWMNormalHints(dpy, window, &hints);
+
+ if(options.fullscreen)
+ XMoveResizeWindow(dpy, window, 0, 0, options.width, options.height);
+ else
+ XResizeWindow(dpy, window, options.width, options.height);
+#endif
+
if(options.fullscreen)
display.set_mode(VideoMode(options.width, options.height));
else if(fullscreen_changed)
display.restore_mode();
+}
+
+void Window::show_cursor(bool s)
+{
+#ifdef WIN32
+ ShowCursor(s);
+#else
+ ::Display *dpy=display.get_display();
+
+ if(s)
+ XUndefineCursor(dpy, window);
+ else
+ {
+ if(!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);
+ GC gc=XCreateGC(dpy, pm, 0, 0);
+ XPutImage(dpy, pm, gc, img, 0, 0, 0, 0, 1, 1);
+
+ XColor black;
+ black.pixel=BlackPixel(dpy, screen);
+ XQueryColor(dpy, DefaultColormap(dpy, screen), &black);
+
+ 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);
+ }
#endif
}
}
RECT rect;
- rect.left=0;
- rect.top=0;
- rect.right=options.width;
- rect.bottom=options.height;
- AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, false, WS_EX_OVERLAPPEDWINDOW);
+ SetRect(&rect, 0, 0, options.width, options.height);
+
+ int style=(options.fullscreen ? WS_POPUP : WS_OVERLAPPEDWINDOW);
+ if(!options.resizable)
+ style&=~WS_THICKFRAME;
+ int exstyle=(options.fullscreen ? WS_EX_APPWINDOW : WS_EX_OVERLAPPEDWINDOW);
+ AdjustWindowRectEx(&rect, style, false, exstyle);
- window=CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
+ window=CreateWindowEx(exstyle,
"mspgbase",
"Window",
- WS_OVERLAPPEDWINDOW,
+ style,
CW_USEDEFAULT, CW_USEDEFAULT,
rect.right-rect.left, rect.bottom-rect.top,
0,
if(!window)
throw Exception("CreateWindowEx failed");
+ if(options.fullscreen)
+ display.set_mode(VideoMode(options.width, options.height));
+
#else
::Display *dpy=display.get_display();
wm_delete_window=XInternAtom(dpy, "WM_DELETE_WINDOW", true);
+ invisible_cursor=0;
XSetWindowAttributes attr;
attr.override_redirect=options.fullscreen;
XSetWMProtocols(dpy, window, &wm_delete_window, 1);
+ if(!options.resizable)
+ {
+ XSizeHints hints;
+ hints.flags=PMinSize|PMaxSize;
+ hints.min_width=hints.max_width=options.width;
+ hints.min_height=hints.max_height=options.height;
+ XSetWMNormalHints(dpy, window, &hints);
+ }
+
if(options.fullscreen)
{
display.set_mode(VideoMode(options.width, options.height));
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(ev.xkey.keycode, ev.xkey.state, buf[0]);
+ signal_key_press.emit(XKeycodeToKeysym(display.get_display(), ev.xkey.keycode, 0), ev.xkey.state, buf[0]);
}
break;
case KeyRelease:
- signal_key_release.emit(ev.xkey.keycode, ev.xkey.state);
+ signal_key_release.emit(XKeycodeToKeysym(display.get_display(), ev.xkey.keycode, 0), ev.xkey.state);
break;
case ConfigureNotify:
options.width=ev.xconfigure.width;
switch(msg)
{
case WM_KEYDOWN:
- signal_key_press.emit((lp>>16)&0x1FF, 0, wp);
+ signal_key_press.emit(wp, 0, wp);
break;
case WM_KEYUP:
- signal_key_release.emit((lp>>16)&0x1FF, 0);
+ signal_key_release.emit(wp, 0);
break;
case WM_LBUTTONDOWN:
signal_button_press.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 1, 0);
case WM_MOUSEMOVE:
signal_pointer_motion.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp));
break;
+ case WM_SIZE:
+ options.width=LOWORD(lp);
+ options.height=HIWORD(lp);
+ signal_resize.emit(options.width, options.height);
+ break;
case WM_CLOSE:
signal_close.emit();
break;