This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
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 <grumbel@gmx.de> 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 */