+++ /dev/null
-/* $Id$
-
-This file is part of libmspgbase
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
-Distributed under the LGPL
-*/
-
-#include <iostream>
-#ifndef WIN32
-#include <X11/Xlib.h>
-#include <X11/extensions/xf86vmode.h>
-#endif
-#include <msp/core/except.h>
-#include <msp/strings/formatter.h>
-#include <msp/strings/lexicalcast.h>
-#include "display.h"
-#include "window.h"
-
-using namespace std;
-
-namespace {
-
-bool error_flag=false;
-std::string error_msg;
-
-#ifndef WIN32
-int x_error_handler(Display *display, XErrorEvent *event)
-{
- char err[128];
- XGetErrorText(display, event->error_code, err, sizeof(err));
-
- string request_code=Msp::lexical_cast(static_cast<int>(event->request_code));
- char req[128];
- XGetErrorDatabaseText(display, "XRequest", request_code.c_str(), request_code.c_str(), req, sizeof(req));
-
- string msg=Msp::format("Request %s failed with %s [%08X]", req, err, event->resourceid);
- if(error_flag)
- cerr<<"Discarding error: "<<msg<<'\n';
- else
- {
- cerr<<msg<<'\n';
- error_msg=msg;
- error_flag=true;
- }
-
- return 0;
-}
-#endif
-
-}
-
-namespace Msp {
-namespace Graphics {
-
-Display::Display(const string &disp_name)
-{
-#ifndef WIN32
- if(disp_name.empty())
- display=XOpenDisplay(0);
- else
- display=XOpenDisplay(disp_name.c_str());
- if(!display)
- throw Exception("Couldn't open X display");
-
- XSetErrorHandler(x_error_handler);
-
- int screen=DefaultScreen(display);
-
- int nmodes;
- XF86VidModeModeInfo **infos;
- XF86VidModeGetAllModeLines(display, screen, &nmodes, &infos);
- for(int i=0; i<nmodes; ++i)
- {
- XF86VidModeModeInfo &info=*infos[i];
-
- VideoMode mode(info.hdisplay, info.vdisplay);
- mode.rate=info.dotclock/(info.htotal*info.vtotal);
- modes.push_back(mode);
- }
-
- XFree(infos);
-
- XF86VidModeModeLine modeline;
- 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;
-#endif
-}
-
-Display::~Display()
-{
-#ifndef WIN32
- XCloseDisplay(display);
- display=0;
-#endif
-}
-
-void Display::add_window(Window *wnd)
-{
- windows[wnd->get_handle()]=wnd;
-}
-
-void Display::remove_window(Window *wnd)
-{
- windows.erase(wnd->get_handle());
-}
-
-void Display::set_mode(const VideoMode &mode)
-{
-#ifndef WIN32
- int screen=DefaultScreen(display);
-
- int nmodes;
- XF86VidModeModeInfo **infos;
- XF86VidModeGetAllModeLines(display, screen, &nmodes, &infos);
- for(int i=0; i<nmodes; ++i)
- {
- XF86VidModeModeInfo &info=*infos[i];
-
- unsigned 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);
- return;
- }
- }
-
- throw InvalidParameterValue("Requested mode not supported");
-#else
- (void)mode;
-#endif
-}
-
-void Display::tick()
-{
- check_error();
-
- while(1)
- {
-#ifdef WIN32
- MSG msg;
- if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
- DispatchMessage(&msg);
- else
- break;
-#else
- int pending=XPending(display);
- if(pending==0)
- break;
-
- for(int i=0; i<pending; ++i)
- {
- XEvent event;
- XNextEvent(display, &event);
-
- check_error();
-
- map<WindowHandle, Window *>::iterator j=windows.find(event.xany.window);
- if(j!=windows.end())
- j->second->event(event);
- }
-#endif
- }
-}
-
-void Display::check_error()
-{
- if(error_flag)
- {
- error_flag=false;
- throw Exception(error_msg);
- }
-}
-
-} // namespace Graphics
-} // namespace Msp