GX11Gui.cxx

Go to the documentation of this file.
00001 // @(#)root/x11:$Id: GX11Gui.cxx 37939 2011-02-02 13:54:07Z couet $
00002 // Author: Fons Rademakers   28/12/97
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TGX11 (GUI related part)                                             //
00015 //                                                                      //
00016 // This class is the basic interface to the X11 graphics system. It is  //
00017 // an implementation of the abstract TVirtualX class. The companion     //
00018 // class for Win32 is TGWin32.                                          //
00019 //                                                                      //
00020 // This file contains the implementation of the GUI methods of the      //
00021 // TGX11 class. Most of the methods are used by the machine independent //
00022 // GUI classes (libGUI.so).                                             //
00023 //                                                                      //
00024 //////////////////////////////////////////////////////////////////////////
00025 
00026 #include <stdio.h>
00027 #include <string.h>
00028 #include <stdlib.h>
00029 #include <ctype.h>
00030 #include <unistd.h>
00031 
00032 #include "TGX11.h"
00033 #include "TROOT.h"
00034 #include "TError.h"
00035 #include "TSystem.h"
00036 #include "TException.h"
00037 #include "TClassTable.h"
00038 #include "KeySymbols.h"
00039 #include "TEnv.h"
00040 
00041 #include <X11/extensions/shape.h>
00042 
00043 //---- MWM Hints stuff
00044 
00045 struct MWMHintsProperty_t {
00046    Handle_t  fFlags;
00047    Handle_t  fFunctions;
00048    Handle_t  fDecorations;
00049    Int_t     fInputMode;
00050 };
00051 
00052 //---- hints
00053 
00054 const ULong_t kMWMHintsFunctions   = BIT(0);
00055 const ULong_t kMWMHintsDecorations = BIT(1);
00056 const ULong_t kMWMHintsInputMode   = BIT(2);
00057 
00058 const Int_t kPropMotifWMHintsElements = 4;
00059 const Int_t kPropMWMHintElements      = kPropMotifWMHintsElements;
00060 
00061 
00062 //---- Key symbol mapping
00063 
00064 struct KeySymbolMap_t {
00065    KeySym    fXKeySym;
00066    EKeySym   fKeySym;
00067 };
00068 
00069 //---- Mapping table of all non-trivial mappings (the ASCII keys map
00070 //---- one to one so are not included)
00071 
00072 static KeySymbolMap_t gKeyMap[] = {
00073    { XK_Escape,          kKey_Escape },
00074    { XK_Tab,             kKey_Tab },
00075 #ifndef XK_ISO_Left_Tab
00076    { 0xFE20,             kKey_Backtab },
00077 #else
00078    { XK_ISO_Left_Tab,    kKey_Backtab },
00079 #endif
00080    { XK_BackSpace,       kKey_Backspace },
00081    { XK_Return,          kKey_Return },
00082    { XK_Insert,          kKey_Insert },
00083    { XK_Delete,          kKey_Delete },
00084    { XK_Clear,           kKey_Delete },
00085    { XK_Pause,           kKey_Pause },
00086    { XK_Print,           kKey_Print },
00087    { 0x1005FF60,         kKey_SysReq },             // hardcoded Sun SysReq
00088    { 0x1007ff00,         kKey_SysReq },             // hardcoded X386 SysReq
00089    { XK_Home,            kKey_Home },               // cursor movement
00090    { XK_End,             kKey_End },
00091    { XK_Left,            kKey_Left },
00092    { XK_Up,              kKey_Up },
00093    { XK_Right,           kKey_Right },
00094    { XK_Down,            kKey_Down },
00095    { XK_Prior,           kKey_Prior },
00096    { XK_Next,            kKey_Next },
00097    { XK_Shift_L,         kKey_Shift },              // modifiers
00098    { XK_Shift_R,         kKey_Shift },
00099    { XK_Shift_Lock,      kKey_Shift },
00100    { XK_Control_L,       kKey_Control },
00101    { XK_Control_R,       kKey_Control },
00102    { XK_Meta_L,          kKey_Meta },
00103    { XK_Meta_R,          kKey_Meta },
00104    { XK_Alt_L,           kKey_Alt },
00105    { XK_Alt_R,           kKey_Alt },
00106    { XK_Caps_Lock,       kKey_CapsLock },
00107    { XK_Num_Lock,        kKey_NumLock },
00108    { XK_Scroll_Lock,     kKey_ScrollLock },
00109    { XK_KP_Space,        kKey_Space },              // numeric keypad
00110    { XK_KP_Tab,          kKey_Tab },
00111    { XK_KP_Enter,        kKey_Enter },
00112    { XK_KP_F1,           kKey_F1 },
00113    { XK_KP_F2,           kKey_F2 },
00114    { XK_KP_F3,           kKey_F3 },
00115    { XK_KP_F4,           kKey_F4 },
00116    { XK_KP_Home,         kKey_Home },
00117    { XK_KP_Left,         kKey_Left },
00118    { XK_KP_Up,           kKey_Up },
00119    { XK_KP_Right,        kKey_Right },
00120    { XK_KP_Down,         kKey_Down },
00121    { XK_KP_Prior,        kKey_Prior },
00122    { XK_KP_Page_Up,      kKey_PageUp },
00123    { XK_KP_Next,         kKey_Next },
00124    { XK_KP_Page_Down,    kKey_PageDown },
00125    { XK_KP_End,          kKey_End },
00126    { XK_KP_Begin,        kKey_Home },
00127    { XK_KP_Insert,       kKey_Insert },
00128    { XK_KP_Delete,       kKey_Delete },
00129    { XK_KP_Equal,        kKey_Equal },
00130    { XK_KP_Multiply,     kKey_Asterisk },
00131    { XK_KP_Add,          kKey_Plus },
00132    { XK_KP_Separator,    kKey_Comma },
00133    { XK_KP_Subtract,     kKey_Minus },
00134    { XK_KP_Decimal,      kKey_Period },
00135    { XK_KP_Divide,       kKey_Slash },
00136    { 0,                  (EKeySym) 0 }
00137 };
00138 
00139 
00140 
00141 //______________________________________________________________________________
00142 inline void SplitLong(Long_t ll, Long_t &i1, Long_t &i2)
00143 {
00144    union { Long_t l; Int_t i[2]; } conv;
00145 
00146    conv.l = ll;
00147    i1 = conv.i[0];
00148    i2 = conv.i[1];
00149 }
00150 
00151 //______________________________________________________________________________
00152 inline void AsmLong(Long_t i1, Long_t i2, Long_t &ll)
00153 {
00154    union { Long_t l; Int_t i[2]; } conv;
00155 
00156    conv.i[0] = (Int_t) i1;
00157    conv.i[1] = (Int_t) i2;
00158    ll = conv.l;
00159 }
00160 
00161 //______________________________________________________________________________
00162 static Int_t RootX11ErrorHandler(Display *disp, XErrorEvent *err)
00163 {
00164    // Handle X11 error.
00165 
00166    char msg[80];
00167    XGetErrorText(disp, err->error_code, msg, 80);
00168 
00169    // force segV. to allow backtracing the error with gdb
00170    if (gDebug == (Long_t)gVirtualX) {
00171       gSystem->ProcessEvents();
00172       ::Error("RootX11ErrorHandler", "%s (XID: %u, XREQ: %u)", msg,
00173                (UInt_t)err->resourceid, err->request_code);
00174       int *kil = (int*)1;
00175       delete kil;
00176       return 0;
00177    }
00178 
00179    if (!err->resourceid) return 0;
00180 
00181    TObject *w = (TObject *)gROOT->ProcessLineFast(Form("gClient->GetWindowById(%lu)", (ULong_t)err->resourceid));
00182 
00183    if (!w) {
00184       ::Error("RootX11ErrorHandler", "%s (XID: %u, XREQ: %u)", msg,
00185                (UInt_t)err->resourceid, err->request_code);
00186    } else {
00187       ::Error("RootX11ErrorHandler", "%s (%s XID: %u, XREQ: %u)", msg, w->ClassName(),
00188                (UInt_t)err->resourceid, err->request_code);
00189       w->Print("tree");
00190    }
00191    if (TROOT::Initialized()) {
00192       //Getlinem(kInit, "Root > ");
00193       Throw(2);
00194    }
00195    return 0;
00196 }
00197 
00198 //______________________________________________________________________________
00199 static Int_t RootX11IOErrorHandler(Display *)
00200 {
00201    // Handle X11 I/O error (happens when connection to display server
00202    // is broken).
00203 
00204    ::Error("RootX11IOErrorHandler", "fatal X11 error (connection to server lost?!)");
00205    fprintf(stderr,"\n**** Save data and exit application ****\n\n");
00206    // delete X connection handler (to avoid looping in TSystem::DispatchOneEvent())
00207    if (gXDisplay && gSystem) {
00208       gSystem->RemoveFileHandler(gXDisplay);
00209       SafeDelete(gXDisplay);
00210    }
00211    if (TROOT::Initialized()) {
00212       //Getlinem(kInit, "Root > ");
00213       Throw(2);
00214    }
00215    return 0;
00216 }
00217 
00218 
00219 //______________________________________________________________________________
00220 void TGX11::MapWindow(Window_t id)
00221 {
00222    // Map window on screen.
00223 
00224    if (!id) return;
00225 
00226    XMapWindow(fDisplay, (Window) id);
00227 }
00228 
00229 //______________________________________________________________________________
00230 void TGX11::MapSubwindows(Window_t id)
00231 {
00232    // Map sub windows.
00233 
00234    if (!id) return;
00235 
00236    XMapSubwindows(fDisplay, (Window) id);
00237 }
00238 
00239 //______________________________________________________________________________
00240 void TGX11::MapRaised(Window_t id)
00241 {
00242    // Map window on screen and put on top of all windows.
00243 
00244    if (!id) return;
00245 
00246    XMapRaised(fDisplay, (Window) id);
00247 }
00248 
00249 //______________________________________________________________________________
00250 void TGX11::UnmapWindow(Window_t id)
00251 {
00252    // Unmap window from screen.
00253 
00254    if (!id) return;
00255 
00256    XUnmapWindow(fDisplay, (Window) id);
00257 }
00258 
00259 //______________________________________________________________________________
00260 void TGX11::DestroyWindow(Window_t id)
00261 {
00262    // Destroy window.
00263 
00264    if (!id) return;
00265 
00266    XDestroyWindow(fDisplay, (Window) id);
00267 }
00268 
00269 //______________________________________________________________________________
00270 void TGX11::DestroySubwindows(Window_t id)
00271 {
00272    // Destroy subwindows of this window.
00273 
00274    if (!id) return;
00275 
00276    XDestroySubwindows(fDisplay, (Window) id);
00277 }
00278 
00279 //______________________________________________________________________________
00280 void TGX11::RaiseWindow(Window_t id)
00281 {
00282    // Put window on top of window stack.
00283 
00284    if (!id) return;
00285 
00286    XRaiseWindow(fDisplay, (Window) id);
00287 }
00288 
00289 //______________________________________________________________________________
00290 void TGX11::LowerWindow(Window_t id)
00291 {
00292    // Lower window so it lays below all its siblings.
00293 
00294    if (!id) return;
00295 
00296    XLowerWindow(fDisplay, (Window) id);
00297 }
00298 
00299 //______________________________________________________________________________
00300 void TGX11::MoveWindow(Window_t id, Int_t x, Int_t y)
00301 {
00302    // Move a window.
00303 
00304    if (!id) return;
00305 
00306    XMoveWindow(fDisplay, (Window) id, x, y);
00307 }
00308 
00309 //______________________________________________________________________________
00310 void TGX11::MoveResizeWindow(Window_t id, Int_t x, Int_t y, UInt_t w, UInt_t h)
00311 {
00312    // Move and resize a window.
00313 
00314    if (!id) return;
00315 
00316    XMoveResizeWindow(fDisplay, (Window) id, x, y, w, h);
00317 }
00318 
00319 //______________________________________________________________________________
00320 void TGX11::ResizeWindow(Window_t id, UInt_t w, UInt_t h)
00321 {
00322    // Resize the window.
00323 
00324    if (!id) return;
00325 
00326    XResizeWindow(fDisplay, (Window) id, w, h);
00327 }
00328 
00329 //______________________________________________________________________________
00330 void TGX11::IconifyWindow(Window_t id)
00331 {
00332    // Iconify the window.
00333 
00334    if (!id) return;
00335 
00336    XIconifyWindow(fDisplay, (Window) id, fScreenNumber);
00337 }
00338 
00339 //______________________________________________________________________________
00340 void TGX11::ReparentWindow(Window_t id, Window_t pid, Int_t x, Int_t y)
00341 {
00342    // Reparent window to new parent window at position (x,y).
00343 
00344    if (!id) return;
00345 
00346    XReparentWindow(fDisplay, (Window) id, (Window) pid, x, y);
00347 }
00348 
00349 //______________________________________________________________________________
00350 void TGX11::SetWindowBackground(Window_t id, ULong_t color)
00351 {
00352    // Set the window background color.
00353 
00354    if (!id) return;
00355 
00356    XSetWindowBackground(fDisplay, (Window) id, color);
00357 }
00358 
00359 //______________________________________________________________________________
00360 void TGX11::SetWindowBackgroundPixmap(Window_t id, Pixmap_t pxm)
00361 {
00362    // Set pixmap as window background.
00363 
00364    if (!id) return;
00365 
00366    XSetWindowBackgroundPixmap(fDisplay, (Window) id, (Pixmap) pxm);
00367 }
00368 
00369 //______________________________________________________________________________
00370 Window_t TGX11::CreateWindow(Window_t parent, Int_t x, Int_t y,
00371                              UInt_t w, UInt_t h, UInt_t border,
00372                              Int_t depth, UInt_t clss,
00373                              void *visual, SetWindowAttributes_t *attr, UInt_t)
00374 {
00375    // Return handle to newly created X window.
00376 
00377    XSetWindowAttributes xattr;
00378    ULong_t              xmask = 0;
00379 
00380    if (attr)
00381       MapSetWindowAttributes(attr, xmask, xattr);
00382 
00383    if (depth == 0)
00384       depth = fDepth;
00385    if (visual == 0)
00386       visual = fVisual;
00387    if (fColormap && !(xmask & CWColormap)) {
00388       xmask |= CWColormap;
00389       xattr.colormap = fColormap;
00390    }
00391    if ((Window)parent == fRootWin && fRootWin != fVisRootWin) {
00392       xmask |= CWBorderPixel;
00393       xattr.border_pixel = fBlackPixel;
00394    }
00395 
00396    return (Window_t) XCreateWindow(fDisplay, (Window) parent, x, y,
00397                                    w, h, border, depth, clss, (Visual*)visual,
00398                                    xmask, &xattr);
00399 }
00400 
00401 //______________________________________________________________________________
00402 void TGX11::MapEventMask(UInt_t &emask, UInt_t &xemask, Bool_t tox)
00403 {
00404    // Map event mask to or from X.
00405 
00406    if (tox) {
00407       Long_t lxemask = NoEventMask;
00408       if ((emask & kKeyPressMask))
00409          lxemask |= KeyPressMask;
00410       if ((emask & kKeyReleaseMask))
00411          lxemask |= KeyReleaseMask;
00412       if ((emask & kButtonPressMask))
00413          lxemask |= ButtonPressMask;
00414       if ((emask & kButtonReleaseMask))
00415          lxemask |= ButtonReleaseMask;
00416       if ((emask & kPointerMotionMask))
00417          lxemask |= PointerMotionMask;
00418       if ((emask & kButtonMotionMask))
00419          lxemask |= ButtonMotionMask;
00420       if ((emask & kExposureMask))
00421          lxemask |= ExposureMask;
00422       if ((emask & kStructureNotifyMask))
00423          lxemask |= StructureNotifyMask;
00424       if ((emask & kEnterWindowMask))
00425          lxemask |= EnterWindowMask;
00426       if ((emask & kLeaveWindowMask))
00427          lxemask |= LeaveWindowMask;
00428       if ((emask & kFocusChangeMask))
00429          lxemask |= FocusChangeMask;
00430       if ((emask & kOwnerGrabButtonMask))
00431          lxemask |= OwnerGrabButtonMask;
00432       if ((emask & kColormapChangeMask))
00433          lxemask |= ColormapChangeMask;
00434       xemask = (UInt_t)lxemask;
00435    } else {
00436       emask = 0;
00437       if ((xemask & KeyPressMask))
00438          emask |= kKeyPressMask;
00439       if ((xemask & KeyReleaseMask))
00440          emask |= kKeyReleaseMask;
00441       if ((xemask & ButtonPressMask))
00442          emask |= kButtonPressMask;
00443       if ((xemask & ButtonReleaseMask))
00444          emask |= kButtonReleaseMask;
00445       if ((xemask & PointerMotionMask))
00446          emask |= kPointerMotionMask;
00447       if ((xemask & ButtonMotionMask))
00448          emask |= kButtonMotionMask;
00449       if ((xemask & ExposureMask))
00450          emask |= kExposureMask;
00451       if ((xemask & StructureNotifyMask))
00452          emask |= kStructureNotifyMask;
00453       if ((xemask & EnterWindowMask))
00454          emask |= kEnterWindowMask;
00455       if ((xemask & LeaveWindowMask))
00456          emask |= kLeaveWindowMask;
00457       if ((xemask & FocusChangeMask))
00458          emask |= kFocusChangeMask;
00459       if ((xemask & OwnerGrabButtonMask))
00460          emask |= kOwnerGrabButtonMask;
00461       if ((xemask & ColormapChangeMask))
00462          emask |= kColormapChangeMask;
00463    }
00464 }
00465 
00466 //______________________________________________________________________________
00467 void TGX11::MapSetWindowAttributes(SetWindowAttributes_t *attr,
00468                                    ULong_t &xmask, XSetWindowAttributes &xattr)
00469 {
00470    // Map a SetWindowAttributes_t to a XSetWindowAttributes structure.
00471 
00472    Mask_t mask = attr->fMask;
00473    xmask = 0;
00474 
00475    if ((mask & kWABackPixmap)) {
00476       xmask |= CWBackPixmap;
00477       if (attr->fBackgroundPixmap == kNone)
00478          xattr.background_pixmap = None;
00479       else if (attr->fBackgroundPixmap == kParentRelative)
00480          xattr.background_pixmap = ParentRelative;
00481       else
00482          xattr.background_pixmap = (Pixmap)attr->fBackgroundPixmap;
00483    }
00484    if ((mask & kWABackPixel)) {
00485       xmask |= CWBackPixel;
00486       xattr.background_pixel = attr->fBackgroundPixel;
00487    }
00488    if ((mask & kWABorderPixmap)) {
00489       xmask |= CWBorderPixmap;
00490       xattr.border_pixmap = (Pixmap)attr->fBorderPixmap;
00491    }
00492    if ((mask & kWABorderPixel)) {
00493       xmask |= CWBorderPixel;
00494       xattr.border_pixel = attr->fBorderPixel;
00495    }
00496    if ((mask & kWABitGravity)) {
00497       xmask |= CWBitGravity;
00498       xattr.bit_gravity = attr->fBitGravity;  //assume ident mapping (rdm)
00499    }
00500    if ((mask & kWAWinGravity)) {
00501       xmask |= CWWinGravity;
00502       xattr.win_gravity = attr->fWinGravity;  // assume ident mapping (rdm)
00503    }
00504    if ((mask & kWABackingStore)) {
00505       xmask |= CWBackingStore;
00506       if (attr->fBackingStore == kNotUseful)
00507          xattr.backing_store = NotUseful;
00508       else if (attr->fBackingStore == kWhenMapped)
00509          xattr.backing_store = WhenMapped;
00510       else if (attr->fBackingStore == kAlways)
00511          xattr.backing_store = Always;
00512       else
00513          xattr.backing_store = attr->fBackingStore;
00514    }
00515    if ((mask & kWABackingPlanes)) {
00516       xmask |= CWBackingPlanes;
00517       xattr.backing_planes = attr->fBackingPlanes;
00518    }
00519    if ((mask & kWABackingPixel)) {
00520       xmask |= CWBackingPixel;
00521       xattr.backing_pixel = attr->fBackingPixel;
00522    }
00523    if ((mask & kWAOverrideRedirect)) {
00524       xmask |= CWOverrideRedirect;
00525       xattr.override_redirect = attr->fOverrideRedirect;
00526    }
00527    if ((mask & kWASaveUnder)) {
00528       xmask |= CWSaveUnder;
00529       xattr.save_under = (Bool)attr->fSaveUnder;
00530    }
00531    if ((mask & kWAEventMask)) {
00532       xmask |= CWEventMask;
00533       UInt_t xmsk, msk = (UInt_t) attr->fEventMask;
00534       MapEventMask(msk, xmsk, kTRUE);
00535       xattr.event_mask = xmsk;
00536    }
00537    if ((mask & kWADontPropagate)) {
00538       xmask |= CWDontPropagate;
00539       xattr.do_not_propagate_mask = attr->fDoNotPropagateMask;
00540    }
00541    if ((mask & kWAColormap)) {
00542       xmask |= CWColormap;
00543       xattr.colormap = (Colormap)attr->fColormap;
00544    }
00545    if ((mask & kWACursor)) {
00546       xmask |= CWCursor;
00547       if (attr->fCursor == kNone)
00548          xattr.cursor = None;
00549       else
00550          xattr.cursor = (Cursor)attr->fCursor;
00551    }
00552 }
00553 
00554 //______________________________________________________________________________
00555 void TGX11::MapGCValues(GCValues_t &gval,
00556                         ULong_t &xmask, XGCValues &xgval, Bool_t tox)
00557 {
00558    // Map a GCValues_t to a XCGValues structure if tox is true. Map
00559    // the other way in case tox is false.
00560 
00561    if (tox) {
00562       // map GCValues_t to XGCValues
00563       Mask_t mask = gval.fMask;
00564       xmask = 0;
00565 
00566       if ((mask & kGCFunction)) {
00567          xmask |= GCFunction;
00568          xgval.function = gval.fFunction;   // ident mapping
00569       }
00570       if ((mask & kGCPlaneMask)) {
00571          xmask |= GCPlaneMask;
00572          xgval.plane_mask = gval.fPlaneMask;
00573       }
00574       if ((mask & kGCForeground)) {
00575          xmask |= GCForeground;
00576          xgval.foreground = gval.fForeground;
00577       }
00578       if ((mask & kGCBackground)) {
00579          xmask |= GCBackground;
00580          xgval.background = gval.fBackground;
00581       }
00582       if ((mask & kGCLineWidth)) {
00583          xmask |= GCLineWidth;
00584          xgval.line_width = gval.fLineWidth;
00585       }
00586       if ((mask & kGCLineStyle)) {
00587          xmask |= GCLineStyle;
00588          xgval.line_style = gval.fLineStyle;   // ident mapping
00589       }
00590       if ((mask & kGCCapStyle)) {
00591          xmask |= GCCapStyle;
00592          xgval.cap_style = gval.fCapStyle;     // ident mapping
00593       }
00594       if ((mask & kGCJoinStyle)) {
00595          xmask |= GCJoinStyle;
00596          xgval.join_style = gval.fJoinStyle;   // ident mapping
00597       }
00598       if ((mask & kGCFillStyle)) {
00599          xmask |= GCFillStyle;
00600          xgval.fill_style = gval.fFillStyle;   // ident mapping
00601       }
00602       if ((mask & kGCFillRule)) {
00603          xmask |= GCFillRule;
00604          xgval.fill_rule = gval.fFillRule;     // ident mapping
00605       }
00606       if ((mask & kGCTile)) {
00607          xmask |= GCTile;
00608          xgval.tile = (Pixmap) gval.fTile;
00609       }
00610       if ((mask & kGCStipple)) {
00611          xmask |= GCStipple;
00612          xgval.stipple = (Pixmap) gval.fStipple;
00613       }
00614       if ((mask & kGCTileStipXOrigin)) {
00615          xmask |= GCTileStipXOrigin;
00616          xgval.ts_x_origin = gval.fTsXOrigin;
00617       }
00618       if ((mask & kGCTileStipYOrigin)) {
00619          xmask |= GCTileStipYOrigin;
00620          xgval.ts_y_origin = gval.fTsYOrigin;
00621       }
00622       if ((mask & kGCFont)) {
00623          xmask |= GCFont;
00624          xgval.font = (Font) gval.fFont;
00625       }
00626       if ((mask & kGCSubwindowMode)) {
00627          xmask |= GCSubwindowMode;
00628          xgval.subwindow_mode = gval.fSubwindowMode;  // ident mapping
00629       }
00630       if ((mask & kGCGraphicsExposures)) {
00631          xmask |= GCGraphicsExposures;
00632          xgval.graphics_exposures = (Bool) gval.fGraphicsExposures;
00633       }
00634       if ((mask & kGCClipXOrigin)) {
00635          xmask |= GCClipXOrigin;
00636          xgval.clip_x_origin = gval.fClipXOrigin;
00637       }
00638       if ((mask & kGCClipYOrigin)) {
00639          xmask |= GCClipYOrigin;
00640          xgval.clip_y_origin = gval.fClipYOrigin;
00641       }
00642       if ((mask & kGCClipMask)) {
00643          xmask |= GCClipMask;
00644          xgval.clip_mask = (Pixmap) gval.fClipMask;
00645       }
00646       if ((mask & kGCDashOffset)) {
00647          xmask |= GCDashOffset;
00648          xgval.dash_offset = gval.fDashOffset;
00649       }
00650       if ((mask & kGCDashList)) {
00651          xmask |= GCDashList;
00652          xgval.dashes = gval.fDashes[0];
00653       }
00654       if ((mask & kGCArcMode)) {
00655          xmask |= GCArcMode;
00656          xgval.arc_mode = gval.fArcMode;   // ident mapping
00657       }
00658 
00659    } else {
00660       // map XValues to GCValues_t
00661       Mask_t mask = 0;
00662 
00663       if ((xmask & GCFunction)) {
00664          mask |= kGCFunction;
00665          gval.fFunction = (EGraphicsFunction) xgval.function; // ident mapping
00666       }
00667       if ((xmask & GCPlaneMask)) {
00668          mask |= kGCPlaneMask;
00669          gval.fPlaneMask = xgval.plane_mask;
00670       }
00671       if ((xmask & GCForeground)) {
00672          mask |= kGCForeground;
00673          gval.fForeground = xgval.foreground;
00674       }
00675       if ((xmask & GCBackground)) {
00676          mask |= kGCBackground;
00677          gval.fBackground = xgval.background;
00678       }
00679       if ((xmask & GCLineWidth)) {
00680          mask |= kGCLineWidth;
00681          gval.fLineWidth = xgval.line_width;
00682       }
00683       if ((xmask & GCLineStyle)) {
00684          mask |= kGCLineStyle;
00685          gval.fLineStyle = xgval.line_style;   // ident mapping
00686       }
00687       if ((xmask & GCCapStyle)) {
00688          mask |= kGCCapStyle;
00689          gval.fCapStyle = xgval.cap_style;     // ident mapping
00690       }
00691       if ((xmask & GCJoinStyle)) {
00692          mask |= kGCJoinStyle;
00693          gval.fJoinStyle = xgval.join_style;   // ident mapping
00694       }
00695       if ((xmask & GCFillStyle)) {
00696          mask |= kGCFillStyle;
00697          gval.fFillStyle = xgval.fill_style;   // ident mapping
00698       }
00699       if ((xmask & GCFillRule)) {
00700          mask |= kGCFillRule;
00701          gval.fFillRule = xgval.fill_rule;     // ident mapping
00702       }
00703       if ((xmask & GCTile)) {
00704          mask |= kGCTile;
00705          gval.fTile = (Pixmap_t) xgval.tile;
00706       }
00707       if ((xmask & GCStipple)) {
00708          mask |= kGCStipple;
00709          gval.fStipple = (Pixmap_t) xgval.stipple;
00710       }
00711       if ((xmask & GCTileStipXOrigin)) {
00712          mask |= kGCTileStipXOrigin;
00713          gval.fTsXOrigin = xgval.ts_x_origin;
00714       }
00715       if ((xmask & GCTileStipYOrigin)) {
00716          mask |= kGCTileStipYOrigin;
00717          gval.fTsYOrigin = xgval.ts_y_origin;
00718       }
00719       if ((xmask & GCFont)) {
00720          mask |= kGCFont;
00721          gval.fFont = (FontH_t) xgval.font;
00722       }
00723       if ((xmask & GCSubwindowMode)) {
00724          mask |= kGCSubwindowMode;
00725          gval.fSubwindowMode = xgval.subwindow_mode;  // ident mapping
00726       }
00727       if ((xmask & GCGraphicsExposures)) {
00728          mask |= kGCGraphicsExposures;
00729          gval.fGraphicsExposures = (Bool_t) xgval.graphics_exposures;
00730       }
00731       if ((xmask & GCClipXOrigin)) {
00732          mask |= kGCClipXOrigin;
00733          gval.fClipXOrigin = xgval.clip_x_origin;
00734       }
00735       if ((xmask & GCClipYOrigin)) {
00736          mask |= kGCClipYOrigin;
00737          gval.fClipYOrigin = xgval.clip_y_origin;
00738       }
00739       if ((xmask & GCClipMask)) {
00740          mask |= kGCClipMask;
00741          gval.fClipMask = (Pixmap_t) xgval.clip_mask;
00742       }
00743       if ((xmask & GCDashOffset)) {
00744          mask |= kGCDashOffset;
00745          gval.fDashOffset = xgval.dash_offset;
00746       }
00747       if ((xmask & GCDashList)) {
00748          mask |= kGCDashList;
00749          gval.fDashes[0] = xgval.dashes;
00750          gval.fDashLen   = 1;
00751       }
00752       if ((xmask & GCArcMode)) {
00753          mask |= kGCArcMode;
00754          gval.fArcMode = xgval.arc_mode;   // ident mapping
00755       }
00756       gval.fMask = mask;
00757    }
00758 }
00759 
00760 //______________________________________________________________________________
00761 void TGX11::GetWindowAttributes(Window_t id, WindowAttributes_t &attr)
00762 {
00763    // Get window attributes and return filled in attributes structure.
00764 
00765    if (!id) return;
00766 
00767    XWindowAttributes xattr;
00768 
00769    XGetWindowAttributes(fDisplay, id, &xattr);
00770 
00771    attr.fX                  = xattr.x;
00772    attr.fY                  = xattr.y;
00773    attr.fWidth              = xattr.width;
00774    attr.fHeight             = xattr.height;
00775    attr.fBorderWidth        = xattr.border_width;
00776    attr.fDepth              = xattr.depth;
00777    attr.fVisual             = xattr.visual;
00778    attr.fRoot               = (Window_t) xattr.root;
00779    if (xattr.c_class == InputOutput) attr.fClass = kInputOutput;
00780    if (xattr.c_class == InputOnly)   attr.fClass = kInputOnly;
00781    attr.fBitGravity         = xattr.bit_gravity;  // assume ident mapping (rdm)
00782    attr.fWinGravity         = xattr.win_gravity;  // assume ident mapping (rdm)
00783    if (xattr.backing_store == NotUseful)  attr.fBackingStore = kNotUseful;
00784    if (xattr.backing_store == WhenMapped) attr.fBackingStore = kWhenMapped;
00785    if (xattr.backing_store == Always)     attr.fBackingStore = kAlways;
00786    attr.fBackingPlanes      = xattr.backing_planes;
00787    attr.fBackingPixel       = xattr.backing_pixel;
00788    attr.fSaveUnder          = (Bool_t) xattr.save_under;
00789    if ((Window) id == fRootWin)
00790       attr.fColormap        = (Colormap_t) fColormap;
00791    else
00792       attr.fColormap        = (Colormap_t) xattr.colormap;
00793    attr.fMapInstalled       = (Bool_t) xattr.map_installed;
00794    attr.fMapState           = xattr.map_state;         // ident mapping
00795    attr.fAllEventMasks      = xattr.all_event_masks;   // not ident, but not used by GUI classes
00796    attr.fYourEventMask      = xattr.your_event_mask;   // not ident, but not used by GUI classes
00797    attr.fDoNotPropagateMask = xattr.do_not_propagate_mask;
00798    attr.fOverrideRedirect   = (Bool_t) xattr.override_redirect;
00799    attr.fScreen             = xattr.screen;
00800 }
00801 
00802 //______________________________________________________________________________
00803 Int_t TGX11::OpenDisplay(const char *dpyName)
00804 {
00805    // Open connection to display server (if such a thing exist on the
00806    // current platform). On X11 this method returns on success the X
00807    // display socket descriptor (> 0), 0 in case of batch mode and < 0
00808    // in case of failure (cannot connect to display dpyName). It also
00809    // initializes the TGX11 class via Init(). Called from TGClient ctor.
00810 
00811 #ifdef _REENTRANT
00812    // In some cases there can be problems due to XInitThreads, like when
00813    // using Qt, so we allow for it to be turned off
00814    if (gEnv->GetValue("X11.XInitThread", 1)) {
00815       // Must be very first call before any X11 call !!
00816       if (!XInitThreads())
00817          Warning("OpenDisplay", "system has no X11 thread support");
00818    }
00819 #endif
00820 
00821    Display *dpy;
00822    if (!(dpy = XOpenDisplay(dpyName)))
00823       return -1;
00824 
00825    // Set custom X11 error handlers
00826    XSetErrorHandler(RootX11ErrorHandler);
00827    XSetIOErrorHandler(RootX11IOErrorHandler);
00828 
00829    if (gEnv->GetValue("X11.Sync", 0))
00830       XSynchronize(dpy, 1);
00831 
00832    // Init the GX11 class, sets a.o. fDisplay.
00833    if (!Init(dpy))
00834       return -1;
00835 
00836    return ConnectionNumber(dpy);
00837 }
00838 
00839 //______________________________________________________________________________
00840 void TGX11::CloseDisplay()
00841 {
00842    // Close connection to display server.
00843 
00844    XCloseDisplay(fDisplay);
00845    fDisplay = 0;
00846 }
00847 
00848 //______________________________________________________________________________
00849 Display_t TGX11::GetDisplay() const
00850 {
00851    // Returns handle to display (might be usefull in some cases where
00852    // direct X11 manipulation outside of TVirtualX is needed, e.g. GL
00853    // interface).
00854 
00855    return (Display_t) fDisplay;
00856 }
00857 
00858 //______________________________________________________________________________
00859 Visual_t TGX11::GetVisual() const
00860 {
00861    // Returns handle to visual (might be usefull in some cases where
00862    // direct X11 manipulation outside of TVirtualX is needed, e.g. GL
00863    // interface).
00864 
00865    return (Visual_t) fVisual;
00866 }
00867 
00868 //______________________________________________________________________________
00869 Colormap_t TGX11::GetColormap() const
00870 {
00871    // Returns handle to colormap (might be usefull in some cases where
00872    // direct X11 manipulation outside of TVirtualX is needed, e.g. GL
00873    // interface).
00874 
00875    return (Colormap_t) fColormap;
00876 }
00877 
00878 //______________________________________________________________________________
00879 Int_t TGX11::GetScreen() const
00880 {
00881    // Returns screen number (might be usefull in some cases where
00882    // direct X11 manipulation outside of TVirtualX is needed, e.g. GL
00883    // interface).
00884 
00885    return fScreenNumber;
00886 }
00887 
00888 //______________________________________________________________________________
00889 Int_t TGX11::GetDepth() const
00890 {
00891    // Returns depth of screen (number of bit planes). Equivalent to
00892    // GetPlanes().
00893 
00894    return fDepth;
00895 }
00896 
00897 //______________________________________________________________________________
00898 Atom_t TGX11::InternAtom(const char *atom_name, Bool_t only_if_exist)
00899 {
00900    // Return atom handle for atom_name. If it does not exist
00901    // create it if only_if_exist is false. Atoms are used to communicate
00902    // between different programs (i.e. window manager) via the X server.
00903 
00904    Atom a = XInternAtom(fDisplay, (char *)atom_name, (Bool)only_if_exist);
00905 
00906    if (a == None) return kNone;
00907    return (Atom_t) a;
00908 }
00909 
00910 //______________________________________________________________________________
00911 Window_t TGX11::GetDefaultRootWindow() const
00912 {
00913    // Return handle to the default root window created when calling
00914    // XOpenDisplay().
00915 
00916    return (Window_t) fRootWin;
00917 }
00918 
00919 //______________________________________________________________________________
00920 Window_t TGX11::GetParent(Window_t id) const
00921 {
00922    // Return the parent of the window.
00923 
00924    if (!id) return (Window_t)0;
00925 
00926    Window  root, parent;
00927    Window *children = 0;
00928    UInt_t  nchildren;
00929 
00930    XQueryTree(fDisplay, (Window) id, &root, &parent, &children, &nchildren);
00931 
00932    if (children) XFree(children);
00933 
00934    return (Window_t) parent;
00935 }
00936 
00937 
00938 //______________________________________________________________________________
00939 FontStruct_t TGX11::LoadQueryFont(const char *font_name)
00940 {
00941    // Load font and query font. If font is not found 0 is returned,
00942    // otherwise an opaque pointer to the FontStruct_t.
00943    // Free the loaded font using DeleteFont().
00944 
00945    XFontStruct *fs = XLoadQueryFont(fDisplay, (char *)font_name);
00946    return (FontStruct_t) fs;
00947 }
00948 
00949 //______________________________________________________________________________
00950 FontH_t TGX11::GetFontHandle(FontStruct_t fs)
00951 {
00952    // Return handle to font described by font structure.
00953 
00954    if (fs) {
00955       XFontStruct *fss = (XFontStruct *)fs;
00956       return fss->fid;
00957    }
00958    return 0;
00959 }
00960 
00961 //______________________________________________________________________________
00962 void TGX11::DeleteFont(FontStruct_t fs)
00963 {
00964    // Explicitely delete font structure obtained with LoadQueryFont().
00965 
00966    if (fDisplay) XFreeFont(fDisplay, (XFontStruct *) fs);
00967 }
00968 
00969 //______________________________________________________________________________
00970 GContext_t TGX11::CreateGC(Drawable_t id, GCValues_t *gval)
00971 {
00972    // Create a graphics context using the values set in gval (but only for
00973    // those entries that are in the mask).
00974 
00975    XGCValues xgval;
00976    ULong_t   xmask = 0;
00977 
00978    if (gval)
00979       MapGCValues(*gval, xmask, xgval);
00980 
00981    if (!id || ((Drawable) id == fRootWin))
00982       id = (Drawable_t) fVisRootWin;
00983 
00984    GC gc = XCreateGC(fDisplay, (Drawable) id, xmask, &xgval);
00985 
00986    return (GContext_t) gc;
00987 }
00988 
00989 //______________________________________________________________________________
00990 void TGX11::ChangeGC(GContext_t gc, GCValues_t *gval)
00991 {
00992    // Change entries in an existing graphics context, gc, by values from gval.
00993 
00994    XGCValues xgval;
00995    ULong_t   xmask = 0;
00996 
00997    if (gval)
00998       MapGCValues(*gval, xmask, xgval);
00999 
01000    XChangeGC(fDisplay, (GC) gc, xmask, &xgval);
01001 }
01002 
01003 //______________________________________________________________________________
01004 void TGX11::CopyGC(GContext_t org, GContext_t dest, Mask_t mask)
01005 {
01006    // Copies graphics context from org to dest. Only the values specified
01007    // in mask are copied. If mask = 0 then copy all fields. Both org and
01008    // dest must exist.
01009 
01010    GCValues_t gval;
01011    XGCValues  xgval;
01012    ULong_t    xmask;
01013 
01014    if (!mask) {
01015       // in this case copy all fields
01016       mask = kMaxUInt;
01017    }
01018 
01019    gval.fMask = mask;  // only set fMask used to convert to xmask
01020    MapGCValues(gval, xmask, xgval);
01021 
01022    XCopyGC(fDisplay, (GC) org, xmask, (GC) dest);
01023 }
01024 
01025 //______________________________________________________________________________
01026 void TGX11::DeleteGC(GContext_t gc)
01027 {
01028    // Explicitely delete a graphics context.
01029 
01030    // Protection against deletion of global TGGC objects, which are
01031    // destructed after fDisplay has been closed.
01032    if (fDisplay)
01033       XFreeGC(fDisplay, (GC) gc);
01034 }
01035 
01036 //______________________________________________________________________________
01037 Cursor_t TGX11::CreateCursor(ECursor cursor)
01038 {
01039    // Create cursor handle (just return cursor from cursor pool fCursors).
01040 
01041    return (Cursor_t) fCursors[cursor];
01042 }
01043 
01044 //______________________________________________________________________________
01045 void TGX11::SetCursor(Window_t id, Cursor_t curid)
01046 {
01047    // Set the specified cursor.
01048 
01049    if (!id) return;
01050 
01051    XDefineCursor(fDisplay, (Window) id, (Cursor) curid);
01052 }
01053 
01054 //______________________________________________________________________________
01055 Pixmap_t TGX11::CreatePixmap(Drawable_t id, UInt_t w, UInt_t h)
01056 {
01057    // Creates a pixmap of the width and height you specified
01058    // and returns a pixmap ID that identifies it.
01059 
01060    return (Pixmap_t) XCreatePixmap(fDisplay, (Drawable) (id ? id : fRootWin), w, h, fDepth);
01061 }
01062 
01063 //______________________________________________________________________________
01064 Pixmap_t TGX11::CreatePixmap(Drawable_t id, const char *bitmap,
01065             UInt_t width, UInt_t height, ULong_t forecolor, ULong_t backcolor,
01066             Int_t depth)
01067 {
01068    // Create a pixmap from bitmap data. Ones will get foreground color and
01069    // zeroes background color.
01070 
01071    return (Pixmap_t) XCreatePixmapFromBitmapData(fDisplay, (id ? id : fRootWin), (char *)bitmap,
01072                            width, height, forecolor, backcolor, depth);
01073 }
01074 
01075 //______________________________________________________________________________
01076 Pixmap_t TGX11::CreateBitmap(Drawable_t id, const char *bitmap,
01077                              UInt_t width, UInt_t height)
01078 {
01079    // Create a bitmap (i.e. pixmap with depth 1) from the bitmap data.
01080 
01081    return (Pixmap_t) XCreateBitmapFromData(fDisplay, (id ? id : fRootWin), (char *)bitmap,
01082                                            width, height);
01083 }
01084 
01085 //______________________________________________________________________________
01086 void TGX11::DeletePixmap(Pixmap_t pmap)
01087 {
01088    // Explicitely delete pixmap resource.
01089 
01090    if (fDisplay) XFreePixmap(fDisplay, (Pixmap) pmap);
01091 }
01092 
01093 //______________________________________________________________________________
01094 void TGX11::MapPictureAttributes(PictureAttributes_t &attr, XpmAttributes &xpmattr,
01095                                  Bool_t toxpm)
01096 {
01097    // Map a PictureAttributes_t to a XpmAttributes structure. If toxpm is
01098    // kTRUE map from attr to xpmattr, else map the other way.
01099 
01100 #ifdef XpmVersion
01101    if (toxpm) {
01102       Mask_t  mask = attr.fMask;
01103       ULong_t xmask = 0;
01104 
01105       if ((mask & kPAColormap)) {
01106          xmask |= XpmColormap;
01107          xpmattr.colormap = (Colormap)attr.fColormap;
01108       }
01109       if ((mask & kPADepth)) {
01110          xmask |= XpmDepth;
01111          xpmattr.depth = attr.fDepth;
01112       }
01113       if ((mask & kPASize)) {
01114          xmask |= XpmSize;
01115          xpmattr.width  = attr.fWidth;
01116          xpmattr.height = attr.fHeight;
01117       }
01118       if ((mask & kPAHotspot)) {
01119          xmask |= XpmHotspot;
01120          xpmattr.x_hotspot = attr.fXHotspot;
01121          xpmattr.y_hotspot = attr.fYHotspot;
01122       }
01123       if ((mask & kPAReturnPixels)) {
01124          xmask |= XpmReturnPixels;
01125          xpmattr.pixels  = 0;  // output parameters
01126          xpmattr.npixels = 0;
01127       }
01128       if ((mask & kPACloseness)) {
01129          xmask |= XpmCloseness;
01130          xpmattr.closeness = attr.fCloseness;
01131       }
01132       xpmattr.valuemask = xmask;
01133    } else {
01134       ULong_t xmask = xpmattr.valuemask;
01135       Mask_t  mask  = 0;
01136 
01137       attr.fPixels  = 0;
01138       attr.fNpixels = 0;
01139 
01140       if ((xmask & XpmColormap)) {
01141          mask |= kPAColormap;
01142          attr.fColormap = (Colormap_t)xpmattr.colormap;
01143          mask |= kPADepth;
01144          attr.fDepth = xpmattr.depth;
01145       }
01146       if ((xmask & XpmSize)) {
01147          mask |= kPASize;
01148          attr.fWidth  = xpmattr.width;
01149          attr.fHeight = xpmattr.height;
01150       }
01151       if ((xmask & XpmHotspot)) {
01152          mask |= kPAHotspot;
01153          attr.fXHotspot = xpmattr.x_hotspot;
01154          attr.fYHotspot = xpmattr.y_hotspot;
01155       }
01156       if ((xmask & XpmReturnPixels)) {
01157          mask |= kPAReturnPixels;
01158          if (xpmattr.npixels) {
01159             attr.fPixels = new ULong_t[xpmattr.npixels];
01160             for (UInt_t i = 0; i < xpmattr.npixels; i++)
01161                attr.fPixels[i] = xpmattr.pixels[i];
01162             attr.fNpixels = xpmattr.npixels;
01163          }
01164       }
01165       if ((xmask & XpmCloseness)) {
01166          mask |= kPACloseness;
01167          attr.fCloseness = xpmattr.closeness;
01168       }
01169       attr.fMask = mask;
01170    }
01171 #endif
01172 }
01173 
01174 //______________________________________________________________________________
01175 Bool_t TGX11::CreatePictureFromFile(Drawable_t id, const char *filename,
01176                                     Pixmap_t &pict, Pixmap_t &pict_mask,
01177                                     PictureAttributes_t &attr)
01178 {
01179    // Create a picture pixmap from data on file. The picture attributes
01180    // are used for input and output. Returns kTRUE in case of success,
01181    // kFALSE otherwise. If mask does not exist it is set to kNone.
01182 
01183    if (strstr(filename, ".gif") || strstr(filename, ".GIF")) {
01184       pict = ReadGIF(0, 0, filename, id);
01185       pict_mask = kNone;
01186       attr.fDepth = fDepth;
01187       Int_t dummy;
01188       GetWindowSize(pict, dummy, dummy, attr.fWidth, attr.fHeight);
01189       return kTRUE;
01190    }
01191 
01192 #ifdef XpmVersion
01193    XpmAttributes xpmattr;
01194 
01195    MapPictureAttributes(attr, xpmattr);
01196 
01197    // make sure pixel depth of pixmap is the same as in the visual
01198    if ((Drawable) id == fRootWin && fRootWin != fVisRootWin) {
01199       xpmattr.valuemask |= XpmDepth;
01200       xpmattr.depth = fDepth;
01201    }
01202 
01203    Int_t res = XpmReadFileToPixmap(fDisplay, (id ? id : fRootWin), (char*)filename,
01204                                    (Pixmap*)&pict, (Pixmap*)&pict_mask, &xpmattr);
01205 
01206    MapPictureAttributes(attr, xpmattr, kFALSE);
01207    XpmFreeAttributes(&xpmattr);
01208 
01209    if (res == XpmSuccess || res == XpmColorError)
01210       return kTRUE;
01211 
01212    if (pict) {
01213       XFreePixmap(fDisplay, (Pixmap)pict);
01214       pict = kNone;
01215    }
01216    if (pict_mask) {
01217       XFreePixmap(fDisplay, (Pixmap)pict_mask);
01218       pict_mask = kNone;
01219    }
01220 #else
01221    Error("CreatePictureFromFile", "cannot get picture, not compiled with Xpm");
01222 #endif
01223 
01224    return kFALSE;
01225 }
01226 
01227 //______________________________________________________________________________
01228 Bool_t TGX11::CreatePictureFromData(Drawable_t id, char **data, Pixmap_t &pict,
01229                                     Pixmap_t &pict_mask, PictureAttributes_t &attr)
01230 {
01231    // Create a pixture pixmap from data. The picture attributes
01232    // are used for input and output. Returns kTRUE in case of success,
01233    // kFALSE otherwise. If mask does not exist it is set to kNone.
01234 
01235 #ifdef XpmVersion
01236    XpmAttributes xpmattr;
01237 
01238    MapPictureAttributes(attr, xpmattr);
01239 
01240    // make sure pixel depth of pixmap is the same as in the visual
01241    if ((Drawable) id == fRootWin && fRootWin != fVisRootWin) {
01242       xpmattr.valuemask |= XpmDepth;
01243       xpmattr.depth = fDepth;
01244    }
01245 
01246    Int_t res = XpmCreatePixmapFromData(fDisplay, (id ? id : fRootWin), data, (Pixmap*)&pict,
01247                                        (Pixmap*)&pict_mask, &xpmattr);
01248 
01249    MapPictureAttributes(attr, xpmattr, kFALSE);
01250    XpmFreeAttributes(&xpmattr);
01251 
01252    if (res == XpmSuccess || res == XpmColorError)
01253       return kTRUE;
01254 
01255    if (pict) {
01256       XFreePixmap(fDisplay, (Pixmap)pict);
01257       pict = kNone;
01258    }
01259    if (pict_mask) {
01260       XFreePixmap(fDisplay, (Pixmap)pict_mask);
01261       pict_mask = kNone;
01262    }
01263 #else
01264    Error("CreatePictureFromData", "cannot get picture, not compiled with Xpm");
01265 #endif
01266 
01267    return kFALSE;
01268 }
01269 
01270 //______________________________________________________________________________
01271 Bool_t TGX11::ReadPictureDataFromFile(const char *filename, char ***ret_data)
01272 {
01273    // Read picture data from file and store in ret_data. Returns kTRUE in
01274    // case of success, kFALSE otherwise.
01275 
01276 #ifdef XpmVersion
01277    if (XpmReadFileToData((char*)filename, ret_data) == XpmSuccess)
01278       return kTRUE;
01279 #else
01280    Error("ReadPictureFromDataFile", "cannot get picture, not compiled with Xpm");
01281 #endif
01282    return kFALSE;
01283 }
01284 
01285 //______________________________________________________________________________
01286 void TGX11::DeletePictureData(void *data)
01287 {
01288    // Delete picture data created by the function ReadPictureDataFromFile.
01289 
01290 #ifdef XpmVersion
01291    // some older libXpm's don't have this function and it is typically
01292    // implemented with a simple free()
01293    // XpmFree(data);
01294    free(data);
01295 #endif
01296 }
01297 
01298 //______________________________________________________________________________
01299 void TGX11::SetDashes(GContext_t gc, Int_t offset, const char *dash_list, Int_t n)
01300 {
01301    // Specify a dash pattertn. Offset defines the phase of the pattern.
01302    // Each element in the dash_list array specifies the length (in pixels)
01303    // of a segment of the pattern. N defines the length of the list.
01304 
01305    XSetDashes(fDisplay, (GC) gc, offset, (char *)dash_list, n);
01306 }
01307 
01308 //______________________________________________________________________________
01309 void TGX11::MapColorStruct(ColorStruct_t *color, XColor &xcolor)
01310 {
01311    // Map a ColorStruct_t to a XColor structure.
01312 
01313    xcolor.pixel = color->fPixel;
01314    xcolor.red   = color->fRed;
01315    xcolor.green = color->fGreen;
01316    xcolor.blue  = color->fBlue;
01317    xcolor.flags = color->fMask;  //ident mapping
01318 }
01319 
01320 //______________________________________________________________________________
01321 Bool_t TGX11::ParseColor(Colormap_t cmap, const char *cname, ColorStruct_t &color)
01322 {
01323    // Parse string cname containing color name, like "green" or "#00FF00".
01324    // It returns a filled in ColorStruct_t. Returns kFALSE in case parsing
01325    // failed, kTRUE in case of success. On success, the ColorStruct_t
01326    // fRed, fGreen and fBlue fields are all filled in and the mask is set
01327    // for all three colors, but fPixel is not set.
01328 
01329    XColor xc;
01330 
01331    if (XParseColor(fDisplay, (Colormap)cmap, (char *)cname, &xc)) {
01332       color.fPixel = 0;
01333       color.fRed   = xc.red;
01334       color.fGreen = xc.green;
01335       color.fBlue  = xc.blue;
01336       color.fMask  = kDoRed | kDoGreen | kDoBlue;
01337       return kTRUE;
01338    }
01339    return kFALSE;
01340 }
01341 
01342 //______________________________________________________________________________
01343 Bool_t TGX11::AllocColor(Colormap_t cmap, ColorStruct_t &color)
01344 {
01345    // Find and allocate a color cell according to the color values specified
01346    // in the ColorStruct_t. If no cell could be allocated it returns kFALSE,
01347    // otherwise kTRUE.
01348 
01349    XColor xc;
01350 
01351    MapColorStruct(&color, xc);
01352 
01353    color.fPixel = 0;
01354    if (AllocColor((Colormap)cmap, &xc)) {
01355       color.fPixel = xc.pixel;
01356       return kTRUE;
01357    }
01358 
01359    return kFALSE;
01360 }
01361 
01362 //______________________________________________________________________________
01363 void TGX11::QueryColor(Colormap_t cmap, ColorStruct_t &color)
01364 {
01365    // Fill in the primary color components for a specific pixel value.
01366    // On input fPixel should be set on return the fRed, fGreen and
01367    // fBlue components will be set.
01368 
01369    XColor xc;
01370 
01371    xc.pixel = color.fPixel;
01372 
01373    // still very slight dark shift ??
01374    //QueryColors((Colormap)cmap, &xc, 1);
01375    //printf("1 xc.red = %u, xc.green = %u, xc.blue = %u\n", xc.red, xc.green, xc.blue);
01376    XQueryColor(fDisplay, (Colormap)cmap, &xc);
01377    //printf("2 xc.red = %u, xc.green = %u, xc.blue = %u\n", xc.red, xc.green, xc.blue);
01378 
01379    color.fRed   = xc.red;
01380    color.fGreen = xc.green;
01381    color.fBlue  = xc.blue;
01382 }
01383 
01384 //______________________________________________________________________________
01385 void TGX11::FreeColor(Colormap_t cmap, ULong_t pixel)
01386 {
01387    // Free color cell with specified pixel value.
01388 
01389    if (fRedDiv == -1)
01390       XFreeColors(fDisplay, (Colormap)cmap, &pixel, 1, 0);
01391 }
01392 
01393 //______________________________________________________________________________
01394 Int_t TGX11::EventsPending()
01395 {
01396    // Returns number of pending events.
01397 
01398    if (!fDisplay) return 0;
01399    return XPending(fDisplay);
01400 }
01401 
01402 //______________________________________________________________________________
01403 void TGX11::NextEvent(Event_t &event)
01404 {
01405    // Copies first pending event from event queue to Event_t structure
01406    // and removes event from queue. Not all of the event fields are valid
01407    // for each event type, except fType and fWindow.
01408 
01409    XNextEvent(fDisplay, fXEvent);
01410 
01411    // fill in Event_t
01412    MapEvent(event, *fXEvent, kFALSE);
01413 }
01414 
01415 //______________________________________________________________________________
01416 void TGX11::MapModifierState(UInt_t &state, UInt_t &xstate, Bool_t tox)
01417 {
01418    // Map modifier key state to or from X.
01419 
01420    if (tox) {
01421       xstate = 0;
01422       if ((state & kKeyShiftMask))
01423          xstate |= ShiftMask;
01424       if ((state & kKeyLockMask))
01425          xstate |= LockMask;
01426       if ((state & kKeyControlMask))
01427          xstate |= ControlMask;
01428       if ((state & kKeyMod1Mask))
01429          xstate |= Mod1Mask;
01430       if ((state & kKeyMod2Mask))
01431          xstate |= Mod2Mask;
01432       if ((state & kKeyMod3Mask))
01433          xstate |= Mod3Mask;
01434       if ((state & kKeyMod4Mask))
01435          xstate |= Mod4Mask;
01436       if ((state & kKeyMod5Mask))
01437          xstate |= Mod5Mask;
01438       if ((state & kButton1Mask))
01439          xstate |= Button1Mask;
01440       if ((state & kButton2Mask))
01441          xstate |= Button2Mask;
01442       if ((state & kButton3Mask))
01443          xstate |= Button3Mask;
01444       if ((state & kAnyModifier))
01445          xstate |= AnyModifier;      // or should it be = instead of |= ?
01446    } else {
01447       state = 0;
01448       if ((xstate & ShiftMask))
01449          state |= kKeyShiftMask;
01450       if ((xstate & LockMask))
01451          state |= kKeyLockMask;
01452       if ((xstate & ControlMask))
01453          state |= kKeyControlMask;
01454       if ((xstate & Mod1Mask))
01455          state |= kKeyMod1Mask;
01456       if ((xstate & Mod2Mask))
01457          state |= kKeyMod2Mask;
01458       if ((xstate & Mod3Mask))
01459          state |= kKeyMod3Mask;
01460       if ((xstate & Mod4Mask))
01461          state |= kKeyMod4Mask;
01462       if ((xstate & Mod5Mask))
01463          state |= kKeyMod5Mask;
01464       if ((xstate & Button1Mask))
01465          state |= kButton1Mask;
01466       if ((xstate & Button2Mask))
01467          state |= kButton2Mask;
01468       if ((xstate & Button3Mask))
01469          state |= kButton3Mask;
01470       if ((xstate & AnyModifier))
01471          state |= kAnyModifier;      // idem
01472    }
01473 }
01474 
01475 //______________________________________________________________________________
01476 void TGX11::MapEvent(Event_t &ev, XEvent &xev, Bool_t tox)
01477 {
01478    // Map Event_t structure to XEvent structure. If tox is false
01479    // map the other way.
01480 
01481    if (tox) {
01482       // map from Event_t to XEvent
01483       xev.type = 0;
01484       if (ev.fType == kGKeyPress)        xev.type = KeyPress;
01485       if (ev.fType == kKeyRelease)       xev.type = KeyRelease;
01486       if (ev.fType == kButtonPress)      xev.type = ButtonPress;
01487       if (ev.fType == kButtonRelease)    xev.type = ButtonRelease;
01488       if (ev.fType == kMotionNotify)     xev.type = MotionNotify;
01489       if (ev.fType == kEnterNotify)      xev.type = EnterNotify;
01490       if (ev.fType == kLeaveNotify)      xev.type = LeaveNotify;
01491       if (ev.fType == kFocusIn)          xev.type = FocusIn;
01492       if (ev.fType == kFocusOut)         xev.type = FocusOut;
01493       if (ev.fType == kExpose)           xev.type = Expose;
01494       if (ev.fType == kConfigureNotify)  xev.type = ConfigureNotify;
01495       if (ev.fType == kMapNotify)        xev.type = MapNotify;
01496       if (ev.fType == kUnmapNotify)      xev.type = UnmapNotify;
01497       if (ev.fType == kDestroyNotify)    xev.type = DestroyNotify;
01498       if (ev.fType == kClientMessage)    xev.type = ClientMessage;
01499       if (ev.fType == kSelectionClear)   xev.type = SelectionClear;
01500       if (ev.fType == kSelectionRequest) xev.type = SelectionRequest;
01501       if (ev.fType == kSelectionNotify)  xev.type = SelectionNotify;
01502       if (ev.fType == kColormapNotify)   xev.type = ColormapNotify;
01503 
01504       xev.xany.window     = (Window) ev.fWindow;
01505       xev.xany.send_event = (Bool) ev.fSendEvent;
01506       xev.xany.display    = fDisplay;
01507 
01508       if (ev.fType == kGKeyPress || ev.fType == kKeyRelease) {
01509          xev.xkey.time   = (Time) ev.fTime;
01510          xev.xkey.x      = ev.fX;
01511          xev.xkey.y      = ev.fY;
01512          xev.xkey.x_root = ev.fXRoot;
01513          xev.xkey.y_root = ev.fYRoot;
01514          MapModifierState(ev.fState, xev.xkey.state, kTRUE); // key mask
01515          xev.xkey.keycode = ev.fCode;    // key code
01516       }
01517       if (ev.fType == kSelectionNotify) {
01518          xev.xselection.time      = (Time) ev.fTime;
01519          xev.xselection.requestor = (Window) ev.fUser[0];
01520          xev.xselection.selection = (Atom) ev.fUser[1];
01521          xev.xselection.target    = (Atom) ev.fUser[2];
01522          xev.xselection.property  = (Atom) ev.fUser[3];
01523       }
01524       if (ev.fType == kClientMessage) {
01525          xev.xclient.message_type = ev.fHandle;
01526          xev.xclient.format       = ev.fFormat;
01527          xev.xclient.data.l[0]    = ev.fUser[0];
01528          if (sizeof(ev.fUser[0]) > 4) {
01529             SplitLong(ev.fUser[1], xev.xclient.data.l[1], xev.xclient.data.l[3]);
01530             SplitLong(ev.fUser[2], xev.xclient.data.l[2], xev.xclient.data.l[4]);
01531          } else {
01532             xev.xclient.data.l[1]    = ev.fUser[1];
01533             xev.xclient.data.l[2]    = ev.fUser[2];
01534             xev.xclient.data.l[3]    = ev.fUser[3];
01535             xev.xclient.data.l[4]    = ev.fUser[4];
01536          }
01537       }
01538    } else {
01539       // map from XEvent to Event_t
01540       ev.fType = kOtherEvent;
01541       if (xev.type == KeyPress)         ev.fType = kGKeyPress;
01542       if (xev.type == KeyRelease)       ev.fType = kKeyRelease;
01543       if (xev.type == ButtonPress)      ev.fType = kButtonPress;
01544       if (xev.type == ButtonRelease)    ev.fType = kButtonRelease;
01545       if (xev.type == MotionNotify)     ev.fType = kMotionNotify;
01546       if (xev.type == EnterNotify)      ev.fType = kEnterNotify;
01547       if (xev.type == LeaveNotify)      ev.fType = kLeaveNotify;
01548       if (xev.type == FocusIn)          ev.fType = kFocusIn;
01549       if (xev.type == FocusOut)         ev.fType = kFocusOut;
01550       if (xev.type == Expose)           ev.fType = kExpose;
01551       if (xev.type == GraphicsExpose)   ev.fType = kExpose;
01552       if (xev.type == ConfigureNotify)  ev.fType = kConfigureNotify;
01553       if (xev.type == MapNotify)        ev.fType = kMapNotify;
01554       if (xev.type == UnmapNotify)      ev.fType = kUnmapNotify;
01555       if (xev.type == DestroyNotify)    ev.fType = kDestroyNotify;
01556       if (xev.type == ClientMessage)    ev.fType = kClientMessage;
01557       if (xev.type == SelectionClear)   ev.fType = kSelectionClear;
01558       if (xev.type == SelectionRequest) ev.fType = kSelectionRequest;
01559       if (xev.type == SelectionNotify)  ev.fType = kSelectionNotify;
01560       if (xev.type == ColormapNotify)   ev.fType = kColormapNotify;
01561 
01562       ev.fWindow    = (Window_t) xev.xany.window;
01563       ev.fSendEvent = xev.xany.send_event ? kTRUE : kFALSE;
01564 
01565       if (ev.fType == kGKeyPress || ev.fType == kKeyRelease) {
01566          ev.fTime      = (Time_t) xev.xkey.time;
01567          ev.fX         = xev.xkey.x;
01568          ev.fY         = xev.xkey.y;
01569          ev.fXRoot     = xev.xkey.x_root;
01570          ev.fYRoot     = xev.xkey.y_root;
01571          MapModifierState(ev.fState, xev.xkey.state, kFALSE); // key mask
01572          ev.fCode      = xev.xkey.keycode;    // key code
01573          ev.fUser[0]   = xev.xkey.subwindow;  // child window
01574       }
01575       if (ev.fType == kButtonPress || ev.fType == kButtonRelease) {
01576          ev.fTime      = (Time_t) xev.xbutton.time;
01577          ev.fX         = xev.xbutton.x;
01578          ev.fY         = xev.xbutton.y;
01579          ev.fXRoot     = xev.xbutton.x_root;
01580          ev.fYRoot     = xev.xbutton.y_root;
01581          MapModifierState(ev.fState, xev.xbutton.state, kFALSE); // button mask
01582          ev.fCode      = xev.xbutton.button;    // button code
01583          ev.fUser[0]   = xev.xbutton.subwindow; // child window
01584       }
01585       if (ev.fType == kMotionNotify) {
01586          ev.fTime      = (Time_t) xev.xmotion.time;
01587          ev.fX         = xev.xmotion.x;
01588          ev.fY         = xev.xmotion.y;
01589          ev.fXRoot     = xev.xmotion.x_root;
01590          ev.fYRoot     = xev.xmotion.y_root;
01591          MapModifierState(ev.fState, xev.xmotion.state, kFALSE); // key or button mask
01592          ev.fUser[0]   = xev.xmotion.subwindow; // child window
01593       }
01594       if (ev.fType == kEnterNotify || ev.fType == kLeaveNotify) {
01595          ev.fTime      = (Time_t) xev.xcrossing.time;
01596          ev.fX         = xev.xcrossing.x;
01597          ev.fY         = xev.xcrossing.y;
01598          ev.fXRoot     = xev.xcrossing.x_root;
01599          ev.fYRoot     = xev.xcrossing.y_root;
01600          ev.fCode      = xev.xcrossing.mode; // NotifyNormal, NotifyGrab, NotifyUngrab
01601          MapModifierState(ev.fState, xev.xcrossing.state, kFALSE); // key or button mask
01602       }
01603       if (ev.fType == kFocusIn || ev.fType == kFocusOut) {
01604          // check this when porting to Win32 (see also TGTextEntry::HandleFocusChange)
01605          ev.fCode      = xev.xfocus.mode; // NotifyNormal, NotifyGrab, NotifyUngrab
01606          ev.fState     = xev.xfocus.detail; // NotifyPointer et al.
01607       }
01608       if (ev.fType == kExpose) {
01609          ev.fX         = xev.xexpose.x;
01610          ev.fY         = xev.xexpose.y;
01611          ev.fWidth     = xev.xexpose.width;   // width and
01612          ev.fHeight    = xev.xexpose.height;  // height of exposed area
01613          ev.fCount     = xev.xexpose.count;   // number of expose events still to come
01614       }
01615       if (ev.fType == kConfigureNotify) {
01616          ev.fX         = xev.xconfigure.x;
01617          ev.fY         = xev.xconfigure.y;
01618          ev.fWidth     = xev.xconfigure.width;
01619          ev.fHeight    = xev.xconfigure.height;
01620       }
01621       if (ev.fType == kMapNotify || ev.fType == kUnmapNotify) {
01622          ev.fHandle = xev.xmap.window;  // window to be (un)mapped
01623       }
01624       if (ev.fType == kDestroyNotify) {
01625          ev.fHandle = xev.xdestroywindow.window;  // window to be destroyed
01626       }
01627       if (ev.fType == kClientMessage) {
01628          ev.fHandle  = xev.xclient.message_type;
01629          ev.fFormat  = xev.xclient.format;
01630          ev.fUser[0] = xev.xclient.data.l[0];
01631          if (sizeof(ev.fUser[0]) > 4) {
01632             AsmLong(xev.xclient.data.l[1], xev.xclient.data.l[3], ev.fUser[1]);
01633             AsmLong(xev.xclient.data.l[2], xev.xclient.data.l[4], ev.fUser[2]);
01634          } else {
01635             ev.fUser[1] = xev.xclient.data.l[1];
01636             ev.fUser[2] = xev.xclient.data.l[2];
01637             ev.fUser[3] = xev.xclient.data.l[3];
01638             ev.fUser[4] = xev.xclient.data.l[4];
01639          }
01640       }
01641       if (ev.fType == kSelectionClear) {
01642          ev.fUser[0] = xev.xselectionclear.selection;
01643       }
01644       if (ev.fType == kSelectionRequest) {
01645          ev.fTime    = (Time_t) xev.xselectionrequest.time;
01646          ev.fUser[0] = xev.xselectionrequest.requestor;
01647          ev.fUser[1] = xev.xselectionrequest.selection;
01648          ev.fUser[2] = xev.xselectionrequest.target;
01649          ev.fUser[3] = xev.xselectionrequest.property;
01650       }
01651       if (ev.fType == kSelectionNotify) {
01652          ev.fTime    = (Time_t) xev.xselection.time;
01653          ev.fUser[0] = xev.xselection.requestor;
01654          ev.fUser[1] = xev.xselection.selection;
01655          ev.fUser[2] = xev.xselection.target;
01656          ev.fUser[3] = xev.xselection.property;
01657       }
01658       if (ev.fType == kColormapNotify) {
01659          ev.fHandle = xev.xcolormap.colormap;
01660          ev.fCode   = xev.xcolormap.state; // ColormapUninstalled, ColormapInstalled
01661          ev.fState  = xev.xcolormap.c_new; // true if new colormap
01662       }
01663    }
01664 }
01665 
01666 //______________________________________________________________________________
01667 void TGX11::Bell(Int_t percent)
01668 {
01669    // Sound bell. Percent is loudness from -100% .. 100%.
01670 
01671    XBell(fDisplay, percent);
01672 }
01673 
01674 //______________________________________________________________________________
01675 void TGX11::CopyArea(Drawable_t src, Drawable_t dest, GContext_t gc,
01676                      Int_t src_x, Int_t src_y, UInt_t width, UInt_t height,
01677                      Int_t dest_x, Int_t dest_y)
01678 {
01679    // Copy a drawable (i.e. pixmap) to another drawable (pixmap, window).
01680    // The graphics context gc will be used and the source will be copied
01681    // from src_x,src_y,src_x+width,src_y+height to dest_x,dest_y.
01682 
01683    if (!src || !dest) return;
01684 
01685    XCopyArea(fDisplay, src, dest, (GC) gc, src_x, src_y, width, height,
01686              dest_x, dest_y);
01687 }
01688 
01689 //______________________________________________________________________________
01690 void TGX11::ChangeWindowAttributes(Window_t id, SetWindowAttributes_t *attr)
01691 {
01692    // Change window attributes.
01693 
01694    if (!id) return;
01695 
01696    XSetWindowAttributes xattr;
01697    ULong_t              xmask = 0;
01698 
01699    if (attr)
01700       MapSetWindowAttributes(attr, xmask, xattr);
01701 
01702    XChangeWindowAttributes(fDisplay, (Window) id, xmask, &xattr);
01703 
01704    if (attr && (attr->fMask & kWABorderWidth))
01705       XSetWindowBorderWidth(fDisplay, (Window) id, attr->fBorderWidth);
01706 }
01707 
01708 //______________________________________________________________________________
01709 void TGX11::ChangeProperty(Window_t id, Atom_t property, Atom_t type,
01710                            UChar_t *data, Int_t len)
01711 {
01712    // This function alters the property for the specified window and
01713    // causes the X server to generate a PropertyNotify event on that
01714    // window.
01715 
01716    if (!id) return;
01717 
01718    XChangeProperty(fDisplay, (Window) id, (Atom) property, (Atom) type,
01719                    8, PropModeReplace, data, len);
01720 }
01721 
01722 //______________________________________________________________________________
01723 void TGX11::DrawLine(Drawable_t id, GContext_t gc, Int_t x1, Int_t y1, Int_t x2, Int_t y2)
01724 {
01725    // Draw a line.
01726 
01727    if (!id) return;
01728 
01729    XDrawLine(fDisplay, (Drawable) id, (GC) gc, x1, y1, x2, y2);
01730 }
01731 
01732 //______________________________________________________________________________
01733 void TGX11::ClearArea(Window_t id, Int_t x, Int_t y, UInt_t w, UInt_t h)
01734 {
01735    // Clear a window area to the bakcground color.
01736 
01737    if (!id) return;
01738 
01739    XClearArea(fDisplay, (Window) id, x, y, w, h, False);
01740 }
01741 
01742 //______________________________________________________________________________
01743 Bool_t TGX11::CheckEvent(Window_t id, EGEventType type, Event_t &ev)
01744 {
01745    // Check if there is for window "id" an event of type "type". If there
01746    // is fill in the event structure and return true. If no such event
01747    // return false.
01748 
01749    if (!id) return kFALSE;
01750 
01751    Event_t tev;
01752    XEvent  xev;
01753 
01754    tev.fType = type;
01755    MapEvent(tev, xev);
01756 
01757    Bool r = XCheckTypedWindowEvent(fDisplay, (Window) id, xev.type, &xev);
01758 
01759    if (r)
01760       MapEvent(ev, xev, kFALSE);
01761 
01762    return r ? kTRUE : kFALSE;
01763 }
01764 
01765 //______________________________________________________________________________
01766 void TGX11::SendEvent(Window_t id, Event_t *ev)
01767 {
01768    // Send event ev to window id.
01769 
01770    if (!ev || !id) return;
01771 
01772    XEvent xev;
01773 
01774    MapEvent(*ev, xev);
01775 
01776    XSendEvent(fDisplay, (Window) id, False, None, &xev);
01777 }
01778 
01779 //______________________________________________________________________________
01780 void TGX11::WMDeleteNotify(Window_t id)
01781 {
01782    // Tell WM to send message when window is closed via WM.
01783 
01784    if (!id) return;
01785 
01786    XSetWMProtocols(fDisplay, (Window) id, &gWM_DELETE_WINDOW, 1);
01787 }
01788 
01789 //______________________________________________________________________________
01790 void TGX11::SetKeyAutoRepeat(Bool_t on)
01791 {
01792    // Turn key auto repeat on or off.
01793 
01794    if (on)
01795       XAutoRepeatOn(fDisplay);
01796    else
01797       XAutoRepeatOff(fDisplay);
01798 }
01799 
01800 //______________________________________________________________________________
01801 void TGX11::GrabKey(Window_t id, Int_t keycode, UInt_t modifier, Bool_t grab)
01802 {
01803    // Establish passive grab on a certain key. That is, when a certain key
01804    // keycode is hit while certain modifier's (Shift, Control, Meta, Alt)
01805    // are active then the keyboard will be grabed for window id.
01806    // When grab is false, ungrab the keyboard for this key and modifier.
01807 
01808 //   if (!id) return;
01809 
01810    UInt_t xmod;
01811 
01812    MapModifierState(modifier, xmod);
01813 
01814    if (grab)
01815       XGrabKey(fDisplay, keycode, xmod, (Window) id, True,
01816                GrabModeAsync, GrabModeAsync);
01817    else
01818       XUngrabKey(fDisplay, keycode, xmod, (Window) id);
01819 }
01820 
01821 //______________________________________________________________________________
01822 void TGX11::GrabButton(Window_t id, EMouseButton button, UInt_t modifier,
01823                        UInt_t evmask, Window_t confine, Cursor_t cursor,
01824                        Bool_t grab)
01825 {
01826    // Establish passive grab on a certain mouse button. That is, when a
01827    // certain mouse button is hit while certain modifier's (Shift, Control,
01828    // Meta, Alt) are active then the mouse will be grabed for window id.
01829    // When grab is false, ungrab the mouse button for this button and modifier.
01830 
01831    if (!id) return;
01832 
01833    UInt_t xmod;
01834 
01835    MapModifierState(modifier, xmod);
01836 
01837    if (grab) {
01838       UInt_t xevmask;
01839       MapEventMask(evmask, xevmask);
01840 
01841       XGrabButton(fDisplay, button, xmod, (Window) id, True, xevmask,
01842                   GrabModeAsync, GrabModeAsync, (Window) confine,
01843                   (Cursor) cursor);
01844    } else
01845       XUngrabButton(fDisplay, button, xmod, (Window) id);
01846 }
01847 
01848 //______________________________________________________________________________
01849 void TGX11::GrabPointer(Window_t id, UInt_t evmask, Window_t confine,
01850                         Cursor_t cursor, Bool_t grab, Bool_t owner_events)
01851 {
01852    // Establish an active pointer grab. While an active pointer grab is in
01853    // effect, further pointer events are only reported to the grabbing
01854    // client window.
01855 
01856 //   if (!id) return;
01857 
01858    if (grab) {
01859       UInt_t xevmask;
01860       MapEventMask(evmask, xevmask);
01861 
01862       XGrabPointer(fDisplay, (Window) id, (Bool) owner_events,
01863                    xevmask, GrabModeAsync, GrabModeAsync, (Window) confine,
01864                    (Cursor) cursor, CurrentTime);
01865    } else
01866       XUngrabPointer(fDisplay, CurrentTime);
01867 }
01868 
01869 //______________________________________________________________________________
01870 void TGX11::SetWindowName(Window_t id, char *name)
01871 {
01872    // Set window name.
01873 
01874    if (!id) return;
01875 
01876    XTextProperty wname;
01877 
01878    if (XStringListToTextProperty(&name, 1, &wname) == 0) {
01879       Error("SetWindowName", "cannot allocate window name \"%s\"", name);
01880       return;
01881    }
01882    XSetWMName(fDisplay, (Window) id, &wname);
01883    XFree(wname.value);
01884 }
01885 
01886 //______________________________________________________________________________
01887 void TGX11::SetIconName(Window_t id, char *name)
01888 {
01889    // Set window icon name.
01890 
01891    if (!id) return;
01892 
01893    XTextProperty wname;
01894 
01895    if (XStringListToTextProperty(&name, 1, &wname) == 0) {
01896       Error("SetIconName", "cannot allocate icon name \"%s\"", name);
01897       return;
01898    }
01899    XSetWMIconName(fDisplay, (Window) id, &wname);
01900    XFree(wname.value);
01901 }
01902 
01903 //______________________________________________________________________________
01904 void TGX11::SetIconPixmap(Window_t id, Pixmap_t pic)
01905 {
01906    // Set pixmap the WM can use when the window is iconized.
01907 
01908    if (!id) return;
01909 
01910    XWMHints hints;
01911 
01912    hints.flags = IconPixmapHint;
01913    hints.icon_pixmap = (Pixmap) pic;
01914 
01915    XSetWMHints(fDisplay, (Window) id, &hints);
01916 }
01917 
01918 //______________________________________________________________________________
01919 void TGX11::SetClassHints(Window_t id, char *className, char *resourceName)
01920 {
01921    // Set the windows class and resource name.
01922 
01923    if (!id) return;
01924 
01925    XClassHint class_hints;
01926 
01927    class_hints.res_class = className;
01928    class_hints.res_name  = resourceName;
01929    XSetClassHint(fDisplay, (Window) id, &class_hints);
01930 }
01931 
01932 //______________________________________________________________________________
01933 void TGX11::SetMWMHints(Window_t id, UInt_t value, UInt_t funcs, UInt_t input)
01934 {
01935    // Set decoration style for MWM-compatible wm (mwm, ncdwm, fvwm?).
01936 
01937    if (!id) return;
01938 
01939    MWMHintsProperty_t prop;
01940 
01941    prop.fDecorations = value;
01942    prop.fFunctions   = funcs;
01943    prop.fInputMode   = input;
01944    prop.fFlags       = kMWMHintsDecorations | kMWMHintsFunctions | kMWMHintsInputMode;
01945 
01946    XChangeProperty(fDisplay, (Window) id, gMOTIF_WM_HINTS, gMOTIF_WM_HINTS, 32,
01947                    PropModeReplace, (UChar_t *)&prop, kPropMWMHintElements);
01948 }
01949 
01950 //______________________________________________________________________________
01951 void TGX11::SetWMPosition(Window_t id, Int_t x, Int_t y)
01952 {
01953    // Tell the window manager the desired window position.
01954 
01955    if (!id) return;
01956 
01957    XSizeHints hints;
01958 
01959    hints.flags = USPosition | PPosition;
01960    hints.x = x;
01961    hints.y = y;
01962 
01963    XSetWMNormalHints(fDisplay, (Window) id, &hints);
01964 }
01965 
01966 //______________________________________________________________________________
01967 void TGX11::SetWMSize(Window_t id, UInt_t w, UInt_t h)
01968 {
01969    // Tell the window manager the desired window size.
01970 
01971    if (!id) return;
01972 
01973    XSizeHints hints;
01974 
01975    hints.flags = USSize | PSize | PBaseSize;
01976    hints.width = hints.base_width = w;
01977    hints.height = hints.base_height = h;
01978 
01979    XSetWMNormalHints(fDisplay, (Window) id, &hints);
01980 }
01981 
01982 //______________________________________________________________________________
01983 void TGX11::SetWMSizeHints(Window_t id, UInt_t wmin, UInt_t hmin,
01984                            UInt_t wmax, UInt_t hmax,
01985                            UInt_t winc, UInt_t hinc)
01986 {
01987    // Give the window manager minimum and maximum size hints. Also
01988    // specify via winc and hinc the resize increments.
01989 
01990    if (!id) return;
01991 
01992    XSizeHints hints;
01993 
01994    hints.flags = PMinSize | PMaxSize | PResizeInc;
01995    hints.min_width   = (Int_t)wmin;
01996    hints.max_width   = (Int_t)wmax;
01997    hints.min_height  = (Int_t)hmin;
01998    hints.max_height  = (Int_t)hmax;
01999    hints.width_inc   = (Int_t)winc;
02000    hints.height_inc  = (Int_t)hinc;
02001 
02002    XSetWMNormalHints(fDisplay, (Window) id, &hints);
02003 }
02004 
02005 //______________________________________________________________________________
02006 void TGX11::SetWMState(Window_t id, EInitialState state)
02007 {
02008    // Set the initial state of the window. Either kNormalState or kIconicState.
02009 
02010    if (!id) return;
02011 
02012    XWMHints hints;
02013    Int_t    xstate = NormalState;
02014 
02015    if (state == kNormalState)
02016       xstate = NormalState;
02017    if (state == kIconicState)
02018       xstate = IconicState;
02019 
02020    hints.flags = StateHint;
02021    hints.initial_state = xstate;
02022 
02023    XSetWMHints(fDisplay, (Window) id, &hints);
02024 }
02025 
02026 //______________________________________________________________________________
02027 void TGX11::SetWMTransientHint(Window_t id, Window_t main_id)
02028 {
02029    // Tell window manager that window is a transient window of main.
02030 
02031    if (!id) return;
02032 
02033    XSetTransientForHint(fDisplay, (Window) id, (Window) main_id);
02034 }
02035 
02036 //______________________________________________________________________________
02037 void TGX11::DrawString(Drawable_t id, GContext_t gc, Int_t x, Int_t y,
02038                        const char *s, Int_t len)
02039 {
02040    // Draw a string using a specific graphics context in position (x,y).
02041 
02042    if (!id) return;
02043 
02044    XDrawString(fDisplay, (Drawable) id, (GC) gc, x, y, (char *) s, len);
02045 }
02046 
02047 //______________________________________________________________________________
02048 Int_t TGX11::TextWidth(FontStruct_t font, const char *s, Int_t len)
02049 {
02050    // Return lenght of string in pixels. Size depends on font.
02051 
02052    return XTextWidth((XFontStruct*) font, (char*) s, len);
02053 }
02054 
02055 //______________________________________________________________________________
02056 void TGX11::GetFontProperties(FontStruct_t font, Int_t &max_ascent, Int_t &max_descent)
02057 {
02058    // Return some font properties.
02059 
02060    XFontStruct *f = (XFontStruct *) font;
02061 
02062    max_ascent  = f->max_bounds.ascent;
02063    max_descent = f->max_bounds.descent;
02064 }
02065 
02066 //______________________________________________________________________________
02067 void TGX11::GetGCValues(GContext_t gc, GCValues_t &gval)
02068 {
02069    // Get current values from graphics context gc. Which values of the
02070    // context to get is encoded in the GCValues::fMask member. If fMask = 0
02071    // then copy all fields.
02072 
02073    XGCValues xgval;
02074    ULong_t   xmask;
02075 
02076    if (!gval.fMask) {
02077       // in this case copy all fields
02078       gval.fMask = kMaxUInt;
02079    }
02080 
02081    MapGCValues(gval, xmask, xgval);
02082 
02083    XGetGCValues(fDisplay, (GC) gc, xmask, &xgval);
02084 
02085    MapGCValues(gval, xmask, xgval, kFALSE);
02086 }
02087 
02088 //______________________________________________________________________________
02089 FontStruct_t TGX11::GetFontStruct(FontH_t fh)
02090 {
02091    // Retrieve associated font structure once we have the font handle.
02092    // Free returned FontStruct_t using FreeFontStruct().
02093 
02094    XFontStruct *fs;
02095 
02096    fs = XQueryFont(fDisplay, (Font) fh);
02097 
02098    return (FontStruct_t) fs;
02099 }
02100 
02101 //______________________________________________________________________________
02102 void TGX11::FreeFontStruct(FontStruct_t fs)
02103 {
02104    // Free font structure returned by GetFontStruct().
02105 
02106    // in XFree86 4.0 XFreeFontInfo() is broken, ok again in 4.0.1
02107    static int xfree86_400 = -1;
02108    if (xfree86_400 == -1) {
02109       if (strstr(XServerVendor(fDisplay), "XFree86") &&
02110           XVendorRelease(fDisplay) == 4000)
02111          xfree86_400 = 1;
02112       else
02113          xfree86_400 = 0;
02114       //printf("Vendor: %s, Release = %d\n", XServerVendor(fDisplay), XVendorRelease(fDisplay));
02115    }
02116 
02117    if (xfree86_400 == 0)
02118       XFreeFontInfo(0, (XFontStruct *) fs, 1);
02119 }
02120 
02121 //______________________________________________________________________________
02122 void TGX11::ClearWindow(Window_t id)
02123 {
02124    // Clear window.
02125 
02126    if (!id) return;
02127 
02128    XClearWindow(fDisplay, (Window) id);
02129 }
02130 
02131 //______________________________________________________________________________
02132 Int_t TGX11::KeysymToKeycode(UInt_t keysym)
02133 {
02134    // Convert a keysym to the appropriate keycode. For example keysym is
02135    // a letter and keycode is the matching keyboard key (which is dependend
02136    // on the current keyboard mapping).
02137 
02138    UInt_t xkeysym;
02139    MapKeySym(keysym, xkeysym);
02140 
02141    return XKeysymToKeycode(fDisplay, xkeysym);
02142 }
02143 
02144 //______________________________________________________________________________
02145 void TGX11::FillRectangle(Drawable_t id, GContext_t gc, Int_t x, Int_t y, UInt_t w, UInt_t h)
02146 {
02147    // Draw a filled rectangle. Filling is done according to the gc.
02148 
02149    if (!id) return;
02150 
02151    XFillRectangle(fDisplay, (Drawable) id, (GC) gc, x, y, w, h);
02152 }
02153 
02154 //______________________________________________________________________________
02155 void TGX11::DrawRectangle(Drawable_t id, GContext_t gc, Int_t x, Int_t y, UInt_t w, UInt_t h)
02156 {
02157    // Draw a rectangle outline.
02158 
02159    if (!id) return;
02160 
02161    XDrawRectangle(fDisplay, (Drawable) id, (GC) gc, x, y, w, h);
02162 }
02163 
02164 //______________________________________________________________________________
02165 void TGX11::DrawSegments(Drawable_t id, GContext_t gc, Segment_t *seg, Int_t nseg)
02166 {
02167    // Draws multiple line segments. Each line is specified by a pair of points.
02168 
02169    if (!id) return;
02170 
02171    XDrawSegments(fDisplay, (Drawable) id, (GC) gc, (XSegment *) seg, nseg);
02172 }
02173 
02174 //______________________________________________________________________________
02175 void TGX11::SelectInput(Window_t id, UInt_t evmask)
02176 {
02177    // Defines which input events the window is interested in. By default
02178    // events are propageted up the window stack. This mask can also be
02179    // set at window creation time via the SetWindowAttributes_t::fEventMask
02180    // attribute.
02181 
02182    if (!id) return;
02183 
02184    UInt_t xevmask;
02185 
02186    MapEventMask(evmask, xevmask);
02187 
02188    XSelectInput(fDisplay, (Window) id, xevmask);
02189 }
02190 
02191 //______________________________________________________________________________
02192 Window_t TGX11::GetInputFocus()
02193 {
02194    // Returns the window id of the window having the input focus.
02195 
02196    Window focus;
02197    int    return_to;
02198 
02199    XGetInputFocus(fDisplay, &focus, &return_to);
02200    return (Window_t) focus;
02201 }
02202 
02203 //______________________________________________________________________________
02204 void TGX11::SetInputFocus(Window_t id)
02205 {
02206    // Set keyboard input focus to window id.
02207 
02208    if (!id) return;
02209 
02210    XWindowAttributes xattr;
02211 
02212    XGetWindowAttributes(fDisplay, (Window) id, &xattr);
02213 
02214    if (xattr.map_state == IsViewable)
02215       XSetInputFocus(fDisplay, (Window) id, RevertToParent, CurrentTime);
02216 }
02217 
02218 //______________________________________________________________________________
02219 Window_t TGX11::GetPrimarySelectionOwner()
02220 {
02221    // Returns the window id of the current owner of the primary selection.
02222    // That is the window in which, for example some text is selected.
02223 
02224    return (Window_t) XGetSelectionOwner(fDisplay, XA_PRIMARY);
02225 }
02226 
02227 //______________________________________________________________________________
02228 void TGX11::SetPrimarySelectionOwner(Window_t id)
02229 {
02230    // Makes the window id the current owner of the primary selection.
02231    // That is the window in which, for example some text is selected.
02232 
02233    if (!id) return;
02234 
02235    XSetSelectionOwner(fDisplay, XA_PRIMARY, id, CurrentTime);
02236 }
02237 
02238 //______________________________________________________________________________
02239 void TGX11::ConvertPrimarySelection(Window_t id, Atom_t clipboard, Time_t when)
02240 {
02241    // XConvertSelection() causes a SelectionRequest event to be sent to the
02242    // current primary selection owner. This event specifies the selection
02243    // property (primary selection), the format into which to convert that
02244    // data before storing it (target = XA_STRING), the property in which
02245    // the owner will place the information (sel_property), the window that
02246    // wants the information (id), and the time of the conversion request
02247    // (when).
02248    // The selection owner responds by sending a SelectionNotify event, which
02249    // confirms the selected atom and type.
02250 
02251    if (!id) return;
02252 
02253    XConvertSelection(fDisplay, XA_PRIMARY, XA_STRING, (Atom) clipboard,
02254                      (Window) id, (Time) when);
02255 }
02256 
02257 //______________________________________________________________________________
02258 void TGX11::LookupString(Event_t *event, char *buf, Int_t buflen, UInt_t &keysym)
02259 {
02260    // Convert the keycode from the event structure to a key symbol (according
02261    // to the modifiers specified in the event structure and the current
02262    // keyboard mapping). In buf a null terminated ASCII string is returned
02263    // representing the string that is currently mapped to the key code.
02264 
02265    XEvent xev;
02266    KeySym xkeysym;
02267 
02268    MapEvent(*event, xev);
02269 
02270    int n = XLookupString(&xev.xkey, buf, buflen-1, &xkeysym, 0);
02271    if (n >= buflen)
02272       Error("LookupString", "buf too small, must be at least %d", n+1);
02273    else
02274       buf[n] = 0;
02275 
02276    UInt_t ks, xks = (UInt_t) xkeysym;
02277    MapKeySym(ks, xks, kFALSE);
02278    keysym = (Int_t) ks;
02279 }
02280 
02281 //______________________________________________________________________________
02282 void TGX11::MapKeySym(UInt_t &keysym, UInt_t &xkeysym, Bool_t tox)
02283 {
02284    // Map to and from X key symbols. Keysym are the values returned by
02285    // XLookUpString.
02286 
02287    if (tox) {
02288       xkeysym = XK_VoidSymbol;
02289       if (keysym < 127) {
02290          xkeysym = keysym;
02291       } else if (keysym >= kKey_F1 && keysym <= kKey_F35) {
02292          xkeysym = XK_F1 + (keysym - (UInt_t)kKey_F1);  // function keys
02293       } else {
02294          for (int i = 0; gKeyMap[i].fKeySym; i++) {    // any other keys
02295             if (keysym == (UInt_t) gKeyMap[i].fKeySym) {
02296                xkeysym = (UInt_t) gKeyMap[i].fXKeySym;
02297                break;
02298             }
02299          }
02300       }
02301    } else {
02302       keysym = kKey_Unknown;
02303       // commentary in X11/keysymdef says that X codes match ASCII
02304       if (xkeysym < 127) {
02305          keysym = xkeysym;
02306       } else if (xkeysym >= XK_F1 && xkeysym <= XK_F35) {
02307          keysym = kKey_F1 + (xkeysym - XK_F1);          // function keys
02308       } else if (xkeysym >= XK_KP_0 && xkeysym <= XK_KP_9) {
02309          keysym = kKey_0 + (xkeysym - XK_KP_0);         // numeric keypad keys
02310       } else {
02311          for (int i = 0; gKeyMap[i].fXKeySym; i++) {   // any other keys
02312             if (xkeysym == gKeyMap[i].fXKeySym) {
02313                keysym = (UInt_t) gKeyMap[i].fKeySym;
02314                break;
02315             }
02316          }
02317       }
02318    }
02319 }
02320 
02321 //______________________________________________________________________________
02322 void TGX11::GetPasteBuffer(Window_t id, Atom_t atom, TString &text, Int_t &nchar,
02323                            Bool_t del)
02324 {
02325    // Get contents of paste buffer atom into string. If del is true delete
02326    // the paste buffer afterwards.
02327 
02328    if (!id) return;
02329 
02330    Atom actual_type, property = (Atom) atom;
02331    int  actual_format;
02332    ULong_t nitems, bytes_after, nread;
02333    unsigned char *data;
02334 
02335    nchar = 0;
02336    text  = "";
02337 
02338    if (property == None) return;
02339 
02340    // get past buffer
02341    nread = 0;
02342    do {
02343       if (XGetWindowProperty(fDisplay, (Window) id, property,
02344                              nread/4, 1024, (Bool)del,
02345                              AnyPropertyType,
02346                              &actual_type, &actual_format,
02347                              &nitems, &bytes_after,
02348                              (unsigned char **) &data)
02349          != Success)
02350       break;
02351 
02352       if (actual_type != XA_STRING) break;
02353 
02354       text.Insert((Int_t) nread, (const char *) data, (Int_t) nitems);
02355       nread += nitems;
02356       XFree(data);
02357 
02358    } while (bytes_after > 0);
02359 
02360    nchar = (Int_t) nread;
02361 }
02362 
02363 //______________________________________________________________________________
02364 void TGX11::TranslateCoordinates(Window_t src, Window_t dest, Int_t src_x,
02365                      Int_t src_y, Int_t &dest_x, Int_t &dest_y, Window_t &child)
02366 {
02367    // TranslateCoordinates translates coordinates from the frame of
02368    // reference of one window to another. If the point is contained
02369    // in a mapped child of the destination, the id of that child is
02370    // returned as well.
02371 
02372    if (!src || !dest) return;
02373 
02374    Window xchild;
02375 
02376    XTranslateCoordinates(fDisplay, (Window) src, (Window) dest, src_x,
02377                          src_y, &dest_x, &dest_y, &xchild);
02378    child = (Window_t) xchild;
02379 }
02380 
02381 //______________________________________________________________________________
02382 void TGX11::GetWindowSize(Drawable_t id, Int_t &x, Int_t &y, UInt_t &w, UInt_t &h)
02383 {
02384    // Return geometry of window (should be called GetGeometry but signature
02385    // already used).
02386 
02387    if (!id) return;
02388 
02389    Window wdummy;
02390    UInt_t bdum, ddum;
02391 
02392    XGetGeometry(fDisplay, (Drawable) id, &wdummy, &x, &y, &w, &h, &bdum, &ddum);
02393 }
02394 
02395 //______________________________________________________________________________
02396 void TGX11::FillPolygon(Window_t id, GContext_t gc, Point_t *points, Int_t npnt)
02397 {
02398    // FillPolygon fills the region closed by the specified path.
02399    // The path is closed automatically if the last point in the list does
02400    // not coincide with the first point. All point coordinates are
02401    // treated as relative to the origin. For every pair of points
02402    // inside the polygon, the line segment connecting them does not
02403    // intersect the path.
02404 
02405    if (!id) return;
02406 
02407    XFillPolygon(fDisplay, (Window) id, (GC) gc, (XPoint *) points, npnt,
02408                 Convex, CoordModeOrigin);
02409 }
02410 
02411 //______________________________________________________________________________
02412 void TGX11::QueryPointer(Window_t id, Window_t &rootw, Window_t &childw,
02413                          Int_t &root_x, Int_t &root_y, Int_t &win_x,
02414                          Int_t &win_y, UInt_t &mask)
02415 {
02416    // Returns the root window the pointer is logically on and the pointer
02417    // coordinates relative to the root window's origin.
02418    // The pointer coordinates returned to win_x and win_y are relative to
02419    // the origin of the specified window. In this case, QueryPointer returns
02420    // the child that contains the pointer, if any, or else kNone to
02421    // childw. QueryPointer returns the current logical state of the
02422    // keyboard buttons and the modifier keys in mask.
02423 
02424    if (!id) return;
02425 
02426    Window xrootw, xchildw;
02427    UInt_t xmask;
02428 
02429    XQueryPointer(fDisplay, (Window) id, &xrootw, &xchildw,
02430                  &root_x, &root_y, &win_x, &win_y, &xmask);
02431 
02432    rootw  = (Window_t) xrootw;
02433    childw = (Window_t) xchildw;
02434 
02435    MapModifierState(mask, xmask, kFALSE);
02436 }
02437 
02438 //______________________________________________________________________________
02439 void TGX11::SetForeground(GContext_t gc, ULong_t foreground)
02440 {
02441    // Set foreground color in graphics context (shortcut for ChangeGC with
02442    // only foreground mask set).
02443 
02444    XSetForeground(fDisplay, (GC) gc, foreground);
02445 }
02446 
02447 //______________________________________________________________________________
02448 void TGX11::SetClipRectangles(GContext_t gc, Int_t x, Int_t y, Rectangle_t *recs, Int_t n)
02449 {
02450    // Set clipping rectangles in graphics context. X, Y specify the origin
02451    // of the rectangles. Recs specifies an array of rectangles that define
02452    // the clipping mask and n is the number of rectangles.
02453 
02454    XSetClipRectangles(fDisplay, (GC) gc, x, y, (XRectangle *) recs, n, Unsorted);
02455 }
02456 
02457 //______________________________________________________________________________
02458 void TGX11::Update(Int_t mode)
02459 {
02460    // Flush (mode = 0, default) or synchronize (mode = 1) X output buffer.
02461    // Flush flushes output buffer. Sync flushes buffer and waits till all
02462    // requests have been processed by X server.
02463 
02464    if (mode == 0)
02465       XFlush(fDisplay);
02466    if (mode == 1)
02467       XSync(fDisplay, False);
02468 }
02469 
02470 //______________________________________________________________________________
02471 Region_t TGX11::CreateRegion()
02472 {
02473    // Create a new empty region.
02474 
02475    return (Region_t) XCreateRegion();
02476 }
02477 
02478 //______________________________________________________________________________
02479 void TGX11::DestroyRegion(Region_t reg)
02480 {
02481    // Destroy region.
02482 
02483    XDestroyRegion((Region)reg);
02484 }
02485 
02486 //______________________________________________________________________________
02487 void TGX11::UnionRectWithRegion(Rectangle_t *rect, Region_t src, Region_t dest)
02488 {
02489    // Union of rectangle with a region.
02490 
02491    XRectangle *r = (XRectangle *) rect;   // 1 on 1 mapping
02492    XUnionRectWithRegion(r, (Region) src, (Region) dest);
02493 }
02494 
02495 //______________________________________________________________________________
02496 Region_t TGX11::PolygonRegion(Point_t *points, Int_t np, Bool_t winding)
02497 {
02498    // Create region for the polygon defined by the points array.
02499    // If winding is true use WindingRule else EvenOddRule as fill rule.
02500 
02501    XPoint *p = (XPoint *) points;
02502    return (Region_t) XPolygonRegion(p, np, winding ? WindingRule : EvenOddRule);
02503 }
02504 
02505 //______________________________________________________________________________
02506 void TGX11::UnionRegion(Region_t rega, Region_t regb, Region_t result)
02507 {
02508    // Compute the union of rega and regb and return result region.
02509    // The output region may be the same result region.
02510 
02511    XUnionRegion((Region) rega, (Region) regb, (Region) result);
02512 }
02513 
02514 //______________________________________________________________________________
02515 void TGX11::IntersectRegion(Region_t rega, Region_t regb, Region_t result)
02516 {
02517    // Compute the intersection of rega and regb and return result region.
02518    // The output region may be the same as the result region.
02519 
02520    XIntersectRegion((Region) rega, (Region) regb, (Region) result);
02521 }
02522 
02523 //______________________________________________________________________________
02524 void TGX11::SubtractRegion(Region_t rega, Region_t regb, Region_t result)
02525 {
02526    // Subtract rega from regb.
02527 
02528    XSubtractRegion((Region) rega, (Region) regb, (Region) result);
02529 }
02530 
02531 //______________________________________________________________________________
02532 void TGX11::XorRegion(Region_t rega, Region_t regb, Region_t result)
02533 {
02534    // Calculate the difference between the union and intersection of
02535    // two regions.
02536 
02537    XXorRegion((Region) rega, (Region) regb, (Region) result);
02538 }
02539 
02540 //______________________________________________________________________________
02541 Bool_t TGX11::EmptyRegion(Region_t reg)
02542 {
02543    // Return true if the region is empty.
02544 
02545    return (Bool_t) XEmptyRegion((Region) reg);
02546 }
02547 
02548 //______________________________________________________________________________
02549 Bool_t TGX11::PointInRegion(Int_t x, Int_t y, Region_t reg)
02550 {
02551    // Returns true if the point x,y is in the region.
02552 
02553    return (Bool_t) XPointInRegion((Region) reg, x, y);
02554 }
02555 
02556 //______________________________________________________________________________
02557 Bool_t TGX11::EqualRegion(Region_t rega, Region_t regb)
02558 {
02559    // Returns true if two regions are equal.
02560 
02561    return (Bool_t) XEqualRegion((Region) rega, (Region) regb);
02562 }
02563 
02564 //______________________________________________________________________________
02565 void TGX11::GetRegionBox(Region_t reg, Rectangle_t *rect)
02566 {
02567    // Return smallest enclosing rectangle.
02568 
02569    XClipBox((Region) reg, (XRectangle*) rect);
02570 }
02571 
02572 //______________________________________________________________________________
02573 char **TGX11::ListFonts(const char *fontname, Int_t max, Int_t &count)
02574 {
02575    // Return list of font names matching fontname regexp, like "-*-times-*".
02576 
02577    char **fontlist;
02578    Int_t fontcount = 0;
02579    fontlist = XListFonts(fDisplay, (char *)fontname, max, &fontcount);
02580    count = fontcount;
02581    return fontlist;
02582 }
02583 
02584 //______________________________________________________________________________
02585 void TGX11::FreeFontNames(char **fontlist)
02586 {
02587    // Free list of font names.
02588 
02589    XFreeFontNames(fontlist);
02590 }
02591 
02592 //______________________________________________________________________________
02593 Drawable_t TGX11::CreateImage(UInt_t width, UInt_t height)
02594 {
02595    // Create a client-side XImage. Returns handle to XImage.
02596 
02597    Int_t bitmap_pad;
02598 
02599    if (fDepth <= 8)
02600       bitmap_pad = 8;
02601    else if (fDepth <= 16)
02602       bitmap_pad = 16;
02603    else
02604       bitmap_pad = 32;
02605 
02606    XImage *xim = XCreateImage(fDisplay, fVisual, fDepth, ZPixmap,
02607                               0, 0, width, height, bitmap_pad, 0);
02608 
02609    // use calloc since Xlib will use free() in XDestroyImage
02610    xim->data = (char *) calloc(xim->bytes_per_line * xim->height, 1);
02611 
02612    return (Drawable_t) xim;
02613 }
02614 
02615 //______________________________________________________________________________
02616 void TGX11::GetImageSize(Drawable_t img, UInt_t &width, UInt_t &height)
02617 {
02618    // Get size of XImage img.
02619 
02620    width  = ((XImage*)img)->width;
02621    height = ((XImage*)img)->height;
02622 }
02623 
02624 //______________________________________________________________________________
02625 void TGX11::PutPixel(Drawable_t img, Int_t x, Int_t y, ULong_t pixel)
02626 {
02627    // Set pixel at specified location in XImage img.
02628 
02629    XPutPixel((XImage*) img, x, y, pixel);
02630 }
02631 
02632 //______________________________________________________________________________
02633 void TGX11::PutImage(Drawable_t win, GContext_t gc, Drawable_t img, Int_t dx,
02634                      Int_t dy, Int_t x, Int_t y, UInt_t w, UInt_t h)
02635 {
02636    // Put (x,y,w,h) part of image img in window win at position dx,dy.
02637 
02638    if (!win) return;
02639 
02640    XPutImage(fDisplay, (Drawable) win, (GC) gc, (XImage*) img,
02641              x, y, dx, dy, w, h);
02642 }
02643 
02644 //______________________________________________________________________________
02645 void TGX11::DeleteImage(Drawable_t img)
02646 {
02647    // Destroy XImage img.
02648 
02649    XDestroyImage((XImage*) img);
02650 }
02651 
02652 //______________________________________________________________________________
02653 void TGX11::ShapeCombineMask(Window_t id, Int_t x, Int_t y, Pixmap_t mask)
02654 {
02655    // The Nonrectangular Window Shape Extension adds nonrectangular
02656    // windows to the System.
02657    // This allows for making shaped (partially transparent) windows
02658 
02659    XShapeCombineMask(fDisplay, (Window) id, ShapeBounding, x, y,
02660                      (Pixmap) mask, ShapeSet);
02661 }
02662 
02663 //______________________________________________________________________________
02664 UInt_t TGX11::ScreenWidthMM() const
02665 {
02666    // Returns the width of the screen in millimeters.
02667 
02668    return (UInt_t)WidthMMOfScreen(DefaultScreenOfDisplay(fDisplay));
02669 }
02670 
02671 //______________________________________________________________________________
02672 void TGX11::DeleteProperty(Window_t win, Atom_t& prop)
02673 {
02674    // Deletes the specified property only if the property was defined on the
02675    // specified window and causes the X server to generate a PropertyNotify
02676    // event on the window unless the property does not exist.
02677 
02678    XDeleteProperty(fDisplay, win, prop);
02679 }
02680 
02681 //______________________________________________________________________________
02682 Int_t TGX11::GetProperty(Window_t win, Atom_t prop, Long_t offset, Long_t length,
02683                          Bool_t del, Atom_t req_type, Atom_t *act_type,
02684                          Int_t *act_format, ULong_t *nitems, ULong_t *bytes,
02685                          unsigned char **prop_list)
02686 {
02687    // Returns the actual type of the property; the actual format of the property;
02688    // the number of 8-bit, 16-bit, or 32-bit items transferred; the number of
02689    // bytes remaining to be read in the property; and a pointer to the data
02690    // actually returned.
02691 
02692    return XGetWindowProperty(fDisplay, win, prop, offset, length, del, req_type,
02693                              act_type, act_format, nitems, bytes, prop_list);
02694 }
02695 
02696 //______________________________________________________________________________
02697 void TGX11::ChangeActivePointerGrab(Window_t /*win*/, UInt_t mask, Cursor_t cur)
02698 {
02699    // Changes the specified dynamic parameters if the pointer is actively
02700    // grabbed by the client.
02701 
02702    UInt_t xevmask;
02703    MapEventMask(mask, xevmask);
02704    if (cur == kNone)
02705       XChangeActivePointerGrab(fDisplay, xevmask, fCursors[kHand], CurrentTime);
02706    else
02707       XChangeActivePointerGrab(fDisplay, xevmask, cur, CurrentTime);
02708 }
02709 
02710 //______________________________________________________________________________
02711 void TGX11::ConvertSelection(Window_t win, Atom_t &sel, Atom_t &target,
02712                              Atom_t &prop, Time_t &stamp)
02713 {
02714    // Requests that the specified selection be converted to the specified
02715    // target type.
02716 
02717    XConvertSelection(fDisplay, sel, target, prop, win, stamp);
02718 }
02719 
02720 //______________________________________________________________________________
02721 Bool_t TGX11::SetSelectionOwner(Window_t owner, Atom_t &sel)
02722 {
02723    // Changes the owner and last-change time for the specified selection
02724 
02725    return XSetSelectionOwner(fDisplay, sel, owner, CurrentTime);
02726 }
02727 
02728 //______________________________________________________________________________
02729 void TGX11::ChangeProperties(Window_t id, Atom_t property, Atom_t type,
02730                              Int_t format, UChar_t *data, Int_t len)
02731 {
02732    // This function alters the property for the specified window and
02733    // causes the X server to generate a PropertyNotify event on that
02734    // window.
02735 
02736    if (!id) return;
02737 
02738    XChangeProperty(fDisplay, (Window) id, (Atom) property, (Atom) type,
02739                    format, PropModeReplace, data, len);
02740 }
02741 
02742 //______________________________________________________________________________
02743 void TGX11::SetDNDAware(Window_t win, Atom_t *typelist)
02744 {
02745    // Add XdndAware property and the list of drag and drop types to the
02746    // Window win.
02747 
02748    unsigned char version = 4;
02749    Atom_t dndaware = InternAtom("XdndAware", kFALSE);
02750    XChangeProperty(fDisplay, (Window) win, (Atom) dndaware, (Atom) XA_ATOM,
02751                    32, PropModeReplace, (unsigned char *) &version, 1);
02752 
02753    if (typelist) {
02754       int n;
02755 
02756       for (n = 0; typelist[n]; n++) { }
02757       if (n > 0) {
02758          XChangeProperty(fDisplay, win, dndaware, XA_ATOM, 32, PropModeAppend,
02759                          (unsigned char *) typelist, n);
02760       }
02761    }
02762 }
02763 
02764 //______________________________________________________________________________
02765 void TGX11::SetTypeList(Window_t win, Atom_t prop, Atom_t *typelist)
02766 {
02767    // Add the list of drag and drop types to the Window win.
02768 
02769    if (typelist) {
02770       int n;
02771       for (n = 0; typelist[n]; n++) { }
02772       if (n > 0) {
02773          XChangeProperty(fDisplay, win, prop, XA_ATOM, 32, PropModeAppend,
02774                          (unsigned char *) typelist, n);
02775       }
02776    }
02777 }
02778 
02779 //______________________________________________________________________________
02780 Window_t TGX11::FindRWindow(Window_t win, Window_t dragwin, Window_t input,
02781                             int x, int y, int maxd)
02782 {
02783    // Recursively search in the children of Window for a Window which is at
02784    // location x, y and is DND aware, with a maximum depth of maxd.
02785    // Possibility to exclude dragwin and input.
02786 
02787    WindowAttributes_t wattr;
02788    static Atom_t *dndTypeList = 0;
02789 
02790    if (dndTypeList == 0) {
02791       dndTypeList = new Atom_t[3];
02792       dndTypeList[0] = InternAtom("application/root", kFALSE);
02793       dndTypeList[1] = InternAtom("text/uri-list", kFALSE);
02794       dndTypeList[2] = 0;
02795    }
02796 
02797    if (maxd <= 0) return kNone;
02798 
02799    if (win == dragwin || win == input) return kNone;
02800 
02801    GetWindowAttributes(win, wattr);
02802    if (wattr.fMapState != kIsUnmapped &&
02803        x >= wattr.fX && x < wattr.fX + wattr.fWidth &&
02804        y >= wattr.fY && y < wattr.fY + wattr.fHeight) {
02805 
02806       if (IsDNDAware(win, dndTypeList)) return win;
02807 
02808       Window r, p, *children;
02809       UInt_t numch;
02810       int i;
02811 
02812       if (XQueryTree(fDisplay, win, &r, &p, &children, &numch)) {
02813          if (children && numch > 0) {
02814             r = kNone;
02815             // upon return from XQueryTree, children are listed in the current
02816             // stacking order, from bottom-most (first) to top-most (last)
02817             for (i = numch-1; i >= 0; --i) {
02818                r = FindRWindow((Window_t)children[i], dragwin, input,
02819                                x - wattr.fX, y - wattr.fY, maxd-1);
02820                if (r != kNone) break;
02821             }
02822             XFree(children);
02823             if (r != kNone) return r;
02824          }
02825          return kNone; //win;   // ?!?
02826       }
02827    }
02828    return kNone;
02829 }
02830 
02831 //______________________________________________________________________________
02832 Bool_t TGX11::IsDNDAware(Window_t win, Atom_t *typelist)
02833 {
02834    // Checks if Window win is DND aware, and knows any of the DND formats
02835    // passed in argument.
02836 
02837    Atom_t  actual;
02838    Int_t   format;
02839    ULong_t count, remaining;
02840    unsigned char *data = 0;
02841    Atom_t *types, *t;
02842    Int_t   result = kTRUE;
02843    static Atom_t dndaware = kNone;
02844 
02845    if (win == kNone) return kFALSE;
02846 
02847    if (dndaware == kNone)
02848       dndaware = InternAtom("XdndAware", kFALSE);
02849 
02850    XGetWindowProperty(fDisplay, win, dndaware, 0, 0x8000000L, kFALSE,
02851                       XA_ATOM, &actual, &format, &count, &remaining, &data);
02852 
02853    if ((actual != XA_ATOM) || (format != 32) || (count == 0) || !data) {
02854       if (data) XFree(data);
02855       return kFALSE;
02856    }
02857 
02858    types = (Atom_t *) data;
02859 
02860    if ((count > 1) && typelist) {
02861       result = kFALSE;
02862       for (t = typelist; *t; t++) {
02863          for (ULong_t j = 1; j < count; j++) {
02864             if (types[j] == *t) {
02865                result = kTRUE;
02866                break;
02867             }
02868          }
02869          if (result) break;
02870       }
02871    }
02872    XFree(data);
02873    return result;
02874 }

Generated on Tue Jul 5 14:14:46 2011 for ROOT_528-00b_version by  doxygen 1.5.1