Display::Display(const string &disp_name)
{
-#ifndef WIN32
+#ifdef WIN32
+ (void)disp_name;
+
+ for(unsigned i=0;; ++i)
+ {
+ DEVMODE info;
+ if(!EnumDisplaySettings(0, i, &info))
+ break;
+
+ VideoMode mode(info.dmPelsWidth, info.dmPelsHeight);
+ mode.rate=info.dmDisplayFrequency;
+ modes.push_back(mode);
+ }
+
+ DEVMODE info;
+ if(EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &info))
+ {
+ orig_mode=VideoMode(info.dmPelsWidth, info.dmPelsHeight);
+ orig_mode.rate=info.dmDisplayFrequency;
+ }
+#else
if(disp_name.empty())
display=XOpenDisplay(0);
else
XF86VidModeModeInfo &info=*infos[i];
VideoMode mode(info.hdisplay, info.vdisplay);
- mode.rate=info.dotclock/(info.htotal*info.vtotal);
+ if(info.htotal && info.vtotal)
+ mode.rate=info.dotclock/(info.htotal*info.vtotal);
modes.push_back(mode);
}
int dotclock;
XF86VidModeGetModeLine(display, screen, &dotclock, &modeline);
orig_mode=VideoMode(modeline.hdisplay, modeline.vdisplay);
- orig_mode.rate=dotclock/(modeline.htotal*modeline.vtotal);
-#else
- (void)disp_name;
+ if(modeline.htotal && modeline.vtotal)
+ orig_mode.rate=dotclock/(modeline.htotal*modeline.vtotal);
#endif
}
void Display::set_mode(const VideoMode &mode)
{
-#ifndef WIN32
+#ifdef WIN32
+ DEVMODE info;
+ info.dmSize=sizeof(DEVMODE);
+ info.dmFields=DM_PELSWIDTH|DM_PELSHEIGHT;
+ info.dmPelsWidth=mode.width;
+ info.dmPelsHeight=mode.height;
+ if(mode.rate)
+ {
+ info.dmFields|=DM_DISPLAYFREQUENCY;
+ info.dmDisplayFrequency=mode.rate;
+ }
+
+ ChangeDisplaySettings(&info, CDS_FULLSCREEN);
+#else
int screen=DefaultScreen(display);
int nmodes;
{
XF86VidModeModeInfo &info=*infos[i];
- unsigned rate=info.dotclock/(info.htotal*info.vtotal);
+ unsigned rate=0;
+ if(info.htotal && info.vtotal)
+ 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);
}
throw InvalidParameterValue("Requested mode not supported");
-#else
- (void)mode;
#endif
}
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();
-#endif
}
void Window::show()
}
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);
- window=CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
+ 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(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();
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));
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;