ROOT  6.06/09
Reference Guide
TGX11.cxx
Go to the documentation of this file.
1 // @(#)root/x11:$Id$
2 // Author: Rene Brun, Olivier Couet, Fons Rademakers 28/11/94
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /// \defgroup x11 X11 backend
13 /// \brief Interface to X11 graphics.
14 /// \ingroup GraphicsBackends
15 
16 /** \class TGX11
17 \ingroup x11
18 This class is the basic interface to the X11 (Xlib) graphics system.
19 It is an implementation of the abstract TVirtualX class.
20 
21 This class gives access to basic X11 graphics, pixmap, text and font handling
22 routines.
23 
24 The companion class for Win32 is TGWin32.
25 
26 The file G11Gui.cxx contains the implementation of the GUI methods of the
27 TGX11 class. Most of the methods are used by the machine independent
28 GUI classes (libGUI.so).
29 
30 This code was initially developed in the context of HIGZ and PAW
31 by Olivier Couet (package X11INT).
32 */
33 
34 #include "TROOT.h"
35 #include "TColor.h"
36 #include "TGX11.h"
37 #include "TPoint.h"
38 #include "TMath.h"
39 #include "TStorage.h"
40 #include "TStyle.h"
41 #include "TExMap.h"
42 #include "TEnv.h"
43 #include "TString.h"
44 #include "TObjString.h"
45 #include "TObjArray.h"
46 #include "RStipples.h"
47 
48 #include <X11/Xlib.h>
49 #include <X11/Xutil.h>
50 #include <X11/Xatom.h>
51 #include <X11/cursorfont.h>
52 #include <X11/keysym.h>
53 #include <X11/xpm.h>
54 
55 #include <stdio.h>
56 #include <string.h>
57 #include <stdlib.h>
58 #include <ctype.h>
59 #include <unistd.h>
60 #ifdef R__AIX
61 # include <sys/socket.h>
62 #endif
63 
64 extern float XRotVersion(char*, int);
65 extern void XRotSetMagnification(float);
66 extern void XRotSetBoundingBoxPad(int);
67 extern int XRotDrawString(Display*, XFontStruct*, float,
68  Drawable, GC, int, int, char*);
69 extern int XRotDrawImageString(Display*, XFontStruct*, float,
70  Drawable, GC, int, int, char*);
71 extern int XRotDrawAlignedString(Display*, XFontStruct*, float,
72  Drawable, GC, int, int, char*, int);
73 extern int XRotDrawAlignedImageString(Display*, XFontStruct*, float,
74  Drawable, GC, int, int, char*, int);
75 extern XPoint *XRotTextExtents(Display*, XFontStruct*, float,
76  int, int, char*, int);
77 
78 //---- globals
79 
80 static XWindow_t *gCws; // gCws: pointer to the current window
81 static XWindow_t *gTws; // gTws: temporary pointer
82 
83 const Int_t kBIGGEST_RGB_VALUE = 65535;
84 
85 //
86 // Primitives Graphic Contexts global for all windows
87 //
88 const int kMAXGC = 7;
89 static GC gGClist[kMAXGC];
90 static GC *gGCline = &gGClist[0]; // PolyLines
91 static GC *gGCmark = &gGClist[1]; // PolyMarker
92 static GC *gGCfill = &gGClist[2]; // Fill areas
93 static GC *gGCtext = &gGClist[3]; // Text
94 static GC *gGCinvt = &gGClist[4]; // Inverse text
95 static GC *gGCdash = &gGClist[5]; // Dashed lines
96 static GC *gGCpxmp = &gGClist[6]; // Pixmap management
97 
98 static GC gGCecho; // Input echo
99 
100 static Int_t gFillHollow; // Flag if fill style is hollow
101 static Pixmap gFillPattern = 0; // Fill pattern
102 
103 //
104 // Text management
105 //
106 const Int_t kMAXFONT = 4;
107 static struct {
108  XFontStruct *id;
109  char name[80]; // Font name
110 } gFont[kMAXFONT]; // List of fonts loaded
111 
112 static XFontStruct *gTextFont; // Current font
113 static Int_t gCurrentFontNumber = 0; // Current font number in gFont[]
114 
115 //
116 // Markers
117 //
118 const Int_t kMAXMK = 100;
119 static struct {
120  int type;
121  int n;
122  XPoint xy[kMAXMK];
123 } gMarker; // Point list to draw marker
124 
125 //
126 // Keep style values for line GC
127 //
128 static int gLineWidth = 0;
129 static int gLineStyle = LineSolid;
130 static int gCapStyle = CapButt;
131 static int gJoinStyle = JoinMiter;
132 static char gDashList[10];
133 static int gDashLength = 0;
134 static int gDashOffset = 0;
135 static int gDashSize = 0;
136 
137 //
138 // Event masks
139 //
140 static ULong_t gMouseMask = ButtonPressMask | ButtonReleaseMask |
141  EnterWindowMask | LeaveWindowMask |
142  PointerMotionMask | KeyPressMask |
143  KeyReleaseMask;
144 static ULong_t gKeybdMask = ButtonPressMask | KeyPressMask |
145  EnterWindowMask | LeaveWindowMask;
146 
147 //
148 // Data to create an invisible cursor
149 //
150 const char null_cursor_bits[] = {
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
154 static Cursor gNullCursor = 0;
155 
156 struct RXGCValues:XGCValues{};
157 struct RXColor:XColor{};
158 struct RXImage:XImage{};
159 struct RXPoint:XPoint{};
160 struct RXVisualInfo:XVisualInfo{};
161 struct RVisual:Visual{};
162 
164 
165 ////////////////////////////////////////////////////////////////////////////////
166 /// Default constructor.
167 
168 TGX11::TGX11()
169 {
170  int i;
171  fDisplay = 0;
172  fScreenNumber = 0;
173  fVisual = 0;
174  fRootWin = 0;
175  fVisRootWin = 0;
176  fColormap = 0;
177  fBlackPixel = 0;
178  fWhitePixel = 0;
179  fWindows = 0;
180  fColors = 0;
181  fXEvent = new XEvent;
182  fRedDiv = -1;
183  fGreenDiv = -1;
184  fBlueDiv = -1;
185  fRedShift = -1;
186  fGreenShift = -1;
187  fBlueShift = -1;
188  fCharacterUpX = 1;
189  fCharacterUpY = 1;
190  fDepth = 0;
191  fHasTTFonts = kFALSE;
192  fHasXft = kFALSE;
193  fMaxNumberOfWindows = 10;
194  fTextAlignH = 1;
195  fTextAlignV = 1;
196  fTextAlign = 7;
197  fTextMagnitude = 1;
198  for (i = 0; i < kNumCursors; i++) fCursors[i] = 0;
199 }
200 
201 ////////////////////////////////////////////////////////////////////////////////
202 /// Normal Constructor.
203 
204 TGX11::TGX11(const char *name, const char *title) : TVirtualX(name, title)
205 {
206  int i;
207  fDisplay = 0;
208  fScreenNumber = 0;
209  fVisual = 0;
210  fRootWin = 0;
211  fVisRootWin = 0;
212  fColormap = 0;
213  fBlackPixel = 0;
214  fWhitePixel = 0;
215  fDrawMode = kCopy;
216  fXEvent = new XEvent;
217  fRedDiv = -1;
218  fGreenDiv = -1;
219  fBlueDiv = -1;
220  fRedShift = -1;
221  fGreenShift = -1;
222  fBlueShift = -1;
223  fCharacterUpX = 1;
224  fCharacterUpY = 1;
225  fDepth = 0;
227  fHasXft = kFALSE;
228  fMaxNumberOfWindows = 10;
229  fTextAlignH = 1;
230  fTextAlignV = 1;
231  fTextAlign = 7;
232  fTextMagnitude = 1;
233  for (i = 0; i < kNumCursors; i++) fCursors[i] = 0;
234 
235  //fWindows = new XWindow_t[fMaxNumberOfWindows];
236  fWindows = (XWindow_t*) TStorage::Alloc(fMaxNumberOfWindows*sizeof(XWindow_t));
237  for (i = 0; i < fMaxNumberOfWindows; i++)
238  fWindows[i].fOpen = 0;
239 
240  fColors = new TExMap;
241 }
242 
243 ////////////////////////////////////////////////////////////////////////////////
244 /// Copy constructor. Currently only used by TGX11TTF.
245 
247 {
248  int i;
249 
250  fDisplay = org.fDisplay;
252  fVisual = org.fVisual;
253  fRootWin = org.fRootWin;
254  fVisRootWin = org.fVisRootWin;
255  fColormap = org.fColormap;
256  fBlackPixel = org.fBlackPixel;
257  fWhitePixel = org.fWhitePixel;
258  fHasTTFonts = org.fHasTTFonts;
259  fHasXft = org.fHasXft;
260  fTextAlignH = org.fTextAlignH;
261  fTextAlignV = org.fTextAlignV;
262  fTextAlign = org.fTextAlign;
266  fDepth = org.fDepth;
267  fRedDiv = org.fRedDiv;
268  fGreenDiv = org.fGreenDiv;
269  fBlueDiv = org.fBlueDiv;
270  fRedShift = org.fRedShift;
271  fGreenShift = org.fGreenShift;
272  fBlueShift = org.fBlueShift;
273  fDrawMode = org.fDrawMode;
274  fXEvent = new XEvent;
275 
277  //fWindows = new XWindow_t[fMaxNumberOfWindows];
278  fWindows = (XWindow_t*) TStorage::Alloc(fMaxNumberOfWindows*sizeof(XWindow_t));
279  for (i = 0; i < fMaxNumberOfWindows; i++) {
280  fWindows[i].fOpen = org.fWindows[i].fOpen;
281  fWindows[i].fDoubleBuffer = org.fWindows[i].fDoubleBuffer;
282  fWindows[i].fIsPixmap = org.fWindows[i].fIsPixmap;
283  fWindows[i].fDrawing = org.fWindows[i].fDrawing;
284  fWindows[i].fWindow = org.fWindows[i].fWindow;
285  fWindows[i].fBuffer = org.fWindows[i].fBuffer;
286  fWindows[i].fWidth = org.fWindows[i].fWidth;
287  fWindows[i].fHeight = org.fWindows[i].fHeight;
288  fWindows[i].fClip = org.fWindows[i].fClip;
289  fWindows[i].fXclip = org.fWindows[i].fXclip;
290  fWindows[i].fYclip = org.fWindows[i].fYclip;
291  fWindows[i].fWclip = org.fWindows[i].fWclip;
292  fWindows[i].fHclip = org.fWindows[i].fHclip;
293  fWindows[i].fNewColors = org.fWindows[i].fNewColors;
294  fWindows[i].fNcolors = org.fWindows[i].fNcolors;
295  fWindows[i].fShared = org.fWindows[i].fShared;
296  }
297 
298  for (i = 0; i < kNumCursors; i++)
299  fCursors[i] = org.fCursors[i];
300 
301  fColors = new TExMap;
302  Long64_t key, value;
303  TExMapIter it(org.fColors);
304  while (it.Next(key, value)) {
305  XColor_t *colo = (XColor_t *) (Long_t)value;
306  XColor_t *col = new XColor_t;
307  col->fPixel = colo->fPixel;
308  col->fRed = colo->fRed;
309  col->fGreen = colo->fGreen;
310  col->fBlue = colo->fBlue;
311  col->fDefined = colo->fDefined;
312  fColors->Add(key, (Long_t) col);
313  }
314 }
315 
316 ////////////////////////////////////////////////////////////////////////////////
317 /// Destructor.
318 
320 {
321  delete (XEvent*)fXEvent;
323 
324  if (!fColors) return;
325  Long64_t key, value;
326  TExMapIter it(fColors);
327  while (it.Next(key, value)) {
328  XColor_t *col = (XColor_t *) (Long_t)value;
329  delete col;
330  }
331  delete fColors;
332 }
333 
334 ////////////////////////////////////////////////////////////////////////////////
335 /// Initialize X11 system. Returns kFALSE in case of failure.
336 
337 Bool_t TGX11::Init(void *display)
338 {
339  if (OpenDisplay((Display *) display) == -1) return kFALSE;
340  return kTRUE;
341 }
342 
343 ////////////////////////////////////////////////////////////////////////////////
344 /// Allocate color in colormap. If we are on an <= 8 plane machine
345 /// we will use XAllocColor. If we are on a >= 15 (15, 16 or 24) plane
346 /// true color machine we will calculate the pixel value using:
347 /// for 15 and 16 bit true colors have 6 bits precision per color however
348 /// only the 5 most significant bits are used in the color index.
349 /// Except for 16 bits where green uses all 6 bits. I.e.:
350 /// ~~~ {.cpp}
351 /// 15 bits = rrrrrgggggbbbbb
352 /// 16 bits = rrrrrggggggbbbbb
353 /// ~~~
354 /// for 24 bits each r, g and b are represented by 8 bits.
355 ///
356 /// Since all colors are set with a max of 65535 (16 bits) per r, g, b
357 /// we just right shift them by 10, 11 and 10 bits for 16 planes, and
358 /// (10, 10, 10 for 15 planes) and by 8 bits for 24 planes.
359 /// Returns kFALSE in case color allocation failed.
360 
361 Bool_t TGX11::AllocColor(Colormap cmap, RXColor *color)
362 {
363  if (fRedDiv == -1) {
364  if (XAllocColor((Display*)fDisplay, cmap, color))
365  return kTRUE;
366  } else {
367  color->pixel = (color->red >> fRedDiv) << fRedShift |
368  (color->green >> fGreenDiv) << fGreenShift |
369  (color->blue >> fBlueDiv) << fBlueShift;
370  return kTRUE;
371  }
372  return kFALSE;
373 }
374 
375 ////////////////////////////////////////////////////////////////////////////////
376 /// Returns the current RGB value for the pixel in the XColor structure.
377 
378 void TGX11::QueryColors(Colormap cmap, RXColor *color, Int_t ncolors)
379 {
380  if (fRedDiv == -1) {
381  XQueryColors((Display*)fDisplay, cmap, color, ncolors);
382  } else {
383  ULong_t r, g, b;
384  for (Int_t i = 0; i < ncolors; i++) {
385  r = (color[i].pixel & fVisual->red_mask) >> fRedShift;
386  color[i].red = UShort_t(r*kBIGGEST_RGB_VALUE/(fVisual->red_mask >> fRedShift));
387 
388  g = (color[i].pixel & fVisual->green_mask) >> fGreenShift;
389  color[i].green = UShort_t(g*kBIGGEST_RGB_VALUE/(fVisual->green_mask >> fGreenShift));
390 
391  b = (color[i].pixel & fVisual->blue_mask) >> fBlueShift;
392  color[i].blue = UShort_t(b*kBIGGEST_RGB_VALUE/(fVisual->blue_mask >> fBlueShift));
393 
394  color[i].flags = DoRed | DoGreen | DoBlue;
395  }
396  }
397 }
398 
399 ////////////////////////////////////////////////////////////////////////////////
400 /// Clear the pixmap pix.
401 
403 {
404  Window root;
405  int xx, yy;
406  unsigned int ww, hh, border, depth;
407  XGetGeometry((Display*)fDisplay, *pix, &root, &xx, &yy, &ww, &hh, &border, &depth);
408  SetColor(gGCpxmp, 0);
409  XFillRectangle((Display*)fDisplay, *pix, *gGCpxmp, 0 ,0 ,ww ,hh);
410  SetColor(gGCpxmp, 1);
411  XFlush((Display*)fDisplay);
412 }
413 
414 ////////////////////////////////////////////////////////////////////////////////
415 /// Clear current window.
416 
418 {
419  if (!gCws->fIsPixmap && !gCws->fDoubleBuffer) {
420  XSetWindowBackground((Display*)fDisplay, gCws->fDrawing, GetColor(0).fPixel);
421  XClearWindow((Display*)fDisplay, gCws->fDrawing);
422  XFlush((Display*)fDisplay);
423  } else {
424  SetColor(gGCpxmp, 0);
425  XFillRectangle((Display*)fDisplay, gCws->fDrawing, *gGCpxmp,
426  0, 0, gCws->fWidth, gCws->fHeight);
427  SetColor(gGCpxmp, 1);
428  }
429 }
430 
431 ////////////////////////////////////////////////////////////////////////////////
432 /// Delete current pixmap.
433 
435 {
436  CloseWindow1();
437 }
438 
439 ////////////////////////////////////////////////////////////////////////////////
440 /// Delete current window.
441 
443 {
444  if (gCws->fShared)
445  gCws->fOpen = 0;
446  else
447  CloseWindow1();
448 
449  // Never close connection. TApplication takes care of that
450  // if (!gCws) Close(); // close X when no open window left
451 }
452 
453 ////////////////////////////////////////////////////////////////////////////////
454 /// Delete current window.
455 
457 {
458  int wid;
459 
460  if (gCws->fIsPixmap)
461  XFreePixmap((Display*)fDisplay, gCws->fWindow);
462  else
463  XDestroyWindow((Display*)fDisplay, gCws->fWindow);
464 
465  if (gCws->fBuffer) XFreePixmap((Display*)fDisplay, gCws->fBuffer);
466 
467  if (gCws->fNewColors) {
468  if (fRedDiv == -1)
469  XFreeColors((Display*)fDisplay, fColormap, gCws->fNewColors, gCws->fNcolors, 0);
470  delete [] gCws->fNewColors;
471  gCws->fNewColors = 0;
472  }
473 
474  XFlush((Display*)fDisplay);
475 
476  gCws->fOpen = 0;
477 
478  // make first window in list the current window
479  for (wid = 0; wid < fMaxNumberOfWindows; wid++)
480  if (fWindows[wid].fOpen) {
481  gCws = &fWindows[wid];
482  return;
483  }
484 
485  gCws = 0;
486 }
487 
488 ////////////////////////////////////////////////////////////////////////////////
489 /// Copy the pixmap wid at the position xpos, ypos in the current window.
490 
491 void TGX11::CopyPixmap(int wid, int xpos, int ypos)
492 {
493  gTws = &fWindows[wid];
494 
495  XCopyArea((Display*)fDisplay, gTws->fDrawing, gCws->fDrawing, *gGCpxmp, 0, 0, gTws->fWidth,
496  gTws->fHeight, xpos, ypos);
497  XFlush((Display*)fDisplay);
498 }
499 
500 ////////////////////////////////////////////////////////////////////////////////
501 /// Copy area of current window in the pixmap pix.
502 
503 void TGX11::CopyWindowtoPixmap(Drawable *pix, int xpos, int ypos )
504 {
505  Window root;
506  int xx, yy;
507  unsigned int ww, hh, border, depth;
508 
509  XGetGeometry((Display*)fDisplay, *pix, &root, &xx, &yy, &ww, &hh, &border, &depth);
510  XCopyArea((Display*)fDisplay, gCws->fDrawing, *pix, *gGCpxmp, xpos, ypos, ww, hh, 0, 0);
511  XFlush((Display*)fDisplay);
512 }
513 
514 ////////////////////////////////////////////////////////////////////////////////
515 /// Draw a box.
516 ///
517 /// - mode=0 hollow (kHollow)
518 /// - mode=1 solid (kSolid)
519 
520 void TGX11::DrawBox(int x1, int y1, int x2, int y2, EBoxMode mode)
521 {
522  Int_t x = TMath::Min(x1, x2);
523  Int_t y = TMath::Min(y1, y2);
524  Int_t w = TMath::Abs(x2 - x1);
525  Int_t h = TMath::Abs(y2 - y1);
526 
527  switch (mode) {
528 
529  case kHollow:
530  XDrawRectangle((Display*)fDisplay, gCws->fDrawing, *gGCline, x, y, w, h);
531  break;
532 
533  case kFilled:
534  XFillRectangle((Display*)fDisplay, gCws->fDrawing, *gGCfill, x, y, w, h);
535  break;
536 
537  default:
538  break;
539  }
540 }
541 
542 ////////////////////////////////////////////////////////////////////////////////
543 /// Draw a cell array.
544 //
545 /// \param [in] x1,y1 : left down corner
546 /// \param [in] x2,y2 : right up corner
547 /// \param [in] nx,ny : array size
548 /// \param [in] ic : array
549 ///
550 /// Draw a cell array. The drawing is done with the pixel precision
551 /// if (X2-X1)/NX (or Y) is not a exact pixel number the position of
552 /// the top right corner may be wrong.
553 
554 void TGX11::DrawCellArray(int x1, int y1, int x2, int y2, int nx, int ny, int *ic)
555 {
556  int i, j, icol, ix, iy, w, h, current_icol;
557 
558  current_icol = -1;
559  w = TMath::Max((x2-x1)/(nx),1);
560  h = TMath::Max((y1-y2)/(ny),1);
561  ix = x1;
562 
563  for (i = 0; i < nx; i++) {
564  iy = y1-h;
565  for (j = 0; j < ny; j++) {
566  icol = ic[i+(nx*j)];
567  if (icol != current_icol) {
568  XSetForeground((Display*)fDisplay, *gGCfill, GetColor(icol).fPixel);
569  current_icol = icol;
570  }
571  XFillRectangle((Display*)fDisplay, gCws->fDrawing, *gGCfill, ix, iy, w, h);
572  iy = iy-h;
573  }
574  ix = ix+w;
575  }
576 }
577 
578 ////////////////////////////////////////////////////////////////////////////////
579 /// Fill area described by polygon.
580 ///
581 /// \param [in] n number of points
582 /// \param [in] xyt list of points
583 
584 void TGX11::DrawFillArea(int n, TPoint *xyt)
585 {
586  XPoint *xy = (XPoint*)xyt;
587 
588  if (gFillHollow)
589  XDrawLines((Display*)fDisplay, gCws->fDrawing, *gGCfill, xy, n, CoordModeOrigin);
590 
591  else {
592  XFillPolygon((Display*)fDisplay, gCws->fDrawing, *gGCfill,
593  xy, n, Nonconvex, CoordModeOrigin);
594  }
595 }
596 
597 ////////////////////////////////////////////////////////////////////////////////
598 /// Draw a line.
599 ///
600 /// \param [in] x1,y1 : begin of line
601 /// \param [in] x2,y2 : end of line
602 
603 void TGX11::DrawLine(int x1, int y1, int x2, int y2)
604 {
605  if (gLineStyle == LineSolid)
606  XDrawLine((Display*)fDisplay, gCws->fDrawing, *gGCline, x1, y1, x2, y2);
607  else {
608  XSetDashes((Display*)fDisplay, *gGCdash, gDashOffset, gDashList, gDashSize);
609  XDrawLine((Display*)fDisplay, gCws->fDrawing, *gGCdash, x1, y1, x2, y2);
610  }
611 }
612 
613 ////////////////////////////////////////////////////////////////////////////////
614 /// Draw a line through all points.
615 ///
616 /// \param [in] n number of points
617 /// \param [in] xyt list of points
618 
619 void TGX11::DrawPolyLine(int n, TPoint *xyt)
620 {
621  XPoint *xy = (XPoint*)xyt;
622 
623  const Int_t kMaxPoints = 1000001;
624 
625  if (n > kMaxPoints) {
626  int ibeg = 0;
627  int iend = kMaxPoints - 1;
628  while (iend < n) {
629  DrawPolyLine( kMaxPoints, &xyt[ibeg] );
630  ibeg = iend;
631  iend += kMaxPoints - 1;
632  }
633  if (ibeg < n) {
634  int npt = n - ibeg;
635  DrawPolyLine( npt, &xyt[ibeg] );
636  }
637  } else if (n > 1) {
638  if (gLineStyle == LineSolid)
639  XDrawLines((Display*)fDisplay, gCws->fDrawing, *gGCline, xy, n, CoordModeOrigin);
640  else {
641  int i;
642  XSetDashes((Display*)fDisplay, *gGCdash,
644  XDrawLines((Display*)fDisplay, gCws->fDrawing, *gGCdash, xy, n, CoordModeOrigin);
645 
646  // calculate length of line to update dash offset
647  for (i = 1; i < n; i++) {
648  int dx = xy[i].x - xy[i-1].x;
649  int dy = xy[i].y - xy[i-1].y;
650  if (dx < 0) dx = - dx;
651  if (dy < 0) dy = - dy;
652  gDashOffset += dx > dy ? dx : dy;
653  }
655  }
656  } else {
657  int px,py;
658  px=xy[0].x;
659  py=xy[0].y;
660  XDrawPoint((Display*)fDisplay, gCws->fDrawing,
661  gLineStyle == LineSolid ? *gGCline : *gGCdash, px, py);
662  }
663 }
664 
665 ////////////////////////////////////////////////////////////////////////////////
666 /// Draw n markers with the current attributes at position x, y.
667 ///
668 /// \param [in] n number of markers to draw
669 /// \param [in] xyt x,y coordinates of markers
670 
672 {
673  XPoint *xy = (XPoint*)xyt;
674 
675  if (gMarker.n <= 0) {
676  const int kNMAX = 1000000;
677  int nt = n/kNMAX;
678  for (int it=0;it<=nt;it++) {
679  if (it < nt) {
680  XDrawPoints((Display*)fDisplay, gCws->fDrawing, *gGCmark, &xy[it*kNMAX], kNMAX, CoordModeOrigin);
681  } else {
682  XDrawPoints((Display*)fDisplay, gCws->fDrawing, *gGCmark, &xy[it*kNMAX], n-it*kNMAX, CoordModeOrigin);
683  }
684  }
685  } else {
686  int r = gMarker.n / 2;
687  int m;
688 
689  for (m = 0; m < n; m++) {
690  int hollow = 0;
691 
692  switch (gMarker.type) {
693  int i;
694 
695  case 0: // hollow circle
696  XDrawArc((Display*)fDisplay, gCws->fDrawing, *gGCmark,
697  xy[m].x - r, xy[m].y - r, gMarker.n, gMarker.n, 0, 360*64);
698  break;
699 
700  case 1: // filled circle
701  XFillArc((Display*)fDisplay, gCws->fDrawing, *gGCmark,
702  xy[m].x - r, xy[m].y - r, gMarker.n, gMarker.n, 0, 360*64);
703  break;
704 
705  case 2: // hollow polygon
706  hollow = 1;
707  case 3: // filled polygon
708  for (i = 0; i < gMarker.n; i++) {
709  gMarker.xy[i].x += xy[m].x;
710  gMarker.xy[i].y += xy[m].y;
711  }
712  if (hollow)
713  XDrawLines((Display*)fDisplay, gCws->fDrawing, *gGCmark,
714  gMarker.xy, gMarker.n, CoordModeOrigin);
715  else
716  XFillPolygon((Display*)fDisplay, gCws->fDrawing, *gGCmark,
717  gMarker.xy, gMarker.n, Nonconvex, CoordModeOrigin);
718  for (i = 0; i < gMarker.n; i++) {
719  gMarker.xy[i].x -= xy[m].x;
720  gMarker.xy[i].y -= xy[m].y;
721  }
722  break;
723 
724  case 4: // segmented line
725  for (i = 0; i < gMarker.n; i += 2)
726  XDrawLine((Display*)fDisplay, gCws->fDrawing, *gGCmark,
727  xy[m].x + gMarker.xy[i].x, xy[m].y + gMarker.xy[i].y,
728  xy[m].x + gMarker.xy[i+1].x, xy[m].y + gMarker.xy[i+1].y);
729  break;
730  }
731  }
732  }
733 }
734 
735 ////////////////////////////////////////////////////////////////////////////////
736 /// Draw a text string using current font.
737 ///
738 /// \param [in] mode : drawing mode
739 /// - mode=0 : the background is not drawn (kClear)
740 /// - mode=1 : the background is drawn (kOpaque)
741 /// \param [in] x,y : text position
742 /// \param [in] angle : text angle
743 /// \param [in] mgn : magnification factor
744 /// \param [in] text : text string
745 
746 void TGX11::DrawText(int x, int y, float angle, float mgn,
747  const char *text, ETextMode mode)
748 {
750 
751  if (!text) return;
752 
753  switch (mode) {
754 
755  case kClear:
756  XRotDrawAlignedString((Display*)fDisplay, gTextFont, angle,
757  gCws->fDrawing, *gGCtext, x, y, (char*)text, fTextAlign);
758  break;
759 
760  case kOpaque:
762  gCws->fDrawing, *gGCtext, x, y, (char*)text, fTextAlign);
763  break;
764 
765  default:
766  break;
767  }
768 }
769 
770 ////////////////////////////////////////////////////////////////////////////////
771 /// Find best visual, i.e. the one with the most planes and TrueColor or
772 /// DirectColor. Sets fVisual, fDepth, fRootWin, fColormap, fBlackPixel
773 /// and fWhitePixel.
774 
776 {
777  Int_t findvis = gEnv->GetValue("X11.FindBestVisual", 1);
778 
779  Visual *vis = DefaultVisual((Display*)fDisplay, fScreenNumber);
780  if (((vis->c_class != TrueColor && vis->c_class != DirectColor) ||
781  DefaultDepth((Display*)fDisplay, fScreenNumber) < 15) && findvis) {
782 
783  // try to find better visual
784  static XVisualInfo templates[] = {
785  // Visual, visualid, screen, depth, class , red_mask, green_mask, blue_mask, colormap_size, bits_per_rgb
786  { 0 , 0 , 0 , 24 , TrueColor , 0 , 0 , 0 , 0 , 0 },
787  { 0 , 0 , 0 , 32 , TrueColor , 0 , 0 , 0 , 0 , 0 },
788  { 0 , 0 , 0 , 16 , TrueColor , 0 , 0 , 0 , 0 , 0 },
789  { 0 , 0 , 0 , 15 , TrueColor , 0 , 0 , 0 , 0 , 0 },
790  // no suitable TrueColorMode found - now do the same thing to DirectColor
791  { 0 , 0 , 0 , 24 , DirectColor, 0 , 0 , 0 , 0 , 0 },
792  { 0 , 0 , 0 , 32 , DirectColor, 0 , 0 , 0 , 0 , 0 },
793  { 0 , 0 , 0 , 16 , DirectColor, 0 , 0 , 0 , 0 , 0 },
794  { 0 , 0 , 0 , 15 , DirectColor, 0 , 0 , 0 , 0 , 0 },
795  { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
796  };
797 
798  Int_t nitems = 0;
799  XVisualInfo *vlist = 0;
800  for (Int_t i = 0; templates[i].depth != 0; i++) {
801  Int_t mask = VisualScreenMask|VisualDepthMask|VisualClassMask;
802  templates[i].screen = fScreenNumber;
803  if ((vlist = XGetVisualInfo((Display*)fDisplay, mask, &(templates[i]), &nitems))) {
804  FindUsableVisual((RXVisualInfo*)vlist, nitems);
805  XFree(vlist);
806  vlist = 0;
807  if (fVisual)
808  break;
809  }
810  }
811  }
812 
813  fRootWin = RootWindow((Display*)fDisplay, fScreenNumber);
814 
815  if (!fVisual) {
816  fDepth = DefaultDepth((Display*)fDisplay, fScreenNumber);
817  fVisual = (RVisual*)DefaultVisual((Display*)fDisplay, fScreenNumber);
819  if (fDepth > 1)
820  fColormap = DefaultColormap((Display*)fDisplay, fScreenNumber);
821  fBlackPixel = BlackPixel((Display*)fDisplay, fScreenNumber);
822  fWhitePixel = WhitePixel((Display*)fDisplay, fScreenNumber);
823  }
824  if (gDebug > 1)
825  Printf("Selected visual 0x%lx: depth %d, class %d, colormap: %s",
826  fVisual->visualid, fDepth, fVisual->c_class,
827  fColormap == DefaultColormap((Display*)fDisplay, fScreenNumber) ? "default" :
828  "custom");
829 }
830 
831 ////////////////////////////////////////////////////////////////////////////////
832 /// Dummy error handler for X11. Used by FindUsableVisual().
833 
834 static Int_t DummyX11ErrorHandler(Display *, XErrorEvent *)
835 {
836  return 0;
837 }
838 
839 ////////////////////////////////////////////////////////////////////////////////
840 /// Check if visual is usable, if so set fVisual, fDepth, fColormap,
841 /// fBlackPixel and fWhitePixel.
842 
843 void TGX11::FindUsableVisual(RXVisualInfo *vlist, Int_t nitems)
844 {
845  Int_t (*oldErrorHandler)(Display *, XErrorEvent *) =
846  XSetErrorHandler(DummyX11ErrorHandler);
847 
848  XSetWindowAttributes attr;
849  memset(&attr, 0, sizeof(attr));
850 
851  Window root = RootWindow((Display*)fDisplay, fScreenNumber);
852 
853  for (Int_t i = 0; i < nitems; i++) {
854  Window w = None, wjunk;
855  UInt_t width, height, ujunk;
856  Int_t junk;
857 
858  // try and use default colormap when possible
859  if (vlist[i].visual == DefaultVisual((Display*)fDisplay, fScreenNumber)) {
860  attr.colormap = DefaultColormap((Display*)fDisplay, fScreenNumber);
861  } else {
862  attr.colormap = XCreateColormap((Display*)fDisplay, root, vlist[i].visual, AllocNone);
863  }
864 
865  static XColor black_xcol = { 0, 0x0000, 0x0000, 0x0000, DoRed|DoGreen|DoBlue, 0 };
866  static XColor white_xcol = { 0, 0xFFFF, 0xFFFF, 0xFFFF, DoRed|DoGreen|DoBlue, 0 };
867  XAllocColor((Display*)fDisplay, attr.colormap, &black_xcol);
868  XAllocColor((Display*)fDisplay, attr.colormap, &white_xcol);
869  attr.border_pixel = black_xcol.pixel;
870  attr.override_redirect = True;
871 
872  w = XCreateWindow((Display*)fDisplay, root, -20, -20, 10, 10, 0, vlist[i].depth,
873  CopyFromParent, vlist[i].visual,
874  CWColormap|CWBorderPixel|CWOverrideRedirect, &attr);
875  if (w != None && XGetGeometry((Display*)fDisplay, w, &wjunk, &junk, &junk,
876  &width, &height, &ujunk, &ujunk)) {
877  fVisual = (RVisual*)vlist[i].visual;
878  fDepth = vlist[i].depth;
879  fColormap = attr.colormap;
880  fBlackPixel = black_xcol.pixel;
881  fWhitePixel = white_xcol.pixel;
882  fVisRootWin = w;
883  break;
884  }
885  if (attr.colormap != DefaultColormap((Display*)fDisplay, fScreenNumber))
886  XFreeColormap((Display*)fDisplay, attr.colormap);
887  }
888  XSetErrorHandler(oldErrorHandler);
889 }
890 
891 ////////////////////////////////////////////////////////////////////////////////
892 /// Return character up vector.
893 
895 {
896  chupx = fCharacterUpX;
897  chupy = fCharacterUpY;
898 }
899 
900 ////////////////////////////////////////////////////////////////////////////////
901 /// Return reference to internal color structure associated
902 /// to color index cid.
903 
905 {
906  XColor_t *col = (XColor_t*) (Long_t)fColors->GetValue(cid);
907  if (!col) {
908  col = new XColor_t;
909  fColors->Add(cid, (Long_t) col);
910  }
911  return *col;
912 }
913 
914 ////////////////////////////////////////////////////////////////////////////////
915 /// Return current window pointer. Protected method used by TGX11TTF.
916 
918 {
919  return (Window_t)(gCws ? gCws->fDrawing : 0);
920 }
921 
922 ////////////////////////////////////////////////////////////////////////////////
923 /// Return desired Graphics Context ("which" maps directly on gGCList[]).
924 /// Protected method used by TGX11TTF.
925 
926 void *TGX11::GetGC(Int_t which) const
927 {
928  if (which >= kMAXGC || which < 0) {
929  Error("GetGC", "trying to get illegal GC (which = %d)", which);
930  return 0;
931  }
932  return &gGClist[which];
933 }
934 
935 ////////////////////////////////////////////////////////////////////////////////
936 /// Query the double buffer value for the window wid.
937 
939 {
940  gTws = &fWindows[wid];
941  if (!gTws->fOpen)
942  return -1;
943  else
944  return gTws->fDoubleBuffer;
945 }
946 
947 ////////////////////////////////////////////////////////////////////////////////
948 /// Return position and size of window wid.
949 ///
950 /// \param [in] wid : window identifier
951 /// \param [in] x,y : window position (output)
952 /// \param [in] w,h : window size (output)
953 ///
954 /// if wid < 0 the size of the display is returned
955 
956 void TGX11::GetGeometry(int wid, int &x, int &y, unsigned int &w, unsigned int &h)
957 {
958  Window junkwin=0;
959 
960  if (wid < 0) {
961  x = 0;
962  y = 0;
963  w = DisplayWidth((Display*)fDisplay,fScreenNumber);
964  h = DisplayHeight((Display*)fDisplay,fScreenNumber);
965  } else {
966  Window root;
967  unsigned int border, depth;
968  unsigned int width, height;
969 
970  gTws = &fWindows[wid];
971  XGetGeometry((Display*)fDisplay, gTws->fWindow, &root, &x, &y,
972  &width, &height, &border, &depth);
973  XTranslateCoordinates((Display*)fDisplay, gTws->fWindow, fRootWin,
974  0, 0, &x, &y, &junkwin);
975  if (width >= 65535)
976  width = 1;
977  if (height >= 65535)
978  height = 1;
979  if (width > 0 && height > 0) {
980  gTws->fWidth = width;
981  gTws->fHeight = height;
982  }
983  w = gTws->fWidth;
984  h = gTws->fHeight;
985  }
986 }
987 
988 ////////////////////////////////////////////////////////////////////////////////
989 /// Return hostname on which the display is opened.
990 
991 const char *TGX11::DisplayName(const char *dpyName)
992 {
993  return XDisplayName(dpyName);
994 }
995 
996 ////////////////////////////////////////////////////////////////////////////////
997 /// Return pixel value associated to specified ROOT color number.
998 
1000 {
1001  TColor *color = gROOT->GetColor(ci);
1002  if (color)
1003  SetRGB(ci, color->GetRed(), color->GetGreen(), color->GetBlue());
1004 // else
1005 // Warning("GetPixel", "color with index %d not defined", ci);
1006 
1007  XColor_t &col = GetColor(ci);
1008  return col.fPixel;
1009 }
1010 
1011 ////////////////////////////////////////////////////////////////////////////////
1012 /// Get maximum number of planes.
1013 
1014 void TGX11::GetPlanes(int &nplanes)
1015 {
1016  nplanes = fDepth;
1017 }
1018 
1019 ////////////////////////////////////////////////////////////////////////////////
1020 /// Get rgb values for color "index".
1021 
1022 void TGX11::GetRGB(int index, float &r, float &g, float &b)
1023 {
1024  if (index == 0) {
1025  r = g = b = 1.0;
1026  } else if (index == 1) {
1027  r = g = b = 0.0;
1028  } else {
1029  XColor_t &col = GetColor(index);
1030  r = ((float) col.fRed) / ((float) kBIGGEST_RGB_VALUE);
1031  g = ((float) col.fGreen) / ((float) kBIGGEST_RGB_VALUE);
1032  b = ((float) col.fBlue) / ((float) kBIGGEST_RGB_VALUE);
1033  }
1034 }
1035 
1036 ////////////////////////////////////////////////////////////////////////////////
1037 /// Return the size of a character string.
1038 ///
1039 /// \param [in] w : text width
1040 /// \param [in] h : text height
1041 /// \param [in] mess : message
1042 
1043 void TGX11::GetTextExtent(unsigned int &w, unsigned int &h, char *mess)
1044 {
1045  w=0; h=0;
1046  if (strlen(mess)==0) return;
1047 
1048  XPoint *cBox;
1050  cBox = XRotTextExtents((Display*)fDisplay, gTextFont, 0., 0, 0, mess, 0);
1051  if (cBox) {
1052  w = cBox[2].x;
1053  h = -cBox[2].y;
1054  free((char *)cBox);
1055  }
1056 }
1057 
1058 ////////////////////////////////////////////////////////////////////////////////
1059 /// Return the X11 window identifier.
1060 ///
1061 /// \param [in] wid : Workstation identifier (input)
1062 
1064 {
1065  return (Window_t) fWindows[wid].fWindow;
1066 }
1067 
1068 ////////////////////////////////////////////////////////////////////////////////
1069 /// Move the window wid.
1070 ///
1071 /// \param [in] wid : Window identifier.
1072 /// \param [in] x : x new window position
1073 /// \param [in] y : y new window position
1074 
1075 void TGX11::MoveWindow(int wid, int x, int y)
1076 {
1077  gTws = &fWindows[wid];
1078  if (!gTws->fOpen) return;
1079 
1080  XMoveWindow((Display*)fDisplay, gTws->fWindow, x, y);
1081 }
1082 
1083 ////////////////////////////////////////////////////////////////////////////////
1084 /// Open the display. Return -1 if the opening fails, 0 when ok.
1085 
1087 {
1088  Pixmap pixmp1, pixmp2;
1089  XColor fore, back;
1090  char **fontlist;
1091  int fontcount = 0;
1092  int i;
1093 
1094  if (fDisplay) return 0;
1095 
1096  fDisplay = disp;
1097  fScreenNumber = DefaultScreen((Display*)fDisplay);
1098 
1099  FindBestVisual();
1100 
1101  GetColor(1).fDefined = kTRUE; // default foreground
1103  GetColor(0).fDefined = kTRUE; // default background
1105 
1106  // Inquire the the XServer Vendor
1107  char vendor[132];
1108  strlcpy(vendor, XServerVendor((Display*)fDisplay),132);
1109 
1110  // Create primitives graphic contexts
1111  for (i = 0; i < kMAXGC; i++)
1112  gGClist[i] = XCreateGC((Display*)fDisplay, fVisRootWin, 0, 0);
1113 
1114  XGCValues values;
1115  if (XGetGCValues((Display*)fDisplay, *gGCtext, GCForeground|GCBackground, &values)) {
1116  XSetForeground((Display*)fDisplay, *gGCinvt, values.background);
1117  XSetBackground((Display*)fDisplay, *gGCinvt, values.foreground);
1118  } else {
1119  Error("OpenDisplay", "cannot get GC values");
1120  }
1121 
1122  // Turn-off GraphicsExpose and NoExpose event reporting for the pixmap
1123  // manipulation GC, this to prevent these events from being stacked up
1124  // without ever being processed and thereby wasting a lot of memory.
1125  XSetGraphicsExposures((Display*)fDisplay, *gGCpxmp, False);
1126 
1127  // Create input echo graphic context
1128  XGCValues echov;
1129  echov.foreground = fBlackPixel;
1130  echov.background = fWhitePixel;
1131  if (strstr(vendor,"Hewlett"))
1132  echov.function = GXxor;
1133  else
1134  echov.function = GXinvert;
1135 
1136  gGCecho = XCreateGC((Display*)fDisplay, fVisRootWin,
1137  GCForeground | GCBackground | GCFunction,
1138  &echov);
1139 
1140  // Load a default Font
1141  static int isdisp = 0;
1142  if (!isdisp) {
1143  for (i = 0; i < kMAXFONT; i++) {
1144  gFont[i].id = 0;
1145  strcpy(gFont[i].name, " ");
1146  }
1147  fontlist = XListFonts((Display*)fDisplay, "*courier*", 1, &fontcount);
1148  if (fontlist && fontcount != 0) {
1149  gFont[gCurrentFontNumber].id = XLoadQueryFont((Display*)fDisplay, fontlist[0]);
1151  strcpy(gFont[gCurrentFontNumber].name, "*courier*");
1153  XFreeFontNames(fontlist);
1154  } else {
1155  // emergency: try fixed font
1156  fontlist = XListFonts((Display*)fDisplay, "fixed", 1, &fontcount);
1157  if (fontlist && fontcount != 0) {
1158  gFont[gCurrentFontNumber].id = XLoadQueryFont((Display*)fDisplay, fontlist[0]);
1160  strcpy(gFont[gCurrentFontNumber].name, "fixed");
1162  XFreeFontNames(fontlist);
1163  } else {
1164  Warning("OpenDisplay", "no default font loaded");
1165  }
1166  }
1167  isdisp = 1;
1168  }
1169 
1170  // Create a null cursor
1171  pixmp1 = XCreateBitmapFromData((Display*)fDisplay, fRootWin,
1172  null_cursor_bits, 16, 16);
1173  pixmp2 = XCreateBitmapFromData((Display*)fDisplay, fRootWin,
1174  null_cursor_bits, 16, 16);
1175  gNullCursor = XCreatePixmapCursor((Display*)fDisplay,pixmp1,pixmp2,&fore,&back,0,0);
1176 
1177  // Create cursors
1178  fCursors[kBottomLeft] = XCreateFontCursor((Display*)fDisplay, XC_bottom_left_corner);
1179  fCursors[kBottomRight] = XCreateFontCursor((Display*)fDisplay, XC_bottom_right_corner);
1180  fCursors[kTopLeft] = XCreateFontCursor((Display*)fDisplay, XC_top_left_corner);
1181  fCursors[kTopRight] = XCreateFontCursor((Display*)fDisplay, XC_top_right_corner);
1182  fCursors[kBottomSide] = XCreateFontCursor((Display*)fDisplay, XC_bottom_side);
1183  fCursors[kLeftSide] = XCreateFontCursor((Display*)fDisplay, XC_left_side);
1184  fCursors[kTopSide] = XCreateFontCursor((Display*)fDisplay, XC_top_side);
1185  fCursors[kRightSide] = XCreateFontCursor((Display*)fDisplay, XC_right_side);
1186  fCursors[kMove] = XCreateFontCursor((Display*)fDisplay, XC_fleur);
1187  fCursors[kCross] = XCreateFontCursor((Display*)fDisplay, XC_tcross);
1188  fCursors[kArrowHor] = XCreateFontCursor((Display*)fDisplay, XC_sb_h_double_arrow);
1189  fCursors[kArrowVer] = XCreateFontCursor((Display*)fDisplay, XC_sb_v_double_arrow);
1190  fCursors[kHand] = XCreateFontCursor((Display*)fDisplay, XC_hand2);
1191  fCursors[kRotate] = XCreateFontCursor((Display*)fDisplay, XC_exchange);
1192  fCursors[kPointer] = XCreateFontCursor((Display*)fDisplay, XC_left_ptr);
1193  fCursors[kArrowRight] = XCreateFontCursor((Display*)fDisplay, XC_arrow);
1194  fCursors[kCaret] = XCreateFontCursor((Display*)fDisplay, XC_xterm);
1195  fCursors[kWatch] = XCreateFontCursor((Display*)fDisplay, XC_watch);
1196  fCursors[kNoDrop] = XCreateFontCursor((Display*)fDisplay, XC_pirate);
1197 
1198  // Setup color information
1200 
1201  if (fVisual->c_class == TrueColor) {
1202  for (i = 0; i < int(sizeof(fVisual->blue_mask)*kBitsPerByte); i++) {
1203  if (fBlueShift == -1 && ((fVisual->blue_mask >> i) & 1))
1204  fBlueShift = i;
1205  if ((fVisual->blue_mask >> i) == 1) {
1206  fBlueDiv = sizeof(UShort_t)*kBitsPerByte - i - 1 + fBlueShift;
1207  break;
1208  }
1209  }
1210  for (i = 0; i < int(sizeof(fVisual->green_mask)*kBitsPerByte); i++) {
1211  if (fGreenShift == -1 && ((fVisual->green_mask >> i) & 1))
1212  fGreenShift = i;
1213  if ((fVisual->green_mask >> i) == 1) {
1214  fGreenDiv = sizeof(UShort_t)*kBitsPerByte - i - 1 + fGreenShift;
1215  break;
1216  }
1217  }
1218  for (i = 0; i < int(sizeof(fVisual->red_mask)*kBitsPerByte); i++) {
1219  if (fRedShift == -1 && ((fVisual->red_mask >> i) & 1))
1220  fRedShift = i;
1221  if ((fVisual->red_mask >> i) == 1) {
1222  fRedDiv = sizeof(UShort_t)*kBitsPerByte - i - 1 + fRedShift;
1223  break;
1224  }
1225  }
1226  //printf("fRedDiv = %d, fGreenDiv = %d, fBlueDiv = %d, fRedShift = %d, fGreenShift = %d, fBlueShift = %d\n",
1227  // fRedDiv, fGreenDiv, fBlueDiv, fRedShift, fGreenShift, fBlueShift);
1228  }
1229 
1230  return 0;
1231 }
1232 
1233 ////////////////////////////////////////////////////////////////////////////////
1234 /// Open a new pixmap.
1235 ///
1236 /// \param [in] w,h : Width and height of the pixmap.
1237 
1238 Int_t TGX11::OpenPixmap(unsigned int w, unsigned int h)
1239 {
1240  Window root;
1241  unsigned int wval, hval;
1242  int xx, yy, i, wid;
1243  unsigned int ww, hh, border, depth;
1244  wval = w;
1245  hval = h;
1246 
1247  // Select next free window number
1248 
1249 again:
1250  for (wid = 0; wid < fMaxNumberOfWindows; wid++)
1251  if (!fWindows[wid].fOpen) {
1252  fWindows[wid].fOpen = 1;
1253  gCws = &fWindows[wid];
1254  break;
1255  }
1256 
1257  if (wid == fMaxNumberOfWindows) {
1258  int newsize = fMaxNumberOfWindows + 10;
1259  fWindows = (XWindow_t*) TStorage::ReAlloc(fWindows, newsize*sizeof(XWindow_t),
1260  fMaxNumberOfWindows*sizeof(XWindow_t));
1261  for (i = fMaxNumberOfWindows; i < newsize; i++)
1262  fWindows[i].fOpen = 0;
1263  fMaxNumberOfWindows = newsize;
1264  goto again;
1265  }
1266 
1267  gCws->fWindow = XCreatePixmap((Display*)fDisplay, fRootWin, wval, hval, fDepth);
1268  XGetGeometry((Display*)fDisplay, gCws->fWindow, &root, &xx, &yy, &ww, &hh, &border, &depth);
1269 
1270  for (i = 0; i < kMAXGC; i++)
1271  XSetClipMask((Display*)fDisplay, gGClist[i], None);
1272 
1273  SetColor(gGCpxmp, 0);
1274  XFillRectangle((Display*)fDisplay, gCws->fWindow, *gGCpxmp, 0, 0, ww, hh);
1275  SetColor(gGCpxmp, 1);
1276 
1277  // Initialise the window structure
1278  gCws->fDrawing = gCws->fWindow;
1279  gCws->fBuffer = 0;
1280  gCws->fDoubleBuffer = 0;
1281  gCws->fIsPixmap = 1;
1282  gCws->fClip = 0;
1283  gCws->fWidth = wval;
1284  gCws->fHeight = hval;
1285  gCws->fNewColors = 0;
1286  gCws->fShared = kFALSE;
1287 
1288  return wid;
1289 }
1290 
1291 ////////////////////////////////////////////////////////////////////////////////
1292 /// Open window and return window number.
1293 ///
1294 /// \return -1 if window initialization fails.
1295 
1297 {
1298  XSetWindowAttributes attributes;
1299  ULong_t attr_mask = 0;
1300  int wid;
1301  int xval, yval;
1302  unsigned int wval, hval, border, depth;
1303  Window root;
1304 
1305  Window wind = (Window) win;
1306 
1307  XGetGeometry((Display*)fDisplay, wind, &root, &xval, &yval, &wval, &hval, &border, &depth);
1308 
1309  // Select next free window number
1310 
1311 again:
1312  for (wid = 0; wid < fMaxNumberOfWindows; wid++)
1313  if (!fWindows[wid].fOpen) {
1314  fWindows[wid].fOpen = 1;
1315  fWindows[wid].fDoubleBuffer = 0;
1316  gCws = &fWindows[wid];
1317  break;
1318  }
1319 
1320  if (wid == fMaxNumberOfWindows) {
1321  int newsize = fMaxNumberOfWindows + 10;
1322  fWindows = (XWindow_t*) TStorage::ReAlloc(fWindows, newsize*sizeof(XWindow_t),
1323  fMaxNumberOfWindows*sizeof(XWindow_t));
1324  for (int i = fMaxNumberOfWindows; i < newsize; i++)
1325  fWindows[i].fOpen = 0;
1326  fMaxNumberOfWindows = newsize;
1327  goto again;
1328  }
1329 
1330  // Create window
1331 
1332  attributes.background_pixel = GetColor(0).fPixel;
1333  attr_mask |= CWBackPixel;
1334  attributes.border_pixel = GetColor(1).fPixel;
1335  attr_mask |= CWBorderPixel;
1336  attributes.event_mask = NoEventMask;
1337  attr_mask |= CWEventMask;
1338  attributes.backing_store = Always;
1339  attr_mask |= CWBackingStore;
1340  attributes.bit_gravity = NorthWestGravity;
1341  attr_mask |= CWBitGravity;
1342  if (fColormap) {
1343  attributes.colormap = fColormap;
1344  attr_mask |= CWColormap;
1345  }
1346 
1347  gCws->fWindow = XCreateWindow((Display*)fDisplay, wind,
1348  xval, yval, wval, hval, 0, fDepth,
1349  InputOutput, fVisual,
1350  attr_mask, &attributes);
1351 
1352  XMapWindow((Display*)fDisplay, gCws->fWindow);
1353  XFlush((Display*)fDisplay);
1354 
1355  // Initialise the window structure
1356 
1357  gCws->fDrawing = gCws->fWindow;
1358  gCws->fBuffer = 0;
1359  gCws->fDoubleBuffer = 0;
1360  gCws->fIsPixmap = 0;
1361  gCws->fClip = 0;
1362  gCws->fWidth = wval;
1363  gCws->fHeight = hval;
1364  gCws->fNewColors = 0;
1365  gCws->fShared = kFALSE;
1366 
1367  return wid;
1368 }
1369 
1370 ////////////////////////////////////////////////////////////////////////////////
1371 /// Register a window created by Qt as a ROOT window (like InitWindow()).
1372 
1374 {
1375  Int_t wid;
1376 
1377  // Select next free window number
1378 
1379 again:
1380  for (wid = 0; wid < fMaxNumberOfWindows; wid++)
1381  if (!fWindows[wid].fOpen) {
1382  fWindows[wid].fOpen = 1;
1383  fWindows[wid].fDoubleBuffer = 0;
1384  gCws = &fWindows[wid];
1385  break;
1386  }
1387 
1388  if (wid == fMaxNumberOfWindows) {
1389  int newsize = fMaxNumberOfWindows + 10;
1390  fWindows = (XWindow_t*) TStorage::ReAlloc(fWindows, newsize*sizeof(XWindow_t),
1391  fMaxNumberOfWindows*sizeof(XWindow_t));
1392  for (int i = fMaxNumberOfWindows; i < newsize; i++)
1393  fWindows[i].fOpen = 0;
1394  fMaxNumberOfWindows = newsize;
1395  goto again;
1396  }
1397 
1398  gCws->fWindow = qwid;
1399 
1400  //init Xwindow_t struct
1401  gCws->fDrawing = gCws->fWindow;
1402  gCws->fBuffer = 0;
1403  gCws->fDoubleBuffer = 0;
1404  gCws->fIsPixmap = 0;
1405  gCws->fClip = 0;
1406  gCws->fWidth = w;
1407  gCws->fHeight = h;
1408  gCws->fNewColors = 0;
1409  gCws->fShared = kTRUE;
1410 
1411  return wid;
1412 }
1413 
1414 ////////////////////////////////////////////////////////////////////////////////
1415 /// Remove a window created by Qt (like CloseWindow1()).
1416 
1418 {
1419  SelectWindow((int)qwid);
1420 
1421  if (gCws->fBuffer) XFreePixmap((Display*)fDisplay, gCws->fBuffer);
1422 
1423  if (gCws->fNewColors) {
1424  if (fRedDiv == -1)
1425  XFreeColors((Display*)fDisplay, fColormap, gCws->fNewColors, gCws->fNcolors, 0);
1426  delete [] gCws->fNewColors;
1427  gCws->fNewColors = 0;
1428  }
1429 
1430  gCws->fOpen = 0;
1431 
1432  // make first window in list the current window
1433  for (Int_t wid = 0; wid < fMaxNumberOfWindows; wid++)
1434  if (fWindows[wid].fOpen) {
1435  gCws = &fWindows[wid];
1436  return;
1437  }
1438 
1439  gCws = 0;
1440 }
1441 
1442 ////////////////////////////////////////////////////////////////////////////////
1443 /// Query pointer position.
1444 ///
1445 /// \param [in] ix : X coordinate of pointer
1446 /// \param [in] iy : Y coordinate of pointer
1447 /// (both coordinates are relative to the origin of the root window)
1448 
1449 void TGX11::QueryPointer(int &ix, int &iy)
1450 {
1451  Window root_return, child_return;
1452  int win_x_return, win_y_return;
1453  int root_x_return, root_y_return;
1454  unsigned int mask_return;
1455 
1456  XQueryPointer((Display*)fDisplay,gCws->fWindow, &root_return,
1457  &child_return, &root_x_return, &root_y_return, &win_x_return,
1458  &win_y_return, &mask_return);
1459 
1460  ix = root_x_return;
1461  iy = root_y_return;
1462 }
1463 
1464 ////////////////////////////////////////////////////////////////////////////////
1465 /// Remove the pixmap pix.
1466 
1468 {
1469  XFreePixmap((Display*)fDisplay,*pix);
1470 }
1471 
1472 ////////////////////////////////////////////////////////////////////////////////
1473 /// Request Locator position.
1474 ///
1475 /// \param [in] x,y : cursor position at moment of button press (output)
1476 /// \param [in] ctyp : cursor type (input)
1477 /// - ctyp=1 tracking cross
1478 /// - ctyp=2 cross-hair
1479 /// - ctyp=3 rubber circle
1480 /// - ctyp=4 rubber band
1481 /// - ctyp=5 rubber rectangle
1482 ///
1483 /// \param [in] mode : input mode
1484 /// - mode=0 request
1485 /// - mode=1 sample
1486 ///
1487 /// Request locator:
1488 /// return button number:
1489 /// - 1 = left is pressed
1490 /// - 2 = middle is pressed
1491 /// - 3 = right is pressed
1492 /// in sample mode:
1493 /// - 11 = left is released
1494 /// - 12 = middle is released
1495 /// - 13 = right is released
1496 /// - -1 = nothing is pressed or released
1497 /// - -2 = leave the window
1498 /// - else = keycode (keyboard is pressed)
1499 
1500 Int_t TGX11::RequestLocator(int mode, int ctyp, int &x, int &y)
1501 {
1502  static int xloc = 0;
1503  static int yloc = 0;
1504  static int xlocp = 0;
1505  static int ylocp = 0;
1506  static Cursor cursor = 0;
1507 
1508  XEvent event;
1509  int button_press;
1510  int radius;
1511 
1512  // Change the cursor shape
1513  if (cursor == 0) {
1514  if (ctyp > 1) {
1515  XDefineCursor((Display*)fDisplay, gCws->fWindow, gNullCursor);
1516  XSetForeground((Display*)fDisplay, gGCecho, GetColor(0).fPixel);
1517  } else {
1518  cursor = XCreateFontCursor((Display*)fDisplay, XC_crosshair);
1519  XDefineCursor((Display*)fDisplay, gCws->fWindow, cursor);
1520  }
1521  }
1522 
1523  // Event loop
1524 
1525  button_press = 0;
1526 
1527  while (button_press == 0) {
1528 
1529  switch (ctyp) {
1530 
1531  case 1 :
1532  break;
1533 
1534  case 2 :
1535  XDrawLine((Display*)fDisplay, gCws->fWindow, gGCecho,
1536  xloc, 0, xloc, gCws->fHeight);
1537  XDrawLine((Display*)fDisplay, gCws->fWindow, gGCecho,
1538  0, yloc, gCws->fWidth, yloc);
1539  break;
1540 
1541  case 3 :
1542  radius = (int) TMath::Sqrt((double)((xloc-xlocp)*(xloc-xlocp) +
1543  (yloc-ylocp)*(yloc-ylocp)));
1544  XDrawArc((Display*)fDisplay, gCws->fWindow, gGCecho,
1545  xlocp-radius, ylocp-radius,
1546  2*radius, 2*radius, 0, 23040);
1547  break;
1548 
1549  case 4 :
1550  XDrawLine((Display*)fDisplay, gCws->fWindow, gGCecho,
1551  xlocp, ylocp, xloc, yloc);
1552  break;
1553 
1554  case 5 :
1555  XDrawRectangle((Display*)fDisplay, gCws->fWindow, gGCecho,
1556  TMath::Min(xlocp,xloc), TMath::Min(ylocp,yloc),
1557  TMath::Abs(xloc-xlocp), TMath::Abs(yloc-ylocp));
1558  break;
1559 
1560  default:
1561  break;
1562  }
1563 
1564  while (XEventsQueued( (Display*)fDisplay, QueuedAlready) > 1) {
1565  XNextEvent((Display*)fDisplay, &event);
1566  }
1567  XWindowEvent((Display*)fDisplay, gCws->fWindow, gMouseMask, &event);
1568 
1569  switch (ctyp) {
1570 
1571  case 1 :
1572  break;
1573 
1574  case 2 :
1575  XDrawLine((Display*)fDisplay, gCws->fWindow, gGCecho,
1576  xloc, 0, xloc, gCws->fHeight);
1577  XDrawLine((Display*)fDisplay, gCws->fWindow, gGCecho,
1578  0, yloc, gCws->fWidth, yloc);
1579  break;
1580 
1581  case 3 :
1582  radius = (int) TMath::Sqrt((double)((xloc-xlocp)*(xloc-xlocp) +
1583  (yloc-ylocp)*(yloc-ylocp)));
1584  XDrawArc((Display*)fDisplay, gCws->fWindow, gGCecho,
1585  xlocp-radius, ylocp-radius,
1586  2*radius, 2*radius, 0, 23040);
1587  break;
1588 
1589  case 4 :
1590  XDrawLine((Display*)fDisplay, gCws->fWindow, gGCecho,
1591  xlocp, ylocp, xloc, yloc);
1592  break;
1593 
1594  case 5 :
1595  XDrawRectangle((Display*)fDisplay, gCws->fWindow, gGCecho,
1596  TMath::Min(xlocp,xloc), TMath::Min(ylocp,yloc),
1597  TMath::Abs(xloc-xlocp), TMath::Abs(yloc-ylocp));
1598  break;
1599 
1600  default:
1601  break;
1602  }
1603 
1604  xloc = event.xbutton.x;
1605  yloc = event.xbutton.y;
1606 
1607  switch (event.type) {
1608 
1609  case LeaveNotify :
1610  if (mode == 0) {
1611  while (1) {
1612  XNextEvent((Display*)fDisplay, &event);
1613  if (event.type == EnterNotify) break;
1614  }
1615  } else {
1616  button_press = -2;
1617  }
1618  break;
1619 
1620  case ButtonPress :
1621  button_press = event.xbutton.button ;
1622  xlocp = event.xbutton.x;
1623  ylocp = event.xbutton.y;
1624  XUndefineCursor( (Display*)fDisplay, gCws->fWindow );
1625  cursor = 0;
1626  break;
1627 
1628  case ButtonRelease :
1629  if (mode == 1) {
1630  button_press = 10+event.xbutton.button ;
1631  xlocp = event.xbutton.x;
1632  ylocp = event.xbutton.y;
1633  }
1634  break;
1635 
1636  case KeyPress :
1637  if (mode == 1) {
1638  button_press = event.xkey.keycode;
1639  xlocp = event.xbutton.x;
1640  ylocp = event.xbutton.y;
1641  }
1642  break;
1643 
1644  case KeyRelease :
1645  if (mode == 1) {
1646  button_press = -event.xkey.keycode;
1647  xlocp = event.xbutton.x;
1648  ylocp = event.xbutton.y;
1649  }
1650  break;
1651 
1652  default :
1653  break;
1654  }
1655 
1656  if (mode == 1) {
1657  if (button_press == 0)
1658  button_press = -1;
1659  break;
1660  }
1661  }
1662  x = event.xbutton.x;
1663  y = event.xbutton.y;
1664 
1665  return button_press;
1666 }
1667 
1668 ////////////////////////////////////////////////////////////////////////////////
1669 /// Request a string.
1670 ///
1671 /// \param [in] x,y : position where text is displayed
1672 /// \param [in] text : text displayed (input), edited text (output)
1673 ///
1674 /// Request string:
1675 /// text is displayed and can be edited with Emacs-like keybinding
1676 /// return termination code (0 for ESC, 1 for RETURN)
1677 
1679 {
1680  static Cursor cursor = 0;
1681  static int percent = 0; // bell volume
1682  Window focuswindow;
1683  int focusrevert;
1684  XEvent event;
1685  KeySym keysym;
1686  int key = -1;
1687  int len_text = strlen(text);
1688  int nt; // defined length of text
1689  int pt; // cursor position in text
1690 
1691  // change the cursor shape
1692  if (cursor == 0) {
1693  XKeyboardState kbstate;
1694  cursor = XCreateFontCursor((Display*)fDisplay, XC_question_arrow);
1695  XGetKeyboardControl((Display*)fDisplay, &kbstate);
1696  percent = kbstate.bell_percent;
1697  }
1698  if (cursor != 0)
1699  XDefineCursor((Display*)fDisplay, gCws->fWindow, cursor);
1700  for (nt = len_text; nt > 0 && text[nt-1] == ' '; nt--) { }
1701  pt = nt;
1702  XGetInputFocus((Display*)fDisplay, &focuswindow, &focusrevert);
1703  XSetInputFocus((Display*)fDisplay, gCws->fWindow, focusrevert, CurrentTime);
1704  while (key < 0) {
1705  char keybuf[8];
1706  char nbytes;
1707  int dx;
1708  int i;
1709  XDrawImageString((Display*)fDisplay, gCws->fWindow, *gGCtext, x, y, text, nt);
1710  dx = XTextWidth(gTextFont, text, nt);
1711  XDrawImageString((Display*)fDisplay, gCws->fWindow, *gGCtext, x + dx, y, " ", 1);
1712  dx = pt == 0 ? 0 : XTextWidth(gTextFont, text, pt);
1713  XDrawImageString((Display*)fDisplay, gCws->fWindow, *gGCinvt,
1714  x + dx, y, pt < len_text ? &text[pt] : " ", 1);
1715  XWindowEvent((Display*)fDisplay, gCws->fWindow, gKeybdMask, &event);
1716  switch (event.type) {
1717  case ButtonPress:
1718  case EnterNotify:
1719  XSetInputFocus((Display*)fDisplay, gCws->fWindow, focusrevert, CurrentTime);
1720  break;
1721  case LeaveNotify:
1722  XSetInputFocus((Display*)fDisplay, focuswindow, focusrevert, CurrentTime);
1723  break;
1724  case KeyPress:
1725  nbytes = XLookupString(&event.xkey, keybuf, sizeof(keybuf),
1726  &keysym, 0);
1727  switch (keysym) { // map cursor keys
1728  case XK_Left:
1729  keybuf[0] = '\002'; // Control-B
1730  nbytes = 1;
1731  break;
1732  case XK_Right:
1733  keybuf[0] = '\006'; // Control-F
1734  nbytes = 1;
1735  break;
1736  }
1737  if (nbytes == 1) {
1738  if (isascii(keybuf[0]) && isprint(keybuf[0])) {
1739  // insert character
1740  if (nt < len_text)
1741  nt++;
1742  for (i = nt - 1; i > pt; i--)
1743  text[i] = text[i-1];
1744  if (pt < len_text) {
1745  text[pt] = keybuf[0];
1746  pt++;
1747  }
1748  } else
1749  switch (keybuf[0]) {
1750  // Emacs-like editing keys
1751 
1752  case '\010': // backspace
1753  case '\177': // delete
1754  // delete backward
1755  if (pt > 0) {
1756  for (i = pt; i < nt; i++)
1757  text[i-1] = text[i];
1758  text[nt-1] = ' ';
1759  nt--;
1760  pt--;
1761  }
1762  break;
1763  case '\001': // ^A
1764  // beginning of line
1765  pt = 0;
1766  break;
1767  case '\002': // ^B
1768  // move backward
1769  if (pt > 0)
1770  pt--;
1771  break;
1772  case '\004': // ^D
1773  // delete forward
1774  if (pt > 0) {
1775  for (i = pt; i < nt; i++)
1776  text[i-1] = text[i];
1777  text[nt-1] = ' ';
1778  pt--;
1779  }
1780  break;
1781  case '\005': // ^E
1782  // end of line
1783  pt = nt;
1784  break;
1785 
1786  case '\006': // ^F
1787  // move forward
1788  if (pt < nt)
1789  pt++;
1790  break;
1791  case '\013': // ^K
1792  // delete to end of line
1793  for (i = pt; i < nt; i++)
1794  text[i] = ' ';
1795  nt = pt;
1796  break;
1797  case '\024': // ^T
1798  // transpose
1799  if (pt > 0) {
1800  char c = text[pt];
1801  text[pt] = text[pt-1];
1802  text[pt-1] = c;
1803  }
1804  break;
1805  case '\012': // newline
1806  case '\015': // return
1807  key = 1;
1808  break;
1809  case '\033': // escape
1810  key = 0;
1811  break;
1812 
1813  default:
1814  XBell((Display*)fDisplay, percent);
1815  }
1816  }
1817  }
1818  }
1819  XSetInputFocus((Display*)fDisplay, focuswindow, focusrevert, CurrentTime);
1820 
1821  if (cursor != 0) {
1822  XUndefineCursor((Display*)fDisplay, gCws->fWindow);
1823  cursor = 0;
1824  }
1825 
1826  return key;
1827 }
1828 
1829 ////////////////////////////////////////////////////////////////////////////////
1830 /// Rescale the window wid.
1831 ///
1832 /// \param [in] wid : Window identifier
1833 /// \param [in] w : Width
1834 /// \param [in] h : Height
1835 
1836 void TGX11::RescaleWindow(int wid, unsigned int w, unsigned int h)
1837 {
1838  int i;
1839 
1840  gTws = &fWindows[wid];
1841  if (!gTws->fOpen) return;
1842 
1843  // don't do anything when size did not change
1844  if (gTws->fWidth == w && gTws->fHeight == h) return;
1845 
1846  XResizeWindow((Display*)fDisplay, gTws->fWindow, w, h);
1847 
1848  if (gTws->fBuffer) {
1849  // don't free and recreate pixmap when new pixmap is smaller
1850  if (gTws->fWidth < w || gTws->fHeight < h) {
1851  XFreePixmap((Display*)fDisplay,gTws->fBuffer);
1852  gTws->fBuffer = XCreatePixmap((Display*)fDisplay, fRootWin, w, h, fDepth);
1853  }
1854  for (i = 0; i < kMAXGC; i++) XSetClipMask((Display*)fDisplay, gGClist[i], None);
1855  SetColor(gGCpxmp, 0);
1856  XFillRectangle( (Display*)fDisplay, gTws->fBuffer, *gGCpxmp, 0, 0, w, h);
1857  SetColor(gGCpxmp, 1);
1858  if (gTws->fDoubleBuffer) gTws->fDrawing = gTws->fBuffer;
1859  }
1860  gTws->fWidth = w;
1861  gTws->fHeight = h;
1862 }
1863 
1864 ////////////////////////////////////////////////////////////////////////////////
1865 /// Resize a pixmap.
1866 ///
1867 /// \param [in] wid : pixmap to be resized
1868 /// \param [in] w,h : Width and height of the pixmap
1869 
1870 int TGX11::ResizePixmap(int wid, unsigned int w, unsigned int h)
1871 {
1872  Window root;
1873  unsigned int wval, hval;
1874  int xx, yy, i;
1875  unsigned int ww, hh, border, depth;
1876  wval = w;
1877  hval = h;
1878 
1879  gTws = &fWindows[wid];
1880 
1881  // don't do anything when size did not change
1882  // if (gTws->fWidth == wval && gTws->fHeight == hval) return 0;
1883 
1884  // due to round-off errors in TPad::Resize() we might get +/- 1 pixel
1885  // change, in those cases don't resize pixmap
1886  if (gTws->fWidth >= wval-1 && gTws->fWidth <= wval+1 &&
1887  gTws->fHeight >= hval-1 && gTws->fHeight <= hval+1) return 0;
1888 
1889  // don't free and recreate pixmap when new pixmap is smaller
1890  if (gTws->fWidth < wval || gTws->fHeight < hval) {
1891  XFreePixmap((Display*)fDisplay, gTws->fWindow);
1892  gTws->fWindow = XCreatePixmap((Display*)fDisplay, fRootWin, wval, hval, fDepth);
1893  }
1894  XGetGeometry((Display*)fDisplay, gTws->fWindow, &root, &xx, &yy, &ww, &hh, &border, &depth);
1895 
1896  for (i = 0; i < kMAXGC; i++)
1897  XSetClipMask((Display*)fDisplay, gGClist[i], None);
1898 
1899  SetColor(gGCpxmp, 0);
1900  XFillRectangle((Display*)fDisplay, gTws->fWindow, *gGCpxmp, 0, 0, ww, hh);
1901  SetColor(gGCpxmp, 1);
1902 
1903  // Initialise the window structure
1904  gTws->fDrawing = gTws->fWindow;
1905  gTws->fWidth = wval;
1906  gTws->fHeight = hval;
1907 
1908  return 1;
1909 }
1910 
1911 ////////////////////////////////////////////////////////////////////////////////
1912 /// Resize the current window if necessary.
1913 
1914 void TGX11::ResizeWindow(int wid)
1915 {
1916  int i;
1917  int xval=0, yval=0;
1918  Window win, root=0;
1919  unsigned int wval=0, hval=0, border=0, depth=0;
1920 
1921  gTws = &fWindows[wid];
1922 
1923  win = gTws->fWindow;
1924 
1925  XGetGeometry((Display*)fDisplay, win, &root,
1926  &xval, &yval, &wval, &hval, &border, &depth);
1927  if (wval >= 65500) wval = 1;
1928  if (hval >= 65500) hval = 1;
1929 
1930  // don't do anything when size did not change
1931  if (gTws->fWidth == wval && gTws->fHeight == hval) return;
1932 
1933  XResizeWindow((Display*)fDisplay, gTws->fWindow, wval, hval);
1934 
1935  if (gTws->fBuffer) {
1936  if (gTws->fWidth < wval || gTws->fHeight < hval) {
1937  XFreePixmap((Display*)fDisplay,gTws->fBuffer);
1938  gTws->fBuffer = XCreatePixmap((Display*)fDisplay, fRootWin, wval, hval, fDepth);
1939  }
1940  for (i = 0; i < kMAXGC; i++) XSetClipMask((Display*)fDisplay, gGClist[i], None);
1941  SetColor(gGCpxmp, 0);
1942  XFillRectangle((Display*)fDisplay, gTws->fBuffer, *gGCpxmp, 0, 0, wval, hval);
1943  SetColor(gGCpxmp, 1);
1944  if (gTws->fDoubleBuffer) gTws->fDrawing = gTws->fBuffer;
1945  }
1946  gTws->fWidth = wval;
1947  gTws->fHeight = hval;
1948 }
1949 
1950 ////////////////////////////////////////////////////////////////////////////////
1951 /// Select window to which subsequent output is directed.
1952 
1953 void TGX11::SelectWindow(int wid)
1954 {
1955  XRectangle region;
1956  int i;
1957 
1958  if (wid < 0 || wid >= fMaxNumberOfWindows || !fWindows[wid].fOpen) return;
1959 
1960  gCws = &fWindows[wid];
1961 
1962  if (gCws->fClip && !gCws->fIsPixmap && !gCws->fDoubleBuffer) {
1963  region.x = gCws->fXclip;
1964  region.y = gCws->fYclip;
1965  region.width = gCws->fWclip;
1966  region.height = gCws->fHclip;
1967  for (i = 0; i < kMAXGC; i++)
1968  XSetClipRectangles((Display*)fDisplay, gGClist[i], 0, 0, &region, 1, YXBanded);
1969  } else {
1970  for (i = 0; i < kMAXGC; i++)
1971  XSetClipMask((Display*)fDisplay, gGClist[i], None);
1972  }
1973 }
1974 
1975 ////////////////////////////////////////////////////////////////////////////////
1976 /// Set character up vector.
1977 
1979 {
1980  if (chupx == fCharacterUpX && chupy == fCharacterUpY) return;
1981 
1982  if (chupx == 0 && chupy == 0) fTextAngle = 0;
1983  else if (chupx == 0 && chupy == 1) fTextAngle = 0;
1984  else if (chupx == -1 && chupy == 0) fTextAngle = 90;
1985  else if (chupx == 0 && chupy == -1) fTextAngle = 180;
1986  else if (chupx == 1 && chupy == 0) fTextAngle = 270;
1987  else {
1988  fTextAngle = ((TMath::ACos(chupx/TMath::Sqrt(chupx*chupx +chupy*chupy))*180.)/TMath::Pi())-90;
1989  if (chupy < 0) fTextAngle = 180 - fTextAngle;
1990  if (TMath::Abs(fTextAngle) <= 0.01) fTextAngle = 0;
1991  }
1992  fCharacterUpX = chupx;
1993  fCharacterUpY = chupy;
1994 }
1995 
1996 ////////////////////////////////////////////////////////////////////////////////
1997 /// Turn off the clipping for the window wid.
1998 
1999 void TGX11::SetClipOFF(int wid)
2000 {
2001  gTws = &fWindows[wid];
2002  gTws->fClip = 0;
2003 
2004  for (int i = 0; i < kMAXGC; i++)
2005  XSetClipMask( (Display*)fDisplay, gGClist[i], None );
2006 }
2007 
2008 ////////////////////////////////////////////////////////////////////////////////
2009 /// Set clipping region for the window wid.
2010 ///
2011 /// \param [in] wid : Window identifier
2012 /// \param [in] x,y : origin of clipping rectangle
2013 /// \param [in] w,h : size of clipping rectangle;
2014 
2015 void TGX11::SetClipRegion(int wid, int x, int y, unsigned int w, unsigned int h)
2016 {
2017 
2018  gTws = &fWindows[wid];
2019  gTws->fXclip = x;
2020  gTws->fYclip = y;
2021  gTws->fWclip = w;
2022  gTws->fHclip = h;
2023  gTws->fClip = 1;
2024  if (gTws->fClip && !gTws->fIsPixmap && !gTws->fDoubleBuffer) {
2025  XRectangle region;
2026  region.x = gTws->fXclip;
2027  region.y = gTws->fYclip;
2028  region.width = gTws->fWclip;
2029  region.height = gTws->fHclip;
2030  for (int i = 0; i < kMAXGC; i++)
2031  XSetClipRectangles((Display*)fDisplay, gGClist[i], 0, 0, &region, 1, YXBanded);
2032  }
2033 }
2034 
2035 ////////////////////////////////////////////////////////////////////////////////
2036 /// Set the foreground color in GC.
2037 
2038 void TGX11::SetColor(void *gci, int ci)
2039 {
2040  GC gc = *(GC *)gci;
2041 
2042  TColor *color = gROOT->GetColor(ci);
2043  if (color)
2044  SetRGB(ci, color->GetRed(), color->GetGreen(), color->GetBlue());
2045 
2046  XColor_t &col = GetColor(ci);
2047  if (fColormap && !col.fDefined) {
2048  col = GetColor(0);
2049  } else if (!fColormap && (ci < 0 || ci > 1)) {
2050  col = GetColor(0);
2051  }
2052 
2053  if (fDrawMode == kXor) {
2054  XGCValues values;
2055  XGetGCValues((Display*)fDisplay, gc, GCBackground, &values);
2056  XSetForeground((Display*)fDisplay, gc, col.fPixel ^ values.background);
2057  } else {
2058  XSetForeground((Display*)fDisplay, gc, col.fPixel);
2059 
2060  // make sure that foreground and background are different
2061  XGCValues values;
2062  XGetGCValues((Display*)fDisplay, gc, GCForeground | GCBackground, &values);
2063  if (values.foreground == values.background)
2064  XSetBackground((Display*)fDisplay, gc, GetColor(!ci).fPixel);
2065  }
2066 }
2067 
2068 ////////////////////////////////////////////////////////////////////////////////
2069 /// Set the cursor.
2070 
2071 void TGX11::SetCursor(int wid, ECursor cursor)
2072 {
2073  gTws = &fWindows[wid];
2074  XDefineCursor((Display*)fDisplay, gTws->fWindow, fCursors[cursor]);
2075 }
2076 
2077 ////////////////////////////////////////////////////////////////////////////////
2078 /// Set the double buffer on/off on window wid.
2079 ///
2080 /// \param [in] wid : Window identifier.
2081 /// - 999 means all the opened windows.
2082 /// \param [in] mode :
2083 /// - 1 double buffer is on
2084 /// - 0 double buffer is off
2085 
2086 void TGX11::SetDoubleBuffer(int wid, int mode)
2087 {
2088  if (wid == 999) {
2089  for (int i = 0; i < fMaxNumberOfWindows; i++) {
2090  gTws = &fWindows[i];
2091  if (gTws->fOpen) {
2092  switch (mode) {
2093  case 1 :
2095  break;
2096  default:
2098  break;
2099  }
2100  }
2101  }
2102  } else {
2103  gTws = &fWindows[wid];
2104  if (!gTws->fOpen) return;
2105  switch (mode) {
2106  case 1 :
2108  return;
2109  default:
2111  return;
2112  }
2113  }
2114 }
2115 
2116 ////////////////////////////////////////////////////////////////////////////////
2117 /// Turn double buffer mode off.
2118 
2120 {
2121  if (!gTws->fDoubleBuffer) return;
2122  gTws->fDoubleBuffer = 0;
2123  gTws->fDrawing = gTws->fWindow;
2124 }
2125 
2126 ////////////////////////////////////////////////////////////////////////////////
2127 /// Turn double buffer mode on.
2128 
2130 {
2131  if (gTws->fDoubleBuffer || gTws->fIsPixmap) return;
2132  if (!gTws->fBuffer) {
2133  gTws->fBuffer = XCreatePixmap((Display*)fDisplay, fRootWin,
2134  gTws->fWidth, gTws->fHeight, fDepth);
2135  SetColor(gGCpxmp, 0);
2136  XFillRectangle((Display*)fDisplay, gTws->fBuffer, *gGCpxmp, 0, 0, gTws->fWidth, gTws->fHeight);
2137  SetColor(gGCpxmp, 1);
2138  }
2139  for (int i = 0; i < kMAXGC; i++) XSetClipMask((Display*)fDisplay, gGClist[i], None);
2140  gTws->fDoubleBuffer = 1;
2141  gTws->fDrawing = gTws->fBuffer;
2142 }
2143 
2144 ////////////////////////////////////////////////////////////////////////////////
2145 /// Set the drawing mode.
2146 ///
2147 /// \param [in] mode : drawing mode
2148 /// - mode=1 copy
2149 /// - mode=2 xor
2150 /// - mode=3 invert
2151 /// - mode=4 set the suitable mode for cursor echo according to
2152 /// the vendor
2153 
2155 {
2156  int i;
2157  if (fDisplay) {
2158  switch (mode) {
2159  case kCopy:
2160  for (i = 0; i < kMAXGC; i++) XSetFunction((Display*)fDisplay, gGClist[i], GXcopy);
2161  break;
2162 
2163  case kXor:
2164  for (i = 0; i < kMAXGC; i++) XSetFunction((Display*)fDisplay, gGClist[i], GXxor);
2165  break;
2166 
2167  case kInvert:
2168  for (i = 0; i < kMAXGC; i++) XSetFunction((Display*)fDisplay, gGClist[i], GXinvert);
2169  break;
2170  }
2171  }
2172  fDrawMode = mode;
2173 }
2174 
2175 ////////////////////////////////////////////////////////////////////////////////
2176 /// Set color index for fill areas.
2177 
2179 {
2180  if (!gStyle->GetFillColor() && cindex > 1) cindex = 0;
2181  if (cindex >= 0) SetColor(gGCfill, Int_t(cindex));
2182  fFillColor = cindex;
2183 
2184  // invalidate fill pattern
2185  if (gFillPattern != 0) {
2186  XFreePixmap((Display*)fDisplay, gFillPattern);
2187  gFillPattern = 0;
2188  }
2189 }
2190 
2191 ////////////////////////////////////////////////////////////////////////////////
2192 /// Set fill area style.
2193 ///
2194 /// \param [in] fstyle : compound fill area interior style
2195 /// - fstyle = 1000*interiorstyle + styleindex
2196 
2198 {
2199  if (fFillStyle == fstyle) return;
2200  fFillStyle = fstyle;
2201  Int_t style = fstyle/1000;
2202  Int_t fasi = fstyle%1000;
2203  SetFillStyleIndex(style,fasi);
2204 }
2205 
2206 ////////////////////////////////////////////////////////////////////////////////
2207 /// Set fill area style index.
2208 
2210 {
2211  static int current_fasi = 0;
2212 
2213  fFillStyle = 1000*style + fasi;
2214 
2215  switch (style) {
2216 
2217  case 1: // solid
2218  gFillHollow = 0;
2219  XSetFillStyle((Display*)fDisplay, *gGCfill, FillSolid);
2220  break;
2221 
2222  case 2: // pattern
2223  gFillHollow = 1;
2224  break;
2225 
2226  case 3: // hatch
2227  gFillHollow = 0;
2228  XSetFillStyle((Display*)fDisplay, *gGCfill, FillStippled);
2229  if (fasi != current_fasi) {
2230  if (gFillPattern != 0) {
2231  XFreePixmap((Display*)fDisplay, gFillPattern);
2232  gFillPattern = 0;
2233  }
2234  int stn = (fasi >= 1 && fasi <=25) ? fasi : 2;
2235 
2236  gFillPattern = XCreateBitmapFromData((Display*)fDisplay, fRootWin,
2237  (const char*)gStipples[stn], 16, 16);
2238 
2239  XSetStipple( (Display*)fDisplay, *gGCfill, gFillPattern );
2240  current_fasi = fasi;
2241  }
2242  break;
2243 
2244  default:
2245  gFillHollow = 1;
2246  }
2247 }
2248 
2249 ////////////////////////////////////////////////////////////////////////////////
2250 /// Set input on or off.
2251 
2252 void TGX11::SetInput(int inp)
2253 {
2254  XSetWindowAttributes attributes;
2255  ULong_t attr_mask;
2256 
2257  if (inp == 1) {
2258  attributes.event_mask = gMouseMask | gKeybdMask;
2259  attr_mask = CWEventMask;
2260  XChangeWindowAttributes((Display*)fDisplay, gCws->fWindow, attr_mask, &attributes);
2261  } else {
2262  attributes.event_mask = NoEventMask;
2263  attr_mask = CWEventMask;
2264  XChangeWindowAttributes((Display*)fDisplay, gCws->fWindow, attr_mask, &attributes);
2265  }
2266 }
2267 
2268 ////////////////////////////////////////////////////////////////////////////////
2269 /// Set color index for lines.
2270 
2272 {
2273  if (cindex < 0) return;
2274 
2275  TAttLine::SetLineColor(cindex);
2276 
2277  SetColor(gGCline, Int_t(cindex));
2278  SetColor(gGCdash, Int_t(cindex));
2279 }
2280 
2281 ////////////////////////////////////////////////////////////////////////////////
2282 /// Set line type.
2283 ///
2284 /// \param [in] n : length of dash list
2285 /// \param [in] dash(n) : dash segment lengths
2286 ///
2287 /// - if n <= 0 use solid lines
2288 /// - if n > 0 use dashed lines described by DASH(N)
2289 /// e.g. N=4,DASH=(6,3,1,3) gives a dashed-dotted line with dash length 6
2290 /// and a gap of 7 between dashes
2291 
2292 void TGX11::SetLineType(int n, int *dash)
2293 {
2294  if (n <= 0) {
2295  gLineStyle = LineSolid;
2296  XSetLineAttributes((Display*)fDisplay, *gGCline, gLineWidth,
2298  } else {
2299  gDashSize = TMath::Min((int)sizeof(gDashList),n);
2300  gDashLength = 0;
2301  for (int i = 0; i < gDashSize; i++ ) {
2302  gDashList[i] = dash[i];
2303  gDashLength += gDashList[i];
2304  }
2305  gDashOffset = 0;
2306  gLineStyle = LineOnOffDash;
2307  XSetLineAttributes((Display*)fDisplay, *gGCline, gLineWidth,
2309  XSetLineAttributes((Display*)fDisplay, *gGCdash, gLineWidth,
2311  }
2312 }
2313 
2314 ////////////////////////////////////////////////////////////////////////////////
2315 /// Set line style.
2316 
2318 {
2319  static Int_t dashed[2] = {3,3};
2320  static Int_t dotted[2] = {1,2};
2321  static Int_t dasheddotted[4] = {3,4,1,4};
2322 
2323  if (fLineStyle != lstyle) { //set style index only if different
2324  fLineStyle = lstyle;
2325  if (lstyle <= 1 ) {
2326  SetLineType(0,0);
2327  } else if (lstyle == 2 ) {
2328  SetLineType(2,dashed);
2329  } else if (lstyle == 3 ) {
2330  SetLineType(2,dotted);
2331  } else if (lstyle == 4 ) {
2332  SetLineType(4,dasheddotted);
2333  } else {
2334  TString st = (TString)gStyle->GetLineStyleString(lstyle);
2335  TObjArray *tokens = st.Tokenize(" ");
2336  Int_t nt;
2337  nt = tokens->GetEntries();
2338  Int_t *linestyle = new Int_t[nt];
2339  for (Int_t j = 0; j<nt; j++) {
2340  Int_t it;
2341  sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
2342  linestyle[j] = (Int_t)(it/4);
2343  }
2344  SetLineType(nt,linestyle);
2345  delete [] linestyle;
2346  delete tokens;
2347  }
2348  }
2349 }
2350 
2351 ////////////////////////////////////////////////////////////////////////////////
2352 /// Set line width.
2353 ///
2354 /// \param [in] width : line width in pixels
2355 
2357 {
2358  if (fLineWidth == width) return;
2359  fLineWidth = width;
2360 
2361  if (width == 1) gLineWidth = 0;
2362  else gLineWidth = width;
2363 
2364  if (gLineWidth < 0) return;
2365 
2366  XSetLineAttributes((Display*)fDisplay, *gGCline, gLineWidth,
2368  XSetLineAttributes((Display*)fDisplay, *gGCdash, gLineWidth,
2370 }
2371 
2372 ////////////////////////////////////////////////////////////////////////////////
2373 /// Set color index for markers.
2374 
2376 {
2377  if (cindex < 0) return;
2378 
2380 
2381  SetColor(gGCmark, Int_t(cindex));
2382 }
2383 
2384 ////////////////////////////////////////////////////////////////////////////////
2385 /// Set marker size index.
2386 ///
2387 /// \param [in] msize : marker scale factor
2388 
2390 {
2391  if (msize == fMarkerSize) return;
2392 
2393  fMarkerSize = msize;
2394  if (msize < 0) return;
2395 
2397 }
2398 
2399 ////////////////////////////////////////////////////////////////////////////////
2400 /// Set marker type.
2401 ///
2402 /// \param [in] type : marker type
2403 /// \param [in] n : length of marker description
2404 /// \param [in] xy : list of points describing marker shape
2405 ///
2406 /// - if n == 0 marker is a single point
2407 /// - if TYPE == 0 marker is hollow circle of diameter N
2408 /// - if TYPE == 1 marker is filled circle of diameter N
2409 /// - if TYPE == 2 marker is a hollow polygon describe by line XY
2410 /// - if TYPE == 3 marker is a filled polygon describe by line XY
2411 /// - if TYPE == 4 marker is described by segmented line XY
2412 /// e.g. TYPE=4,N=4,XY=(-3,0,3,0,0,-3,0,3) sets a plus shape of 7x7 pixels
2413 
2414 void TGX11::SetMarkerType(int type, int n, RXPoint *xy)
2415 {
2416  gMarker.type = type;
2417  gMarker.n = n < kMAXMK ? n : kMAXMK;
2418  if (gMarker.type >= 2) {
2419  for (int i = 0; i < gMarker.n; i++) {
2420  gMarker.xy[i].x = xy[i].x;
2421  gMarker.xy[i].y = xy[i].y;
2422  }
2423  }
2424 }
2425 
2426 ////////////////////////////////////////////////////////////////////////////////
2427 /// Set marker style.
2428 
2430 {
2431  if (fMarkerStyle == markerstyle) return;
2432  static RXPoint shape[15];
2433  if (markerstyle >= 35) return;
2434  markerstyle = TMath::Abs(markerstyle);
2435  fMarkerStyle = markerstyle;
2436  Int_t im = Int_t(4*fMarkerSize + 0.5);
2437  if (markerstyle == 2) {
2438  // + shaped marker
2439  shape[0].x = -im; shape[0].y = 0;
2440  shape[1].x = im; shape[1].y = 0;
2441  shape[2].x = 0 ; shape[2].y = -im;
2442  shape[3].x = 0 ; shape[3].y = im;
2443  SetMarkerType(4,4,shape);
2444  } else if (markerstyle == 3 || markerstyle == 31) {
2445  // * shaped marker
2446  shape[0].x = -im; shape[0].y = 0;
2447  shape[1].x = im; shape[1].y = 0;
2448  shape[2].x = 0 ; shape[2].y = -im;
2449  shape[3].x = 0 ; shape[3].y = im;
2450  im = Int_t(0.707*Float_t(im) + 0.5);
2451  shape[4].x = -im; shape[4].y = -im;
2452  shape[5].x = im; shape[5].y = im;
2453  shape[6].x = -im; shape[6].y = im;
2454  shape[7].x = im; shape[7].y = -im;
2455  SetMarkerType(4,8,shape);
2456  } else if (markerstyle == 4 || markerstyle == 24) {
2457  // O shaped marker
2458  SetMarkerType(0,im*2,shape);
2459  } else if (markerstyle == 5) {
2460  // X shaped marker
2461  im = Int_t(0.707*Float_t(im) + 0.5);
2462  shape[0].x = -im; shape[0].y = -im;
2463  shape[1].x = im; shape[1].y = im;
2464  shape[2].x = -im; shape[2].y = im;
2465  shape[3].x = im; shape[3].y = -im;
2466  SetMarkerType(4,4,shape);
2467  } else if (markerstyle == 6) {
2468  // + shaped marker (with 1 pixel)
2469  shape[0].x = -1 ; shape[0].y = 0;
2470  shape[1].x = 1 ; shape[1].y = 0;
2471  shape[2].x = 0 ; shape[2].y = -1;
2472  shape[3].x = 0 ; shape[3].y = 1;
2473  SetMarkerType(4,4,shape);
2474  } else if (markerstyle == 7) {
2475  // . shaped marker (with 9 pixel)
2476  shape[0].x = -1 ; shape[0].y = 1;
2477  shape[1].x = 1 ; shape[1].y = 1;
2478  shape[2].x = -1 ; shape[2].y = 0;
2479  shape[3].x = 1 ; shape[3].y = 0;
2480  shape[4].x = -1 ; shape[4].y = -1;
2481  shape[5].x = 1 ; shape[5].y = -1;
2482  SetMarkerType(4,6,shape);
2483  } else if (markerstyle == 8 || markerstyle == 20) {
2484  // O shaped marker (filled)
2485  SetMarkerType(1,im*2,shape);
2486  } else if (markerstyle == 21) {
2487  // full square
2488  shape[0].x = -im; shape[0].y = -im;
2489  shape[1].x = im; shape[1].y = -im;
2490  shape[2].x = im; shape[2].y = im;
2491  shape[3].x = -im; shape[3].y = im;
2492  shape[4].x = -im; shape[4].y = -im;
2493  SetMarkerType(3,5,shape);
2494  } else if (markerstyle == 22) {
2495  // full triangle up
2496  shape[0].x = -im; shape[0].y = im;
2497  shape[1].x = im; shape[1].y = im;
2498  shape[2].x = 0; shape[2].y = -im;
2499  shape[3].x = -im; shape[3].y = im;
2500  SetMarkerType(3,4,shape);
2501  } else if (markerstyle == 23) {
2502  // full triangle down
2503  shape[0].x = 0; shape[0].y = im;
2504  shape[1].x = im; shape[1].y = -im;
2505  shape[2].x = -im; shape[2].y = -im;
2506  shape[3].x = 0; shape[3].y = im;
2507  SetMarkerType(3,4,shape);
2508  } else if (markerstyle == 25) {
2509  // open square
2510  shape[0].x = -im; shape[0].y = -im;
2511  shape[1].x = im; shape[1].y = -im;
2512  shape[2].x = im; shape[2].y = im;
2513  shape[3].x = -im; shape[3].y = im;
2514  shape[4].x = -im; shape[4].y = -im;
2515  SetMarkerType(2,5,shape);
2516  } else if (markerstyle == 26) {
2517  // open triangle up
2518  shape[0].x = -im; shape[0].y = im;
2519  shape[1].x = im; shape[1].y = im;
2520  shape[2].x = 0; shape[2].y = -im;
2521  shape[3].x = -im; shape[3].y = im;
2522  SetMarkerType(2,4,shape);
2523  } else if (markerstyle == 27) {
2524  // open losange
2525  Int_t imx = Int_t(2.66*fMarkerSize + 0.5);
2526  shape[0].x =-imx; shape[0].y = 0;
2527  shape[1].x = 0; shape[1].y = -im;
2528  shape[2].x = imx; shape[2].y = 0;
2529  shape[3].x = 0; shape[3].y = im;
2530  shape[4].x =-imx; shape[4].y = 0;
2531  SetMarkerType(2,5,shape);
2532  } else if (markerstyle == 28) {
2533  // open cross
2534  Int_t imx = Int_t(1.33*fMarkerSize + 0.5);
2535  shape[0].x = -im; shape[0].y =-imx;
2536  shape[1].x =-imx; shape[1].y =-imx;
2537  shape[2].x =-imx; shape[2].y = -im;
2538  shape[3].x = imx; shape[3].y = -im;
2539  shape[4].x = imx; shape[4].y =-imx;
2540  shape[5].x = im; shape[5].y =-imx;
2541  shape[6].x = im; shape[6].y = imx;
2542  shape[7].x = imx; shape[7].y = imx;
2543  shape[8].x = imx; shape[8].y = im;
2544  shape[9].x =-imx; shape[9].y = im;
2545  shape[10].x=-imx; shape[10].y= imx;
2546  shape[11].x= -im; shape[11].y= imx;
2547  shape[12].x= -im; shape[12].y=-imx;
2548  SetMarkerType(2,13,shape);
2549  } else if (markerstyle == 29) {
2550  // full star pentagone
2551  Int_t im1 = Int_t(0.66*fMarkerSize + 0.5);
2552  Int_t im2 = Int_t(2.00*fMarkerSize + 0.5);
2553  Int_t im3 = Int_t(2.66*fMarkerSize + 0.5);
2554  Int_t im4 = Int_t(1.33*fMarkerSize + 0.5);
2555  shape[0].x = -im; shape[0].y = im4;
2556  shape[1].x =-im2; shape[1].y =-im1;
2557  shape[2].x =-im3; shape[2].y = -im;
2558  shape[3].x = 0; shape[3].y =-im2;
2559  shape[4].x = im3; shape[4].y = -im;
2560  shape[5].x = im2; shape[5].y =-im1;
2561  shape[6].x = im; shape[6].y = im4;
2562  shape[7].x = im4; shape[7].y = im4;
2563  shape[8].x = 0; shape[8].y = im;
2564  shape[9].x =-im4; shape[9].y = im4;
2565  shape[10].x= -im; shape[10].y= im4;
2566  SetMarkerType(3,11,shape);
2567  } else if (markerstyle == 30) {
2568  // open star pentagone
2569  Int_t im1 = Int_t(0.66*fMarkerSize + 0.5);
2570  Int_t im2 = Int_t(2.00*fMarkerSize + 0.5);
2571  Int_t im3 = Int_t(2.66*fMarkerSize + 0.5);
2572  Int_t im4 = Int_t(1.33*fMarkerSize + 0.5);
2573  shape[0].x = -im; shape[0].y = im4;
2574  shape[1].x =-im2; shape[1].y =-im1;
2575  shape[2].x =-im3; shape[2].y = -im;
2576  shape[3].x = 0; shape[3].y =-im2;
2577  shape[4].x = im3; shape[4].y = -im;
2578  shape[5].x = im2; shape[5].y =-im1;
2579  shape[6].x = im; shape[6].y = im4;
2580  shape[7].x = im4; shape[7].y = im4;
2581  shape[8].x = 0; shape[8].y = im;
2582  shape[9].x =-im4; shape[9].y = im4;
2583  shape[10].x= -im; shape[10].y= im4;
2584  SetMarkerType(2,11,shape);
2585  } else if (markerstyle == 32) {
2586  // open triangle down
2587  shape[0].x = 0; shape[0].y = im;
2588  shape[1].x = im; shape[1].y = -im;
2589  shape[2].x = -im; shape[2].y = -im;
2590  shape[3].x = 0; shape[3].y = im;
2591  SetMarkerType(2,4,shape);
2592  } else if (markerstyle == 33) {
2593  // full losange
2594  Int_t imx = Int_t(2.66*fMarkerSize + 0.5);
2595  shape[0].x =-imx; shape[0].y = 0;
2596  shape[1].x = 0; shape[1].y = -im;
2597  shape[2].x = imx; shape[2].y = 0;
2598  shape[3].x = 0; shape[3].y = im;
2599  shape[4].x =-imx; shape[4].y = 0;
2600  SetMarkerType(3,5,shape);
2601  } else if (markerstyle == 34) {
2602  // full cross
2603  Int_t imx = Int_t(1.33*fMarkerSize + 0.5);
2604  shape[0].x = -im; shape[0].y =-imx;
2605  shape[1].x =-imx; shape[1].y =-imx;
2606  shape[2].x =-imx; shape[2].y = -im;
2607  shape[3].x = imx; shape[3].y = -im;
2608  shape[4].x = imx; shape[4].y =-imx;
2609  shape[5].x = im; shape[5].y =-imx;
2610  shape[6].x = im; shape[6].y = imx;
2611  shape[7].x = imx; shape[7].y = imx;
2612  shape[8].x = imx; shape[8].y = im;
2613  shape[9].x =-imx; shape[9].y = im;
2614  shape[10].x=-imx; shape[10].y= imx;
2615  shape[11].x= -im; shape[11].y= imx;
2616  shape[12].x= -im; shape[12].y=-imx;
2617  SetMarkerType(3,13,shape);
2618  } else {
2619  // single dot
2620  SetMarkerType(0,0,shape);
2621  }
2622 }
2623 
2624 ////////////////////////////////////////////////////////////////////////////////
2625 /// Set opacity of a window. This image manipulation routine works
2626 /// by adding to a percent amount of neutral to each pixels RGB.
2627 /// Since it requires quite some additional color map entries is it
2628 /// only supported on displays with more than > 8 color planes (> 256
2629 /// colors).
2630 
2632 {
2633  if (fDepth <= 8) return;
2634  if (percent == 0) return;
2635  // if 100 percent then just make white
2636 
2637  ULong_t *orgcolors = 0, *tmpc = 0;
2638  Int_t maxcolors = 0, ncolors = 0, ntmpc = 0;
2639 
2640  // save previous allocated colors, delete at end when not used anymore
2641  if (gCws->fNewColors) {
2642  tmpc = gCws->fNewColors;
2643  ntmpc = gCws->fNcolors;
2644  }
2645 
2646  // get pixmap from server as image
2647  XImage *image = XGetImage((Display*)fDisplay, gCws->fDrawing, 0, 0, gCws->fWidth,
2648  gCws->fHeight, AllPlanes, ZPixmap);
2649  if (!image) return;
2650  // collect different image colors
2651  int x, y;
2652  for (y = 0; y < (int) gCws->fHeight; y++) {
2653  for (x = 0; x < (int) gCws->fWidth; x++) {
2654  ULong_t pixel = XGetPixel(image, x, y);
2655  CollectImageColors(pixel, orgcolors, ncolors, maxcolors);
2656  }
2657  }
2658  if (ncolors == 0) {
2659  XDestroyImage(image);
2660  ::operator delete(orgcolors);
2661  return;
2662  }
2663 
2664  // create opaque counter parts
2665  MakeOpaqueColors(percent, orgcolors, ncolors);
2666 
2667  if (gCws->fNewColors) {
2668  // put opaque colors in image
2669  for (y = 0; y < (int) gCws->fHeight; y++) {
2670  for (x = 0; x < (int) gCws->fWidth; x++) {
2671  ULong_t pixel = XGetPixel(image, x, y);
2672  Int_t idx = FindColor(pixel, orgcolors, ncolors);
2673  XPutPixel(image, x, y, gCws->fNewColors[idx]);
2674  }
2675  }
2676  }
2677 
2678  // put image back in pixmap on server
2679  XPutImage((Display*)fDisplay, gCws->fDrawing, *gGCpxmp, image, 0, 0, 0, 0,
2680  gCws->fWidth, gCws->fHeight);
2681  XFlush((Display*)fDisplay);
2682 
2683  // clean up
2684  if (tmpc) {
2685  if (fRedDiv == -1)
2686  XFreeColors((Display*)fDisplay, fColormap, tmpc, ntmpc, 0);
2687  delete [] tmpc;
2688  }
2689  XDestroyImage(image);
2690  ::operator delete(orgcolors);
2691 }
2692 
2693 ////////////////////////////////////////////////////////////////////////////////
2694 /// Collect in orgcolors all different original image colors.
2695 
2696 void TGX11::CollectImageColors(ULong_t pixel, ULong_t *&orgcolors, Int_t &ncolors,
2697  Int_t &maxcolors)
2698 {
2699  if (maxcolors == 0) {
2700  ncolors = 0;
2701  maxcolors = 100;
2702  orgcolors = (ULong_t*) ::operator new(maxcolors*sizeof(ULong_t));
2703  }
2704 
2705  for (int i = 0; i < ncolors; i++)
2706  if (pixel == orgcolors[i]) return;
2707 
2708  if (ncolors >= maxcolors) {
2709  orgcolors = (ULong_t*) TStorage::ReAlloc(orgcolors,
2710  maxcolors*2*sizeof(ULong_t), maxcolors*sizeof(ULong_t));
2711  maxcolors *= 2;
2712  }
2713 
2714  orgcolors[ncolors++] = pixel;
2715 }
2716 
2717 ////////////////////////////////////////////////////////////////////////////////
2718 /// Get RGB values for orgcolors, add percent neutral to the RGB and
2719 /// allocate fNewColors.
2720 
2721 void TGX11::MakeOpaqueColors(Int_t percent, ULong_t *orgcolors, Int_t ncolors)
2722 {
2723  if (ncolors == 0) return;
2724 
2725  RXColor *xcol = new RXColor[ncolors];
2726 
2727  int i;
2728  for (i = 0; i < ncolors; i++) {
2729  xcol[i].pixel = orgcolors[i];
2730  xcol[i].red = xcol[i].green = xcol[i].blue = 0;
2731  xcol[i].flags = DoRed | DoGreen | DoBlue;
2732  }
2733  QueryColors(fColormap, xcol, ncolors);
2734 
2735  UShort_t add = percent * kBIGGEST_RGB_VALUE / 100;
2736 
2737  Int_t val;
2738  for (i = 0; i < ncolors; i++) {
2739  val = xcol[i].red + add;
2740  if (val > kBIGGEST_RGB_VALUE) val = kBIGGEST_RGB_VALUE;
2741  xcol[i].red = (UShort_t) val;
2742  val = xcol[i].green + add;
2743  if (val > kBIGGEST_RGB_VALUE) val = kBIGGEST_RGB_VALUE;
2744  xcol[i].green = (UShort_t) val;
2745  val = xcol[i].blue + add;
2746  if (val > kBIGGEST_RGB_VALUE) val = kBIGGEST_RGB_VALUE;
2747  xcol[i].blue = (UShort_t) val;
2748  if (!AllocColor(fColormap, &xcol[i]))
2749  Warning("MakeOpaqueColors", "failed to allocate color %hd, %hd, %hd",
2750  xcol[i].red, xcol[i].green, xcol[i].blue);
2751  // assumes that in case of failure xcol[i].pixel is not changed
2752  }
2753 
2754  gCws->fNewColors = new ULong_t[ncolors];
2755  gCws->fNcolors = ncolors;
2756 
2757  for (i = 0; i < ncolors; i++)
2758  gCws->fNewColors[i] = xcol[i].pixel;
2759 
2760  delete [] xcol;
2761 }
2762 
2763 ////////////////////////////////////////////////////////////////////////////////
2764 /// Returns index in orgcolors (and fNewColors) for pixel.
2765 
2766 Int_t TGX11::FindColor(ULong_t pixel, ULong_t *orgcolors, Int_t ncolors)
2767 {
2768  for (int i = 0; i < ncolors; i++)
2769  if (pixel == orgcolors[i]) return i;
2770 
2771  Error("FindColor", "did not find color, should never happen!");
2772 
2773  return 0;
2774 }
2775 
2776 ////////////////////////////////////////////////////////////////////////////////
2777 /// Set color intensities for given color index.
2778 ///
2779 /// \param [in] cindex : color index
2780 /// \param [in] r,g,b : red, green, blue intensities between 0.0 and 1.0
2781 
2782 void TGX11::SetRGB(int cindex, float r, float g, float b)
2783 {
2784  if (fColormap) {
2785  RXColor xcol;
2786  xcol.red = (UShort_t)(r * kBIGGEST_RGB_VALUE);
2787  xcol.green = (UShort_t)(g * kBIGGEST_RGB_VALUE);
2788  xcol.blue = (UShort_t)(b * kBIGGEST_RGB_VALUE);
2789  xcol.flags = DoRed | DoGreen | DoBlue;
2790  XColor_t &col = GetColor(cindex);
2791  if (col.fDefined) {
2792  // if color is already defined with same rgb just return
2793  if (col.fRed == xcol.red && col.fGreen == xcol.green &&
2794  col.fBlue == xcol.blue)
2795  return;
2796  col.fDefined = kFALSE;
2797  if (fRedDiv == -1)
2798  XFreeColors((Display*)fDisplay, fColormap, &col.fPixel, 1, 0);
2799  }
2800  if (AllocColor(fColormap, &xcol)) {
2801  col.fDefined = kTRUE;
2802  col.fPixel = xcol.pixel;
2803  col.fRed = xcol.red;
2804  col.fGreen = xcol.green;
2805  col.fBlue = xcol.blue;
2806  }
2807  }
2808 }
2809 
2810 ////////////////////////////////////////////////////////////////////////////////
2811 /// Set text alignment.
2812 ///
2813 /// \param [in] talign text alignment
2814 
2816 {
2817  Int_t txalh = talign/10;
2818  Int_t txalv = talign%10;
2819  fTextAlignH = txalh;
2820  fTextAlignV = txalv;
2821 
2822  switch (txalh) {
2823 
2824  case 0 :
2825  case 1 :
2826  switch (txalv) { //left
2827  case 1 :
2828  fTextAlign = 7; //bottom
2829  break;
2830  case 2 :
2831  fTextAlign = 4; //center
2832  break;
2833  case 3 :
2834  fTextAlign = 1; //top
2835  break;
2836  }
2837  break;
2838  case 2 :
2839  switch (txalv) { //center
2840  case 1 :
2841  fTextAlign = 8; //bottom
2842  break;
2843  case 2 :
2844  fTextAlign = 5; //center
2845  break;
2846  case 3 :
2847  fTextAlign = 2; //top
2848  break;
2849  }
2850  break;
2851  case 3 :
2852  switch (txalv) { //right
2853  case 1 :
2854  fTextAlign = 9; //bottom
2855  break;
2856  case 2 :
2857  fTextAlign = 6; //center
2858  break;
2859  case 3 :
2860  fTextAlign = 3; //top
2861  break;
2862  }
2863  break;
2864  }
2865 
2867 }
2868 
2869 ////////////////////////////////////////////////////////////////////////////////
2870 /// Set color index for text.
2871 
2873 {
2874  if (cindex < 0) return;
2875 
2876  TAttText::SetTextColor(cindex);
2877 
2878  SetColor(gGCtext, Int_t(cindex));
2879 
2880  XGCValues values;
2881  if (XGetGCValues((Display*)fDisplay, *gGCtext, GCForeground | GCBackground, &values)) {
2882  XSetForeground( (Display*)fDisplay, *gGCinvt, values.background );
2883  XSetBackground( (Display*)fDisplay, *gGCinvt, values.foreground );
2884  } else {
2885  Error("SetTextColor", "cannot get GC values");
2886  }
2887  XSetBackground((Display*)fDisplay, *gGCtext, GetColor(0).fPixel);
2888 }
2889 
2890 ////////////////////////////////////////////////////////////////////////////////
2891 /// Set text font to specified name.
2892 ///
2893 /// \param [in] fontname font name
2894 /// \param [in] mode loading flag
2895 /// - mode=0 search if the font exist (kCheck)
2896 /// - mode=1 search the font and load it if it exists (kLoad)
2897 ///
2898 /// Set text font to specified name. This function returns 0 if
2899 /// the specified font is found, 1 if not.
2900 
2902 {
2903  char **fontlist;
2904  int fontcount;
2905  int i;
2906 
2907  if (mode == kLoad) {
2908  for (i = 0; i < kMAXFONT; i++) {
2909  if (strcmp(fontname, gFont[i].name) == 0) {
2910  gTextFont = gFont[i].id;
2911  XSetFont((Display*)fDisplay, *gGCtext, gTextFont->fid);
2912  XSetFont((Display*)fDisplay, *gGCinvt, gTextFont->fid);
2913  return 0;
2914  }
2915  }
2916  }
2917 
2918  fontlist = XListFonts((Display*)fDisplay, fontname, 1, &fontcount);
2919 
2920  if (fontlist && fontcount != 0) {
2921  if (mode == kLoad) {
2922  if (gFont[gCurrentFontNumber].id)
2923  XFreeFont((Display*)fDisplay, gFont[gCurrentFontNumber].id);
2924  gTextFont = XLoadQueryFont((Display*)fDisplay, fontlist[0]);
2925  XSetFont((Display*)fDisplay, *gGCtext, gTextFont->fid);
2926  XSetFont((Display*)fDisplay, *gGCinvt, gTextFont->fid);
2928  strlcpy(gFont[gCurrentFontNumber].name,fontname,80);
2931  }
2932  XFreeFontNames(fontlist);
2933  return 0;
2934  } else {
2935  return 1;
2936  }
2937 }
2938 
2939 ////////////////////////////////////////////////////////////////////////////////
2940 /// Set current text font number.
2941 
2942 void TGX11::SetTextFont(Font_t fontnumber)
2943 {
2944  fTextFont = fontnumber;
2945 }
2946 
2947 ////////////////////////////////////////////////////////////////////////////////
2948 /// Set current text size.
2949 
2951 {
2952  fTextSize = textsize;
2953 }
2954 
2955 ////////////////////////////////////////////////////////////////////////////////
2956 /// Set synchronisation on or off.
2957 ///
2958 /// \param [in] mode : synchronisation on/off
2959 /// - mode=1 on
2960 /// - mode<>0 off
2961 
2962 void TGX11::Sync(int mode)
2963 {
2964  switch (mode) {
2965 
2966  case 1 :
2967  XSynchronize((Display*)fDisplay,1);
2968  break;
2969 
2970  default:
2971  XSynchronize((Display*)fDisplay,0);
2972  break;
2973  }
2974 }
2975 
2976 ////////////////////////////////////////////////////////////////////////////////
2977 /// Update display.
2978 ///
2979 /// \param [in] mode : (1) update (0) sync
2980 ///
2981 /// Synchronise client and server once (not permanent).
2982 /// Copy the pixmap gCws->fDrawing on the window gCws->fWindow
2983 /// if the double buffer is on.
2984 
2985 void TGX11::UpdateWindow(int mode)
2986 {
2987  if (gCws->fDoubleBuffer) {
2988  XCopyArea((Display*)fDisplay, gCws->fDrawing, gCws->fWindow,
2989  *gGCpxmp, 0, 0, gCws->fWidth, gCws->fHeight, 0, 0);
2990  }
2991  if (mode == 1) {
2992  XFlush((Display*)fDisplay);
2993  } else {
2994  XSync((Display*)fDisplay, False);
2995  }
2996 }
2997 
2998 ////////////////////////////////////////////////////////////////////////////////
2999 /// Set pointer position.
3000 ///
3001 /// \param [in] ix New X coordinate of pointer
3002 /// \param [in] iy New Y coordinate of pointer
3003 /// \param [in] id Window identifier
3004 ///
3005 /// Coordinates are relative to the origin of the window id
3006 /// or to the origin of the current window if id == 0.
3007 
3009 {
3010  if (!id) {
3011  // Causes problems when calling ProcessEvents()... BadWindow
3012  //XWarpPointer((Display*)fDisplay, None, gCws->fWindow, 0, 0, 0, 0, ix, iy);
3013  } else {
3014  XWarpPointer((Display*)fDisplay, None, (Window) id, 0, 0, 0, 0, ix, iy);
3015  }
3016 }
3017 
3018 ////////////////////////////////////////////////////////////////////////////////
3019 /// Write the pixmap wid in the bitmap file pxname.
3020 ///
3021 /// \param [in] wid : Pixmap address
3022 /// \param [in] w,h : Width and height of the pixmap.
3023 /// \param [in] pxname : pixmap name
3024 
3025 void TGX11::WritePixmap(int wid, unsigned int w, unsigned int h, char *pxname)
3026 {
3027  unsigned int wval, hval;
3028  wval = w;
3029  hval = h;
3030 
3031  gTws = &fWindows[wid];
3032  XWriteBitmapFile((Display*)fDisplay, pxname, gTws->fDrawing, wval, hval, -1, -1);
3033 }
3034 
3035 
3036 //
3037 // Functions for GIFencode()
3038 //
3039 
3040 static FILE *gOut; // output unit used WriteGIF and PutByte
3041 static XImage *gXimage = 0; // image used in WriteGIF and GetPixel
3042 
3043 extern "C" {
3044  int GIFquantize(UInt_t width, UInt_t height, Int_t *ncol, Byte_t *red, Byte_t *green,
3045  Byte_t *blue, Byte_t *outputBuf, Byte_t *outputCmap);
3046  long GIFencode(int Width, int Height, Int_t Ncol, Byte_t R[], Byte_t G[], Byte_t B[], Byte_t ScLine[],
3047  void (*get_scline) (int, int, Byte_t *), void (*pb)(Byte_t));
3048  int GIFdecode(Byte_t *gifArr, Byte_t *pixArr, int *Width, int *Height, int *Ncols, Byte_t *R, Byte_t *G, Byte_t *B);
3049  int GIFinfo(Byte_t *gifArr, int *Width, int *Height, int *Ncols);
3050 }
3051 
3052 ////////////////////////////////////////////////////////////////////////////////
3053 /// Get pixels in line y and put in array scline.
3054 
3055 static void GetPixel(int y, int width, Byte_t *scline)
3056 {
3057  for (int i = 0; i < width; i++)
3058  scline[i] = Byte_t(XGetPixel(gXimage, i, y));
3059 }
3060 
3061 ////////////////////////////////////////////////////////////////////////////////
3062 /// Put byte b in output stream.
3063 
3064 static void PutByte(Byte_t b)
3065 {
3066  if (ferror(gOut) == 0) fputc(b, gOut);
3067 }
3068 
3069 ////////////////////////////////////////////////////////////////////////////////
3070 /// Returns in R G B the ncol colors of the palette used by the image.
3071 /// The image pixels are changed to index values in these R G B arrays.
3072 /// This produces a colormap with only the used colors (so even on displays
3073 /// with more than 8 planes we will be able to create GIF's when the image
3074 /// contains no more than 256 different colors). If it does contain more
3075 /// colors we will have to use GIFquantize to reduce the number of colors.
3076 /// The R G B arrays must be deleted by the caller.
3077 
3078 void TGX11::ImgPickPalette(RXImage *image, Int_t &ncol, Int_t *&R, Int_t *&G, Int_t *&B)
3079 {
3080  ULong_t *orgcolors = 0;
3081  Int_t maxcolors = 0, ncolors = 0;
3082 
3083  // collect different image colors
3084  int x, y;
3085  for (x = 0; x < (int) gCws->fWidth; x++) {
3086  for (y = 0; y < (int) gCws->fHeight; y++) {
3087  ULong_t pixel = XGetPixel(image, x, y);
3088  CollectImageColors(pixel, orgcolors, ncolors, maxcolors);
3089  }
3090  }
3091 
3092  // get RGB values belonging to pixels
3093  RXColor *xcol = new RXColor[ncolors];
3094 
3095  int i;
3096  for (i = 0; i < ncolors; i++) {
3097  xcol[i].pixel = orgcolors[i];
3098  xcol[i].red = xcol[i].green = xcol[i].blue = 0;
3099  xcol[i].flags = DoRed | DoGreen | DoBlue;
3100  }
3101  QueryColors(fColormap, xcol, ncolors);
3102 
3103  // create RGB arrays and store RGB's for each color and set number of colors
3104  // (space must be delete by caller)
3105  R = new Int_t[ncolors];
3106  G = new Int_t[ncolors];
3107  B = new Int_t[ncolors];
3108 
3109  for (i = 0; i < ncolors; i++) {
3110  R[i] = xcol[i].red;
3111  G[i] = xcol[i].green;
3112  B[i] = xcol[i].blue;
3113  }
3114  ncol = ncolors;
3115 
3116  // update image with indices (pixels) into the new RGB colormap
3117  for (x = 0; x < (int) gCws->fWidth; x++) {
3118  for (y = 0; y < (int) gCws->fHeight; y++) {
3119  ULong_t pixel = XGetPixel(image, x, y);
3120  Int_t idx = FindColor(pixel, orgcolors, ncolors);
3121  XPutPixel(image, x, y, idx);
3122  }
3123  }
3124 
3125  // cleanup
3126  delete [] xcol;
3127  ::operator delete(orgcolors);
3128 }
3129 
3130 ////////////////////////////////////////////////////////////////////////////////
3131 /// Writes the current window into GIF file. Returns 1 in case of success,
3132 /// 0 otherwise.
3133 
3135 {
3136  Byte_t scline[2000], r[256], b[256], g[256];
3137  Int_t *red, *green, *blue;
3138  Int_t ncol, maxcol, i;
3139 
3140  if (gXimage) {
3141  XDestroyImage(gXimage);
3142  gXimage = 0;
3143  }
3144 
3145  gXimage = XGetImage((Display*)fDisplay, gCws->fDrawing, 0, 0,
3146  gCws->fWidth, gCws->fHeight,
3147  AllPlanes, ZPixmap);
3148 
3149  ImgPickPalette((RXImage*)gXimage, ncol, red, green, blue);
3150 
3151  if (ncol > 256) {
3152  //GIFquantize(...);
3153  Error("WriteGIF", "can not create GIF of image containing more than 256 colors");
3154  delete [] red;
3155  delete [] green;
3156  delete [] blue;
3157  return 0;
3158  }
3159 
3160  maxcol = 0;
3161  for (i = 0; i < ncol; i++) {
3162  if (maxcol < red[i] ) maxcol = red[i];
3163  if (maxcol < green[i] ) maxcol = green[i];
3164  if (maxcol < blue[i] ) maxcol = blue[i];
3165  r[i] = 0;
3166  g[i] = 0;
3167  b[i] = 0;
3168  }
3169  if (maxcol != 0) {
3170  for (i = 0; i < ncol; i++) {
3171  r[i] = red[i] * 255/maxcol;
3172  g[i] = green[i] * 255/maxcol;
3173  b[i] = blue[i] * 255/maxcol;
3174  }
3175  }
3176 
3177  gOut = fopen(name, "w+");
3178 
3179  if (gOut) {
3180  GIFencode(gCws->fWidth, gCws->fHeight,
3181  ncol, r, g, b, scline, ::GetPixel, PutByte);
3182  fclose(gOut);
3183  i = 1;
3184  } else {
3185  Error("WriteGIF","cannot write file: %s",name);
3186  i = 0;
3187  }
3188  delete [] red;
3189  delete [] green;
3190  delete [] blue;
3191  return i;
3192 }
3193 
3194 ////////////////////////////////////////////////////////////////////////////////
3195 /// Draw image.
3196 
3197 void TGX11::PutImage(int offset,int itran,int x0,int y0,int nx,int ny,int xmin,
3198  int ymin,int xmax,int ymax, unsigned char *image,Drawable_t wid)
3199 {
3200  const int maxSegment = 20;
3201  int i, n, x, y, xcur, x1, x2, y1, y2;
3202  unsigned char *jimg, *jbase, icol;
3203  int nlines[256];
3204  XSegment lines[256][maxSegment];
3205  Drawable_t id;
3206 
3207  if (wid) {
3208  id = wid;
3209  } else {
3210  id = gCws->fDrawing;
3211  }
3212 
3213  for (i = 0; i < 256; i++) nlines[i] = 0;
3214 
3215  x1 = x0 + xmin; y1 = y0 + ny - ymax - 1;
3216  x2 = x0 + xmax; y2 = y0 + ny - ymin - 1;
3217  jbase = image + (ymin-1)*nx + xmin;
3218 
3219  for (y = y2; y >= y1; y--) {
3220  xcur = x1; jbase += nx;
3221  for (jimg = jbase, icol = *jimg++, x = x1+1; x <= x2; jimg++, x++) {
3222  if (icol != *jimg) {
3223  if (icol != itran) {
3224  n = nlines[icol]++;
3225  lines[icol][n].x1 = xcur; lines[icol][n].y1 = y;
3226  lines[icol][n].x2 = x-1; lines[icol][n].y2 = y;
3227  if (nlines[icol] == maxSegment) {
3228  SetColor(gGCline,(int)icol+offset);
3229  XDrawSegments((Display*)fDisplay,id,*gGCline,&lines[icol][0],
3230  maxSegment);
3231  nlines[icol] = 0;
3232  }
3233  }
3234  icol = *jimg; xcur = x;
3235  }
3236  }
3237  if (icol != itran) {
3238  n = nlines[icol]++;
3239  lines[icol][n].x1 = xcur; lines[icol][n].y1 = y;
3240  lines[icol][n].x2 = x-1; lines[icol][n].y2 = y;
3241  if (nlines[icol] == maxSegment) {
3242  SetColor(gGCline,(int)icol+offset);
3243  XDrawSegments((Display*)fDisplay,id,*gGCline,&lines[icol][0],
3244  maxSegment);
3245  nlines[icol] = 0;
3246  }
3247  }
3248  }
3249 
3250  for (i = 0; i < 256; i++) {
3251  if (nlines[i] != 0) {
3252  SetColor(gGCline,i+offset);
3253  XDrawSegments((Display*)fDisplay,id,*gGCline,&lines[i][0],nlines[i]);
3254  }
3255  }
3256 }
3257 
3258 ////////////////////////////////////////////////////////////////////////////////
3259 /// If id is NULL - loads the specified gif file at position [x0,y0] in the
3260 /// current window. Otherwise creates pixmap from gif file
3261 
3262 Pixmap_t TGX11::ReadGIF(int x0, int y0, const char *file, Window_t id)
3263 {
3264  FILE *fd;
3265  Seek_t filesize = 0;
3266  unsigned char *gifArr, *pixArr, red[256], green[256], blue[256], *j1, *j2, icol;
3267  int i, j, k, width, height, ncolor, irep, offset;
3268  float rr, gg, bb;
3269  Pixmap_t pic = 0;
3270 
3271  fd = fopen(file, "r");
3272  if (!fd) {
3273  Error("ReadGIF", "unable to open GIF file");
3274  return pic;
3275  }
3276 
3277  fseek(fd, 0L, 2);
3278  long ft = ftell(fd);
3279  if (ft <=0) {
3280  Error("ReadGIF", "unable to open GIF file");
3281  fclose(fd);
3282  return pic;
3283  } else {
3284  filesize = Seek_t(ft);
3285  }
3286  fseek(fd, 0L, 0);
3287 
3288  if (!(gifArr = (unsigned char *) calloc(filesize+256,1))) {
3289  Error("ReadGIF", "unable to allocate array for gif");
3290  fclose(fd);
3291  return pic;
3292  }
3293 
3294  if (fread(gifArr, filesize, 1, fd) != 1) {
3295  Error("ReadGIF", "GIF file read failed");
3296  free(gifArr);
3297  fclose(fd);
3298  return pic;
3299  }
3300  fclose(fd);
3301 
3302  irep = GIFinfo(gifArr, &width, &height, &ncolor);
3303  if (irep != 0) {
3304  free(gifArr);
3305  return pic;
3306  }
3307 
3308  if (!(pixArr = (unsigned char *) calloc((width*height),1))) {
3309  Error("ReadGIF", "unable to allocate array for image");
3310  free(gifArr);
3311  return pic;
3312  }
3313 
3314  irep = GIFdecode(gifArr, pixArr, &width, &height, &ncolor, red, green, blue);
3315  if (irep != 0) {
3316  free(gifArr);
3317  free(pixArr);
3318  return pic;
3319  }
3320 
3321  // S E T P A L E T T E
3322 
3323  offset = 8;
3324 
3325  for (i = 0; i < ncolor; i++) {
3326  rr = red[i]/255.;
3327  gg = green[i]/255.;
3328  bb = blue[i]/255.;
3329  j = i+offset;
3330  SetRGB(j,rr,gg,bb);
3331  }
3332 
3333  // O U T P U T I M A G E
3334 
3335  for (i = 1; i <= height/2; i++) {
3336  j1 = pixArr + (i-1)*width;
3337  j2 = pixArr + (height-i)*width;
3338  for (k = 0; k < width; k++) {
3339  icol = *j1; *j1++ = *j2; *j2++ = icol;
3340  }
3341  }
3342  if (id) pic = CreatePixmap(id, width, height);
3343  PutImage(offset,-1,x0,y0,width,height,0,0,width-1,height-1,pixArr,pic);
3344 
3345  free(gifArr);
3346  free(pixArr);
3347 
3348  if (pic)
3349  return pic;
3350  else if (gCws->fDrawing)
3351  return (Pixmap_t)gCws->fDrawing;
3352  return 0;
3353 }
3354 
3355 ////////////////////////////////////////////////////////////////////////////////
3356 /// Returns an array of pixels created from a part of drawable (defined by x, y, w, h)
3357 /// in format:
3358 /// `b1, g1, r1, 0, b2, g2, r2, 0 ... bn, gn, rn, 0 ..`
3359 ///
3360 /// Pixels are numbered from left to right and from top to bottom.
3361 /// By default all pixels from the whole drawable are returned.
3362 ///
3363 /// Note that return array is 32-bit aligned
3364 
3365 unsigned char *TGX11::GetColorBits(Drawable_t /*wid*/, Int_t /*x*/, Int_t /*y*/,
3366  UInt_t /*w*/, UInt_t /*h*/)
3367 {
3368  return 0;
3369 }
3370 
3371 ////////////////////////////////////////////////////////////////////////////////
3372 /// create pixmap from RGB data. RGB data is in format :
3373 /// b1, g1, r1, 0, b2, g2, r2, 0 ... bn, gn, rn, 0 ..
3374 ///
3375 /// Pixels are numbered from left to right and from top to bottom.
3376 /// Note that data must be 32-bit aligned
3377 
3378 Pixmap_t TGX11::CreatePixmapFromData(unsigned char * /*bits*/, UInt_t /*width*/,
3379  UInt_t /*height*/)
3380 {
3381  return (Pixmap_t)0;
3382 }
3383 
3384 ////////////////////////////////////////////////////////////////////////////////
3385 /// Register pixmap created by gVirtualGL
3386 ///
3387 /// \param [in] pixid Pixmap identifier
3388 /// \param [in] w,h Width and height of the pixmap
3389 ///
3390 /// register new pixmap
3391 
3393 {
3394  Int_t wid = 0;
3395 
3396  // Select next free window number
3397  for (; wid < fMaxNumberOfWindows; ++wid)
3398  if (!fWindows[wid].fOpen)
3399  break;
3400 
3401  if (wid == fMaxNumberOfWindows) {
3402  Int_t newsize = fMaxNumberOfWindows + 10;
3403  fWindows = (XWindow_t*) TStorage::ReAlloc(
3404  fWindows, newsize * sizeof(XWindow_t),
3405  fMaxNumberOfWindows*sizeof(XWindow_t)
3406  );
3407 
3408  for (Int_t i = fMaxNumberOfWindows; i < newsize; ++i)
3409  fWindows[i].fOpen = 0;
3410 
3411  fMaxNumberOfWindows = newsize;
3412  }
3413 
3414  fWindows[wid].fOpen = 1;
3415  gCws = fWindows + wid;
3416  gCws->fWindow = pixid;
3417  gCws->fDrawing = gCws->fWindow;
3418  gCws->fBuffer = 0;
3419  gCws->fDoubleBuffer = 0;
3420  gCws->fIsPixmap = 1;
3421  gCws->fClip = 0;
3422  gCws->fWidth = w;
3423  gCws->fHeight = h;
3424  gCws->fNewColors = 0;
3425  gCws->fShared = kFALSE;
3426 
3427  return wid;
3428 }
3429 
3430 ////////////////////////////////////////////////////////////////////////////////
3431 /// Returns 1 if window system server supports extension given by the
3432 /// argument, returns 0 in case extension is not supported and returns -1
3433 /// in case of error (like server not initialized).
3434 /// Examples:
3435 /// - "Apple-WM" - does server run on MacOS X;
3436 /// - "XINERAMA" - does server support Xinerama.
3437 /// See also the output of xdpyinfo.
3438 
3439 Int_t TGX11::SupportsExtension(const char *ext) const
3440 {
3441  Int_t major_opcode, first_event, first_error;
3442  if (!(Display*)fDisplay)
3443  return -1;
3444  return XQueryExtension((Display*)fDisplay, ext, &major_opcode, &first_event, &first_error);
3445 }
const int nx
Definition: kalman.C:16
static void Dealloc(void *ptr)
De-allocate block of memory, that was allocated via TStorage::Alloc().
Definition: TStorage.cxx:164
void ImgPickPalette(RXImage *image, Int_t &ncol, Int_t *&R, Int_t *&G, Int_t *&B)
Returns in R G B the ncol colors of the palette used by the image.
Definition: TGX11.cxx:3078
const char * GetLineStyleString(Int_t i=1) const
Return line style string (used by PostScript).
Definition: TStyle.cxx:787
void * fDisplay
Pointer to display.
Definition: TGX11.h:130
EDrawMode fDrawMode
Definition: TVirtualX.h:79
static double B[]
void Add(ULong64_t hash, Long64_t key, Long64_t value)
Add an (key,value) pair to the table. The key should be unique.
Definition: TExMap.cxx:85
Int_t fBlueDiv
Blue value divider.
Definition: TGX11.h:147
Int_t fMaxNumberOfWindows
Maximum number of windows.
Definition: TGX11.h:88
Semi-Abstract base class defining a generic interface to the underlying, low level, native graphics backend (X11, Win32, MacOS, OpenGL...).
Definition: TVirtualX.h:70
static GC * gGCpxmp
Definition: TGX11.cxx:96
An array of TObjects.
Definition: TObjArray.h:39
void RemovePixmap(Drawable *pix)
Remove the pixmap pix.
Definition: TGX11.cxx:1467
void SetMarkerColor(Color_t cindex)
Set color index for markers.
Definition: TGX11.cxx:2375
float xmin
Definition: THbookFile.cxx:93
XID Drawable
Definition: TGX11.h:38
static void GetPixel(int y, int width, Byte_t *scline)
Get pixels in line y and put in array scline.
Definition: TGX11.cxx:3055
static GC * gGCline
Definition: TGX11.cxx:90
void ClearPixmap(Drawable *pix)
Clear the pixmap pix.
Definition: TGX11.cxx:402
void SetLineStyle(Style_t linestyle)
Set line style.
Definition: TGX11.cxx:2317
long long Long64_t
Definition: RtypesCore.h:69
short Style_t
Definition: RtypesCore.h:76
void GetPlanes(Int_t &nplanes)
Get maximum number of planes.
Definition: TGX11.cxx:1014
void PutImage(Int_t offset, Int_t itran, Int_t x0, Int_t y0, Int_t nx, Int_t ny, Int_t xmin, Int_t ymin, Int_t xmax, Int_t ymax, UChar_t *image, Drawable_t id)
Draw image.
Definition: TGX11.cxx:3197
Collectable string class.
Definition: TObjString.h:32
float Float_t
Definition: RtypesCore.h:53
static Int_t gFillHollow
Definition: TGX11.cxx:100
Pixmap_t CreatePixmapFromData(unsigned char *bits, UInt_t width, UInt_t height)
create pixmap from RGB data.
Definition: TGX11.cxx:3378
UShort_t fBlue
blue value
Definition: TGX11.h:77
RooArgList L(const RooAbsArg &v1)
void DrawLine(Int_t x1, Int_t y1, Int_t x2, Int_t y2)
Draw a line.
Definition: TGX11.cxx:603
Float_t fCharacterUpX
Character Up vector along X.
Definition: TGX11.h:141
float ymin
Definition: THbookFile.cxx:93
void SetColor(void *gc, Int_t ci)
Set the foreground color in GC.
Definition: TGX11.cxx:2038
Bool_t Init(void *display)
Initialize X11 system. Returns kFALSE in case of failure.
Definition: TGX11.cxx:337
Bool_t fHasXft
True when XftFonts are used.
Definition: TGX11.h:152
UShort_t fGreen
green value
Definition: TGX11.h:76
Int_t fScreenNumber
Screen number.
Definition: TGX11.h:137
void CopyPixmap(Int_t wid, Int_t xpos, Int_t ypos)
Copy the pixmap wid at the position xpos, ypos in the current window.
Definition: TGX11.cxx:491
XID Cursor
Definition: TGX11.h:39
R__EXTERN TStyle * gStyle
Definition: TStyle.h:423
void DrawPolyMarker(Int_t n, TPoint *xy)
Draw n markers with the current attributes at position x, y.
Definition: TGX11.cxx:671
unsigned short UShort_t
Definition: RtypesCore.h:36
void WritePixmap(Int_t wid, UInt_t w, UInt_t h, char *pxname)
Write the pixmap wid in the bitmap file pxname.
Definition: TGX11.cxx:3025
void SetLineWidth(Width_t width)
Set line width.
Definition: TGX11.cxx:2356
TH1 * h
Definition: legend2.C:5
Description of a X11 color.
Definition: TGWin32.h:72
Int_t RequestString(Int_t x, Int_t y, char *text)
Request a string.
Definition: TGX11.cxx:1678
void CloseWindow()
Delete current window.
Definition: TGX11.cxx:442
static XWindow_t * gTws
Definition: TGX11.cxx:81
virtual void GetTextExtent(UInt_t &w, UInt_t &h, char *mess)
Return the size of a character string.
Definition: TGX11.cxx:1043
void SetDrawMode(EDrawMode mode)
Set the drawing mode.
Definition: TGX11.cxx:2154
Size_t fMarkerSize
Definition: TAttMarker.h:37
#define gROOT
Definition: TROOT.h:340
void DrawCellArray(Int_t x1, Int_t y1, Int_t x2, Int_t y2, Int_t nx, Int_t ny, Int_t *ic)
Draw a cell array.
Definition: TGX11.cxx:554
Basic string class.
Definition: TString.h:137
static Cursor gNullCursor
Definition: TGX11.cxx:154
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
static FILE * gOut
Definition: TGX11.cxx:3040
const Bool_t kFALSE
Definition: Rtypes.h:92
Float_t GetGreen() const
Definition: TColor.h:61
Handle_t Drawable_t
Definition: GuiTypes.h:32
Cursor fCursors[kNumCursors]
List of cursors.
Definition: TGX11.h:91
static GC * gGCmark
Definition: TGX11.cxx:91
void DrawPolyLine(Int_t n, TPoint *xy)
Draw a line through all points.
Definition: TGX11.cxx:619
static int gJoinStyle
Definition: TGX11.cxx:131
void CollectImageColors(ULong_t pixel, ULong_t *&orgcolors, Int_t &ncolors, Int_t &maxcolors)
Collect in orgcolors all different original image colors.
Definition: TGX11.cxx:2696
Float_t fCharacterUpY
Character Up vector along Y.
Definition: TGX11.h:142
void SelectWindow(Int_t wid)
Select window to which subsequent output is directed.
Definition: TGX11.cxx:1953
ClassImp(TGX11) TGX11
Default constructor.
Definition: TGX11.cxx:163
ECursor
Definition: TVirtualX.h:56
Int_t WriteGIF(char *name)
Writes the current window into GIF file.
Definition: TGX11.cxx:3134
int GIFquantize(UInt_t width, UInt_t height, Int_t *ncol, Byte_t *red, Byte_t *green, Byte_t *blue, Byte_t *outputBuf, Byte_t *outputCmap)
short Font_t
Definition: RtypesCore.h:75
XID Colormap
Definition: TGX11.h:40
Int_t fTextAlign
Text alignment (set in SetTextAlign)
Definition: TGX11.h:140
static struct @65 gMarker
void SetCursor(Int_t win, ECursor cursor)
Set the cursor.
Definition: TGX11.cxx:2071
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
Int_t ResizePixmap(Int_t wid, UInt_t w, UInt_t h)
Resize a pixmap.
Definition: TGX11.cxx:1870
#define G(x, y, z)
static GC * gGCtext
Definition: TGX11.cxx:93
void DrawBox(Int_t x1, Int_t y1, Int_t x2, Int_t y2, EBoxMode mode)
Draw a box.
Definition: TGX11.cxx:520
void GetGeometry(Int_t wid, Int_t &x, Int_t &y, UInt_t &w, UInt_t &h)
Return position and size of window wid.
Definition: TGX11.cxx:956
Int_t fGreenDiv
Green value divider.
Definition: TGX11.h:146
virtual Int_t SetTextFont(char *fontname, ETextSetMode mode)
Set text font to specified name.
Definition: TGX11.cxx:2901
void DrawFillArea(Int_t n, TPoint *xy)
Fill area described by polygon.
Definition: TGX11.cxx:584
void SetMarkerStyle(Style_t markerstyle)
Set marker style.
Definition: TGX11.cxx:2429
static Int_t DummyX11ErrorHandler(Display *, XErrorEvent *)
Dummy error handler for X11. Used by FindUsableVisual().
Definition: TGX11.cxx:834
Int_t OpenDisplay(void *display)
Open the display. Return -1 if the opening fails, 0 when ok.
Definition: TGX11.cxx:1086
void * GetGC(Int_t which) const
Return desired Graphics Context ("which" maps directly on gGCList[]).
Definition: TGX11.cxx:926
void CloseWindow1()
Delete current window.
Definition: TGX11.cxx:456
static const double x2[5]
void SetFillStyleIndex(Int_t style, Int_t fasi)
Set fill area style index.
Definition: TGX11.cxx:2209
const char * True
Double_t x[n]
Definition: legend1.C:17
unsigned long KeySym
Definition: TGWin32.h:66
void GetRGB(Int_t index, Float_t &r, Float_t &g, Float_t &b)
Get rgb values for color "index".
Definition: TGX11.cxx:1022
Window_t GetCurrentWindow() const
Return current window pointer. Protected method used by TGX11TTF.
Definition: TGX11.cxx:917
Vc_ALWAYS_INLINE void free(T *p)
Frees memory that was allocated with Vc::malloc.
Definition: memory.h:94
Drawable fVisRootWin
Root window with fVisual to be used to create GC's and XImages.
Definition: TGX11.h:133
TExMap * fColors
Hash list of colors.
Definition: TGX11.h:90
ULong_t fWhitePixel
Value of white pixel in colormap.
Definition: TGX11.h:136
unsigned char Byte_t
Definition: RtypesCore.h:60
long GIFencode(int Width, int Height, Int_t Ncol, Byte_t R[], Byte_t G[], Byte_t B[], Byte_t ScLine[], void(*get_scline)(int, int, Byte_t *), void(*pb)(Byte_t))
const int ny
Definition: kalman.C:17
void ResizeWindow(Int_t wid)
Resize the current window if necessary.
Definition: TGX11.cxx:1914
Float_t GetBlue() const
Definition: TColor.h:62
void RemoveWindow(ULong_t qwid)
Remove a window created by Qt (like CloseWindow1()).
Definition: TGX11.cxx:1417
const Int_t kMAXMK
Definition: TGX11.cxx:118
XWindow_t * fWindows
List of windows.
Definition: TGX11.h:89
UShort_t fRed
red value in range [0,kBIGGEST_RGB_VALUE]
Definition: TGX11.h:75
void ClearWindow()
Clear current window.
Definition: TGX11.cxx:417
virtual void SetMarkerColor(Color_t mcolor=1)
Definition: TAttMarker.h:51
void SetRGB(Int_t cindex, Float_t r, Float_t g, Float_t b)
Set color intensities for given color index.
Definition: TGX11.cxx:2782
Colormap fColormap
Default colormap, 0 if b/w.
Definition: TGX11.h:134
void SetDoubleBufferOFF()
Turn double buffer mode off.
Definition: TGX11.cxx:2119
void SetMarkerSize(Float_t markersize)
Set marker size index.
Definition: TGX11.cxx:2389
static GC * gGCfill
Definition: TGX11.cxx:92
XFontStruct * id
Definition: TGX11.cxx:108
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
void Sync(Int_t mode)
Set synchronisation on or off.
Definition: TGX11.cxx:2962
void QueryColors(Colormap cmap, RXColor *colors, Int_t ncolors)
Returns the current RGB value for the pixel in the XColor structure.
Definition: TGX11.cxx:378
static GC * gGCdash
Definition: TGX11.cxx:95
ULong_t GetPixel(Color_t cindex)
Return pixel value associated to specified ROOT color number.
Definition: TGX11.cxx:999
short Color_t
Definition: RtypesCore.h:79
void SetTextColor(Color_t cindex)
Set color index for text.
Definition: TGX11.cxx:2872
int GIFdecode(Byte_t *gifArr, Byte_t *pixArr, int *Width, int *Height, int *Ncols, Byte_t *R, Byte_t *G, Byte_t *B)
Definition: gifdecode.c:149
static int gDashOffset
Definition: TGX11.cxx:134
Int_t fDepth
Number of color planes.
Definition: TGX11.h:144
virtual void SetTextAlign(Short_t align=11)
Definition: TAttText.h:55
void SetTextAlign(Short_t talign=11)
Set text alignment.
Definition: TGX11.cxx:2815
Definition: TPoint.h:33
Style_t fMarkerStyle
Definition: TAttMarker.h:36
Int_t GetDoubleBuffer(Int_t wid)
Query the double buffer value for the window wid.
Definition: TGX11.cxx:938
void Warp(Int_t ix, Int_t iy, Window_t id=0)
Set pointer position.
Definition: TGX11.cxx:3008
void UpdateWindow(Int_t mode)
Update display.
Definition: TGX11.cxx:2985
static int gLineWidth
Definition: TGX11.cxx:128
#define None
Definition: TGWin32.h:68
void * fXEvent
Current native (X11) event.
Definition: TGX11.h:92
Int_t AddPixmap(ULong_t pixid, UInt_t w, UInt_t h)
Register pixmap created by gVirtualGL.
Definition: TGX11.cxx:3392
virtual void SetLineColor(Color_t lcolor)
Definition: TAttLine.h:54
void QueryPointer(Int_t &ix, Int_t &iy)
Query pointer position.
Definition: TGX11.cxx:1449
static XWindow_t * gCws
Definition: TGX11.cxx:80
Float_t fTextAngle
Definition: TAttText.h:35
float ymax
Definition: THbookFile.cxx:93
XColor_t & GetColor(Int_t cid)
Return reference to internal color structure associated to color index cid.
Definition: TGX11.cxx:904
Int_t fTextAlignH
Text Alignment Horizontal.
Definition: TGX11.h:138
Style_t fLineStyle
Definition: TAttLine.h:36
Pixmap_t CreatePixmap(Drawable_t id, UInt_t w, UInt_t h)
Creates a pixmap of the width and height you specified and returns a pixmap ID that identifies it...
Definition: GX11Gui.cxx:1076
void SetDoubleBufferON()
Turn double buffer mode on.
Definition: TGX11.cxx:2129
Long64_t GetValue(ULong64_t hash, Long64_t key)
Return the value belonging to specified key and hash value.
Definition: TExMap.cxx:171
TPaveText * pt
virtual void DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn, const char *text, ETextMode mode)
Draw a text string using current font.
Definition: TGX11.cxx:746
ROOT::R::TRInterface & r
Definition: Object.C:4
Int_t OpenPixmap(UInt_t w, UInt_t h)
Open a new pixmap.
Definition: TGX11.cxx:1238
XPoint xy[kMAXMK]
Definition: TGX11.cxx:122
Window_t GetWindowID(Int_t wid)
Return the X11 window identifier.
Definition: TGX11.cxx:1063
ULong_t fPixel
color pixel value
Definition: TGX11.h:74
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:494
Int_t InitWindow(ULong_t window)
Open window and return window number.
Definition: TGX11.cxx:1296
Int_t fTextAlignV
Text Alignment Vertical.
Definition: TGX11.h:139
void XRotSetMagnification(float)
Set the font magnification factor for all subsequent operations.
Definition: Rotated.cxx:248
virtual Color_t GetFillColor() const
Definition: TAttFill.h:43
void SetDoubleBuffer(Int_t wid, Int_t mode)
Set the double buffer on/off on window wid.
Definition: TGX11.cxx:2086
unsigned int UInt_t
Definition: RtypesCore.h:42
unsigned char * GetColorBits(Drawable_t wid, Int_t x=0, Int_t y=0, UInt_t w=0, UInt_t h=0)
Returns an array of pixels created from a part of drawable (defined by x, y, w, h) in format: `b1...
Definition: TGX11.cxx:3365
Width_t fLineWidth
Definition: TAttLine.h:37
TMarker * m
Definition: textangle.C:8
Int_t FindColor(ULong_t pixel, ULong_t *orgcolors, Int_t ncolors)
Returns index in orgcolors (and fNewColors) for pixel.
Definition: TGX11.cxx:2766
Pixmap_t ReadGIF(Int_t x0, Int_t y0, const char *file, Window_t id=0)
If id is NULL - loads the specified gif file at position [x0,y0] in the current window.
Definition: TGX11.cxx:3262
Int_t fGreenShift
Bits to left shift green.
Definition: TGX11.h:149
void SetFillStyle(Style_t style)
Set fill area style.
Definition: TGX11.cxx:2197
Bool_t fHasTTFonts
True when TrueType fonts are used.
Definition: TGX11.h:151
void MoveWindow(Int_t wid, Int_t x, Int_t y)
Move the window wid.
Definition: TGX11.cxx:1075
short Short_t
Definition: RtypesCore.h:35
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
const char * DisplayName(const char *dpyName=0)
Return hostname on which the display is opened.
Definition: TGX11.cxx:991
static void PutByte(Byte_t b)
Put byte b in output stream.
Definition: TGX11.cxx:3064
Double_t ACos(Double_t)
Definition: TMath.h:445
float xmax
Definition: THbookFile.cxx:93
int GIFinfo(Byte_t *gifArr, int *Width, int *Height, int *Ncols)
Definition: gifdecode.c:80
void SetClipRegion(Int_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h)
Set clipping region for the window wid.
Definition: TGX11.cxx:2015
Font_t fTextFont
Definition: TAttText.h:39
const unsigned char gStipples[26][32]
Definition: RStipples.h:28
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2240
const Int_t kMAXFONT
Definition: TGX11.cxx:106
void MakeOpaqueColors(Int_t percent, ULong_t *orgcolors, Int_t ncolors)
Get RGB values for orgcolors, add percent neutral to the RGB and allocate fNewColors.
Definition: TGX11.cxx:2721
#define Printf
Definition: TGeoToOCC.h:18
short Width_t
Definition: RtypesCore.h:78
This class is the basic interface to the X11 (Xlib) graphics system.
Definition: TGX11.h:85
static void * Alloc(size_t size)
Allocate a block of memory, that later can be resized using TStorage::ReAlloc().
Definition: TStorage.cxx:146
Double_t Pi()
Definition: TMath.h:44
XID Window
Definition: TGX11.h:41
long Long_t
Definition: RtypesCore.h:50
void FindBestVisual()
Find best visual, i.e.
Definition: TGX11.cxx:775
void GetCharacterUp(Float_t &chupx, Float_t &chupy)
Return character up vector.
Definition: TGX11.cxx:894
virtual void SetTextSize(Float_t textsize)
Set current text size.
Definition: TGX11.cxx:2950
static struct @64 gFont[kMAXFONT]
void RescaleWindow(Int_t wid, UInt_t w, UInt_t h)
Rescale the window wid.
Definition: TGX11.cxx:1836
static const double x1[5]
int n
Definition: TGX11.cxx:121
int XRotDrawImageString(Display *, XFontStruct *, float, Drawable, GC, int, int, char *)
A front end to XRotPaintAlignedString: -no alignment, paints background.
Definition: Rotated.cxx:303
TText * text
const int kNumCursors
Definition: TVirtualX.h:55
static GC gGCecho
Definition: TGX11.cxx:98
int type
Definition: TGX11.cxx:120
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
void ClosePixmap()
Delete current pixmap.
Definition: TGX11.cxx:434
unsigned long ULong_t
Definition: RtypesCore.h:51
TCanvas * style()
Definition: style.C:1
Double_t y[n]
Definition: legend1.C:17
Bool_t AllocColor(Colormap cmap, RXColor *color)
Allocate color in colormap.
Definition: TGX11.cxx:361
void SetLineColor(Color_t cindex)
Set color index for lines.
Definition: TGX11.cxx:2271
static int gDashSize
Definition: TGX11.cxx:135
XPoint * XRotTextExtents(Display *, XFontStruct *, float, int, int, char *, int)
Calculate the bounding box some text will have when painted.
Definition: Rotated.cxx:1350
The color creation and management class.
Definition: TColor.h:23
Float_t GetRed() const
Definition: TColor.h:60
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:493
void FindUsableVisual(RXVisualInfo *vlist, Int_t nitems)
Check if visual is usable, if so set fVisual, fDepth, fColormap, fBlackPixel and fWhitePixel.
Definition: TGX11.cxx:843
const char null_cursor_bits[]
Definition: TGX11.cxx:150
Float_t fTextSize
Definition: TAttText.h:36
static GC gGClist[kMAXGC]
Definition: TGX11.cxx:89
Int_t fBlueShift
Bits to left shift blue.
Definition: TGX11.h:150
void SetLineType(Int_t n, Int_t *dash)
Set line type.
Definition: TGX11.cxx:2292
static Pixmap gFillPattern
Definition: TGX11.cxx:101
#define org(otri, vertexptr)
Definition: triangle.c:1037
Float_t fTextMagnitude
Text Magnitude.
Definition: TGX11.h:143
static void * ReAlloc(void *vp, size_t size)
Reallocate (i.e.
Definition: TStorage.cxx:177
static char gDashList[10]
Definition: TGX11.cxx:132
Handle_t Window_t
Definition: GuiTypes.h:30
static XImage * gXimage
Definition: TGX11.cxx:3041
Int_t RequestLocator(Int_t mode, Int_t ctyp, Int_t &x, Int_t &y)
Request Locator position.
Definition: TGX11.cxx:1500
virtual ~TGX11()
Destructor.
Definition: TGX11.cxx:319
void XRotSetBoundingBoxPad(int)
Set the padding used when calculating bounding boxes.
Definition: Rotated.cxx:257
Bool_t Next(ULong64_t &hash, Long64_t &key, Long64_t &value)
Get next entry from TExMap. Returns kFALSE at end of map.
Definition: TExMap.cxx:409
const size_t kBitsPerByte
Definition: Rtypes.h:114
RVisual * fVisual
Pointer to visual used by all windows.
Definition: TGX11.h:131
Color_t fFillColor
Definition: TAttFill.h:35
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
void SetOpacity(Int_t percent)
Set opacity of a window.
Definition: TGX11.cxx:2631
Handle_t Pixmap_t
Definition: GuiTypes.h:31
void SetMarkerType(Int_t type, Int_t n, RXPoint *xy)
Set marker type.
Definition: TGX11.cxx:2414
int Seek_t
Definition: RtypesCore.h:49
static int gLineStyle
Definition: TGX11.cxx:129
const Int_t kBIGGEST_RGB_VALUE
Definition: TGX11.cxx:83
float XRotVersion(char *, int)
Return version/copyright information.
Definition: Rotated.cxx:238
static ULong_t gKeybdMask
Definition: TGX11.cxx:144
virtual void SetTextColor(Color_t tcolor=1)
Definition: TAttText.h:57
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
void SetFillColor(Color_t cindex)
Set color index for fill areas.
Definition: TGX11.cxx:2178
Bool_t fDefined
true if pixel value is defined
Definition: TGWin32.h:74
static int gDashLength
Definition: TGX11.cxx:133
Drawable fRootWin
Root window used as parent of all windows.
Definition: TGX11.h:132
void CopyWindowtoPixmap(Drawable *pix, Int_t xpos, Int_t ypos)
Copy area of current window in the pixmap pix.
Definition: TGX11.cxx:503
int XRotDrawAlignedString(Display *, XFontStruct *, float, Drawable, GC, int, int, char *, int)
A front end to XRotPaintAlignedString: -does alignment, no background.
Definition: Rotated.cxx:314
static int gCapStyle
Definition: TGX11.cxx:130
void SetCharacterUp(Float_t chupx, Float_t chupy)
Set character up vector.
Definition: TGX11.cxx:1978
Int_t fRedDiv
Red value divider, -1 if no TrueColor visual.
Definition: TGX11.h:145
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
void SetInput(Int_t inp)
Set input on or off.
Definition: TGX11.cxx:2252
static Int_t gCurrentFontNumber
Definition: TGX11.cxx:113
const Bool_t kTRUE
Definition: Rtypes.h:91
float value
Definition: math.cpp:443
const int kMAXGC
Definition: TGX11.cxx:88
ULong_t fBlackPixel
Value of black pixel in colormap.
Definition: TGX11.h:135
Int_t AddWindow(ULong_t qwid, UInt_t w, UInt_t h)
Register a window created by Qt as a ROOT window (like InitWindow()).
Definition: TGX11.cxx:1373
static XFontStruct * gTextFont
Definition: TGX11.cxx:112
void SetClipOFF(Int_t wid)
Turn off the clipping for the window wid.
Definition: TGX11.cxx:1999
TRandom3 R
a TMatrixD.
Definition: testIO.cxx:28
char name[80]
Definition: TGX11.cxx:109
This class stores a (key,value) pair using an external hash.
Definition: TExMap.h:35
static ULong_t gMouseMask
Definition: TGX11.cxx:140
const char * False
int XRotDrawString(Display *, XFontStruct *, float, Drawable, GC, int, int, char *)
A front end to XRotPaintAlignedString: -no alignment, no background.
Definition: Rotated.cxx:292
Int_t SupportsExtension(const char *ext) const
Returns 1 if window system server supports extension given by the argument, returns 0 in case extensi...
Definition: TGX11.cxx:3439
Int_t fRedShift
Bits to left shift red, -1 if no TrueColor visual.
Definition: TGX11.h:148
Style_t fFillStyle
Definition: TAttFill.h:36
const char Int_t const char * image
Definition: TXSlave.cxx:46
const Int_t kNMAX
static GC * gGCinvt
Definition: TGX11.cxx:94
int XRotDrawAlignedImageString(Display *, XFontStruct *, float, Drawable, GC, int, int, char *, int)
A front end to XRotPaintAlignedString: -does alignment, paints background.
Definition: Rotated.cxx:325
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904