Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

x11_display.cxx

Go to the documentation of this file.
00001 //  $Id: x11_display.cxx,v 1.32 2003/01/12 19:06:08 grumbel Exp $
00002 //
00003 //  Construo - A wire-frame construction game
00004 //  Copyright (C) 2002 Ingo Ruhnke <[email protected]>
00005 //
00006 //  This program is free software; you can redistribute it and/or
00007 //  modify it under the terms of the GNU General Public License
00008 //  as published by the Free Software Foundation; either version 2
00009 //  of the License, or (at your option) any later version.
00010 //
00011 //  This program is distributed in the hope that it will be useful,
00012 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //  GNU General Public License for more details.
00015 //
00016 //  You should have received a copy of the GNU General Public License
00017 //  along with this program; if not, write to the Free Software
00018 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 
00020 #include <iostream>
00021 #include <X11/Xutil.h>
00022 #include <X11/keysym.h>
00023 
00024 #include "construo_error.hxx"
00025 #include "config.h"
00026 #include "x11_display.hxx"
00027 #include "settings.hxx"
00028 #include "construo_main.hxx"
00029 
00030 #include "controller.hxx"
00031 #include "screen_manager.hxx"
00032 
00033 extern ConstruoMain* construo_main;
00034 Atom wm_delete_window;
00035 
00036 static char zoom_tool_cursor[] = {
00037     /* -------- -------- */  0x00,
00038     /* -------- -------- */  0x00,
00039     /* ------xx xx------ */  0x18,                         
00040     /* ----xxxx xxxx---- */  0x3c,
00041     /* ----xxxx xxxx---- */  0x3c,
00042     /* ------xx xx------ */  0x18,
00043     /* -------- -------- */  0x00,
00044     /* -------- -------- */  0x00
00045 };
00046 
00047 X11Display::X11Display(int w, int h, bool fullscreen_)
00048   : doublebuffer (settings.doublebuffer),
00049     width(w), height(h), shift_pressed (false), fullscreen (fullscreen_)
00050 {
00051   std::cout << "Opening X11 display" << std::endl;
00052   display = XOpenDisplay(NULL);
00053 
00054   if (!display)
00055     throw ConstruoError("X11Display: Couldn't conncet to X server");
00056 
00057   int screen = DefaultScreen(display);
00058   XSetWindowAttributes attributes;
00059 
00060   attributes.background_pixel  = BlackPixel(display, screen);
00061   attributes.border_pixel      = WhitePixel(display, screen);
00062   if (fullscreen)
00063     attributes.override_redirect = True;
00064   else
00065     attributes.override_redirect = False;
00066 
00067   attributes.event_mask = 
00068     KeyPressMask         |
00069     KeyReleaseMask       |
00070     ExposureMask         | 
00071     PointerMotionMask    |
00072     ButtonPressMask      |
00073     ButtonReleaseMask    |
00074     StructureNotifyMask  |
00075     ExposureMask;
00076 
00077   colormap = DefaultColormap (display, screen);
00078   attributes.colormap = colormap;
00079   window = XCreateWindow(display, RootWindow(display, screen),
00080                          0,0, // position
00081                          width, height, 0,
00082                          CopyFromParent, InputOutput, CopyFromParent, 
00083                          CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWEventMask | CWColormap,
00084                          &attributes);
00085 
00086   { // Communicate a bit with the window manager
00087     char *title = "Construo " VERSION;
00088 
00089     XTextProperty text_property;
00090     XStringListToTextProperty(&title, 1, &text_property);
00091     XSizeHints size_hints;
00092     size_hints.x = 0;
00093     size_hints.y = 0;
00094     size_hints.flags  = PSize | PMinSize | PMaxSize;
00095 
00096     size_hints.width  = width;
00097     size_hints.height = height;
00098     
00099     size_hints.min_width  = width;
00100     size_hints.min_height = height;
00101     size_hints.max_width  = width;
00102     size_hints.max_height = height;
00103 
00104     XSetWMProperties(
00105                      display,
00106                      window,
00107                      &text_property,
00108                      &text_property,
00109                      0,
00110                      0,
00111                      &size_hints,
00112                      0,
00113                      0);
00114 
00115     // Set WM_DELETE_WINDOW atom in WM_PROTOCOLS property (to get window_delete requests).
00116     wm_delete_window = XInternAtom (display, "WM_DELETE_WINDOW", False);
00117     XSetWMProtocols (display, window, &wm_delete_window, 1);
00118   }
00119 
00120   if (doublebuffer)
00121     drawable = XCreatePixmap (display, window, width, height, 
00122                               DefaultDepth(display, screen));  
00123   else
00124     drawable = window;
00125 
00126   XMapRaised(display, window);
00127 
00128   XGCValues gcv;
00129   gcv.foreground = 0xFFFFFF;
00130   gcv.background = 0x000000;
00131   gcv.line_width = 2;
00132   gc = XCreateGC(display, window, 
00133                  GCLineWidth | GCForeground | GCBackground,
00134                  &gcv);
00135 
00136   if (fullscreen)
00137     set_fullscreen (true);
00138 
00139   if (0) // custom cursor code
00140     {
00141       XColor cursor_fg;
00142       XColor cursor_bg;
00143 
00144       //set colors here
00145 
00146       Pixmap cursor_pm = XCreateBitmapFromData (display, window, zoom_tool_cursor, 8, 8);
00147       Cursor cursor = XCreatePixmapCursor(display, cursor_pm, None, &cursor_bg, &cursor_fg, 4, 4);
00148       XDefineCursor (display, window, cursor);
00149     }
00150 }
00151 
00152 X11Display::~X11Display ()
00153 {
00154   std::cout << "Closing X11 display" << std::endl;
00155   if (fullscreen)
00156     restore_mode ();
00157   
00158   if (doublebuffer)
00159     XFreePixmap (display, drawable);
00160   
00161   XDestroyWindow (display, window);
00162   XCloseDisplay(display); 
00163 }
00164 
00165 void
00166 X11Display::draw_lines (std::vector<Line>& lines, Color color, int wide)
00167 {
00168   std::vector<XSegment> segments (lines.size());
00169   
00170   for (std::vector<Line>::size_type i = 0; i < lines.size(); ++i)
00171     {
00172       segments[i].x1 = static_cast<short>(lines[i].x1);
00173       segments[i].y1 = static_cast<short>(lines[i].y1);
00174       segments[i].x2 = static_cast<short>(lines[i].x2);      
00175       segments[i].y2 = static_cast<short>(lines[i].y2);
00176     }
00177 
00178   XDrawSegments(display, drawable, gc, &*segments.begin(), segments.size());
00179 }
00180 
00181 void
00182 X11Display::draw_circles(std::vector<Circle>& circles, Color color)
00183 {
00184   std::vector<XArc> arcs (circles.size());
00185   for (std::vector<Circle>::size_type i = 0; i < circles.size(); ++i)
00186     {
00187       arcs[i].x = static_cast<short>(circles[i].x - circles[i].r);
00188       arcs[i].y = static_cast<short>(circles[i].y - circles[i].r);
00189       arcs[i].width  = static_cast<short>(2 * circles[i].r);
00190       arcs[i].height = static_cast<short>(2 * circles[i].r);
00191       arcs[i].angle1 = 0;
00192       arcs[i].angle2 = 360 * 64;
00193     }
00194 
00195   XSetForeground(display, gc, get_color_value(color));
00196   XFillArcs(display, drawable, gc, 
00197             &*arcs.begin(), arcs.size());
00198 }
00199 
00200 void
00201 X11Display::draw_line(float x1, float y1, float x2, float y2, Color color, int wide)
00202 {
00203   XSetForeground(display, gc, get_color_value(color));
00204   XDrawLine (display, drawable, gc, (int) x1, (int) y1, (int) x2, (int) y2);
00205 }
00206 
00207 void
00208 X11Display::draw_fill_rect(float x1, float y1, float x2, float y2, Color color)
00209 {
00210   XSetForeground(display, gc, get_color_value(color));
00211   XFillRectangle (display, drawable, gc, 
00212                   int(x1), int(y1), 
00213                   int(x2 - x1), int(y2 - y1));
00214 }
00215 
00216 void
00217 X11Display::draw_fill_circle(float x, float y, float r, Color color)
00218 {
00219   // FIXME: doesn't work
00220   XSetForeground(display, gc, get_color_value(color));
00221   XFillArc(display, drawable, gc, 
00222            int(x-r), int(y-r),
00223            int(r*2), int(r*2), 0, 
00224            360*64);
00225 }
00226 
00227 void
00228 X11Display::draw_circle(float x, float y, float r, Color color)
00229 {
00230   // FIXME: doesn't work
00231   XSetForeground(display, gc, get_color_value(color));
00232   XDrawArc(display, drawable, gc, int(x-r), int(y-r), int(r*2.0f), int(r*2.0f), 0, 360*64);
00233 }
00234 
00235 void
00236 X11Display::draw_rect(float x1, float y1, float x2, float y2, Color color)
00237 {
00238   XSetForeground(display, gc, get_color_value(color));
00239   XDrawRectangle (display, drawable, gc, 
00240                   int(x1), int(y1), 
00241                   int(x2 - x1), int(y2 - y1));
00242 }
00243 
00244 void
00245 X11Display::draw_string(float x, float y, const std::string& str, Color color)
00246 {
00247   XSetForeground(display, gc, get_color_value(color));
00248   XDrawString (display, drawable, gc, int(x), int(y), str.c_str (), str.length ());
00249 }
00250 
00251 void
00252 X11Display::draw_string_centered(float x, float y, const std::string& str, Color color)
00253 {
00254   XSetForeground(display, gc, get_color_value(color));
00255   XDrawString (display, drawable, gc, 
00256                int(x) - ((str.length() * 6) / 2), int(y), 
00257                str.c_str (), str.length ());
00258 }
00259 
00260 int
00261 X11Display::get_mouse_x ()
00262 {
00263   return mouse_x;
00264 }
00265 
00266 int
00267 X11Display::get_mouse_y ()
00268 {
00269   return mouse_y;
00270 }
00271 
00272 bool
00273 X11Display::get_key (int key)
00274 {
00275   return false;
00276 }
00277 
00278 void
00279 X11Display::wait_for_events_blocking ()
00280 {
00281   do {
00282     while (read_event () == false); 
00283   } while (XPending (display) > 0);
00284 }
00285 
00286 void
00287 X11Display::wait_for_events ()
00288 {
00289   while (XPending (display) > 0)
00290     {
00291       read_event ();
00292     }
00293 }
00294 
00295 bool
00296 X11Display::read_event ()
00297 {
00298   XEvent event;
00299 
00300   XNextEvent (display, &event);
00301      
00302   switch (event.type)
00303     {
00304     case MotionNotify:
00305       mouse_x = event.xmotion.x;
00306       mouse_y = event.xmotion.y;
00307       break;
00308 
00309     case Expose:
00310       if (event.xexpose.count == 0)
00311         flip ();
00312       break;
00313 
00314     case NoExpose:
00315       //std::cout << "NoExpose" << std::endl;
00316       return false; // FIXME: Hack, no idea how to handle NoExpose
00317       break;
00318 
00319     case ButtonPress:
00320       {
00321         //std::cout << "ButtonID: " << event.xbutton.button << " " << event.xbutton.state << std::endl;
00322 
00323         if (event.xbutton.button == 1)
00324           send_button_press(BUTTON_PRIMARY);
00325         else if (event.xbutton.button == 2)
00326           send_button_press(BUTTON_TERTIARY);
00327         else if (event.xbutton.button == 3)
00328           send_button_press(BUTTON_SECONDARY);
00329         else if (event.xbutton.button == 4)
00330           send_button_press(BUTTON_ZOOM_IN);
00331         else if (event.xbutton.button == 5)
00332           send_button_press(BUTTON_ZOOM_OUT);
00333       }
00334       break;
00335 
00336     case ButtonRelease:
00337       {
00338         //std::cout << "ButtonID: " << event.xbutton.button << " " << event.xbutton.state << std::endl;
00339         if (event.xbutton.button == 1)
00340           send_button_release(BUTTON_PRIMARY);
00341         else if (event.xbutton.button == 2)
00342           send_button_release(BUTTON_TERTIARY);
00343         else if (event.xbutton.button == 3)
00344           send_button_release(BUTTON_SECONDARY);
00345         else if (event.xbutton.button == 4)
00346           send_button_release(BUTTON_ZOOM_IN);
00347         else if (event.xbutton.button == 5)
00348           send_button_release(BUTTON_ZOOM_OUT);
00349       }
00350       break;
00351 
00352     case KeyPress:
00353       {
00354         KeySym sym = XLookupKeysym(&event.xkey,0);
00355             
00356         switch (sym)
00357           {
00358           case XK_Left:
00359             send_button_press(BUTTON_SCROLL_LEFT);
00360             break;
00361 
00362           case XK_Right:
00363             send_button_press(BUTTON_SCROLL_RIGHT);
00364             break;
00365 
00366           case XK_Up:
00367             send_button_press(BUTTON_SCROLL_UP);
00368             break;
00369 
00370           case XK_Down:
00371             send_button_press(BUTTON_SCROLL_DOWN);
00372             break;
00373 
00374           case XK_a:
00375             send_button_press(BUTTON_ACTIONCAM);
00376             break;
00377 
00378           case XK_o:
00379             send_button_press(BUTTON_HIDEDOTS);
00380             break;
00381 
00382           case XK_v:
00383             send_button_press(BUTTON_SETVELOCITY);
00384             break;
00385 
00386           case XK_Shift_L:
00387           case XK_Shift_R:
00388             shift_pressed = true;
00389             break;
00390           case XK_m:
00391             send_button_press(BUTTON_MODE_CHANGE);
00392             break;
00393           case XK_f:
00394             send_button_press(BUTTON_FIX);
00395             break;
00396           case XK_h:
00397             send_button_press(BUTTON_FLIP);
00398             break;
00399           case XK_c:
00400             send_button_press(BUTTON_CLEAR);
00401             break;
00402           case XK_Delete:
00403             send_button_press(BUTTON_DELETE);
00404             break;
00405           case XK_Escape:
00406             send_button_press(BUTTON_ESCAPE);
00407             break;
00408           case XK_u:
00409             send_button_press(BUTTON_UNDO);
00410             break;
00411           case XK_r:
00412             send_button_press(BUTTON_REDO);
00413             break;
00414           case XK_d:
00415             send_button_press(BUTTON_DUPLICATE);
00416             break;
00417           case XK_space:
00418             send_button_press(BUTTON_RUN);
00419             break;
00420           case XK_Tab:
00421             send_button_press(BUTTON_TOGGLESLOWMO);
00422             break;
00423           case 65451: // FIXME: insert symbol here
00424           case XK_equal:
00425           case XK_plus:
00426             send_button_press(BUTTON_ZOOM_IN);
00427             break;
00428           case 65453: // FIXME: insert symbol here
00429           case XK_minus:
00430             send_button_press(BUTTON_ZOOM_OUT);
00431             break;
00432           case XK_0:
00433             send_load_or_save(0);
00434             break;
00435           case XK_1:
00436             send_load_or_save(1);
00437             break;
00438           case XK_2:
00439             send_load_or_save(2);
00440             break;
00441           case XK_3:
00442             send_load_or_save(3);
00443             break;
00444           case XK_4:
00445             send_load_or_save(4);
00446             break;
00447           case XK_5:
00448             send_load_or_save(5);
00449             break;
00450           case XK_6:
00451             send_load_or_save(6);
00452             break;
00453           case XK_7:
00454             send_load_or_save(7);
00455             break;
00456           case XK_8:
00457             send_load_or_save(8);
00458             break;
00459           case XK_9:
00460             send_load_or_save(9);
00461             break;
00462               
00463           default:
00464             std::cout << "X11Display: unhandled keypress: " << sym << " " << XK_grave << std::endl;
00465             break;
00466           }
00467       }
00468       break;
00469 
00470     case KeyRelease:
00471       {
00472         KeySym sym = XLookupKeysym(&event.xkey,0);
00473             
00474         switch (sym)
00475           {
00476           case XK_Shift_L:
00477           case XK_Shift_R:
00478             shift_pressed = false;
00479             break;
00480           default:
00481             //std::cout << "X11Display: unhandled keyrelease: " << sym << " " << XK_f << std::endl;
00482             break;
00483           }
00484       }
00485       break;
00486 
00487     case ConfigureNotify:
00488       //std::cout << "X11Display: " << event.xconfigure.width << "x" << event.xconfigure.height 
00489       //<< "+" << event.xconfigure.x << "+" << event.xconfigure.y << std::endl;
00490       break;
00491 
00492     case DestroyNotify:
00493       std::cout << "Window got destroyed" << std::endl;
00494       break;
00495 
00496     case ClientMessage:
00497       std::cout << "X11Display: got client message" << std::endl;
00498       // Window close request
00499       if ((int) event.xclient.data.l[0] == (int) wm_delete_window) {
00500         std::cout << "Window is destroyed" << std::endl;
00501         send_button_press(BUTTON_ESCAPE);
00502       }
00503       break;
00504 
00505     default: 
00506       std::cout << "X11Display: Unhandled event: " << event.type << std::endl;
00507       break;
00508     }
00509   return true;
00510 }
00511 
00512 void
00513 X11Display::send_load_or_save(int n)
00514 {
00515   if (shift_pressed)
00516     send_button_press(BUTTON_QUICKLOAD0 + n);
00517   else
00518     send_button_press(BUTTON_QUICKSAVE0 + n);
00519 }
00520 
00521 void
00522 X11Display::send_button_press (int i)
00523 {
00524   Event ev;
00525   ev.button.type = BUTTON_EVENT;
00526   ev.button.id = i;
00527   ev.button.pressed = true;
00528   events.push(ev); 
00529 }
00530 
00531 void
00532 X11Display::send_button_release (int i)
00533 {
00534   Event ev;
00535   ev.button.type = BUTTON_EVENT;
00536   ev.button.id = i;
00537   ev.button.pressed = false;
00538   events.push(ev); 
00539 }
00540 
00541 void
00542 X11Display::clear ()
00543 {
00544   XSetForeground (display, gc, 0x000000);
00545   XFillRectangle (display, drawable, gc, 0, 0, width, height);
00546 }
00547 
00548 void
00549 X11Display::flip (int x1, int y1, int x2, int y2)
00550 {
00551   if (doublebuffer)
00552     {
00553       FlipRect flip_rect;
00554 
00555       flip_rect.x1 = x1;
00556       flip_rect.y1 = y1;
00557       flip_rect.x2 = x2;
00558       flip_rect.y2 = y2;
00559 
00560       //flip_rects.push_back(flip_rect);
00561     }
00562 }
00563 
00564 void
00565 X11Display::real_flip ()
00566 {
00567   if (doublebuffer)
00568     {
00569       for (std::vector<FlipRect>::iterator i = flip_rects.begin ();
00570            i != flip_rects.end ();
00571            ++i)
00572         {
00573           XCopyArea (display, drawable, window, gc,
00574                      i->x1, i->y1, // source
00575                      i->x2 - i->x1, i->y2 - i->y1, // width/height
00576                      i->x1, i->y1 // destination
00577                      );
00578         }
00579       flip_rects.clear ();
00580     }
00581 }
00582 
00583 void
00584 X11Display::flip ()
00585 {
00586   if (doublebuffer)
00587     {
00588       // FIXME: Use another gc here
00589       XCopyArea (display, drawable, window, gc,
00590                  0, 0, // source
00591                  width, height,
00592                  0, 0 // destination
00593                  );
00594       //XFlush(display);
00595     }
00596 }
00597 
00598 void
00599 X11Display::set_fullscreen (bool fullscreen)
00600 {
00601 #ifdef HAVE_LIBXXF86VM
00602   int event_base;
00603   int error_base;
00604   if (XF86VidModeQueryExtension(display, &event_base, &error_base) != True)
00605     {
00606       // No VidMode extension available, bailout
00607       std::cout << "X11Display: VidMode extension not available, bailout." << std::endl;
00608       return;
00609     }
00610 
00611   int screen = DefaultScreen(display);
00612 
00613   memset(&orig_modeline, 0, sizeof(orig_modeline));
00614   // Get the current display settings for later restore
00615   XF86VidModeGetModeLine(display, 
00616                          screen,
00617                          &orig_dotclock,
00618                          &orig_modeline);
00619 
00620   XF86VidModeGetViewPort(display,
00621                          screen,
00622                          &orig_viewport_x,
00623                          &orig_viewport_y);
00624 
00625   XF86VidModeModeInfo **modes;
00626   int nmodes;
00627   int mode_index = -1;
00628   if (XF86VidModeGetAllModeLines(display,
00629                                  screen,
00630                                  &nmodes,&modes))
00631     {
00632       std::cout << "VideoModes: (searching for " << width << "x" << height << ")" << std::endl;
00633       for (int i = 0; i < nmodes; i++)
00634         {
00635           //std::cout << i << "  " << mode.Width,mode.Height);
00636           std::cout << "  " << modes[i]->hdisplay
00637                     << "x" << modes[i]->vdisplay;
00638 
00639           if (modes[i]->hdisplay == width && modes[i]->vdisplay == height)
00640             {
00641               std::cout << " <-";
00642               mode_index = i;
00643             }
00644           std::cout << std::endl;
00645         }
00646 
00647       if (mode_index != -1) // Found a good mode
00648         {
00649           if (0)
00650             { // FIXME: doesn't work to change override_redirect after window creation
00651               std::cout << "Changing override_redirect" << std::endl;
00652               // Switch border away and go to 0,0
00653               XSetWindowAttributes attributes;
00654               attributes.override_redirect = True;
00655               XChangeWindowAttributes(display, window, CWOverrideRedirect, &attributes);
00656             }
00657 
00658           std::cout << "Switching to: "
00659                     << modes[mode_index]->hdisplay << "x" << modes[mode_index]->vdisplay
00660                     << std::endl;
00661 
00662           if(XF86VidModeSwitchToMode(display,
00663                                      screen,
00664                                      modes[mode_index]))
00665             {
00666               XF86VidModeSetViewPort(display, screen, 0, 0);
00667               // Hijack the focus (works only till the next focus change)
00668               XSetInputFocus(display, window, RevertToParent, CurrentTime);
00669               
00670               // Capture the pointer
00671               if (XGrabPointer(display, window, true, 0, GrabModeAsync, GrabModeAsync, window, None, CurrentTime)
00672                   != GrabSuccess)
00673                 {
00674                   std::cout << "X11Display: Couldn't grab the pointer" << std::endl;
00675                 }
00676             }
00677         }
00678       else // No mode found
00679         {
00680           std::cout << "Disabling override redirect" << std::endl;
00681           // Fullscreen not possible, switch Window attributes back to windowed mode
00682           XSetWindowAttributes attributes;
00683           attributes.override_redirect = False;
00684           XChangeWindowAttributes(display, window, CWOverrideRedirect, &attributes);
00685 
00686           // Remap the Window to let the allow override to take effect
00687           XUnmapWindow (display, window);
00688           XMapRaised(display, window);
00689         }
00690     }
00691   else
00692     {
00693       std::cout << "X11Display: Couldn't get available video modes" << std::endl;
00694     }
00695 #endif
00696 }
00697 
00698 void
00699 X11Display::run()
00700 {
00701   while (!ScreenManager::instance ()->is_finished ())
00702     {
00703       if (Controller::instance()->is_running())
00704         {
00705           system_context->sleep (0); // limit CPU usage via brute force
00706           wait_for_events();
00707         }
00708       else
00709         {
00710           wait_for_events_blocking();
00711         }
00712       ScreenManager::instance ()->run_once();
00713     }
00714 }
00715 
00716 void
00717 X11Display::restore_mode ()
00718 {
00719 #ifdef HAVE_LIBXXF86VM
00720   XF86VidModeModeInfo modeinfo;
00721   
00722   modeinfo.dotclock   = orig_dotclock;
00723   
00724   // Copy XF86VidModeModeLine struct into XF86VidModeModeInfo
00725   modeinfo.hdisplay   = orig_modeline.hdisplay;
00726   modeinfo.hsyncstart = orig_modeline.hsyncstart;
00727   modeinfo.hsyncend   = orig_modeline.hsyncend;
00728   modeinfo.htotal     = orig_modeline.htotal;
00729   modeinfo.hskew      = orig_modeline.hskew;
00730   modeinfo.vdisplay   = orig_modeline.vdisplay;
00731   modeinfo.vsyncstart = orig_modeline.vsyncstart;
00732   modeinfo.vsyncend   = orig_modeline.vsyncend;
00733   modeinfo.vtotal     = orig_modeline.vtotal;
00734   modeinfo.flags      = orig_modeline.flags;
00735   modeinfo.privsize   = orig_modeline.privsize;
00736   modeinfo.c_private  = orig_modeline.c_private;
00737 
00738   XF86VidModeSwitchToMode(display, DefaultScreen(display),
00739                           &modeinfo);
00740   XF86VidModeSetViewPort(display, DefaultScreen(display),
00741                          orig_viewport_x, orig_viewport_y);
00742 
00743   fullscreen = false;
00744 #endif
00745 }
00746 
00747 void
00748 X11Display::set_clip_rect (int x1, int y1, int x2, int y2)
00749 {
00750   XRectangle rect[1];
00751 
00752   rect[0].x = x1;
00753   rect[0].y = y1;
00754   rect[0].width  = x2 - x1 + 1;
00755   rect[0].height = y2 - y1 + 1;
00756 
00757   XSetClipRectangles (display, gc, 
00758                       0, 0, // clip origin
00759                       rect, 1,
00760                       Unsorted);
00761 }
00762 
00763 unsigned int
00764 X11Display::get_color_value(Color& color)
00765 {
00766   XColor x_color;
00767 
00768   x_color.red   = int(color.r * 65535);
00769   x_color.green = int(color.g * 65535);
00770   x_color.blue  = int(color.b * 65535);
00771 
00772   XAllocColor(display, colormap, &x_color);
00773 
00774   return x_color.pixel;
00775 }
00776 
00777 /* EOF */

Generated on Thu Jul 24 10:24:32 2003 for Construo by doxygen1.3-rc3