00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "TROOT.h"
00025 #include "TColor.h"
00026 #include "TGX11.h"
00027 #include "TPoint.h"
00028 #include "TMath.h"
00029 #include "TStorage.h"
00030 #include "TStyle.h"
00031 #include "TExMap.h"
00032 #include "TEnv.h"
00033 #include "TString.h"
00034 #include "TObjString.h"
00035 #include "TObjArray.h"
00036 #include "RStipples.h"
00037
00038 #include <stdio.h>
00039 #include <string.h>
00040 #include <stdlib.h>
00041 #include <ctype.h>
00042 #include <unistd.h>
00043 #ifdef R__AIX
00044 # include <sys/socket.h>
00045 #endif
00046
00047 extern float XRotVersion(char*, int);
00048 extern void XRotSetMagnification(float);
00049 extern void XRotSetBoundingBoxPad(int);
00050 extern int XRotDrawString(Display*, XFontStruct*, float,
00051 Drawable, GC, int, int, char*);
00052 extern int XRotDrawImageString(Display*, XFontStruct*, float,
00053 Drawable, GC, int, int, char*);
00054 extern int XRotDrawAlignedString(Display*, XFontStruct*, float,
00055 Drawable, GC, int, int, char*, int);
00056 extern int XRotDrawAlignedImageString(Display*, XFontStruct*, float,
00057 Drawable, GC, int, int, char*, int);
00058 extern XPoint *XRotTextExtents(Display*, XFontStruct*, float,
00059 int, int, char*, int);
00060
00061
00062
00063 static XWindow_t *gCws;
00064 static XWindow_t *gTws;
00065
00066 const Int_t kBIGGEST_RGB_VALUE = 65535;
00067
00068
00069
00070
00071 const int kMAXGC = 7;
00072 static GC gGClist[kMAXGC];
00073 static GC *gGCline = &gGClist[0];
00074 static GC *gGCmark = &gGClist[1];
00075 static GC *gGCfill = &gGClist[2];
00076 static GC *gGCtext = &gGClist[3];
00077 static GC *gGCinvt = &gGClist[4];
00078 static GC *gGCdash = &gGClist[5];
00079 static GC *gGCpxmp = &gGClist[6];
00080
00081 static GC gGCecho;
00082
00083 static Int_t gFillHollow;
00084 static Pixmap gFillPattern = 0;
00085
00086
00087
00088
00089 const Int_t kMAXFONT = 4;
00090 static struct {
00091 XFontStruct *id;
00092 char name[80];
00093 } gFont[kMAXFONT];
00094
00095 static XFontStruct *gTextFont;
00096 static Int_t gCurrentFontNumber = 0;
00097
00098
00099
00100
00101 const Int_t kMAXMK = 100;
00102 static struct {
00103 int type;
00104 int n;
00105 XPoint xy[kMAXMK];
00106 } gMarker;
00107
00108
00109
00110
00111 static int gLineWidth = 0;
00112 static int gLineStyle = LineSolid;
00113 static int gCapStyle = CapButt;
00114 static int gJoinStyle = JoinMiter;
00115 static char gDashList[10];
00116 static int gDashLength = 0;
00117 static int gDashOffset = 0;
00118 static int gDashSize = 0;
00119
00120
00121
00122
00123 static ULong_t gMouseMask = ButtonPressMask | ButtonReleaseMask |
00124 EnterWindowMask | LeaveWindowMask |
00125 PointerMotionMask | KeyPressMask |
00126 KeyReleaseMask;
00127 static ULong_t gKeybdMask = ButtonPressMask | KeyPressMask |
00128 EnterWindowMask | LeaveWindowMask;
00129
00130
00131
00132
00133 const char null_cursor_bits[] = {
00134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
00137 static Cursor gNullCursor = 0;
00138
00139
00140 ClassImp(TGX11)
00141
00142
00143 TGX11::TGX11()
00144 {
00145
00146
00147 int i;
00148 fDisplay = 0;
00149 fScreenNumber = 0;
00150 fVisual = 0;
00151 fRootWin = 0;
00152 fVisRootWin = 0;
00153 fColormap = 0;
00154 fBlackPixel = 0;
00155 fWhitePixel = 0;
00156 fWindows = 0;
00157 fColors = 0;
00158 fXEvent = new XEvent;
00159 fRedDiv = -1;
00160 fGreenDiv = -1;
00161 fBlueDiv = -1;
00162 fRedShift = -1;
00163 fGreenShift = -1;
00164 fBlueShift = -1;
00165 fCharacterUpX = 1;
00166 fCharacterUpY = 1;
00167 fDepth = 0;
00168 fHasTTFonts = kFALSE;
00169 fMaxNumberOfWindows = 10;
00170 fTextAlignH = 1;
00171 fTextAlignV = 1;
00172 fTextAlign = 7;
00173 fTextMagnitude = 1;
00174 for (i = 0; i < kNumCursors; i++) fCursors[i] = 0;
00175 }
00176
00177
00178 TGX11::TGX11(const char *name, const char *title) : TVirtualX(name, title)
00179 {
00180
00181
00182 int i;
00183 fDisplay = 0;
00184 fScreenNumber = 0;
00185 fVisual = 0;
00186 fRootWin = 0;
00187 fVisRootWin = 0;
00188 fColormap = 0;
00189 fBlackPixel = 0;
00190 fWhitePixel = 0;
00191 fDrawMode = kCopy;
00192 fXEvent = new XEvent;
00193 fRedDiv = -1;
00194 fGreenDiv = -1;
00195 fBlueDiv = -1;
00196 fRedShift = -1;
00197 fGreenShift = -1;
00198 fBlueShift = -1;
00199 fCharacterUpX = 1;
00200 fCharacterUpY = 1;
00201 fDepth = 0;
00202 fHasTTFonts = kFALSE;
00203 fMaxNumberOfWindows = 10;
00204 fTextAlignH = 1;
00205 fTextAlignV = 1;
00206 fTextAlign = 7;
00207 fTextMagnitude = 1;
00208 for (i = 0; i < kNumCursors; i++) fCursors[i] = 0;
00209
00210
00211 fWindows = (XWindow_t*) TStorage::Alloc(fMaxNumberOfWindows*sizeof(XWindow_t));
00212 for (i = 0; i < fMaxNumberOfWindows; i++)
00213 fWindows[i].fOpen = 0;
00214
00215 fColors = new TExMap;
00216 }
00217
00218
00219 TGX11::TGX11(const TGX11 &org) : TVirtualX(org)
00220 {
00221
00222
00223 int i;
00224
00225 fDisplay = org.fDisplay;
00226 fScreenNumber = org.fScreenNumber;
00227 fVisual = org.fVisual;
00228 fRootWin = org.fRootWin;
00229 fVisRootWin = org.fVisRootWin;
00230 fColormap = org.fColormap;
00231 fBlackPixel = org.fBlackPixel;
00232 fWhitePixel = org.fWhitePixel;
00233 fHasTTFonts = org.fHasTTFonts;
00234 fTextAlignH = org.fTextAlignH;
00235 fTextAlignV = org.fTextAlignV;
00236 fTextAlign = org.fTextAlign;
00237 fTextMagnitude = org.fTextMagnitude;
00238 fCharacterUpX = org.fCharacterUpX;
00239 fCharacterUpY = org.fCharacterUpY;
00240 fDepth = org.fDepth;
00241 fRedDiv = org.fRedDiv;
00242 fGreenDiv = org.fGreenDiv;
00243 fBlueDiv = org.fBlueDiv;
00244 fRedShift = org.fRedShift;
00245 fGreenShift = org.fGreenShift;
00246 fBlueShift = org.fBlueShift;
00247 fDrawMode = org.fDrawMode;
00248 fXEvent = new XEvent;
00249
00250 fMaxNumberOfWindows = org.fMaxNumberOfWindows;
00251
00252 fWindows = (XWindow_t*) TStorage::Alloc(fMaxNumberOfWindows*sizeof(XWindow_t));
00253 for (i = 0; i < fMaxNumberOfWindows; i++) {
00254 fWindows[i].fOpen = org.fWindows[i].fOpen;
00255 fWindows[i].fDoubleBuffer = org.fWindows[i].fDoubleBuffer;
00256 fWindows[i].fIsPixmap = org.fWindows[i].fIsPixmap;
00257 fWindows[i].fDrawing = org.fWindows[i].fDrawing;
00258 fWindows[i].fWindow = org.fWindows[i].fWindow;
00259 fWindows[i].fBuffer = org.fWindows[i].fBuffer;
00260 fWindows[i].fWidth = org.fWindows[i].fWidth;
00261 fWindows[i].fHeight = org.fWindows[i].fHeight;
00262 fWindows[i].fClip = org.fWindows[i].fClip;
00263 fWindows[i].fXclip = org.fWindows[i].fXclip;
00264 fWindows[i].fYclip = org.fWindows[i].fYclip;
00265 fWindows[i].fWclip = org.fWindows[i].fWclip;
00266 fWindows[i].fHclip = org.fWindows[i].fHclip;
00267 fWindows[i].fNewColors = org.fWindows[i].fNewColors;
00268 fWindows[i].fNcolors = org.fWindows[i].fNcolors;
00269 fWindows[i].fShared = org.fWindows[i].fShared;
00270 }
00271
00272 for (i = 0; i < kNumCursors; i++)
00273 fCursors[i] = org.fCursors[i];
00274
00275 fColors = new TExMap;
00276 Long64_t key, value;
00277 TExMapIter it(org.fColors);
00278 while (it.Next(key, value)) {
00279 XColor_t *colo = (XColor_t *) (Long_t)value;
00280 XColor_t *col = new XColor_t;
00281 col->fPixel = colo->fPixel;
00282 col->fRed = colo->fRed;
00283 col->fGreen = colo->fGreen;
00284 col->fBlue = colo->fBlue;
00285 col->fDefined = colo->fDefined;
00286 fColors->Add(key, (Long_t) col);
00287 }
00288 }
00289
00290
00291 TGX11::~TGX11()
00292 {
00293
00294
00295 delete fXEvent;
00296 if (fWindows) TStorage::Dealloc(fWindows);
00297
00298 if (!fColors) return;
00299 Long64_t key, value;
00300 TExMapIter it(fColors);
00301 while (it.Next(key, value)) {
00302 XColor_t *col = (XColor_t *) (Long_t)value;
00303 delete col;
00304 }
00305 delete fColors;
00306 }
00307
00308
00309 Bool_t TGX11::Init(void *display)
00310 {
00311
00312
00313 if (OpenDisplay((Display *) display) == -1) return kFALSE;
00314 return kTRUE;
00315 }
00316
00317
00318 Bool_t TGX11::AllocColor(Colormap cmap, XColor *color)
00319 {
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 if (fRedDiv == -1) {
00336 if (XAllocColor(fDisplay, cmap, color))
00337 return kTRUE;
00338 } else {
00339 color->pixel = (color->red >> fRedDiv) << fRedShift |
00340 (color->green >> fGreenDiv) << fGreenShift |
00341 (color->blue >> fBlueDiv) << fBlueShift;
00342 return kTRUE;
00343 }
00344 return kFALSE;
00345 }
00346
00347
00348 void TGX11::QueryColors(Colormap cmap, XColor *color, Int_t ncolors)
00349 {
00350
00351
00352 if (fRedDiv == -1) {
00353 XQueryColors(fDisplay, cmap, color, ncolors);
00354 } else {
00355 ULong_t r, g, b;
00356 for (Int_t i = 0; i < ncolors; i++) {
00357 r = (color[i].pixel & fVisual->red_mask) >> fRedShift;
00358 color[i].red = UShort_t(r*kBIGGEST_RGB_VALUE/(fVisual->red_mask >> fRedShift));
00359
00360 g = (color[i].pixel & fVisual->green_mask) >> fGreenShift;
00361 color[i].green = UShort_t(g*kBIGGEST_RGB_VALUE/(fVisual->green_mask >> fGreenShift));
00362
00363 b = (color[i].pixel & fVisual->blue_mask) >> fBlueShift;
00364 color[i].blue = UShort_t(b*kBIGGEST_RGB_VALUE/(fVisual->blue_mask >> fBlueShift));
00365
00366 color[i].flags = DoRed | DoGreen | DoBlue;
00367 }
00368 }
00369 }
00370
00371
00372 void TGX11::ClearPixmap(Drawable *pix)
00373 {
00374
00375
00376 Window root;
00377 int xx, yy;
00378 unsigned int ww, hh, border, depth;
00379 XGetGeometry(fDisplay, *pix, &root, &xx, &yy, &ww, &hh, &border, &depth);
00380 SetColor(*gGCpxmp, 0);
00381 XFillRectangle(fDisplay, *pix, *gGCpxmp, 0 ,0 ,ww ,hh);
00382 SetColor(*gGCpxmp, 1);
00383 XFlush(fDisplay);
00384 }
00385
00386
00387 void TGX11::ClearWindow()
00388 {
00389
00390
00391 if (!gCws->fIsPixmap && !gCws->fDoubleBuffer) {
00392 XSetWindowBackground(fDisplay, gCws->fDrawing, GetColor(0).fPixel);
00393 XClearWindow(fDisplay, gCws->fDrawing);
00394 XFlush(fDisplay);
00395 } else {
00396 SetColor(*gGCpxmp, 0);
00397 XFillRectangle(fDisplay, gCws->fDrawing, *gGCpxmp,
00398 0, 0, gCws->fWidth, gCws->fHeight);
00399 SetColor(*gGCpxmp, 1);
00400 }
00401 }
00402
00403
00404 void TGX11::ClosePixmap()
00405 {
00406
00407
00408 CloseWindow1();
00409 }
00410
00411
00412 void TGX11::CloseWindow()
00413 {
00414
00415
00416 if (gCws->fShared)
00417 gCws->fOpen = 0;
00418 else
00419 CloseWindow1();
00420
00421
00422
00423 }
00424
00425
00426 void TGX11::CloseWindow1()
00427 {
00428
00429
00430 int wid;
00431
00432 if (gCws->fIsPixmap)
00433 XFreePixmap(fDisplay, gCws->fWindow);
00434 else
00435 XDestroyWindow(fDisplay, gCws->fWindow);
00436
00437 if (gCws->fBuffer) XFreePixmap(fDisplay, gCws->fBuffer);
00438
00439 if (gCws->fNewColors) {
00440 if (fRedDiv == -1)
00441 XFreeColors(fDisplay, fColormap, gCws->fNewColors, gCws->fNcolors, 0);
00442 delete [] gCws->fNewColors;
00443 gCws->fNewColors = 0;
00444 }
00445
00446 XFlush(fDisplay);
00447
00448 gCws->fOpen = 0;
00449
00450
00451 for (wid = 0; wid < fMaxNumberOfWindows; wid++)
00452 if (fWindows[wid].fOpen) {
00453 gCws = &fWindows[wid];
00454 return;
00455 }
00456
00457 gCws = 0;
00458 }
00459
00460
00461 void TGX11::CopyPixmap(int wid, int xpos, int ypos)
00462 {
00463
00464
00465 gTws = &fWindows[wid];
00466
00467 XCopyArea(fDisplay, gTws->fDrawing, gCws->fDrawing, *gGCpxmp, 0, 0, gTws->fWidth,
00468 gTws->fHeight, xpos, ypos);
00469 XFlush(fDisplay);
00470 }
00471
00472
00473 void TGX11::CopyWindowtoPixmap(Drawable *pix, int xpos, int ypos )
00474 {
00475
00476
00477 Window root;
00478 int xx, yy;
00479 unsigned int ww, hh, border, depth;
00480
00481 XGetGeometry(fDisplay, *pix, &root, &xx, &yy, &ww, &hh, &border, &depth);
00482 XCopyArea(fDisplay, gCws->fDrawing, *pix, *gGCpxmp, xpos, ypos, ww, hh, 0, 0);
00483 XFlush(fDisplay);
00484 }
00485
00486
00487 void TGX11::DrawBox(int x1, int y1, int x2, int y2, EBoxMode mode)
00488 {
00489
00490
00491
00492
00493 Int_t x = TMath::Min(x1, x2);
00494 Int_t y = TMath::Min(y1, y2);
00495 Int_t w = TMath::Abs(x2 - x1);
00496 Int_t h = TMath::Abs(y2 - y1);
00497
00498 switch (mode) {
00499
00500 case kHollow:
00501 XDrawRectangle(fDisplay, gCws->fDrawing, *gGCline, x, y, w, h);
00502 break;
00503
00504 case kFilled:
00505 XFillRectangle(fDisplay, gCws->fDrawing, *gGCfill, x, y, w, h);
00506 break;
00507
00508 default:
00509 break;
00510 }
00511 }
00512
00513
00514 void TGX11::DrawCellArray(int x1, int y1, int x2, int y2, int nx, int ny, int *ic)
00515 {
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 int i, j, icol, ix, iy, w, h, current_icol;
00527
00528 current_icol = -1;
00529 w = TMath::Max((x2-x1)/(nx),1);
00530 h = TMath::Max((y1-y2)/(ny),1);
00531 ix = x1;
00532
00533 for (i = 0; i < nx; i++) {
00534 iy = y1-h;
00535 for (j = 0; j < ny; j++) {
00536 icol = ic[i+(nx*j)];
00537 if (icol != current_icol) {
00538 XSetForeground(fDisplay, *gGCfill, GetColor(icol).fPixel);
00539 current_icol = icol;
00540 }
00541 XFillRectangle(fDisplay, gCws->fDrawing, *gGCfill, ix, iy, w, h);
00542 iy = iy-h;
00543 }
00544 ix = ix+w;
00545 }
00546 }
00547
00548
00549 void TGX11::DrawFillArea(int n, TPoint *xyt)
00550 {
00551
00552
00553
00554
00555 XPoint *xy = (XPoint*)xyt;
00556
00557 if (gFillHollow)
00558 XDrawLines(fDisplay, gCws->fDrawing, *gGCfill, xy, n, CoordModeOrigin);
00559
00560 else {
00561 XFillPolygon(fDisplay, gCws->fDrawing, *gGCfill,
00562 xy, n, Nonconvex, CoordModeOrigin);
00563 }
00564 }
00565
00566
00567 void TGX11::DrawLine(int x1, int y1, int x2, int y2)
00568 {
00569
00570
00571
00572
00573 if (gLineStyle == LineSolid)
00574 XDrawLine(fDisplay, gCws->fDrawing, *gGCline, x1, y1, x2, y2);
00575 else {
00576 XSetDashes(fDisplay, *gGCdash, gDashOffset, gDashList, gDashSize);
00577 XDrawLine(fDisplay, gCws->fDrawing, *gGCdash, x1, y1, x2, y2);
00578 }
00579 }
00580
00581
00582 void TGX11::DrawPolyLine(int n, TPoint *xyt)
00583 {
00584
00585
00586
00587
00588 XPoint *xy = (XPoint*)xyt;
00589
00590 const Int_t kMaxPoints = 1000001;
00591
00592 if (n > kMaxPoints) {
00593 int ibeg = 0;
00594 int iend = kMaxPoints - 1;
00595 while (iend < n) {
00596 DrawPolyLine( kMaxPoints, &xyt[ibeg] );
00597 ibeg = iend;
00598 iend += kMaxPoints - 1;
00599 }
00600 if (ibeg < n) {
00601 int npt = n - ibeg;
00602 DrawPolyLine( npt, &xyt[ibeg] );
00603 }
00604 } else if (n > 1) {
00605 if (gLineStyle == LineSolid)
00606 XDrawLines(fDisplay, gCws->fDrawing, *gGCline, xy, n, CoordModeOrigin);
00607 else {
00608 int i;
00609 XSetDashes(fDisplay, *gGCdash,
00610 gDashOffset, gDashList, gDashSize);
00611 XDrawLines(fDisplay, gCws->fDrawing, *gGCdash, xy, n, CoordModeOrigin);
00612
00613
00614 for (i = 1; i < n; i++) {
00615 int dx = xy[i].x - xy[i-1].x;
00616 int dy = xy[i].y - xy[i-1].y;
00617 if (dx < 0) dx = - dx;
00618 if (dy < 0) dy = - dy;
00619 gDashOffset += dx > dy ? dx : dy;
00620 }
00621 gDashOffset %= gDashLength;
00622 }
00623 } else {
00624 int px,py;
00625 px=xy[0].x;
00626 py=xy[0].y;
00627 XDrawPoint(fDisplay, gCws->fDrawing,
00628 gLineStyle == LineSolid ? *gGCline : *gGCdash, px, py);
00629 }
00630 }
00631
00632
00633 void TGX11::DrawPolyMarker(int n, TPoint *xyt)
00634 {
00635
00636
00637
00638
00639 XPoint *xy = (XPoint*)xyt;
00640
00641 if (gMarker.n <= 0) {
00642 const int kNMAX = 1000000;
00643 int nt = n/kNMAX;
00644 for (int it=0;it<=nt;it++) {
00645 if (it < nt) {
00646 XDrawPoints(fDisplay, gCws->fDrawing, *gGCmark, &xy[it*kNMAX], kNMAX, CoordModeOrigin);
00647 } else {
00648 XDrawPoints(fDisplay, gCws->fDrawing, *gGCmark, &xy[it*kNMAX], n-it*kNMAX, CoordModeOrigin);
00649 }
00650 }
00651 } else {
00652 int r = gMarker.n / 2;
00653 int m;
00654
00655 for (m = 0; m < n; m++) {
00656 int hollow = 0;
00657
00658 switch (gMarker.type) {
00659 int i;
00660
00661 case 0:
00662 XDrawArc(fDisplay, gCws->fDrawing, *gGCmark,
00663 xy[m].x - r, xy[m].y - r, gMarker.n, gMarker.n, 0, 360*64);
00664 break;
00665
00666 case 1:
00667 XFillArc(fDisplay, gCws->fDrawing, *gGCmark,
00668 xy[m].x - r, xy[m].y - r, gMarker.n, gMarker.n, 0, 360*64);
00669 break;
00670
00671 case 2:
00672 hollow = 1;
00673 case 3:
00674 for (i = 0; i < gMarker.n; i++) {
00675 gMarker.xy[i].x += xy[m].x;
00676 gMarker.xy[i].y += xy[m].y;
00677 }
00678 if (hollow)
00679 XDrawLines(fDisplay, gCws->fDrawing, *gGCmark,
00680 gMarker.xy, gMarker.n, CoordModeOrigin);
00681 else
00682 XFillPolygon(fDisplay, gCws->fDrawing, *gGCmark,
00683 gMarker.xy, gMarker.n, Nonconvex, CoordModeOrigin);
00684 for (i = 0; i < gMarker.n; i++) {
00685 gMarker.xy[i].x -= xy[m].x;
00686 gMarker.xy[i].y -= xy[m].y;
00687 }
00688 break;
00689
00690 case 4:
00691 for (i = 0; i < gMarker.n; i += 2)
00692 XDrawLine(fDisplay, gCws->fDrawing, *gGCmark,
00693 xy[m].x + gMarker.xy[i].x, xy[m].y + gMarker.xy[i].y,
00694 xy[m].x + gMarker.xy[i+1].x, xy[m].y + gMarker.xy[i+1].y);
00695 break;
00696 }
00697 }
00698 }
00699 }
00700
00701
00702 void TGX11::DrawText(int x, int y, float angle, float mgn,
00703 const char *text, ETextMode mode)
00704 {
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714 XRotSetMagnification(mgn);
00715
00716 if (!text) return;
00717
00718 switch (mode) {
00719
00720 case kClear:
00721 XRotDrawAlignedString(fDisplay, gTextFont, angle,
00722 gCws->fDrawing, *gGCtext, x, y, (char*)text, fTextAlign);
00723 break;
00724
00725 case kOpaque:
00726 XRotDrawAlignedImageString(fDisplay, gTextFont, angle,
00727 gCws->fDrawing, *gGCtext, x, y, (char*)text, fTextAlign);
00728 break;
00729
00730 default:
00731 break;
00732 }
00733 }
00734
00735
00736 void TGX11::FindBestVisual()
00737 {
00738
00739
00740
00741
00742 Int_t findvis = gEnv->GetValue("X11.FindBestVisual", 1);
00743
00744 Visual *vis = DefaultVisual(fDisplay, fScreenNumber);
00745 if (((vis->c_class != TrueColor && vis->c_class != DirectColor) ||
00746 DefaultDepth(fDisplay, fScreenNumber) < 15) && findvis) {
00747
00748
00749 static XVisualInfo templates[] = {
00750
00751 { 0 , 0 , 0 , 24 , TrueColor , 0 , 0 , 0 , 0 , 0 },
00752 { 0 , 0 , 0 , 32 , TrueColor , 0 , 0 , 0 , 0 , 0 },
00753 { 0 , 0 , 0 , 16 , TrueColor , 0 , 0 , 0 , 0 , 0 },
00754 { 0 , 0 , 0 , 15 , TrueColor , 0 , 0 , 0 , 0 , 0 },
00755
00756 { 0 , 0 , 0 , 24 , DirectColor, 0 , 0 , 0 , 0 , 0 },
00757 { 0 , 0 , 0 , 32 , DirectColor, 0 , 0 , 0 , 0 , 0 },
00758 { 0 , 0 , 0 , 16 , DirectColor, 0 , 0 , 0 , 0 , 0 },
00759 { 0 , 0 , 0 , 15 , DirectColor, 0 , 0 , 0 , 0 , 0 },
00760 { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
00761 };
00762
00763 Int_t nitems = 0;
00764 XVisualInfo *vlist = 0;
00765 for (Int_t i = 0; templates[i].depth != 0; i++) {
00766 Int_t mask = VisualScreenMask|VisualDepthMask|VisualClassMask;
00767 templates[i].screen = fScreenNumber;
00768 if ((vlist = XGetVisualInfo(fDisplay, mask, &(templates[i]), &nitems))) {
00769 FindUsableVisual(vlist, nitems);
00770 XFree(vlist);
00771 vlist = 0;
00772 if (fVisual)
00773 break;
00774 }
00775 }
00776 }
00777
00778 fRootWin = RootWindow(fDisplay, fScreenNumber);
00779
00780 if (!fVisual) {
00781 fDepth = DefaultDepth(fDisplay, fScreenNumber);
00782 fVisual = DefaultVisual(fDisplay, fScreenNumber);
00783 fVisRootWin = fRootWin;
00784 if (fDepth > 1)
00785 fColormap = DefaultColormap(fDisplay, fScreenNumber);
00786 fBlackPixel = BlackPixel(fDisplay, fScreenNumber);
00787 fWhitePixel = WhitePixel(fDisplay, fScreenNumber);
00788 }
00789 if (gDebug > 1)
00790 Printf("Selected visual 0x%lx: depth %d, class %d, colormap: %s",
00791 fVisual->visualid, fDepth, fVisual->c_class,
00792 fColormap == DefaultColormap(fDisplay, fScreenNumber) ? "default" :
00793 "custom");
00794 }
00795
00796
00797 static Int_t DummyX11ErrorHandler(Display *, XErrorEvent *)
00798 {
00799
00800
00801 return 0;
00802 }
00803
00804
00805 void TGX11::FindUsableVisual(XVisualInfo *vlist, Int_t nitems)
00806 {
00807
00808
00809
00810 Int_t (*oldErrorHandler)(Display *, XErrorEvent *) =
00811 XSetErrorHandler(DummyX11ErrorHandler);
00812
00813 XSetWindowAttributes attr;
00814 memset(&attr, 0, sizeof(attr));
00815
00816 Window root = RootWindow(fDisplay, fScreenNumber);
00817
00818 for (Int_t i = 0; i < nitems; i++) {
00819 Window w = None, wjunk;
00820 UInt_t width, height, ujunk;
00821 Int_t junk;
00822
00823
00824 if (vlist[i].visual == DefaultVisual(fDisplay, fScreenNumber)) {
00825 attr.colormap = DefaultColormap(fDisplay, fScreenNumber);
00826 } else {
00827 attr.colormap = XCreateColormap(fDisplay, root, vlist[i].visual, AllocNone);
00828 }
00829
00830 static XColor black_xcol = { 0, 0x0000, 0x0000, 0x0000, DoRed|DoGreen|DoBlue, 0 };
00831 static XColor white_xcol = { 0, 0xFFFF, 0xFFFF, 0xFFFF, DoRed|DoGreen|DoBlue, 0 };
00832 XAllocColor(fDisplay, attr.colormap, &black_xcol);
00833 XAllocColor(fDisplay, attr.colormap, &white_xcol);
00834 attr.border_pixel = black_xcol.pixel;
00835 attr.override_redirect = True;
00836
00837 w = XCreateWindow(fDisplay, root, -20, -20, 10, 10, 0, vlist[i].depth,
00838 CopyFromParent, vlist[i].visual,
00839 CWColormap|CWBorderPixel|CWOverrideRedirect, &attr);
00840 if (w != None && XGetGeometry(fDisplay, w, &wjunk, &junk, &junk,
00841 &width, &height, &ujunk, &ujunk)) {
00842 fVisual = vlist[i].visual;
00843 fDepth = vlist[i].depth;
00844 fColormap = attr.colormap;
00845 fBlackPixel = black_xcol.pixel;
00846 fWhitePixel = white_xcol.pixel;
00847 fVisRootWin = w;
00848 break;
00849 }
00850 if (attr.colormap != DefaultColormap(fDisplay, fScreenNumber))
00851 XFreeColormap(fDisplay, attr.colormap);
00852 }
00853 XSetErrorHandler(oldErrorHandler);
00854 }
00855
00856
00857 void TGX11::GetCharacterUp(Float_t &chupx, Float_t &chupy)
00858 {
00859
00860
00861 chupx = fCharacterUpX;
00862 chupy = fCharacterUpY;
00863 }
00864
00865
00866 XColor_t &TGX11::GetColor(Int_t cid)
00867 {
00868
00869
00870
00871 XColor_t *col = (XColor_t*) (Long_t)fColors->GetValue(cid);
00872 if (!col) {
00873 col = new XColor_t;
00874 fColors->Add(cid, (Long_t) col);
00875 }
00876 return *col;
00877 }
00878
00879
00880 Window_t TGX11::GetCurrentWindow() const
00881 {
00882
00883
00884 return (Window_t)(gCws ? gCws->fDrawing : 0);
00885 }
00886
00887
00888 GC *TGX11::GetGC(Int_t which) const
00889 {
00890
00891
00892
00893 if (which >= kMAXGC || which < 0) {
00894 Error("GetGC", "trying to get illegal GC (which = %d)", which);
00895 return 0;
00896 }
00897 return &gGClist[which];
00898 }
00899
00900
00901 Int_t TGX11::GetDoubleBuffer(int wid)
00902 {
00903
00904
00905 gTws = &fWindows[wid];
00906 if (!gTws->fOpen)
00907 return -1;
00908 else
00909 return gTws->fDoubleBuffer;
00910 }
00911
00912
00913 void TGX11::GetGeometry(int wid, int &x, int &y, unsigned int &w, unsigned int &h)
00914 {
00915
00916
00917
00918
00919
00920
00921 Window junkwin=0;
00922
00923 if (wid < 0) {
00924 x = 0;
00925 y = 0;
00926 w = DisplayWidth(fDisplay,fScreenNumber);
00927 h = DisplayHeight(fDisplay,fScreenNumber);
00928 } else {
00929 Window root;
00930 unsigned int border, depth;
00931 unsigned int width, height;
00932
00933 gTws = &fWindows[wid];
00934 XGetGeometry(fDisplay, gTws->fWindow, &root, &x, &y,
00935 &width, &height, &border, &depth);
00936 XTranslateCoordinates(fDisplay, gTws->fWindow, fRootWin,
00937 0, 0, &x, &y, &junkwin);
00938 if (width >= 65535)
00939 width = 1;
00940 if (height >= 65535)
00941 height = 1;
00942 if (width > 0 && height > 0) {
00943 gTws->fWidth = width;
00944 gTws->fHeight = height;
00945 }
00946 w = gTws->fWidth;
00947 h = gTws->fHeight;
00948 }
00949 }
00950
00951
00952 const char *TGX11::DisplayName(const char *dpyName)
00953 {
00954
00955
00956 return XDisplayName(dpyName);
00957 }
00958
00959
00960 ULong_t TGX11::GetPixel(Color_t ci)
00961 {
00962
00963
00964 TColor *color = gROOT->GetColor(ci);
00965 if (color)
00966 SetRGB(ci, color->GetRed(), color->GetGreen(), color->GetBlue());
00967
00968
00969
00970 XColor_t &col = GetColor(ci);
00971 return col.fPixel;
00972 }
00973
00974
00975 void TGX11::GetPlanes(int &nplanes)
00976 {
00977
00978
00979 nplanes = fDepth;
00980 }
00981
00982
00983 void TGX11::GetRGB(int index, float &r, float &g, float &b)
00984 {
00985
00986
00987 if (index == 0) {
00988 r = g = b = 1.0;
00989 } else if (index == 1) {
00990 r = g = b = 0.0;
00991 } else {
00992 XColor_t &col = GetColor(index);
00993 r = ((float) col.fRed) / ((float) kBIGGEST_RGB_VALUE);
00994 g = ((float) col.fGreen) / ((float) kBIGGEST_RGB_VALUE);
00995 b = ((float) col.fBlue) / ((float) kBIGGEST_RGB_VALUE);
00996 }
00997 }
00998
00999
01000 void TGX11::GetTextExtent(unsigned int &w, unsigned int &h, char *mess)
01001 {
01002
01003
01004
01005
01006
01007 w=0; h=0;
01008 if (strlen(mess)==0) return;
01009
01010 XPoint *cBox;
01011 XRotSetMagnification(fTextMagnitude);
01012 cBox = XRotTextExtents(fDisplay, gTextFont, 0., 0, 0, mess, 0);
01013 w = cBox[2].x;
01014 h = -cBox[2].y;
01015 free((char *)cBox);
01016 }
01017
01018
01019 Window_t TGX11::GetWindowID(int wid)
01020 {
01021
01022
01023
01024 return (Window_t) fWindows[wid].fWindow;
01025 }
01026
01027
01028 void TGX11::MoveWindow(int wid, int x, int y)
01029 {
01030
01031
01032
01033
01034
01035 gTws = &fWindows[wid];
01036 if (!gTws->fOpen) return;
01037
01038 XMoveWindow(fDisplay, gTws->fWindow, x, y);
01039 }
01040
01041
01042 Int_t TGX11::OpenDisplay(Display *disp)
01043 {
01044
01045
01046 Pixmap pixmp1, pixmp2;
01047 XColor fore, back;
01048 char **fontlist;
01049 int fontcount = 0;
01050 int i;
01051
01052 if (fDisplay) return 0;
01053
01054 fDisplay = disp;
01055 fScreenNumber = DefaultScreen(fDisplay);
01056
01057 FindBestVisual();
01058
01059 GetColor(1).fDefined = kTRUE;
01060 GetColor(1).fPixel = fBlackPixel;
01061 GetColor(0).fDefined = kTRUE;
01062 GetColor(0).fPixel = fWhitePixel;
01063
01064
01065 char vendor[132];
01066 strlcpy(vendor, XServerVendor(fDisplay),132);
01067
01068
01069 for (i = 0; i < kMAXGC; i++)
01070 gGClist[i] = XCreateGC(fDisplay, fVisRootWin, 0, 0);
01071
01072 XGCValues values;
01073 if (XGetGCValues(fDisplay, *gGCtext, GCForeground|GCBackground, &values)) {
01074 XSetForeground(fDisplay, *gGCinvt, values.background);
01075 XSetBackground(fDisplay, *gGCinvt, values.foreground);
01076 } else {
01077 Error("OpenDisplay", "cannot get GC values");
01078 }
01079
01080
01081
01082
01083 XSetGraphicsExposures(fDisplay, *gGCpxmp, False);
01084
01085
01086 XGCValues echov;
01087 echov.foreground = fBlackPixel;
01088 echov.background = fWhitePixel;
01089 if (strstr(vendor,"Hewlett"))
01090 echov.function = GXxor;
01091 else
01092 echov.function = GXinvert;
01093
01094 gGCecho = XCreateGC(fDisplay, fVisRootWin,
01095 GCForeground | GCBackground | GCFunction,
01096 &echov);
01097
01098
01099 static int isdisp = 0;
01100 if (!isdisp) {
01101 for (i = 0; i < kMAXFONT; i++) {
01102 gFont[i].id = 0;
01103 strcpy(gFont[i].name, " ");
01104 }
01105 fontlist = XListFonts(fDisplay, "*courier*", 1, &fontcount);
01106 if (fontcount != 0) {
01107 gFont[gCurrentFontNumber].id = XLoadQueryFont(fDisplay, fontlist[0]);
01108 gTextFont = gFont[gCurrentFontNumber].id;
01109 strcpy(gFont[gCurrentFontNumber].name, "*courier*");
01110 gCurrentFontNumber++;
01111 XFreeFontNames(fontlist);
01112 } else {
01113
01114 fontlist = XListFonts(fDisplay, "fixed", 1, &fontcount);
01115 if (fontcount != 0) {
01116 gFont[gCurrentFontNumber].id = XLoadQueryFont(fDisplay, fontlist[0]);
01117 gTextFont = gFont[gCurrentFontNumber].id;
01118 strcpy(gFont[gCurrentFontNumber].name, "fixed");
01119 gCurrentFontNumber++;
01120 XFreeFontNames(fontlist);
01121 } else {
01122 Warning("OpenDisplay", "no default font loaded");
01123 }
01124 }
01125 isdisp = 1;
01126 }
01127
01128
01129 pixmp1 = XCreateBitmapFromData(fDisplay, fRootWin,
01130 null_cursor_bits, 16, 16);
01131 pixmp2 = XCreateBitmapFromData(fDisplay, fRootWin,
01132 null_cursor_bits, 16, 16);
01133 gNullCursor = XCreatePixmapCursor(fDisplay,pixmp1,pixmp2,&fore,&back,0,0);
01134
01135
01136 fCursors[kBottomLeft] = XCreateFontCursor(fDisplay, XC_bottom_left_corner);
01137 fCursors[kBottomRight] = XCreateFontCursor(fDisplay, XC_bottom_right_corner);
01138 fCursors[kTopLeft] = XCreateFontCursor(fDisplay, XC_top_left_corner);
01139 fCursors[kTopRight] = XCreateFontCursor(fDisplay, XC_top_right_corner);
01140 fCursors[kBottomSide] = XCreateFontCursor(fDisplay, XC_bottom_side);
01141 fCursors[kLeftSide] = XCreateFontCursor(fDisplay, XC_left_side);
01142 fCursors[kTopSide] = XCreateFontCursor(fDisplay, XC_top_side);
01143 fCursors[kRightSide] = XCreateFontCursor(fDisplay, XC_right_side);
01144 fCursors[kMove] = XCreateFontCursor(fDisplay, XC_fleur);
01145 fCursors[kCross] = XCreateFontCursor(fDisplay, XC_tcross);
01146 fCursors[kArrowHor] = XCreateFontCursor(fDisplay, XC_sb_h_double_arrow);
01147 fCursors[kArrowVer] = XCreateFontCursor(fDisplay, XC_sb_v_double_arrow);
01148 fCursors[kHand] = XCreateFontCursor(fDisplay, XC_hand2);
01149 fCursors[kRotate] = XCreateFontCursor(fDisplay, XC_exchange);
01150 fCursors[kPointer] = XCreateFontCursor(fDisplay, XC_left_ptr);
01151 fCursors[kArrowRight] = XCreateFontCursor(fDisplay, XC_arrow);
01152 fCursors[kCaret] = XCreateFontCursor(fDisplay, XC_xterm);
01153 fCursors[kWatch] = XCreateFontCursor(fDisplay, XC_watch);
01154 fCursors[kNoDrop] = XCreateFontCursor(fDisplay, XC_pirate);
01155
01156
01157 fRedDiv = fGreenDiv = fBlueDiv = fRedShift = fGreenShift = fBlueShift = -1;
01158
01159 if (fVisual->c_class == TrueColor) {
01160 for (i = 0; i < int(sizeof(fVisual->blue_mask)*kBitsPerByte); i++) {
01161 if (fBlueShift == -1 && ((fVisual->blue_mask >> i) & 1))
01162 fBlueShift = i;
01163 if ((fVisual->blue_mask >> i) == 1) {
01164 fBlueDiv = sizeof(UShort_t)*kBitsPerByte - i - 1 + fBlueShift;
01165 break;
01166 }
01167 }
01168 for (i = 0; i < int(sizeof(fVisual->green_mask)*kBitsPerByte); i++) {
01169 if (fGreenShift == -1 && ((fVisual->green_mask >> i) & 1))
01170 fGreenShift = i;
01171 if ((fVisual->green_mask >> i) == 1) {
01172 fGreenDiv = sizeof(UShort_t)*kBitsPerByte - i - 1 + fGreenShift;
01173 break;
01174 }
01175 }
01176 for (i = 0; i < int(sizeof(fVisual->red_mask)*kBitsPerByte); i++) {
01177 if (fRedShift == -1 && ((fVisual->red_mask >> i) & 1))
01178 fRedShift = i;
01179 if ((fVisual->red_mask >> i) == 1) {
01180 fRedDiv = sizeof(UShort_t)*kBitsPerByte - i - 1 + fRedShift;
01181 break;
01182 }
01183 }
01184
01185
01186 }
01187
01188 return 0;
01189 }
01190
01191
01192 Int_t TGX11::OpenPixmap(unsigned int w, unsigned int h)
01193 {
01194
01195
01196
01197 Window root;
01198 unsigned int wval, hval;
01199 int xx, yy, i, wid;
01200 unsigned int ww, hh, border, depth;
01201 wval = w;
01202 hval = h;
01203
01204
01205
01206 again:
01207 for (wid = 0; wid < fMaxNumberOfWindows; wid++)
01208 if (!fWindows[wid].fOpen) {
01209 fWindows[wid].fOpen = 1;
01210 gCws = &fWindows[wid];
01211 break;
01212 }
01213
01214 if (wid == fMaxNumberOfWindows) {
01215 int newsize = fMaxNumberOfWindows + 10;
01216 fWindows = (XWindow_t*) TStorage::ReAlloc(fWindows, newsize*sizeof(XWindow_t),
01217 fMaxNumberOfWindows*sizeof(XWindow_t));
01218 for (i = fMaxNumberOfWindows; i < newsize; i++)
01219 fWindows[i].fOpen = 0;
01220 fMaxNumberOfWindows = newsize;
01221 goto again;
01222 }
01223
01224 gCws->fWindow = XCreatePixmap(fDisplay, fRootWin, wval, hval, fDepth);
01225 XGetGeometry(fDisplay, gCws->fWindow, &root, &xx, &yy, &ww, &hh, &border, &depth);
01226
01227 for (i = 0; i < kMAXGC; i++)
01228 XSetClipMask(fDisplay, gGClist[i], None);
01229
01230 SetColor(*gGCpxmp, 0);
01231 XFillRectangle(fDisplay, gCws->fWindow, *gGCpxmp, 0, 0, ww, hh);
01232 SetColor(*gGCpxmp, 1);
01233
01234
01235 gCws->fDrawing = gCws->fWindow;
01236 gCws->fBuffer = 0;
01237 gCws->fDoubleBuffer = 0;
01238 gCws->fIsPixmap = 1;
01239 gCws->fClip = 0;
01240 gCws->fWidth = wval;
01241 gCws->fHeight = hval;
01242 gCws->fNewColors = 0;
01243 gCws->fShared = kFALSE;
01244
01245 return wid;
01246 }
01247
01248
01249 Int_t TGX11::InitWindow(ULong_t win)
01250 {
01251
01252
01253
01254 XSetWindowAttributes attributes;
01255 ULong_t attr_mask = 0;
01256 int wid;
01257 int xval, yval;
01258 unsigned int wval, hval, border, depth;
01259 Window root;
01260
01261 Window wind = (Window) win;
01262
01263 XGetGeometry(fDisplay, wind, &root, &xval, &yval, &wval, &hval, &border, &depth);
01264
01265
01266
01267 again:
01268 for (wid = 0; wid < fMaxNumberOfWindows; wid++)
01269 if (!fWindows[wid].fOpen) {
01270 fWindows[wid].fOpen = 1;
01271 fWindows[wid].fDoubleBuffer = 0;
01272 gCws = &fWindows[wid];
01273 break;
01274 }
01275
01276 if (wid == fMaxNumberOfWindows) {
01277 int newsize = fMaxNumberOfWindows + 10;
01278 fWindows = (XWindow_t*) TStorage::ReAlloc(fWindows, newsize*sizeof(XWindow_t),
01279 fMaxNumberOfWindows*sizeof(XWindow_t));
01280 for (int i = fMaxNumberOfWindows; i < newsize; i++)
01281 fWindows[i].fOpen = 0;
01282 fMaxNumberOfWindows = newsize;
01283 goto again;
01284 }
01285
01286
01287
01288 attributes.background_pixel = GetColor(0).fPixel;
01289 attr_mask |= CWBackPixel;
01290 attributes.border_pixel = GetColor(1).fPixel;
01291 attr_mask |= CWBorderPixel;
01292 attributes.event_mask = NoEventMask;
01293 attr_mask |= CWEventMask;
01294 attributes.backing_store = Always;
01295 attr_mask |= CWBackingStore;
01296 attributes.bit_gravity = NorthWestGravity;
01297 attr_mask |= CWBitGravity;
01298 if (fColormap) {
01299 attributes.colormap = fColormap;
01300 attr_mask |= CWColormap;
01301 }
01302
01303 gCws->fWindow = XCreateWindow(fDisplay, wind,
01304 xval, yval, wval, hval, 0, fDepth,
01305 InputOutput, fVisual,
01306 attr_mask, &attributes);
01307
01308 XMapWindow(fDisplay, gCws->fWindow);
01309 XFlush(fDisplay);
01310
01311
01312
01313 gCws->fDrawing = gCws->fWindow;
01314 gCws->fBuffer = 0;
01315 gCws->fDoubleBuffer = 0;
01316 gCws->fIsPixmap = 0;
01317 gCws->fClip = 0;
01318 gCws->fWidth = wval;
01319 gCws->fHeight = hval;
01320 gCws->fNewColors = 0;
01321 gCws->fShared = kFALSE;
01322
01323 return wid;
01324 }
01325
01326
01327 Int_t TGX11::AddWindow(ULong_t qwid, UInt_t w, UInt_t h)
01328 {
01329
01330
01331 Int_t wid;
01332
01333
01334
01335 again:
01336 for (wid = 0; wid < fMaxNumberOfWindows; wid++)
01337 if (!fWindows[wid].fOpen) {
01338 fWindows[wid].fOpen = 1;
01339 fWindows[wid].fDoubleBuffer = 0;
01340 gCws = &fWindows[wid];
01341 break;
01342 }
01343
01344 if (wid == fMaxNumberOfWindows) {
01345 int newsize = fMaxNumberOfWindows + 10;
01346 fWindows = (XWindow_t*) TStorage::ReAlloc(fWindows, newsize*sizeof(XWindow_t),
01347 fMaxNumberOfWindows*sizeof(XWindow_t));
01348 for (int i = fMaxNumberOfWindows; i < newsize; i++)
01349 fWindows[i].fOpen = 0;
01350 fMaxNumberOfWindows = newsize;
01351 goto again;
01352 }
01353
01354 gCws->fWindow = qwid;
01355
01356
01357 gCws->fDrawing = gCws->fWindow;
01358 gCws->fBuffer = 0;
01359 gCws->fDoubleBuffer = 0;
01360 gCws->fIsPixmap = 0;
01361 gCws->fClip = 0;
01362 gCws->fWidth = w;
01363 gCws->fHeight = h;
01364 gCws->fNewColors = 0;
01365 gCws->fShared = kTRUE;
01366
01367 return wid;
01368 }
01369
01370
01371 void TGX11::RemoveWindow(ULong_t qwid)
01372 {
01373
01374
01375 SelectWindow((int)qwid);
01376
01377 if (gCws->fBuffer) XFreePixmap(fDisplay, gCws->fBuffer);
01378
01379 if (gCws->fNewColors) {
01380 if (fRedDiv == -1)
01381 XFreeColors(fDisplay, fColormap, gCws->fNewColors, gCws->fNcolors, 0);
01382 delete [] gCws->fNewColors;
01383 gCws->fNewColors = 0;
01384 }
01385
01386 gCws->fOpen = 0;
01387
01388
01389 for (Int_t wid = 0; wid < fMaxNumberOfWindows; wid++)
01390 if (fWindows[wid].fOpen) {
01391 gCws = &fWindows[wid];
01392 return;
01393 }
01394
01395 gCws = 0;
01396 }
01397
01398
01399 void TGX11::QueryPointer(int &ix, int &iy)
01400 {
01401
01402
01403
01404
01405
01406 Window root_return, child_return;
01407 int win_x_return, win_y_return;
01408 int root_x_return, root_y_return;
01409 unsigned int mask_return;
01410
01411 XQueryPointer(fDisplay,gCws->fWindow, &root_return,
01412 &child_return, &root_x_return, &root_y_return, &win_x_return,
01413 &win_y_return, &mask_return);
01414
01415 ix = root_x_return;
01416 iy = root_y_return;
01417 }
01418
01419
01420 void TGX11::RemovePixmap(Drawable *pix)
01421 {
01422
01423
01424 XFreePixmap(fDisplay,*pix);
01425 }
01426
01427
01428 Int_t TGX11::RequestLocator(int mode, int ctyp, int &x, int &y)
01429 {
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455 static int xloc = 0;
01456 static int yloc = 0;
01457 static int xlocp = 0;
01458 static int ylocp = 0;
01459 static Cursor cursor = 0;
01460
01461 XEvent event;
01462 int button_press;
01463 int radius;
01464
01465
01466 if (cursor == 0) {
01467 if (ctyp > 1) {
01468 XDefineCursor(fDisplay, gCws->fWindow, gNullCursor);
01469 XSetForeground(fDisplay, gGCecho, GetColor(0).fPixel);
01470 } else {
01471 cursor = XCreateFontCursor(fDisplay, XC_crosshair);
01472 XDefineCursor(fDisplay, gCws->fWindow, cursor);
01473 }
01474 }
01475
01476
01477
01478 button_press = 0;
01479
01480 while (button_press == 0) {
01481
01482 switch (ctyp) {
01483
01484 case 1 :
01485 break;
01486
01487 case 2 :
01488 XDrawLine(fDisplay, gCws->fWindow, gGCecho,
01489 xloc, 0, xloc, gCws->fHeight);
01490 XDrawLine(fDisplay, gCws->fWindow, gGCecho,
01491 0, yloc, gCws->fWidth, yloc);
01492 break;
01493
01494 case 3 :
01495 radius = (int) TMath::Sqrt((double)((xloc-xlocp)*(xloc-xlocp) +
01496 (yloc-ylocp)*(yloc-ylocp)));
01497 XDrawArc(fDisplay, gCws->fWindow, gGCecho,
01498 xlocp-radius, ylocp-radius,
01499 2*radius, 2*radius, 0, 23040);
01500 break;
01501
01502 case 4 :
01503 XDrawLine(fDisplay, gCws->fWindow, gGCecho,
01504 xlocp, ylocp, xloc, yloc);
01505 break;
01506
01507 case 5 :
01508 XDrawRectangle(fDisplay, gCws->fWindow, gGCecho,
01509 TMath::Min(xlocp,xloc), TMath::Min(ylocp,yloc),
01510 TMath::Abs(xloc-xlocp), TMath::Abs(yloc-ylocp));
01511 break;
01512
01513 default:
01514 break;
01515 }
01516
01517 while (XEventsQueued( fDisplay, QueuedAlready) > 1) {
01518 XNextEvent(fDisplay, &event);
01519 }
01520 XWindowEvent(fDisplay, gCws->fWindow, gMouseMask, &event);
01521
01522 switch (ctyp) {
01523
01524 case 1 :
01525 break;
01526
01527 case 2 :
01528 XDrawLine(fDisplay, gCws->fWindow, gGCecho,
01529 xloc, 0, xloc, gCws->fHeight);
01530 XDrawLine(fDisplay, gCws->fWindow, gGCecho,
01531 0, yloc, gCws->fWidth, yloc);
01532 break;
01533
01534 case 3 :
01535 radius = (int) TMath::Sqrt((double)((xloc-xlocp)*(xloc-xlocp) +
01536 (yloc-ylocp)*(yloc-ylocp)));
01537 XDrawArc(fDisplay, gCws->fWindow, gGCecho,
01538 xlocp-radius, ylocp-radius,
01539 2*radius, 2*radius, 0, 23040);
01540 break;
01541
01542 case 4 :
01543 XDrawLine(fDisplay, gCws->fWindow, gGCecho,
01544 xlocp, ylocp, xloc, yloc);
01545 break;
01546
01547 case 5 :
01548 XDrawRectangle(fDisplay, gCws->fWindow, gGCecho,
01549 TMath::Min(xlocp,xloc), TMath::Min(ylocp,yloc),
01550 TMath::Abs(xloc-xlocp), TMath::Abs(yloc-ylocp));
01551 break;
01552
01553 default:
01554 break;
01555 }
01556
01557 xloc = event.xbutton.x;
01558 yloc = event.xbutton.y;
01559
01560 switch (event.type) {
01561
01562 case LeaveNotify :
01563 if (mode == 0) {
01564 while (1) {
01565 XNextEvent(fDisplay, &event);
01566 if (event.type == EnterNotify) break;
01567 }
01568 } else {
01569 button_press = -2;
01570 }
01571 break;
01572
01573 case ButtonPress :
01574 button_press = event.xbutton.button ;
01575 xlocp = event.xbutton.x;
01576 ylocp = event.xbutton.y;
01577 XUndefineCursor( fDisplay, gCws->fWindow );
01578 cursor = 0;
01579 break;
01580
01581 case ButtonRelease :
01582 if (mode == 1) {
01583 button_press = 10+event.xbutton.button ;
01584 xlocp = event.xbutton.x;
01585 ylocp = event.xbutton.y;
01586 }
01587 break;
01588
01589 case KeyPress :
01590 if (mode == 1) {
01591 button_press = event.xkey.keycode;
01592 xlocp = event.xbutton.x;
01593 ylocp = event.xbutton.y;
01594 }
01595 break;
01596
01597 case KeyRelease :
01598 if (mode == 1) {
01599 button_press = -event.xkey.keycode;
01600 xlocp = event.xbutton.x;
01601 ylocp = event.xbutton.y;
01602 }
01603 break;
01604
01605 default :
01606 break;
01607 }
01608
01609 if (mode == 1) {
01610 if (button_press == 0)
01611 button_press = -1;
01612 break;
01613 }
01614 }
01615 x = event.xbutton.x;
01616 y = event.xbutton.y;
01617
01618 return button_press;
01619 }
01620
01621
01622 Int_t TGX11::RequestString(int x, int y, char *text)
01623 {
01624
01625
01626
01627
01628
01629
01630
01631
01632 static Cursor cursor = 0;
01633 static int percent = 0;
01634 Window focuswindow;
01635 int focusrevert;
01636 XEvent event;
01637 KeySym keysym;
01638 int key = -1;
01639 int len_text = strlen(text);
01640 int nt;
01641 int pt;
01642
01643
01644 if (cursor == 0) {
01645 XKeyboardState kbstate;
01646 cursor = XCreateFontCursor(fDisplay, XC_question_arrow);
01647 XGetKeyboardControl(fDisplay, &kbstate);
01648 percent = kbstate.bell_percent;
01649 }
01650 if (cursor != 0)
01651 XDefineCursor(fDisplay, gCws->fWindow, cursor);
01652 for (nt = len_text; nt > 0 && text[nt-1] == ' '; nt--) { }
01653 pt = nt;
01654 XGetInputFocus(fDisplay, &focuswindow, &focusrevert);
01655 XSetInputFocus(fDisplay, gCws->fWindow, focusrevert, CurrentTime);
01656 while (key < 0) {
01657 char keybuf[8];
01658 char nbytes;
01659 int dx;
01660 int i;
01661 XDrawImageString(fDisplay, gCws->fWindow, *gGCtext, x, y, text, nt);
01662 dx = XTextWidth(gTextFont, text, nt);
01663 XDrawImageString(fDisplay, gCws->fWindow, *gGCtext, x + dx, y, " ", 1);
01664 dx = pt == 0 ? 0 : XTextWidth(gTextFont, text, pt);
01665 XDrawImageString(fDisplay, gCws->fWindow, *gGCinvt,
01666 x + dx, y, pt < len_text ? &text[pt] : " ", 1);
01667 XWindowEvent(fDisplay, gCws->fWindow, gKeybdMask, &event);
01668 switch (event.type) {
01669 case ButtonPress:
01670 case EnterNotify:
01671 XSetInputFocus(fDisplay, gCws->fWindow, focusrevert, CurrentTime);
01672 break;
01673 case LeaveNotify:
01674 XSetInputFocus(fDisplay, focuswindow, focusrevert, CurrentTime);
01675 break;
01676 case KeyPress:
01677 nbytes = XLookupString(&event.xkey, keybuf, sizeof(keybuf),
01678 &keysym, 0);
01679 switch (keysym) {
01680 case XK_Left:
01681 keybuf[0] = '\002';
01682 nbytes = 1;
01683 break;
01684 case XK_Right:
01685 keybuf[0] = '\006';
01686 nbytes = 1;
01687 break;
01688 }
01689 if (nbytes == 1) {
01690 if (isascii(keybuf[0]) && isprint(keybuf[0])) {
01691
01692 if (nt < len_text)
01693 nt++;
01694 for (i = nt - 1; i > pt; i--)
01695 text[i] = text[i-1];
01696 if (pt < len_text) {
01697 text[pt] = keybuf[0];
01698 pt++;
01699 }
01700 } else
01701 switch (keybuf[0]) {
01702
01703
01704 case '\010':
01705 case '\177':
01706
01707 if (pt > 0) {
01708 for (i = pt; i < nt; i++)
01709 text[i-1] = text[i];
01710 text[nt-1] = ' ';
01711 nt--;
01712 pt--;
01713 }
01714 break;
01715 case '\001':
01716
01717 pt = 0;
01718 break;
01719 case '\002':
01720
01721 if (pt > 0)
01722 pt--;
01723 break;
01724 case '\004':
01725
01726 if (pt > 0) {
01727 for (i = pt; i < nt; i++)
01728 text[i-1] = text[i];
01729 text[nt-1] = ' ';
01730 pt--;
01731 }
01732 break;
01733 case '\005':
01734
01735 pt = nt;
01736 break;
01737
01738 case '\006':
01739
01740 if (pt < nt)
01741 pt++;
01742 break;
01743 case '\013':
01744
01745 for (i = pt; i < nt; i++)
01746 text[i] = ' ';
01747 nt = pt;
01748 break;
01749 case '\024':
01750
01751 if (pt > 0) {
01752 char c = text[pt];
01753 text[pt] = text[pt-1];
01754 text[pt-1] = c;
01755 }
01756 break;
01757 case '\012':
01758 case '\015':
01759 key = 1;
01760 break;
01761 case '\033':
01762 key = 0;
01763 break;
01764
01765 default:
01766 XBell(fDisplay, percent);
01767 }
01768 }
01769 }
01770 }
01771 XSetInputFocus(fDisplay, focuswindow, focusrevert, CurrentTime);
01772
01773 if (cursor != 0) {
01774 XUndefineCursor(fDisplay, gCws->fWindow);
01775 cursor = 0;
01776 }
01777
01778 return key;
01779 }
01780
01781
01782 void TGX11::RescaleWindow(int wid, unsigned int w, unsigned int h)
01783 {
01784
01785
01786
01787
01788
01789 int i;
01790
01791 gTws = &fWindows[wid];
01792 if (!gTws->fOpen) return;
01793
01794
01795 if (gTws->fWidth == w && gTws->fHeight == h) return;
01796
01797 XResizeWindow(fDisplay, gTws->fWindow, w, h);
01798
01799 if (gTws->fBuffer) {
01800
01801 if (gTws->fWidth < w || gTws->fHeight < h) {
01802 XFreePixmap(fDisplay,gTws->fBuffer);
01803 gTws->fBuffer = XCreatePixmap(fDisplay, fRootWin, w, h, fDepth);
01804 }
01805 for (i = 0; i < kMAXGC; i++) XSetClipMask(fDisplay, gGClist[i], None);
01806 SetColor(*gGCpxmp, 0);
01807 XFillRectangle( fDisplay, gTws->fBuffer, *gGCpxmp, 0, 0, w, h);
01808 SetColor(*gGCpxmp, 1);
01809 if (gTws->fDoubleBuffer) gTws->fDrawing = gTws->fBuffer;
01810 }
01811 gTws->fWidth = w;
01812 gTws->fHeight = h;
01813 }
01814
01815
01816 int TGX11::ResizePixmap(int wid, unsigned int w, unsigned int h)
01817 {
01818
01819
01820
01821
01822 Window root;
01823 unsigned int wval, hval;
01824 int xx, yy, i;
01825 unsigned int ww, hh, border, depth;
01826 wval = w;
01827 hval = h;
01828
01829 gTws = &fWindows[wid];
01830
01831
01832
01833
01834
01835
01836 if (gTws->fWidth >= wval-1 && gTws->fWidth <= wval+1 &&
01837 gTws->fHeight >= hval-1 && gTws->fHeight <= hval+1) return 0;
01838
01839
01840 if (gTws->fWidth < wval || gTws->fHeight < hval) {
01841 XFreePixmap(fDisplay, gTws->fWindow);
01842 gTws->fWindow = XCreatePixmap(fDisplay, fRootWin, wval, hval, fDepth);
01843 }
01844 XGetGeometry(fDisplay, gTws->fWindow, &root, &xx, &yy, &ww, &hh, &border, &depth);
01845
01846 for (i = 0; i < kMAXGC; i++)
01847 XSetClipMask(fDisplay, gGClist[i], None);
01848
01849 SetColor(*gGCpxmp, 0);
01850 XFillRectangle(fDisplay, gTws->fWindow, *gGCpxmp, 0, 0, ww, hh);
01851 SetColor(*gGCpxmp, 1);
01852
01853
01854 gTws->fDrawing = gTws->fWindow;
01855 gTws->fWidth = wval;
01856 gTws->fHeight = hval;
01857
01858 return 1;
01859 }
01860
01861
01862 void TGX11::ResizeWindow(int wid)
01863 {
01864
01865
01866 int i;
01867 int xval=0, yval=0;
01868 Window win, root=0;
01869 unsigned int wval=0, hval=0, border=0, depth=0;
01870
01871 gTws = &fWindows[wid];
01872
01873 win = gTws->fWindow;
01874
01875 XGetGeometry(fDisplay, win, &root,
01876 &xval, &yval, &wval, &hval, &border, &depth);
01877 if (wval >= 65500) wval = 1;
01878 if (hval >= 65500) hval = 1;
01879
01880
01881 if (gTws->fWidth == wval && gTws->fHeight == hval) return;
01882
01883 XResizeWindow(fDisplay, gTws->fWindow, wval, hval);
01884
01885 if (gTws->fBuffer) {
01886 if (gTws->fWidth < wval || gTws->fHeight < hval) {
01887 XFreePixmap(fDisplay,gTws->fBuffer);
01888 gTws->fBuffer = XCreatePixmap(fDisplay, fRootWin, wval, hval, fDepth);
01889 }
01890 for (i = 0; i < kMAXGC; i++) XSetClipMask(fDisplay, gGClist[i], None);
01891 SetColor(*gGCpxmp, 0);
01892 XFillRectangle(fDisplay, gTws->fBuffer, *gGCpxmp, 0, 0, wval, hval);
01893 SetColor(*gGCpxmp, 1);
01894 if (gTws->fDoubleBuffer) gTws->fDrawing = gTws->fBuffer;
01895 }
01896 gTws->fWidth = wval;
01897 gTws->fHeight = hval;
01898 }
01899
01900
01901 void TGX11::SelectWindow(int wid)
01902 {
01903
01904
01905 XRectangle region;
01906 int i;
01907
01908 if (wid < 0 || wid >= fMaxNumberOfWindows || !fWindows[wid].fOpen) return;
01909
01910 gCws = &fWindows[wid];
01911
01912 if (gCws->fClip && !gCws->fIsPixmap && !gCws->fDoubleBuffer) {
01913 region.x = gCws->fXclip;
01914 region.y = gCws->fYclip;
01915 region.width = gCws->fWclip;
01916 region.height = gCws->fHclip;
01917 for (i = 0; i < kMAXGC; i++)
01918 XSetClipRectangles(fDisplay, gGClist[i], 0, 0, ®ion, 1, YXBanded);
01919 } else {
01920 for (i = 0; i < kMAXGC; i++)
01921 XSetClipMask(fDisplay, gGClist[i], None);
01922 }
01923 }
01924
01925
01926 void TGX11::SetCharacterUp(Float_t chupx, Float_t chupy)
01927 {
01928
01929
01930 if (chupx == fCharacterUpX && chupy == fCharacterUpY) return;
01931
01932 if (chupx == 0 && chupy == 0) fTextAngle = 0;
01933 else if (chupx == 0 && chupy == 1) fTextAngle = 0;
01934 else if (chupx == -1 && chupy == 0) fTextAngle = 90;
01935 else if (chupx == 0 && chupy == -1) fTextAngle = 180;
01936 else if (chupx == 1 && chupy == 0) fTextAngle = 270;
01937 else {
01938 fTextAngle = ((TMath::ACos(chupx/TMath::Sqrt(chupx*chupx +chupy*chupy))*180.)/TMath::Pi())-90;
01939 if (chupy < 0) fTextAngle = 180 - fTextAngle;
01940 if (TMath::Abs(fTextAngle) <= 0.01) fTextAngle = 0;
01941 }
01942 fCharacterUpX = chupx;
01943 fCharacterUpY = chupy;
01944 }
01945
01946
01947 void TGX11::SetClipOFF(int wid)
01948 {
01949
01950
01951 gTws = &fWindows[wid];
01952 gTws->fClip = 0;
01953
01954 for (int i = 0; i < kMAXGC; i++)
01955 XSetClipMask( fDisplay, gGClist[i], None );
01956 }
01957
01958
01959 void TGX11::SetClipRegion(int wid, int x, int y, unsigned int w, unsigned int h)
01960 {
01961
01962
01963
01964
01965
01966
01967 gTws = &fWindows[wid];
01968 gTws->fXclip = x;
01969 gTws->fYclip = y;
01970 gTws->fWclip = w;
01971 gTws->fHclip = h;
01972 gTws->fClip = 1;
01973 if (gTws->fClip && !gTws->fIsPixmap && !gTws->fDoubleBuffer) {
01974 XRectangle region;
01975 region.x = gTws->fXclip;
01976 region.y = gTws->fYclip;
01977 region.width = gTws->fWclip;
01978 region.height = gTws->fHclip;
01979 for (int i = 0; i < kMAXGC; i++)
01980 XSetClipRectangles(fDisplay, gGClist[i], 0, 0, ®ion, 1, YXBanded);
01981 }
01982 }
01983
01984
01985 void TGX11::SetColor(GC gc, int ci)
01986 {
01987
01988
01989 TColor *color = gROOT->GetColor(ci);
01990 if (color)
01991 SetRGB(ci, color->GetRed(), color->GetGreen(), color->GetBlue());
01992
01993
01994
01995 XColor_t &col = GetColor(ci);
01996 if (fColormap && !col.fDefined) {
01997 col = GetColor(0);
01998 } else if (!fColormap && (ci < 0 || ci > 1)) {
01999 col = GetColor(0);
02000 }
02001
02002 if (fDrawMode == kXor) {
02003 XGCValues values;
02004 XGetGCValues(fDisplay, gc, GCBackground, &values);
02005 XSetForeground(fDisplay, gc, col.fPixel ^ values.background);
02006 } else {
02007 XSetForeground(fDisplay, gc, col.fPixel);
02008
02009
02010 XGCValues values;
02011 XGetGCValues(fDisplay, gc, GCForeground | GCBackground, &values);
02012 if (values.foreground == values.background)
02013 XSetBackground(fDisplay, gc, GetColor(!ci).fPixel);
02014 }
02015 }
02016
02017
02018 void TGX11::SetCursor(int wid, ECursor cursor)
02019 {
02020
02021
02022 gTws = &fWindows[wid];
02023 XDefineCursor(fDisplay, gTws->fWindow, fCursors[cursor]);
02024 }
02025
02026
02027 void TGX11::SetDoubleBuffer(int wid, int mode)
02028 {
02029
02030
02031
02032
02033
02034
02035 if (wid == 999) {
02036 for (int i = 0; i < fMaxNumberOfWindows; i++) {
02037 gTws = &fWindows[i];
02038 if (gTws->fOpen) {
02039 switch (mode) {
02040 case 1 :
02041 SetDoubleBufferON();
02042 break;
02043 default:
02044 SetDoubleBufferOFF();
02045 break;
02046 }
02047 }
02048 }
02049 } else {
02050 gTws = &fWindows[wid];
02051 if (!gTws->fOpen) return;
02052 switch (mode) {
02053 case 1 :
02054 SetDoubleBufferON();
02055 return;
02056 default:
02057 SetDoubleBufferOFF();
02058 return;
02059 }
02060 }
02061 }
02062
02063
02064 void TGX11::SetDoubleBufferOFF()
02065 {
02066
02067
02068 if (!gTws->fDoubleBuffer) return;
02069 gTws->fDoubleBuffer = 0;
02070 gTws->fDrawing = gTws->fWindow;
02071 }
02072
02073
02074 void TGX11::SetDoubleBufferON()
02075 {
02076
02077
02078 if (gTws->fDoubleBuffer || gTws->fIsPixmap) return;
02079 if (!gTws->fBuffer) {
02080 gTws->fBuffer = XCreatePixmap(fDisplay, fRootWin,
02081 gTws->fWidth, gTws->fHeight, fDepth);
02082 SetColor(*gGCpxmp, 0);
02083 XFillRectangle(fDisplay, gTws->fBuffer, *gGCpxmp, 0, 0, gTws->fWidth, gTws->fHeight);
02084 SetColor(*gGCpxmp, 1);
02085 }
02086 for (int i = 0; i < kMAXGC; i++) XSetClipMask(fDisplay, gGClist[i], None);
02087 gTws->fDoubleBuffer = 1;
02088 gTws->fDrawing = gTws->fBuffer;
02089 }
02090
02091
02092 void TGX11::SetDrawMode(EDrawMode mode)
02093 {
02094
02095
02096
02097
02098
02099
02100
02101
02102 int i;
02103 switch (mode) {
02104 case kCopy:
02105 for (i = 0; i < kMAXGC; i++) XSetFunction(fDisplay, gGClist[i], GXcopy);
02106 break;
02107
02108 case kXor:
02109 for (i = 0; i < kMAXGC; i++) XSetFunction(fDisplay, gGClist[i], GXxor);
02110 break;
02111
02112 case kInvert:
02113 for (i = 0; i < kMAXGC; i++) XSetFunction(fDisplay, gGClist[i], GXinvert);
02114 break;
02115 }
02116 fDrawMode = mode;
02117 }
02118
02119
02120 void TGX11::SetFillColor(Color_t cindex)
02121 {
02122
02123
02124 if (!gStyle->GetFillColor() && cindex > 1) cindex = 0;
02125 if (cindex >= 0) SetColor(*gGCfill, Int_t(cindex));
02126 fFillColor = cindex;
02127
02128
02129 if (gFillPattern != 0) {
02130 XFreePixmap(fDisplay, gFillPattern);
02131 gFillPattern = 0;
02132 }
02133 }
02134
02135
02136 void TGX11::SetFillStyle(Style_t fstyle)
02137 {
02138
02139
02140
02141
02142 if (fFillStyle == fstyle) return;
02143 fFillStyle = fstyle;
02144 Int_t style = fstyle/1000;
02145 Int_t fasi = fstyle%1000;
02146 SetFillStyleIndex(style,fasi);
02147 }
02148
02149
02150 void TGX11::SetFillStyleIndex(Int_t style, Int_t fasi)
02151 {
02152
02153
02154 static int current_fasi = 0;
02155
02156 fFillStyle = 1000*style + fasi;
02157
02158 switch (style) {
02159
02160 case 1:
02161 gFillHollow = 0;
02162 XSetFillStyle(fDisplay, *gGCfill, FillSolid);
02163 break;
02164
02165 case 2:
02166 gFillHollow = 1;
02167 break;
02168
02169 case 3:
02170 gFillHollow = 0;
02171 XSetFillStyle(fDisplay, *gGCfill, FillStippled);
02172 if (fasi != current_fasi) {
02173 if (gFillPattern != 0) {
02174 XFreePixmap(fDisplay, gFillPattern);
02175 gFillPattern = 0;
02176 }
02177 int stn = (fasi >= 1 && fasi <=25) ? fasi : 2;
02178
02179 gFillPattern = XCreateBitmapFromData(fDisplay, fRootWin,
02180 (const char*)gStipples[stn], 16, 16);
02181
02182 XSetStipple( fDisplay, *gGCfill, gFillPattern );
02183 current_fasi = fasi;
02184 }
02185 break;
02186
02187 default:
02188 gFillHollow = 1;
02189 }
02190 }
02191
02192
02193 void TGX11::SetInput(int inp)
02194 {
02195
02196
02197 XSetWindowAttributes attributes;
02198 ULong_t attr_mask;
02199
02200 if (inp == 1) {
02201 attributes.event_mask = gMouseMask | gKeybdMask;
02202 attr_mask = CWEventMask;
02203 XChangeWindowAttributes(fDisplay, gCws->fWindow, attr_mask, &attributes);
02204 } else {
02205 attributes.event_mask = NoEventMask;
02206 attr_mask = CWEventMask;
02207 XChangeWindowAttributes(fDisplay, gCws->fWindow, attr_mask, &attributes);
02208 }
02209 }
02210
02211
02212 void TGX11::SetLineColor(Color_t cindex)
02213 {
02214
02215
02216 if (cindex < 0) return;
02217
02218 TAttLine::SetLineColor(cindex);
02219
02220 SetColor(*gGCline, Int_t(cindex));
02221 SetColor(*gGCdash, Int_t(cindex));
02222 }
02223
02224
02225 void TGX11::SetLineType(int n, int *dash)
02226 {
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236 if (n <= 0) {
02237 gLineStyle = LineSolid;
02238 XSetLineAttributes(fDisplay, *gGCline, gLineWidth,
02239 gLineStyle, gCapStyle, gJoinStyle);
02240 } else {
02241 gDashSize = TMath::Min((int)sizeof(gDashList),n);
02242 gDashLength = 0;
02243 for (int i = 0; i < gDashSize; i++ ) {
02244 gDashList[i] = dash[i];
02245 gDashLength += gDashList[i];
02246 }
02247 gDashOffset = 0;
02248 gLineStyle = LineOnOffDash;
02249 XSetLineAttributes(fDisplay, *gGCline, gLineWidth,
02250 gLineStyle, gCapStyle, gJoinStyle);
02251 XSetLineAttributes(fDisplay, *gGCdash, gLineWidth,
02252 gLineStyle, gCapStyle, gJoinStyle);
02253 }
02254 }
02255
02256
02257 void TGX11::SetLineStyle(Style_t lstyle)
02258 {
02259
02260
02261 static Int_t dashed[2] = {3,3};
02262 static Int_t dotted[2] = {1,2};
02263 static Int_t dasheddotted[4] = {3,4,1,4};
02264
02265 if (fLineStyle != lstyle) {
02266 fLineStyle = lstyle;
02267 if (lstyle <= 1 ) {
02268 SetLineType(0,0);
02269 } else if (lstyle == 2 ) {
02270 SetLineType(2,dashed);
02271 } else if (lstyle == 3 ) {
02272 SetLineType(2,dotted);
02273 } else if (lstyle == 4 ) {
02274 SetLineType(4,dasheddotted);
02275 } else {
02276 TString st = (TString)gStyle->GetLineStyleString(lstyle);
02277 TObjArray *tokens = st.Tokenize(" ");
02278 Int_t nt;
02279 nt = tokens->GetEntries();
02280 Int_t *linestyle = new Int_t[nt];
02281 for (Int_t j = 0; j<nt; j++) {
02282 Int_t it;
02283 sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
02284 linestyle[j] = (Int_t)(it/4);
02285 }
02286 SetLineType(nt,linestyle);
02287 delete [] linestyle;
02288 delete tokens;
02289 }
02290 }
02291 }
02292
02293
02294 void TGX11::SetLineWidth(Width_t width )
02295 {
02296
02297
02298
02299 if (fLineWidth == width) return;
02300 if (width == 1) gLineWidth = 0;
02301 else gLineWidth = width;
02302
02303 fLineWidth = gLineWidth;
02304 if (gLineWidth < 0) return;
02305
02306 XSetLineAttributes(fDisplay, *gGCline, gLineWidth,
02307 gLineStyle, gCapStyle, gJoinStyle);
02308 XSetLineAttributes(fDisplay, *gGCdash, gLineWidth,
02309 gLineStyle, gCapStyle, gJoinStyle);
02310 }
02311
02312
02313 void TGX11::SetMarkerColor(Color_t cindex)
02314 {
02315
02316
02317 if (cindex < 0) return;
02318
02319 TAttMarker::SetMarkerColor(cindex);
02320
02321 SetColor(*gGCmark, Int_t(cindex));
02322 }
02323
02324
02325 void TGX11::SetMarkerSize(Float_t msize)
02326 {
02327
02328
02329
02330 if (msize == fMarkerSize) return;
02331
02332 fMarkerSize = msize;
02333 if (msize < 0) return;
02334
02335 SetMarkerStyle(-fMarkerStyle);
02336 }
02337
02338
02339 void TGX11::SetMarkerType(int type, int n, XPoint *xy)
02340 {
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354 gMarker.type = type;
02355 gMarker.n = n < kMAXMK ? n : kMAXMK;
02356 if (gMarker.type >= 2) {
02357 for (int i = 0; i < gMarker.n; i++) {
02358 gMarker.xy[i].x = xy[i].x;
02359 gMarker.xy[i].y = xy[i].y;
02360 }
02361 }
02362 }
02363
02364
02365 void TGX11::SetMarkerStyle(Style_t markerstyle)
02366 {
02367
02368
02369 if (fMarkerStyle == markerstyle) return;
02370 static XPoint shape[15];
02371 if (markerstyle >= 35) return;
02372 markerstyle = TMath::Abs(markerstyle);
02373 fMarkerStyle = markerstyle;
02374 Int_t im = Int_t(4*fMarkerSize + 0.5);
02375 if (markerstyle == 2) {
02376
02377 shape[0].x = -im; shape[0].y = 0;
02378 shape[1].x = im; shape[1].y = 0;
02379 shape[2].x = 0 ; shape[2].y = -im;
02380 shape[3].x = 0 ; shape[3].y = im;
02381 SetMarkerType(4,4,shape);
02382 } else if (markerstyle == 3 || markerstyle == 31) {
02383
02384 shape[0].x = -im; shape[0].y = 0;
02385 shape[1].x = im; shape[1].y = 0;
02386 shape[2].x = 0 ; shape[2].y = -im;
02387 shape[3].x = 0 ; shape[3].y = im;
02388 im = Int_t(0.707*Float_t(im) + 0.5);
02389 shape[4].x = -im; shape[4].y = -im;
02390 shape[5].x = im; shape[5].y = im;
02391 shape[6].x = -im; shape[6].y = im;
02392 shape[7].x = im; shape[7].y = -im;
02393 SetMarkerType(4,8,shape);
02394 } else if (markerstyle == 4 || markerstyle == 24) {
02395
02396 SetMarkerType(0,im*2,shape);
02397 } else if (markerstyle == 5) {
02398
02399 im = Int_t(0.707*Float_t(im) + 0.5);
02400 shape[0].x = -im; shape[0].y = -im;
02401 shape[1].x = im; shape[1].y = im;
02402 shape[2].x = -im; shape[2].y = im;
02403 shape[3].x = im; shape[3].y = -im;
02404 SetMarkerType(4,4,shape);
02405 } else if (markerstyle == 6) {
02406
02407 shape[0].x = -1 ; shape[0].y = 0;
02408 shape[1].x = 1 ; shape[1].y = 0;
02409 shape[2].x = 0 ; shape[2].y = -1;
02410 shape[3].x = 0 ; shape[3].y = 1;
02411 SetMarkerType(4,4,shape);
02412 } else if (markerstyle == 7) {
02413
02414 shape[0].x = -1 ; shape[0].y = 1;
02415 shape[1].x = 1 ; shape[1].y = 1;
02416 shape[2].x = -1 ; shape[2].y = 0;
02417 shape[3].x = 1 ; shape[3].y = 0;
02418 shape[4].x = -1 ; shape[4].y = -1;
02419 shape[5].x = 1 ; shape[5].y = -1;
02420 SetMarkerType(4,6,shape);
02421 } else if (markerstyle == 8 || markerstyle == 20) {
02422
02423 SetMarkerType(1,im*2,shape);
02424 } else if (markerstyle == 21) {
02425
02426 shape[0].x = -im; shape[0].y = -im;
02427 shape[1].x = im; shape[1].y = -im;
02428 shape[2].x = im; shape[2].y = im;
02429 shape[3].x = -im; shape[3].y = im;
02430 shape[4].x = -im; shape[4].y = -im;
02431 SetMarkerType(3,5,shape);
02432 } else if (markerstyle == 22) {
02433
02434 shape[0].x = -im; shape[0].y = im;
02435 shape[1].x = im; shape[1].y = im;
02436 shape[2].x = 0; shape[2].y = -im;
02437 shape[3].x = -im; shape[3].y = im;
02438 SetMarkerType(3,4,shape);
02439 } else if (markerstyle == 23) {
02440
02441 shape[0].x = 0; shape[0].y = im;
02442 shape[1].x = im; shape[1].y = -im;
02443 shape[2].x = -im; shape[2].y = -im;
02444 shape[3].x = 0; shape[3].y = im;
02445 SetMarkerType(3,4,shape);
02446 } else if (markerstyle == 25) {
02447
02448 shape[0].x = -im; shape[0].y = -im;
02449 shape[1].x = im; shape[1].y = -im;
02450 shape[2].x = im; shape[2].y = im;
02451 shape[3].x = -im; shape[3].y = im;
02452 shape[4].x = -im; shape[4].y = -im;
02453 SetMarkerType(2,5,shape);
02454 } else if (markerstyle == 26) {
02455
02456 shape[0].x = -im; shape[0].y = im;
02457 shape[1].x = im; shape[1].y = im;
02458 shape[2].x = 0; shape[2].y = -im;
02459 shape[3].x = -im; shape[3].y = im;
02460 SetMarkerType(2,4,shape);
02461 } else if (markerstyle == 27) {
02462
02463 Int_t imx = Int_t(2.66*fMarkerSize + 0.5);
02464 shape[0].x =-imx; shape[0].y = 0;
02465 shape[1].x = 0; shape[1].y = -im;
02466 shape[2].x = imx; shape[2].y = 0;
02467 shape[3].x = 0; shape[3].y = im;
02468 shape[4].x =-imx; shape[4].y = 0;
02469 SetMarkerType(2,5,shape);
02470 } else if (markerstyle == 28) {
02471
02472 Int_t imx = Int_t(1.33*fMarkerSize + 0.5);
02473 shape[0].x = -im; shape[0].y =-imx;
02474 shape[1].x =-imx; shape[1].y =-imx;
02475 shape[2].x =-imx; shape[2].y = -im;
02476 shape[3].x = imx; shape[3].y = -im;
02477 shape[4].x = imx; shape[4].y =-imx;
02478 shape[5].x = im; shape[5].y =-imx;
02479 shape[6].x = im; shape[6].y = imx;
02480 shape[7].x = imx; shape[7].y = imx;
02481 shape[8].x = imx; shape[8].y = im;
02482 shape[9].x =-imx; shape[9].y = im;
02483 shape[10].x=-imx; shape[10].y= imx;
02484 shape[11].x= -im; shape[11].y= imx;
02485 shape[12].x= -im; shape[12].y=-imx;
02486 SetMarkerType(2,13,shape);
02487 } else if (markerstyle == 29) {
02488
02489 Int_t im1 = Int_t(0.66*fMarkerSize + 0.5);
02490 Int_t im2 = Int_t(2.00*fMarkerSize + 0.5);
02491 Int_t im3 = Int_t(2.66*fMarkerSize + 0.5);
02492 Int_t im4 = Int_t(1.33*fMarkerSize + 0.5);
02493 shape[0].x = -im; shape[0].y = im4;
02494 shape[1].x =-im2; shape[1].y =-im1;
02495 shape[2].x =-im3; shape[2].y = -im;
02496 shape[3].x = 0; shape[3].y =-im2;
02497 shape[4].x = im3; shape[4].y = -im;
02498 shape[5].x = im2; shape[5].y =-im1;
02499 shape[6].x = im; shape[6].y = im4;
02500 shape[7].x = im4; shape[7].y = im4;
02501 shape[8].x = 0; shape[8].y = im;
02502 shape[9].x =-im4; shape[9].y = im4;
02503 shape[10].x= -im; shape[10].y= im4;
02504 SetMarkerType(3,11,shape);
02505 } else if (markerstyle == 30) {
02506
02507 Int_t im1 = Int_t(0.66*fMarkerSize + 0.5);
02508 Int_t im2 = Int_t(2.00*fMarkerSize + 0.5);
02509 Int_t im3 = Int_t(2.66*fMarkerSize + 0.5);
02510 Int_t im4 = Int_t(1.33*fMarkerSize + 0.5);
02511 shape[0].x = -im; shape[0].y = im4;
02512 shape[1].x =-im2; shape[1].y =-im1;
02513 shape[2].x =-im3; shape[2].y = -im;
02514 shape[3].x = 0; shape[3].y =-im2;
02515 shape[4].x = im3; shape[4].y = -im;
02516 shape[5].x = im2; shape[5].y =-im1;
02517 shape[6].x = im; shape[6].y = im4;
02518 shape[7].x = im4; shape[7].y = im4;
02519 shape[8].x = 0; shape[8].y = im;
02520 shape[9].x =-im4; shape[9].y = im4;
02521 shape[10].x= -im; shape[10].y= im4;
02522 SetMarkerType(2,11,shape);
02523 } else if (markerstyle == 32) {
02524
02525 shape[0].x = 0; shape[0].y = im;
02526 shape[1].x = im; shape[1].y = -im;
02527 shape[2].x = -im; shape[2].y = -im;
02528 shape[3].x = 0; shape[3].y = im;
02529 SetMarkerType(2,4,shape);
02530 } else if (markerstyle == 33) {
02531
02532 Int_t imx = Int_t(2.66*fMarkerSize + 0.5);
02533 shape[0].x =-imx; shape[0].y = 0;
02534 shape[1].x = 0; shape[1].y = -im;
02535 shape[2].x = imx; shape[2].y = 0;
02536 shape[3].x = 0; shape[3].y = im;
02537 shape[4].x =-imx; shape[4].y = 0;
02538 SetMarkerType(3,5,shape);
02539 } else if (markerstyle == 34) {
02540
02541 Int_t imx = Int_t(1.33*fMarkerSize + 0.5);
02542 shape[0].x = -im; shape[0].y =-imx;
02543 shape[1].x =-imx; shape[1].y =-imx;
02544 shape[2].x =-imx; shape[2].y = -im;
02545 shape[3].x = imx; shape[3].y = -im;
02546 shape[4].x = imx; shape[4].y =-imx;
02547 shape[5].x = im; shape[5].y =-imx;
02548 shape[6].x = im; shape[6].y = imx;
02549 shape[7].x = imx; shape[7].y = imx;
02550 shape[8].x = imx; shape[8].y = im;
02551 shape[9].x =-imx; shape[9].y = im;
02552 shape[10].x=-imx; shape[10].y= imx;
02553 shape[11].x= -im; shape[11].y= imx;
02554 shape[12].x= -im; shape[12].y=-imx;
02555 SetMarkerType(3,13,shape);
02556 } else {
02557
02558 SetMarkerType(0,0,shape);
02559 }
02560 }
02561
02562
02563 void TGX11::SetOpacity(Int_t percent)
02564 {
02565
02566
02567
02568
02569
02570
02571 if (fDepth <= 8) return;
02572 if (percent == 0) return;
02573
02574
02575 ULong_t *orgcolors = 0, *tmpc = 0;
02576 Int_t maxcolors = 0, ncolors, ntmpc = 0;
02577
02578
02579 if (gCws->fNewColors) {
02580 tmpc = gCws->fNewColors;
02581 ntmpc = gCws->fNcolors;
02582 }
02583
02584
02585 XImage *image = XGetImage(fDisplay, gCws->fDrawing, 0, 0, gCws->fWidth,
02586 gCws->fHeight, AllPlanes, ZPixmap);
02587
02588
02589 int x, y;
02590 for (y = 0; y < (int) gCws->fHeight; y++) {
02591 for (x = 0; x < (int) gCws->fWidth; x++) {
02592 ULong_t pixel = XGetPixel(image, x, y);
02593 CollectImageColors(pixel, orgcolors, ncolors, maxcolors);
02594 }
02595 }
02596 if (ncolors == 0) {
02597 XDestroyImage(image);
02598 ::operator delete(orgcolors);
02599 return;
02600 }
02601
02602
02603 MakeOpaqueColors(percent, orgcolors, ncolors);
02604
02605
02606 for (y = 0; y < (int) gCws->fHeight; y++) {
02607 for (x = 0; x < (int) gCws->fWidth; x++) {
02608 ULong_t pixel = XGetPixel(image, x, y);
02609 Int_t idx = FindColor(pixel, orgcolors, ncolors);
02610 XPutPixel(image, x, y, gCws->fNewColors[idx]);
02611 }
02612 }
02613
02614
02615 XPutImage(fDisplay, gCws->fDrawing, *gGCpxmp, image, 0, 0, 0, 0,
02616 gCws->fWidth, gCws->fHeight);
02617 XFlush(fDisplay);
02618
02619
02620 if (tmpc) {
02621 if (fRedDiv == -1)
02622 XFreeColors(fDisplay, fColormap, tmpc, ntmpc, 0);
02623 delete [] tmpc;
02624 }
02625 XDestroyImage(image);
02626 ::operator delete(orgcolors);
02627 }
02628
02629
02630 void TGX11::CollectImageColors(ULong_t pixel, ULong_t *&orgcolors, Int_t &ncolors,
02631 Int_t &maxcolors)
02632 {
02633
02634
02635 if (maxcolors == 0) {
02636 ncolors = 0;
02637 maxcolors = 100;
02638 orgcolors = (ULong_t*) ::operator new(maxcolors*sizeof(ULong_t));
02639 }
02640
02641 for (int i = 0; i < ncolors; i++)
02642 if (pixel == orgcolors[i]) return;
02643
02644 if (ncolors >= maxcolors) {
02645 orgcolors = (ULong_t*) TStorage::ReAlloc(orgcolors,
02646 maxcolors*2*sizeof(ULong_t), maxcolors*sizeof(ULong_t));
02647 maxcolors *= 2;
02648 }
02649
02650 orgcolors[ncolors++] = pixel;
02651 }
02652
02653
02654 void TGX11::MakeOpaqueColors(Int_t percent, ULong_t *orgcolors, Int_t ncolors)
02655 {
02656
02657
02658
02659 if (ncolors == 0) return;
02660
02661 XColor *xcol = new XColor[ncolors];
02662
02663 int i;
02664 for (i = 0; i < ncolors; i++) {
02665 xcol[i].pixel = orgcolors[i];
02666 xcol[i].red = xcol[i].green = xcol[i].blue = 0;
02667 xcol[i].flags = DoRed | DoGreen | DoBlue;
02668 }
02669 QueryColors(fColormap, xcol, ncolors);
02670
02671 UShort_t add = percent * kBIGGEST_RGB_VALUE / 100;
02672
02673 Int_t val;
02674 for (i = 0; i < ncolors; i++) {
02675 val = xcol[i].red + add;
02676 if (val > kBIGGEST_RGB_VALUE) val = kBIGGEST_RGB_VALUE;
02677 xcol[i].red = (UShort_t) val;
02678 val = xcol[i].green + add;
02679 if (val > kBIGGEST_RGB_VALUE) val = kBIGGEST_RGB_VALUE;
02680 xcol[i].green = (UShort_t) val;
02681 val = xcol[i].blue + add;
02682 if (val > kBIGGEST_RGB_VALUE) val = kBIGGEST_RGB_VALUE;
02683 xcol[i].blue = (UShort_t) val;
02684 if (!AllocColor(fColormap, &xcol[i]))
02685 Warning("MakeOpaqueColors", "failed to allocate color %hd, %hd, %hd",
02686 xcol[i].red, xcol[i].green, xcol[i].blue);
02687
02688 }
02689
02690 gCws->fNewColors = new ULong_t[ncolors];
02691 gCws->fNcolors = ncolors;
02692
02693 for (i = 0; i < ncolors; i++)
02694 gCws->fNewColors[i] = xcol[i].pixel;
02695
02696 delete [] xcol;
02697 }
02698
02699
02700 Int_t TGX11::FindColor(ULong_t pixel, ULong_t *orgcolors, Int_t ncolors)
02701 {
02702
02703
02704 for (int i = 0; i < ncolors; i++)
02705 if (pixel == orgcolors[i]) return i;
02706
02707 Error("FindColor", "did not find color, should never happen!");
02708
02709 return 0;
02710 }
02711
02712
02713 void TGX11::SetRGB(int cindex, float r, float g, float b)
02714 {
02715
02716
02717
02718
02719 if (fColormap) {
02720 XColor xcol;
02721 xcol.red = (UShort_t)(r * kBIGGEST_RGB_VALUE);
02722 xcol.green = (UShort_t)(g * kBIGGEST_RGB_VALUE);
02723 xcol.blue = (UShort_t)(b * kBIGGEST_RGB_VALUE);
02724 xcol.flags = DoRed | DoGreen | DoBlue;
02725 XColor_t &col = GetColor(cindex);
02726 if (col.fDefined) {
02727
02728 if (col.fRed == xcol.red && col.fGreen == xcol.green &&
02729 col.fBlue == xcol.blue)
02730 return;
02731 col.fDefined = kFALSE;
02732 if (fRedDiv == -1)
02733 XFreeColors(fDisplay, fColormap, &col.fPixel, 1, 0);
02734 }
02735 if (AllocColor(fColormap, &xcol)) {
02736 col.fDefined = kTRUE;
02737 col.fPixel = xcol.pixel;
02738 col.fRed = xcol.red;
02739 col.fGreen = xcol.green;
02740 col.fBlue = xcol.blue;
02741 }
02742 }
02743 }
02744
02745
02746 void TGX11::SetTextAlign(Short_t talign)
02747 {
02748
02749
02750
02751
02752 Int_t txalh = talign/10;
02753 Int_t txalv = talign%10;
02754 fTextAlignH = txalh;
02755 fTextAlignV = txalv;
02756
02757 switch (txalh) {
02758
02759 case 0 :
02760 case 1 :
02761 switch (txalv) {
02762 case 1 :
02763 fTextAlign = 7;
02764 break;
02765 case 2 :
02766 fTextAlign = 4;
02767 break;
02768 case 3 :
02769 fTextAlign = 1;
02770 break;
02771 }
02772 break;
02773 case 2 :
02774 switch (txalv) {
02775 case 1 :
02776 fTextAlign = 8;
02777 break;
02778 case 2 :
02779 fTextAlign = 5;
02780 break;
02781 case 3 :
02782 fTextAlign = 2;
02783 break;
02784 }
02785 break;
02786 case 3 :
02787 switch (txalv) {
02788 case 1 :
02789 fTextAlign = 9;
02790 break;
02791 case 2 :
02792 fTextAlign = 6;
02793 break;
02794 case 3 :
02795 fTextAlign = 3;
02796 break;
02797 }
02798 break;
02799 }
02800
02801 TAttText::SetTextAlign(fTextAlign);
02802 }
02803
02804
02805 void TGX11::SetTextColor(Color_t cindex)
02806 {
02807
02808
02809 if (cindex < 0) return;
02810
02811 TAttText::SetTextColor(cindex);
02812
02813 SetColor(*gGCtext, Int_t(cindex));
02814
02815 XGCValues values;
02816 if (XGetGCValues(fDisplay, *gGCtext, GCForeground | GCBackground, &values)) {
02817 XSetForeground( fDisplay, *gGCinvt, values.background );
02818 XSetBackground( fDisplay, *gGCinvt, values.foreground );
02819 } else {
02820 Error("SetTextColor", "cannot get GC values");
02821 }
02822 XSetBackground(fDisplay, *gGCtext, GetColor(0).fPixel);
02823 }
02824
02825
02826 Int_t TGX11::SetTextFont(char *fontname, ETextSetMode mode)
02827 {
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837 char **fontlist;
02838 int fontcount;
02839 int i;
02840
02841 if (mode == kLoad) {
02842 for (i = 0; i < kMAXFONT; i++) {
02843 if (strcmp(fontname, gFont[i].name) == 0) {
02844 gTextFont = gFont[i].id;
02845 XSetFont(fDisplay, *gGCtext, gTextFont->fid);
02846 XSetFont(fDisplay, *gGCinvt, gTextFont->fid);
02847 return 0;
02848 }
02849 }
02850 }
02851
02852 fontlist = XListFonts(fDisplay, fontname, 1, &fontcount);
02853
02854 if (fontcount != 0) {
02855 if (mode == kLoad) {
02856 if (gFont[gCurrentFontNumber].id)
02857 XFreeFont(fDisplay, gFont[gCurrentFontNumber].id);
02858 gTextFont = XLoadQueryFont(fDisplay, fontlist[0]);
02859 XSetFont(fDisplay, *gGCtext, gTextFont->fid);
02860 XSetFont(fDisplay, *gGCinvt, gTextFont->fid);
02861 gFont[gCurrentFontNumber].id = gTextFont;
02862 strlcpy(gFont[gCurrentFontNumber].name,fontname,80);
02863 gCurrentFontNumber++;
02864 if (gCurrentFontNumber == kMAXFONT) gCurrentFontNumber = 0;
02865 }
02866 XFreeFontNames(fontlist);
02867 return 0;
02868 } else {
02869 return 1;
02870 }
02871 }
02872
02873
02874 void TGX11::SetTextFont(Font_t fontnumber)
02875 {
02876
02877
02878 fTextFont = fontnumber;
02879 }
02880
02881
02882 void TGX11::SetTextSize(Float_t textsize)
02883 {
02884
02885
02886 fTextSize = textsize;
02887 }
02888
02889
02890 void TGX11::Sync(int mode)
02891 {
02892
02893
02894
02895
02896
02897 switch (mode) {
02898
02899 case 1 :
02900 XSynchronize(fDisplay,1);
02901 break;
02902
02903 default:
02904 XSynchronize(fDisplay,0);
02905 break;
02906 }
02907 }
02908
02909
02910 void TGX11::UpdateWindow(int mode)
02911 {
02912
02913
02914
02915
02916
02917
02918
02919
02920 if (gCws->fDoubleBuffer) {
02921 XCopyArea(fDisplay, gCws->fDrawing, gCws->fWindow,
02922 *gGCpxmp, 0, 0, gCws->fWidth, gCws->fHeight, 0, 0);
02923 }
02924 if (mode == 1) {
02925 XFlush(fDisplay);
02926 } else {
02927 XSync(fDisplay, False);
02928 }
02929 }
02930
02931
02932 void TGX11::Warp(Int_t ix, Int_t iy, Window_t id)
02933 {
02934
02935
02936
02937
02938
02939
02940 if (!id) {
02941
02942
02943 } else {
02944 XWarpPointer(fDisplay, None, (Window) id, 0, 0, 0, 0, ix, iy);
02945 }
02946 }
02947
02948
02949 void TGX11::WritePixmap(int wid, unsigned int w, unsigned int h, char *pxname)
02950 {
02951
02952
02953
02954
02955
02956
02957 unsigned int wval, hval;
02958 wval = w;
02959 hval = h;
02960
02961 gTws = &fWindows[wid];
02962 XWriteBitmapFile(fDisplay, pxname, gTws->fDrawing, wval, hval, -1, -1);
02963 }
02964
02965
02966
02967
02968
02969
02970 static FILE *gOut;
02971 static XImage *gXimage = 0;
02972
02973 extern "C" {
02974 int GIFquantize(UInt_t width, UInt_t height, Int_t *ncol, Byte_t *red, Byte_t *green,
02975 Byte_t *blue, Byte_t *outputBuf, Byte_t *outputCmap);
02976 long GIFencode(int Width, int Height, Int_t Ncol, Byte_t R[], Byte_t G[], Byte_t B[], Byte_t ScLine[],
02977 void (*get_scline) (int, int, Byte_t *), void (*pb)(Byte_t));
02978 int GIFdecode(Byte_t *gifArr, Byte_t *pixArr, int *Width, int *Height, int *Ncols, Byte_t *R, Byte_t *G, Byte_t *B);
02979 int GIFinfo(Byte_t *gifArr, int *Width, int *Height, int *Ncols);
02980 }
02981
02982
02983 static void GetPixel(int y, int width, Byte_t *scline)
02984 {
02985
02986
02987 for (int i = 0; i < width; i++)
02988 scline[i] = Byte_t(XGetPixel(gXimage, i, y));
02989 }
02990
02991
02992 static void PutByte(Byte_t b)
02993 {
02994
02995
02996 if (ferror(gOut) == 0) fputc(b, gOut);
02997 }
02998
02999
03000 void TGX11::ImgPickPalette(XImage *image, Int_t &ncol, Int_t *&R, Int_t *&G, Int_t *&B)
03001 {
03002
03003
03004
03005
03006
03007
03008
03009
03010 ULong_t *orgcolors = 0;
03011 Int_t maxcolors = 0, ncolors;
03012
03013
03014 int x, y;
03015 for (x = 0; x < (int) gCws->fWidth; x++) {
03016 for (y = 0; y < (int) gCws->fHeight; y++) {
03017 ULong_t pixel = XGetPixel(image, x, y);
03018 CollectImageColors(pixel, orgcolors, ncolors, maxcolors);
03019 }
03020 }
03021
03022
03023 XColor *xcol = new XColor[ncolors];
03024
03025 int i;
03026 for (i = 0; i < ncolors; i++) {
03027 xcol[i].pixel = orgcolors[i];
03028 xcol[i].red = xcol[i].green = xcol[i].blue = 0;
03029 xcol[i].flags = DoRed | DoGreen | DoBlue;
03030 }
03031 QueryColors(fColormap, xcol, ncolors);
03032
03033
03034
03035 R = new Int_t[ncolors];
03036 G = new Int_t[ncolors];
03037 B = new Int_t[ncolors];
03038
03039 for (i = 0; i < ncolors; i++) {
03040 R[i] = xcol[i].red;
03041 G[i] = xcol[i].green;
03042 B[i] = xcol[i].blue;
03043 }
03044 ncol = ncolors;
03045
03046
03047 for (x = 0; x < (int) gCws->fWidth; x++) {
03048 for (y = 0; y < (int) gCws->fHeight; y++) {
03049 ULong_t pixel = XGetPixel(image, x, y);
03050 Int_t idx = FindColor(pixel, orgcolors, ncolors);
03051 XPutPixel(image, x, y, idx);
03052 }
03053 }
03054
03055
03056 delete [] xcol;
03057 ::operator delete(orgcolors);
03058 }
03059
03060
03061 Int_t TGX11::WriteGIF(char *name)
03062 {
03063
03064
03065
03066 Byte_t scline[2000], r[256], b[256], g[256];
03067 Int_t *red, *green, *blue;
03068 Int_t ncol, maxcol, i;
03069
03070 if (gXimage) {
03071 XDestroyImage(gXimage);
03072 gXimage = 0;
03073 }
03074
03075 gXimage = XGetImage(fDisplay, gCws->fDrawing, 0, 0,
03076 gCws->fWidth, gCws->fHeight,
03077 AllPlanes, ZPixmap);
03078
03079 ImgPickPalette(gXimage, ncol, red, green, blue);
03080
03081 if (ncol > 256) {
03082
03083 Error("WriteGIF", "can not create GIF of image containing more than 256 colors");
03084 delete [] red;
03085 delete [] green;
03086 delete [] blue;
03087 return 0;
03088 }
03089
03090 maxcol = 0;
03091 for (i = 0; i < ncol; i++) {
03092 if (maxcol < red[i] ) maxcol = red[i];
03093 if (maxcol < green[i] ) maxcol = green[i];
03094 if (maxcol < blue[i] ) maxcol = blue[i];
03095 r[i] = 0;
03096 g[i] = 0;
03097 b[i] = 0;
03098 }
03099 if (maxcol != 0) {
03100 for (i = 0; i < ncol; i++) {
03101 r[i] = red[i] * 255/maxcol;
03102 g[i] = green[i] * 255/maxcol;
03103 b[i] = blue[i] * 255/maxcol;
03104 }
03105 }
03106
03107 gOut = fopen(name, "w+");
03108
03109 if (gOut) {
03110 GIFencode(gCws->fWidth, gCws->fHeight,
03111 ncol, r, g, b, scline, ::GetPixel, PutByte);
03112 fclose(gOut);
03113 i = 1;
03114 } else {
03115 Error("WriteGIF","cannot write file: %s",name);
03116 i = 0;
03117 }
03118 delete [] red;
03119 delete [] green;
03120 delete [] blue;
03121 return i;
03122 }
03123
03124
03125 void TGX11::PutImage(int offset,int itran,int x0,int y0,int nx,int ny,int xmin,
03126 int ymin,int xmax,int ymax, unsigned char *image,Drawable_t wid)
03127 {
03128
03129
03130 const int maxSegment = 20;
03131 int i, n, x, y, xcur, x1, x2, y1, y2;
03132 unsigned char *jimg, *jbase, icol;
03133 int nlines[256];
03134 XSegment lines[256][maxSegment];
03135 Drawable_t id;
03136
03137 if (wid) {
03138 id = wid;
03139 } else {
03140 id = gCws->fDrawing;
03141 }
03142
03143 for (i = 0; i < 256; i++) nlines[i] = 0;
03144
03145 x1 = x0 + xmin; y1 = y0 + ny - ymax - 1;
03146 x2 = x0 + xmax; y2 = y0 + ny - ymin - 1;
03147 jbase = image + (ymin-1)*nx + xmin;
03148
03149 for (y = y2; y >= y1; y--) {
03150 xcur = x1; jbase += nx;
03151 for (jimg = jbase, icol = *jimg++, x = x1+1; x <= x2; jimg++, x++) {
03152 if (icol != *jimg) {
03153 if (icol != itran) {
03154 n = nlines[icol]++;
03155 lines[icol][n].x1 = xcur; lines[icol][n].y1 = y;
03156 lines[icol][n].x2 = x-1; lines[icol][n].y2 = y;
03157 if (nlines[icol] == maxSegment) {
03158 SetColor(*gGCline,(int)icol+offset);
03159 XDrawSegments(fDisplay,id,*gGCline,&lines[icol][0],
03160 maxSegment);
03161 nlines[icol] = 0;
03162 }
03163 }
03164 icol = *jimg; xcur = x;
03165 }
03166 }
03167 if (icol != itran) {
03168 n = nlines[icol]++;
03169 lines[icol][n].x1 = xcur; lines[icol][n].y1 = y;
03170 lines[icol][n].x2 = x-1; lines[icol][n].y2 = y;
03171 if (nlines[icol] == maxSegment) {
03172 SetColor(*gGCline,(int)icol+offset);
03173 XDrawSegments(fDisplay,id,*gGCline,&lines[icol][0],
03174 maxSegment);
03175 nlines[icol] = 0;
03176 }
03177 }
03178 }
03179
03180 for (i = 0; i < 256; i++) {
03181 if (nlines[i] != 0) {
03182 SetColor(*gGCline,i+offset);
03183 XDrawSegments(fDisplay,id,*gGCline,&lines[i][0],nlines[i]);
03184 }
03185 }
03186 }
03187
03188
03189 Pixmap_t TGX11::ReadGIF(int x0, int y0, const char *file, Window_t id)
03190 {
03191
03192
03193
03194 FILE *fd;
03195 Seek_t filesize = 0;
03196 unsigned char *gifArr, *pixArr, red[256], green[256], blue[256], *j1, *j2, icol;
03197 int i, j, k, width, height, ncolor, irep, offset;
03198 float rr, gg, bb;
03199 Pixmap_t pic = 0;
03200
03201 fd = fopen(file, "r");
03202 if (!fd) {
03203 Error("ReadGIF", "unable to open GIF file");
03204 return pic;
03205 }
03206
03207 fseek(fd, 0L, 2);
03208 long ft = ftell(fd);
03209 if (ft <=0) {
03210 Error("ReadGIF", "unable to open GIF file");
03211 fclose(fd);
03212 return pic;
03213 } else {
03214 filesize = Seek_t(ft);
03215 }
03216 fseek(fd, 0L, 0);
03217
03218 if (!(gifArr = (unsigned char *) calloc(filesize+256,1))) {
03219 Error("ReadGIF", "unable to allocate array for gif");
03220 fclose(fd);
03221 return pic;
03222 }
03223
03224 if (fread(gifArr, filesize, 1, fd) != 1) {
03225 Error("ReadGIF", "GIF file read failed");
03226 free(gifArr);
03227 fclose(fd);
03228 return pic;
03229 }
03230 fclose(fd);
03231
03232 irep = GIFinfo(gifArr, &width, &height, &ncolor);
03233 if (irep != 0) {
03234 free(gifArr);
03235 return pic;
03236 }
03237
03238 if (!(pixArr = (unsigned char *) calloc((width*height),1))) {
03239 Error("ReadGIF", "unable to allocate array for image");
03240 free(gifArr);
03241 return pic;
03242 }
03243
03244 irep = GIFdecode(gifArr, pixArr, &width, &height, &ncolor, red, green, blue);
03245 if (irep != 0) {
03246 free(gifArr);
03247 free(pixArr);
03248 return pic;
03249 }
03250
03251
03252
03253 offset = 8;
03254
03255 for (i = 0; i < ncolor; i++) {
03256 rr = red[i]/255.;
03257 gg = green[i]/255.;
03258 bb = blue[i]/255.;
03259 j = i+offset;
03260 SetRGB(j,rr,gg,bb);
03261 }
03262
03263
03264
03265 for (i = 1; i <= height/2; i++) {
03266 j1 = pixArr + (i-1)*width;
03267 j2 = pixArr + (height-i)*width;
03268 for (k = 0; k < width; k++) {
03269 icol = *j1; *j1++ = *j2; *j2++ = icol;
03270 }
03271 }
03272 if (id) pic = CreatePixmap(id, width, height);
03273 PutImage(offset,-1,x0,y0,width,height,0,0,width-1,height-1,pixArr,pic);
03274
03275 free(gifArr);
03276 free(pixArr);
03277
03278 if (pic)
03279 return pic;
03280 else if (gCws->fDrawing)
03281 return (Pixmap_t)gCws->fDrawing;
03282 return 0;
03283 }
03284
03285
03286 unsigned char *TGX11::GetColorBits(Drawable_t , Int_t , Int_t ,
03287 UInt_t , UInt_t )
03288 {
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298 return 0;
03299 }
03300
03301
03302 Pixmap_t TGX11::CreatePixmapFromData(unsigned char * , UInt_t ,
03303 UInt_t )
03304 {
03305
03306
03307
03308
03309
03310
03311 return (Pixmap_t)0;
03312 }
03313
03314
03315 Int_t TGX11::AddPixmap(ULong_t pixid, UInt_t w, UInt_t h)
03316 {
03317
03318
03319
03320 Int_t wid = 0;
03321
03322
03323 for (; wid < fMaxNumberOfWindows; ++wid)
03324 if (!fWindows[wid].fOpen)
03325 break;
03326
03327 if (wid == fMaxNumberOfWindows) {
03328 Int_t newsize = fMaxNumberOfWindows + 10;
03329 fWindows = (XWindow_t*) TStorage::ReAlloc(
03330 fWindows, newsize * sizeof(XWindow_t),
03331 fMaxNumberOfWindows*sizeof(XWindow_t)
03332 );
03333
03334 for (Int_t i = fMaxNumberOfWindows; i < newsize; ++i)
03335 fWindows[i].fOpen = 0;
03336
03337 fMaxNumberOfWindows = newsize;
03338 }
03339
03340 fWindows[wid].fOpen = 1;
03341 gCws = fWindows + wid;
03342 gCws->fWindow = pixid;
03343 gCws->fDrawing = gCws->fWindow;
03344 gCws->fBuffer = 0;
03345 gCws->fDoubleBuffer = 0;
03346 gCws->fIsPixmap = 1;
03347 gCws->fClip = 0;
03348 gCws->fWidth = w;
03349 gCws->fHeight = h;
03350 gCws->fNewColors = 0;
03351 gCws->fShared = kFALSE;
03352
03353 return wid;
03354 }
03355
03356
03357 Int_t TGX11::SupportsExtension(const char *ext) const
03358 {
03359
03360
03361
03362
03363
03364
03365
03366
03367 Int_t major_opcode, first_event, first_error;
03368 if (!fDisplay)
03369 return -1;
03370 return XQueryExtension(fDisplay, ext, &major_opcode, &first_event, &first_error);
03371 }