Logo ROOT   6.18/05
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
18This class is the basic interface to the X11 (Xlib) graphics system.
19It is an implementation of the abstract TVirtualX class.
20
21This class gives access to basic X11 graphics, pixmap, text and font handling
22routines.
23
24The companion class for Win32 is TGWin32.
25
26The file G11Gui.cxx contains the implementation of the GUI methods of the
27TGX11 class. Most of the methods are used by the machine independent
28GUI classes (libGUI.so).
29
30This code was initially developed in the context of HIGZ and PAW
31by 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
64extern float XRotVersion(char*, int);
65extern void XRotSetMagnification(float);
66extern void XRotSetBoundingBoxPad(int);
67extern int XRotDrawString(Display*, XFontStruct*, float,
68 Drawable, GC, int, int, char*);
69extern int XRotDrawImageString(Display*, XFontStruct*, float,
70 Drawable, GC, int, int, char*);
71extern int XRotDrawAlignedString(Display*, XFontStruct*, float,
72 Drawable, GC, int, int, char*, int);
73extern int XRotDrawAlignedImageString(Display*, XFontStruct*, float,
74 Drawable, GC, int, int, char*, int);
75extern XPoint *XRotTextExtents(Display*, XFontStruct*, float,
76 int, int, char*, int);
77
78//---- globals
79
80static XWindow_t *gCws; // gCws: pointer to the current window
81static XWindow_t *gTws; // gTws: temporary pointer
82
84
85//
86// Primitives Graphic Contexts global for all windows
87//
88const int kMAXGC = 7;
89static GC gGClist[kMAXGC];
90static GC *gGCline = &gGClist[0]; // PolyLines
91static GC *gGCmark = &gGClist[1]; // PolyMarker
92static GC *gGCfill = &gGClist[2]; // Fill areas
93static GC *gGCtext = &gGClist[3]; // Text
94static GC *gGCinvt = &gGClist[4]; // Inverse text
95static GC *gGCdash = &gGClist[5]; // Dashed lines
96static GC *gGCpxmp = &gGClist[6]; // Pixmap management
97
98static GC gGCecho; // Input echo
99
100static Int_t gFillHollow; // Flag if fill style is hollow
101static Pixmap gFillPattern = 0; // Fill pattern
102
103//
104// Text management
105//
106const Int_t kMAXFONT = 4;
107static struct {
108 XFontStruct *id;
109 char name[80]; // Font name
110} gFont[kMAXFONT]; // List of fonts loaded
111
112static XFontStruct *gTextFont; // Current font
113static Int_t gCurrentFontNumber = 0; // Current font number in gFont[]
114
115//
116// Markers
117//
118const Int_t kMAXMK = 100;
119static 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//
128static int gLineWidth = 0;
129static int gLineStyle = LineSolid;
130static int gCapStyle = CapButt;
131static int gJoinStyle = JoinMiter;
132static char gDashList[10];
133static int gDashLength = 0;
134static int gDashOffset = 0;
135static int gDashSize = 0;
136
137//
138// Event masks
139//
140static ULong_t gMouseMask = ButtonPressMask | ButtonReleaseMask |
141 EnterWindowMask | LeaveWindowMask |
142 PointerMotionMask | KeyPressMask |
143 KeyReleaseMask;
144static ULong_t gKeybdMask = ButtonPressMask | KeyPressMask |
145 EnterWindowMask | LeaveWindowMask;
146
147//
148// Data to create an invisible cursor
149//
150const char null_cursor_bits[] = {
1510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
155
156struct RXGCValues:XGCValues{};
157struct RXColor:XColor{};
158struct RXImage:XImage{};
159struct RXPoint:XPoint{};
160struct RXVisualInfo:XVisualInfo{};
161struct RVisual:Visual{};
162
164
165////////////////////////////////////////////////////////////////////////////////
166/// Default constructor.
167
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;
192 fHasXft = kFALSE;
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
204TGX11::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;
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;
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;
251 fScreenNumber = org.fScreenNumber;
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;
263 fTextMagnitude = org.fTextMagnitude;
264 fCharacterUpX = org.fCharacterUpX;
265 fCharacterUpY = org.fCharacterUpY;
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
276 fMaxNumberOfWindows = org.fMaxNumberOfWindows;
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;
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
337Bool_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
361Bool_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
378void 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
491void 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
503void 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
520void 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
554void 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
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
603void 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
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
746void 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
834static 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
843void 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
926void *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
956void 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
991const 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
1014void TGX11::GetPlanes(int &nplanes)
1015{
1016 nplanes = fDepth;
1017}
1018
1019////////////////////////////////////////////////////////////////////////////////
1020/// Get rgb values for color "index".
1021
1022void 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
1043void 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
1075void 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
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
1238Int_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
1249again:
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
1311again:
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
1379again:
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
1449void 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
1500Int_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
1836void 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
1870int 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
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
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
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
2015void 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
2038void 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
2071void 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
2086void 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;
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
2252void 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
2292void 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 if (gLineWidth == 0) gLineWidth =1;
2308 XSetLineAttributes((Display*)fDisplay, *gGCline, gLineWidth,
2310 XSetLineAttributes((Display*)fDisplay, *gGCdash, gLineWidth,
2312 }
2313}
2314
2315////////////////////////////////////////////////////////////////////////////////
2316/// Set line style.
2317
2319{
2320 static Int_t dashed[2] = {3,3};
2321 static Int_t dotted[2] = {1,2};
2322 static Int_t dasheddotted[4] = {3,4,1,4};
2323
2324 if (fLineStyle != lstyle) { //set style index only if different
2325 fLineStyle = lstyle;
2326 if (lstyle <= 1 ) {
2327 SetLineType(0,0);
2328 } else if (lstyle == 2 ) {
2329 SetLineType(2,dashed);
2330 } else if (lstyle == 3 ) {
2331 SetLineType(2,dotted);
2332 } else if (lstyle == 4 ) {
2333 SetLineType(4,dasheddotted);
2334 } else {
2336 TObjArray *tokens = st.Tokenize(" ");
2337 Int_t nt;
2338 nt = tokens->GetEntries();
2339 Int_t *linestyle = new Int_t[nt];
2340 for (Int_t j = 0; j<nt; j++) {
2341 Int_t it;
2342 sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
2343 linestyle[j] = (Int_t)(it/4);
2344 }
2345 SetLineType(nt,linestyle);
2346 delete [] linestyle;
2347 delete tokens;
2348 }
2349 }
2350}
2351
2352////////////////////////////////////////////////////////////////////////////////
2353/// Set line width.
2354///
2355/// \param [in] width : line width in pixels
2356
2358{
2359 if (fLineWidth == width) return;
2360 fLineWidth = width;
2361
2362 if (width == 1 && gLineStyle == LineSolid) gLineWidth = 0;
2363 else gLineWidth = width;
2364
2365 if (gLineWidth < 0) return;
2366
2367 XSetLineAttributes((Display*)fDisplay, *gGCline, gLineWidth,
2369 XSetLineAttributes((Display*)fDisplay, *gGCdash, gLineWidth,
2371}
2372
2373////////////////////////////////////////////////////////////////////////////////
2374/// Set color index for markers.
2375
2377{
2378 if (cindex < 0) return;
2379
2381
2382 SetColor(gGCmark, Int_t(cindex));
2383}
2384
2385////////////////////////////////////////////////////////////////////////////////
2386/// Set marker size index.
2387///
2388/// \param [in] msize : marker scale factor
2389
2391{
2392 if (msize == fMarkerSize) return;
2393
2394 fMarkerSize = msize;
2395 if (msize < 0) return;
2396
2398}
2399
2400////////////////////////////////////////////////////////////////////////////////
2401/// Set marker type.
2402///
2403/// \param [in] type : marker type
2404/// \param [in] n : length of marker description
2405/// \param [in] xy : list of points describing marker shape
2406///
2407/// - if n == 0 marker is a single point
2408/// - if TYPE == 0 marker is hollow circle of diameter N
2409/// - if TYPE == 1 marker is filled circle of diameter N
2410/// - if TYPE == 2 marker is a hollow polygon describe by line XY
2411/// - if TYPE == 3 marker is a filled polygon describe by line XY
2412/// - if TYPE == 4 marker is described by segmented line XY
2413/// e.g. TYPE=4,N=4,XY=(-3,0,3,0,0,-3,0,3) sets a plus shape of 7x7 pixels
2414
2415void TGX11::SetMarkerType(int type, int n, RXPoint *xy)
2416{
2417 gMarker.type = type;
2418 gMarker.n = n < kMAXMK ? n : kMAXMK;
2419 if (gMarker.type >= 2) {
2420 for (int i = 0; i < gMarker.n; i++) {
2421 gMarker.xy[i].x = xy[i].x;
2422 gMarker.xy[i].y = xy[i].y;
2423 }
2424 }
2425}
2426
2427////////////////////////////////////////////////////////////////////////////////
2428/// Set marker style.
2429
2431{
2432 if (fMarkerStyle == markerstyle) return;
2433 static RXPoint shape[30];
2434 if (markerstyle >= 50) return;
2435 markerstyle = TMath::Abs(markerstyle);
2436 fMarkerStyle = markerstyle;
2437 Int_t im = Int_t(4*fMarkerSize + 0.5);
2438 if (markerstyle == 2) {
2439 // + shaped marker
2440 shape[0].x = -im; shape[0].y = 0;
2441 shape[1].x = im; shape[1].y = 0;
2442 shape[2].x = 0 ; shape[2].y = -im;
2443 shape[3].x = 0 ; shape[3].y = im;
2444 SetMarkerType(4,4,shape);
2445 } else if (markerstyle == 3 || markerstyle == 31) {
2446 // * shaped marker
2447 shape[0].x = -im; shape[0].y = 0;
2448 shape[1].x = im; shape[1].y = 0;
2449 shape[2].x = 0 ; shape[2].y = -im;
2450 shape[3].x = 0 ; shape[3].y = im;
2451 im = Int_t(0.707*Float_t(im) + 0.5);
2452 shape[4].x = -im; shape[4].y = -im;
2453 shape[5].x = im; shape[5].y = im;
2454 shape[6].x = -im; shape[6].y = im;
2455 shape[7].x = im; shape[7].y = -im;
2456 SetMarkerType(4,8,shape);
2457 } else if (markerstyle == 4 || markerstyle == 24) {
2458 // O shaped marker
2459 SetMarkerType(0,im*2,shape);
2460 } else if (markerstyle == 5) {
2461 // X shaped marker
2462 im = Int_t(0.707*Float_t(im) + 0.5);
2463 shape[0].x = -im; shape[0].y = -im;
2464 shape[1].x = im; shape[1].y = im;
2465 shape[2].x = -im; shape[2].y = im;
2466 shape[3].x = im; shape[3].y = -im;
2467 SetMarkerType(4,4,shape);
2468 } else if (markerstyle == 6) {
2469 // + shaped marker (with 1 pixel)
2470 shape[0].x = -1 ; shape[0].y = 0;
2471 shape[1].x = 1 ; shape[1].y = 0;
2472 shape[2].x = 0 ; shape[2].y = -1;
2473 shape[3].x = 0 ; shape[3].y = 1;
2474 SetMarkerType(4,4,shape);
2475 } else if (markerstyle == 7) {
2476 // . shaped marker (with 9 pixel)
2477 shape[0].x = -1 ; shape[0].y = 1;
2478 shape[1].x = 1 ; shape[1].y = 1;
2479 shape[2].x = -1 ; shape[2].y = 0;
2480 shape[3].x = 1 ; shape[3].y = 0;
2481 shape[4].x = -1 ; shape[4].y = -1;
2482 shape[5].x = 1 ; shape[5].y = -1;
2483 SetMarkerType(4,6,shape);
2484 } else if (markerstyle == 8 || markerstyle == 20) {
2485 // O shaped marker (filled)
2486 SetMarkerType(1,im*2,shape);
2487 } else if (markerstyle == 21) {
2488 // full square
2489 shape[0].x = -im; shape[0].y = -im;
2490 shape[1].x = im; shape[1].y = -im;
2491 shape[2].x = im; shape[2].y = im;
2492 shape[3].x = -im; shape[3].y = im;
2493 shape[4].x = -im; shape[4].y = -im;
2494 SetMarkerType(3,5,shape);
2495 } else if (markerstyle == 22) {
2496 // full triangle up
2497 shape[0].x = -im; shape[0].y = im;
2498 shape[1].x = im; shape[1].y = im;
2499 shape[2].x = 0; shape[2].y = -im;
2500 shape[3].x = -im; shape[3].y = im;
2501 SetMarkerType(3,4,shape);
2502 } else if (markerstyle == 23) {
2503 // full triangle down
2504 shape[0].x = 0; shape[0].y = im;
2505 shape[1].x = im; shape[1].y = -im;
2506 shape[2].x = -im; shape[2].y = -im;
2507 shape[3].x = 0; shape[3].y = im;
2508 SetMarkerType(3,4,shape);
2509 } else if (markerstyle == 25) {
2510 // open square
2511 shape[0].x = -im; shape[0].y = -im;
2512 shape[1].x = im; shape[1].y = -im;
2513 shape[2].x = im; shape[2].y = im;
2514 shape[3].x = -im; shape[3].y = im;
2515 shape[4].x = -im; shape[4].y = -im;
2516 SetMarkerType(2,5,shape);
2517 } else if (markerstyle == 26) {
2518 // open triangle up
2519 shape[0].x = -im; shape[0].y = im;
2520 shape[1].x = im; shape[1].y = im;
2521 shape[2].x = 0; shape[2].y = -im;
2522 shape[3].x = -im; shape[3].y = im;
2523 SetMarkerType(2,4,shape);
2524 } else if (markerstyle == 27) {
2525 // open losange
2526 Int_t imx = Int_t(2.66*fMarkerSize + 0.5);
2527 shape[0].x =-imx; shape[0].y = 0;
2528 shape[1].x = 0; shape[1].y = -im;
2529 shape[2].x = imx; shape[2].y = 0;
2530 shape[3].x = 0; shape[3].y = im;
2531 shape[4].x =-imx; shape[4].y = 0;
2532 SetMarkerType(2,5,shape);
2533 } else if (markerstyle == 28) {
2534 // open cross
2535 Int_t imx = Int_t(1.33*fMarkerSize + 0.5);
2536 shape[0].x = -im; shape[0].y =-imx;
2537 shape[1].x =-imx; shape[1].y =-imx;
2538 shape[2].x =-imx; shape[2].y = -im;
2539 shape[3].x = imx; shape[3].y = -im;
2540 shape[4].x = imx; shape[4].y =-imx;
2541 shape[5].x = im; shape[5].y =-imx;
2542 shape[6].x = im; shape[6].y = imx;
2543 shape[7].x = imx; shape[7].y = imx;
2544 shape[8].x = imx; shape[8].y = im;
2545 shape[9].x =-imx; shape[9].y = im;
2546 shape[10].x=-imx; shape[10].y= imx;
2547 shape[11].x= -im; shape[11].y= imx;
2548 shape[12].x= -im; shape[12].y=-imx;
2549 SetMarkerType(2,13,shape);
2550 } else if (markerstyle == 29) {
2551 // full star pentagone
2552 Int_t im1 = Int_t(0.66*fMarkerSize + 0.5);
2553 Int_t im2 = Int_t(2.00*fMarkerSize + 0.5);
2554 Int_t im3 = Int_t(2.66*fMarkerSize + 0.5);
2555 Int_t im4 = Int_t(1.33*fMarkerSize + 0.5);
2556 shape[0].x = -im; shape[0].y = im4;
2557 shape[1].x =-im2; shape[1].y =-im1;
2558 shape[2].x =-im3; shape[2].y = -im;
2559 shape[3].x = 0; shape[3].y =-im2;
2560 shape[4].x = im3; shape[4].y = -im;
2561 shape[5].x = im2; shape[5].y =-im1;
2562 shape[6].x = im; shape[6].y = im4;
2563 shape[7].x = im4; shape[7].y = im4;
2564 shape[8].x = 0; shape[8].y = im;
2565 shape[9].x =-im4; shape[9].y = im4;
2566 shape[10].x= -im; shape[10].y= im4;
2567 SetMarkerType(3,11,shape);
2568 } else if (markerstyle == 30) {
2569 // open star pentagone
2570 Int_t im1 = Int_t(0.66*fMarkerSize + 0.5);
2571 Int_t im2 = Int_t(2.00*fMarkerSize + 0.5);
2572 Int_t im3 = Int_t(2.66*fMarkerSize + 0.5);
2573 Int_t im4 = Int_t(1.33*fMarkerSize + 0.5);
2574 shape[0].x = -im; shape[0].y = im4;
2575 shape[1].x =-im2; shape[1].y =-im1;
2576 shape[2].x =-im3; shape[2].y = -im;
2577 shape[3].x = 0; shape[3].y =-im2;
2578 shape[4].x = im3; shape[4].y = -im;
2579 shape[5].x = im2; shape[5].y =-im1;
2580 shape[6].x = im; shape[6].y = im4;
2581 shape[7].x = im4; shape[7].y = im4;
2582 shape[8].x = 0; shape[8].y = im;
2583 shape[9].x =-im4; shape[9].y = im4;
2584 shape[10].x= -im; shape[10].y= im4;
2585 SetMarkerType(2,11,shape);
2586 } else if (markerstyle == 32) {
2587 // open triangle down
2588 shape[0].x = 0; shape[0].y = im;
2589 shape[1].x = im; shape[1].y = -im;
2590 shape[2].x = -im; shape[2].y = -im;
2591 shape[3].x = 0; shape[3].y = im;
2592 SetMarkerType(2,4,shape);
2593 } else if (markerstyle == 33) {
2594 // full losange
2595 Int_t imx = Int_t(2.66*fMarkerSize + 0.5);
2596 shape[0].x =-imx; shape[0].y = 0;
2597 shape[1].x = 0; shape[1].y = -im;
2598 shape[2].x = imx; shape[2].y = 0;
2599 shape[3].x = 0; shape[3].y = im;
2600 shape[4].x =-imx; shape[4].y = 0;
2601 SetMarkerType(3,5,shape);
2602 } else if (markerstyle == 34) {
2603 // full cross
2604 Int_t imx = Int_t(1.33*fMarkerSize + 0.5);
2605 shape[0].x = -im; shape[0].y =-imx;
2606 shape[1].x =-imx; shape[1].y =-imx;
2607 shape[2].x =-imx; shape[2].y = -im;
2608 shape[3].x = imx; shape[3].y = -im;
2609 shape[4].x = imx; shape[4].y =-imx;
2610 shape[5].x = im; shape[5].y =-imx;
2611 shape[6].x = im; shape[6].y = imx;
2612 shape[7].x = imx; shape[7].y = imx;
2613 shape[8].x = imx; shape[8].y = im;
2614 shape[9].x =-imx; shape[9].y = im;
2615 shape[10].x=-imx; shape[10].y= imx;
2616 shape[11].x= -im; shape[11].y= imx;
2617 shape[12].x= -im; shape[12].y=-imx;
2618 SetMarkerType(3,13,shape);
2619 } else if (markerstyle == 35) {
2620 // diamond with cross
2621 shape[0].x =-im; shape[0].y = 0;
2622 shape[1].x = 0; shape[1].y = -im;
2623 shape[2].x = im; shape[2].y = 0;
2624 shape[3].x = 0; shape[3].y = im;
2625 shape[4].x =-im; shape[4].y = 0;
2626 shape[5].x = im; shape[5].y = 0;
2627 shape[6].x = 0; shape[6].y = im;
2628 shape[7].x = 0; shape[7].y =-im;
2629 SetMarkerType(2,8,shape);
2630 } else if (markerstyle == 36) {
2631 // square with diagonal cross
2632 shape[0].x = -im; shape[0].y = -im;
2633 shape[1].x = im; shape[1].y = -im;
2634 shape[2].x = im; shape[2].y = im;
2635 shape[3].x = -im; shape[3].y = im;
2636 shape[4].x = -im; shape[4].y = -im;
2637 shape[5].x = im; shape[5].y = im;
2638 shape[6].x = -im; shape[6].y = im;
2639 shape[7].x = im; shape[7].y = -im;
2640 SetMarkerType(2,8,shape);
2641 } else if (markerstyle == 37) {
2642 // open three triangles
2643 Int_t im2 = Int_t(2.0*fMarkerSize + 0.5);
2644 shape[0].x = 0; shape[0].y = 0;
2645 shape[1].x =-im2; shape[1].y = im;
2646 shape[2].x = im2; shape[2].y = im;
2647 shape[3].x = 0; shape[3].y = 0;
2648 shape[4].x =-im2; shape[4].y = -im;
2649 shape[5].x = -im; shape[5].y = 0;
2650 shape[6].x = 0; shape[6].y = 0;
2651 shape[7].x = im; shape[7].y = 0;
2652 shape[8].x = im2; shape[8].y = -im;
2653 shape[9].x = 0; shape[9].y = 0;
2654 SetMarkerType(2, 10,shape);
2655 } else if (markerstyle == 38) {
2656 // + shaped marker with octagon
2657 Int_t im2 = Int_t(2.0*fMarkerSize + 0.5);
2658 shape[0].x = -im; shape[0].y = 0;
2659 shape[1].x = -im; shape[1].y =-im2;
2660 shape[2].x =-im2; shape[2].y = -im;
2661 shape[3].x = im2; shape[3].y = -im;
2662 shape[4].x = im; shape[4].y =-im2;
2663 shape[5].x = im; shape[5].y = im2;
2664 shape[6].x = im2; shape[6].y = im;
2665 shape[7].x =-im2; shape[7].y = im;
2666 shape[8].x = -im; shape[8].y = im2;
2667 shape[9].x = -im; shape[9].y = 0;
2668 shape[10].x = im; shape[10].y = 0;
2669 shape[11].x = 0; shape[11].y = 0;
2670 shape[12].x = 0; shape[12].y = -im;
2671 shape[13].x = 0; shape[13].y = im;
2672 shape[14].x = 0; shape[14].y = 0;
2673 SetMarkerType(2,15,shape);
2674 } else if (markerstyle == 39) {
2675 // filled three triangles
2676 Int_t im2 = Int_t(2.0*fMarkerSize + 0.5);
2677 shape[0].x = 0; shape[0].y = 0;
2678 shape[1].x =-im2; shape[1].y = im;
2679 shape[2].x = im2; shape[2].y = im;
2680 shape[3].x = 0; shape[3].y = 0;
2681 shape[4].x =-im2; shape[4].y = -im;
2682 shape[5].x = -im; shape[5].y = 0;
2683 shape[6].x = 0; shape[6].y = 0;
2684 shape[7].x = im; shape[7].y = 0;
2685 shape[8].x = im2; shape[8].y = -im;
2686 SetMarkerType(3,9,shape);
2687 } else if (markerstyle == 40) {
2688 // four open triangles X
2689 Int_t im2 = Int_t(2.0*fMarkerSize + 0.5);
2690 shape[0].x = 0; shape[0].y = 0;
2691 shape[1].x = im2; shape[1].y = im;
2692 shape[2].x = im; shape[2].y = im2;
2693 shape[3].x = 0; shape[3].y = 0;
2694 shape[4].x = im; shape[4].y = -im2;
2695 shape[5].x = im2; shape[5].y = -im;
2696 shape[6].x = 0; shape[6].y = 0;
2697 shape[7].x = -im2; shape[7].y = -im;
2698 shape[8].x = -im; shape[8].y = -im2;
2699 shape[9].x = 0; shape[9].y = 0;
2700 shape[10].x = -im; shape[10].y = im2;
2701 shape[11].x = -im2; shape[11].y = im;
2702 shape[12].x = 0; shape[12].y = 0;
2703 SetMarkerType(2,13,shape);
2704 } else if (markerstyle == 41) {
2705 // four filled triangles X
2706 Int_t im2 = Int_t(2.0*fMarkerSize + 0.5);
2707 shape[0].x = 0; shape[0].y = 0;
2708 shape[1].x = im2; shape[1].y = im;
2709 shape[2].x = im; shape[2].y = im2;
2710 shape[3].x = 0; shape[3].y = 0;
2711 shape[4].x = im; shape[4].y = -im2;
2712 shape[5].x = im2; shape[5].y = -im;
2713 shape[6].x = 0; shape[6].y = 0;
2714 shape[7].x = -im2; shape[7].y = -im;
2715 shape[8].x = -im; shape[8].y = -im2;
2716 shape[9].x = 0; shape[9].y = 0;
2717 shape[10].x = -im; shape[10].y = im2;
2718 shape[11].x = -im2; shape[11].y = im;
2719 shape[12].x = 0; shape[12].y = 0;
2720 SetMarkerType(3,13,shape);
2721 } else if (markerstyle == 42) {
2722 // open double diamonds
2723 Int_t imx = Int_t(fMarkerSize + 0.5);
2724 shape[0].x= 0; shape[0].y= im;
2725 shape[1].x= -imx; shape[1].y= imx;
2726 shape[2].x = -im; shape[2].y = 0;
2727 shape[3].x = -imx; shape[3].y = -imx;
2728 shape[4].x = 0; shape[4].y = -im;
2729 shape[5].x = imx; shape[5].y = -imx;
2730 shape[6].x = im; shape[6].y = 0;
2731 shape[7].x= imx; shape[7].y= imx;
2732 shape[8].x= 0; shape[8].y= im;
2733 SetMarkerType(2,9,shape);
2734 } else if (markerstyle == 43) {
2735 // filled double diamonds
2736 Int_t imx = Int_t(fMarkerSize + 0.5);
2737 shape[0].x = 0; shape[0].y = im;
2738 shape[1].x = -imx; shape[1].y = imx;
2739 shape[2].x = -im; shape[2].y = 0;
2740 shape[3].x = -imx; shape[3].y = -imx;
2741 shape[4].x = 0; shape[4].y = -im;
2742 shape[5].x = imx; shape[5].y = -imx;
2743 shape[6].x = im; shape[6].y = 0;
2744 shape[7].x = imx; shape[7].y = imx;
2745 shape[8].x = 0; shape[8].y = im;
2746 SetMarkerType(3,9,shape);
2747 } else if (markerstyle == 44) {
2748 // open four triangles plus
2749 Int_t im2 = Int_t(2.0*fMarkerSize + 0.5);
2750 shape[0].x = 0; shape[0].y = 0;
2751 shape[1].x = im2; shape[1].y = im;
2752 shape[2].x = -im2; shape[2].y = im;
2753 shape[3].x = im2; shape[3].y = -im;
2754 shape[4].x = -im2; shape[4].y = -im;
2755 shape[5].x = 0; shape[5].y = 0;
2756 shape[6].x = im; shape[6].y = im2;
2757 shape[7].x = im; shape[7].y = -im2;
2758 shape[8].x = -im; shape[8].y = im2;
2759 shape[9].x = -im; shape[9].y = -im2;
2760 shape[10].x = 0; shape[10].y = 0;
2761 SetMarkerType(2,11,shape);
2762 } else if (markerstyle == 45) {
2763 // filled four triangles plus
2764 Int_t im0 = Int_t(0.4*fMarkerSize + 0.5);
2765 Int_t im2 = Int_t(2.0*fMarkerSize + 0.5);
2766 shape[0].x = im0; shape[0].y = im0;
2767 shape[1].x = im2; shape[1].y = im;
2768 shape[2].x = -im2; shape[2].y = im;
2769 shape[3].x = -im0; shape[3].y = im0;
2770 shape[4].x = -im; shape[4].y = im2;
2771 shape[5].x = -im; shape[5].y = -im2;
2772 shape[6].x = -im0; shape[6].y = -im0;
2773 shape[7].x = -im2; shape[7].y = -im;
2774 shape[8].x = im2; shape[8].y = -im;
2775 shape[9].x = im0; shape[9].y = -im0;
2776 shape[10].x = im; shape[10].y = -im2;
2777 shape[11].x = im; shape[11].y = im2;
2778 shape[12].x = im0; shape[12].y = im0;
2779 SetMarkerType(3,13,shape);
2780 } else if (markerstyle == 46) {
2781 // open four triangles X
2782 Int_t im2 = Int_t(2.0*fMarkerSize + 0.5);
2783 shape[0].x = 0; shape[0].y = im2;
2784 shape[1].x = -im2; shape[1].y = im;
2785 shape[2].x = -im; shape[2].y = im2;
2786 shape[3].x = -im2; shape[3].y = 0;
2787 shape[4].x = -im; shape[4].y = -im2;
2788 shape[5].x = -im2; shape[5].y = -im;
2789 shape[6].x = 0; shape[6].y = -im2;
2790 shape[7].x = im2; shape[7].y = -im;
2791 shape[8].x = im; shape[8].y = -im2;
2792 shape[9].x = im2; shape[9].y = 0;
2793 shape[10].x = im; shape[10].y = im2;
2794 shape[11].x = im2; shape[11].y = im;
2795 shape[12].x = 0; shape[12].y = im2;
2796 SetMarkerType(2,13,shape);
2797 } else if (markerstyle == 47) {
2798 // filled four triangles X
2799 Int_t im2 = Int_t(2.0*fMarkerSize + 0.5);
2800 shape[0].x = 0; shape[0].y = im2;
2801 shape[1].x = -im2; shape[1].y = im;
2802 shape[2].x = -im; shape[2].y = im2;
2803 shape[3].x = -im2; shape[3].y = 0;
2804 shape[4].x = -im; shape[4].y = -im2;
2805 shape[5].x = -im2; shape[5].y = -im;
2806 shape[6].x = 0; shape[6].y = -im2;
2807 shape[7].x = im2; shape[7].y = -im;
2808 shape[8].x = im; shape[8].y = -im2;
2809 shape[9].x = im2; shape[9].y = 0;
2810 shape[10].x = im; shape[10].y = im2;
2811 shape[11].x = im2; shape[11].y = im;
2812 shape[12].x = 0; shape[12].y = im2;
2813 SetMarkerType(3,13,shape);
2814 } else if (markerstyle == 48) {
2815 // four filled squares X
2816 Int_t im2 = Int_t(2.0*fMarkerSize + 0.5);
2817 shape[0].x = 0; shape[0].y = im2*1.005;
2818 shape[1].x = -im2; shape[1].y = im;
2819 shape[2].x = -im; shape[2].y = im2;
2820 shape[3].x = -im2; shape[3].y = 0;
2821 shape[4].x = -im; shape[4].y = -im2;
2822 shape[5].x = -im2; shape[5].y = -im;
2823 shape[6].x = 0; shape[6].y = -im2;
2824 shape[7].x = im2; shape[7].y = -im;
2825 shape[8].x = im; shape[8].y = -im2;
2826 shape[9].x = im2; shape[9].y = 0;
2827 shape[10].x = im; shape[10].y = im2;
2828 shape[11].x = im2; shape[11].y = im;
2829 shape[12].x = 0; shape[12].y = im2*0.995;
2830 shape[13].x = im2*0.995; shape[13].y = 0;
2831 shape[14].x = 0; shape[14].y = -im2*0.995;
2832 shape[15].x = -im2*0.995; shape[15].y = 0;
2833 shape[16].x = 0; shape[16].y = im2*0.995;
2834 SetMarkerType(3,16,shape);
2835 } else if (markerstyle == 49) {
2836 // four filled squares plus
2837 Int_t imx = Int_t(1.33*fMarkerSize + 0.5);
2838 shape[0].x =-imx; shape[0].y =-imx*1.005;
2839 shape[1].x =-imx; shape[1].y = -im;
2840 shape[2].x = imx; shape[2].y = -im;
2841 shape[3].x = imx; shape[3].y =-imx;
2842 shape[4].x = im; shape[4].y =-imx;
2843 shape[5].x = im; shape[5].y = imx;
2844 shape[6].x = imx; shape[6].y = imx;
2845 shape[7].x = imx; shape[7].y = im;
2846 shape[8].x =-imx; shape[8].y = im;
2847 shape[9].x =-imx; shape[9].y = imx;
2848 shape[10].x = -im; shape[10].y = imx;
2849 shape[11].x = -im; shape[11].y =-imx;
2850 shape[12].x =-imx; shape[12].y =-imx*0.995;
2851 shape[13].x =-imx; shape[13].y = imx;
2852 shape[14].x = imx; shape[14].y = imx;
2853 shape[15].x = imx; shape[15].y =-imx;
2854 shape[16].x =-imx; shape[16].y =-imx*1.005;
2855 SetMarkerType(3,17,shape);
2856 } else {
2857 // single dot
2858 SetMarkerType(0,0,shape);
2859 }
2860}
2861
2862////////////////////////////////////////////////////////////////////////////////
2863/// Set opacity of a window. This image manipulation routine works
2864/// by adding to a percent amount of neutral to each pixels RGB.
2865/// Since it requires quite some additional color map entries is it
2866/// only supported on displays with more than > 8 color planes (> 256
2867/// colors).
2868
2870{
2871 if (fDepth <= 8) return;
2872 if (percent == 0) return;
2873 // if 100 percent then just make white
2874
2875 ULong_t *orgcolors = 0, *tmpc = 0;
2876 Int_t maxcolors = 0, ncolors = 0, ntmpc = 0;
2877
2878 // save previous allocated colors, delete at end when not used anymore
2879 if (gCws->fNewColors) {
2880 tmpc = gCws->fNewColors;
2881 ntmpc = gCws->fNcolors;
2882 }
2883
2884 // get pixmap from server as image
2885 XImage *image = XGetImage((Display*)fDisplay, gCws->fDrawing, 0, 0, gCws->fWidth,
2886 gCws->fHeight, AllPlanes, ZPixmap);
2887 if (!image) return;
2888 // collect different image colors
2889 int x, y;
2890 for (y = 0; y < (int) gCws->fHeight; y++) {
2891 for (x = 0; x < (int) gCws->fWidth; x++) {
2892 ULong_t pixel = XGetPixel(image, x, y);
2893 CollectImageColors(pixel, orgcolors, ncolors, maxcolors);
2894 }
2895 }
2896 if (ncolors == 0) {
2897 XDestroyImage(image);
2898 ::operator delete(orgcolors);
2899 return;
2900 }
2901
2902 // create opaque counter parts
2903 MakeOpaqueColors(percent, orgcolors, ncolors);
2904
2905 if (gCws->fNewColors) {
2906 // put opaque colors in image
2907 for (y = 0; y < (int) gCws->fHeight; y++) {
2908 for (x = 0; x < (int) gCws->fWidth; x++) {
2909 ULong_t pixel = XGetPixel(image, x, y);
2910 Int_t idx = FindColor(pixel, orgcolors, ncolors);
2911 XPutPixel(image, x, y, gCws->fNewColors[idx]);
2912 }
2913 }
2914 }
2915
2916 // put image back in pixmap on server
2917 XPutImage((Display*)fDisplay, gCws->fDrawing, *gGCpxmp, image, 0, 0, 0, 0,
2918 gCws->fWidth, gCws->fHeight);
2919 XFlush((Display*)fDisplay);
2920
2921 // clean up
2922 if (tmpc) {
2923 if (fRedDiv == -1)
2924 XFreeColors((Display*)fDisplay, fColormap, tmpc, ntmpc, 0);
2925 delete [] tmpc;
2926 }
2927 XDestroyImage(image);
2928 ::operator delete(orgcolors);
2929}
2930
2931////////////////////////////////////////////////////////////////////////////////
2932/// Collect in orgcolors all different original image colors.
2933
2934void TGX11::CollectImageColors(ULong_t pixel, ULong_t *&orgcolors, Int_t &ncolors,
2935 Int_t &maxcolors)
2936{
2937 if (maxcolors == 0) {
2938 ncolors = 0;
2939 maxcolors = 100;
2940 orgcolors = (ULong_t*) ::operator new(maxcolors*sizeof(ULong_t));
2941 }
2942
2943 for (int i = 0; i < ncolors; i++)
2944 if (pixel == orgcolors[i]) return;
2945
2946 if (ncolors >= maxcolors) {
2947 orgcolors = (ULong_t*) TStorage::ReAlloc(orgcolors,
2948 maxcolors*2*sizeof(ULong_t), maxcolors*sizeof(ULong_t));
2949 maxcolors *= 2;
2950 }
2951
2952 orgcolors[ncolors++] = pixel;
2953}
2954
2955////////////////////////////////////////////////////////////////////////////////
2956/// Get RGB values for orgcolors, add percent neutral to the RGB and
2957/// allocate fNewColors.
2958
2959void TGX11::MakeOpaqueColors(Int_t percent, ULong_t *orgcolors, Int_t ncolors)
2960{
2961 if (ncolors == 0) return;
2962
2963 RXColor *xcol = new RXColor[ncolors];
2964
2965 int i;
2966 for (i = 0; i < ncolors; i++) {
2967 xcol[i].pixel = orgcolors[i];
2968 xcol[i].red = xcol[i].green = xcol[i].blue = 0;
2969 xcol[i].flags = DoRed | DoGreen | DoBlue;
2970 }
2971 QueryColors(fColormap, xcol, ncolors);
2972
2973 UShort_t add = percent * kBIGGEST_RGB_VALUE / 100;
2974
2975 Int_t val;
2976 for (i = 0; i < ncolors; i++) {
2977 val = xcol[i].red + add;
2978 if (val > kBIGGEST_RGB_VALUE) val = kBIGGEST_RGB_VALUE;
2979 xcol[i].red = (UShort_t) val;
2980 val = xcol[i].green + add;
2981 if (val > kBIGGEST_RGB_VALUE) val = kBIGGEST_RGB_VALUE;
2982 xcol[i].green = (UShort_t) val;
2983 val = xcol[i].blue + add;
2984 if (val > kBIGGEST_RGB_VALUE) val = kBIGGEST_RGB_VALUE;
2985 xcol[i].blue = (UShort_t) val;
2986 if (!AllocColor(fColormap, &xcol[i]))
2987 Warning("MakeOpaqueColors", "failed to allocate color %hd, %hd, %hd",
2988 xcol[i].red, xcol[i].green, xcol[i].blue);
2989 // assumes that in case of failure xcol[i].pixel is not changed
2990 }
2991
2992 gCws->fNewColors = new ULong_t[ncolors];
2993 gCws->fNcolors = ncolors;
2994
2995 for (i = 0; i < ncolors; i++)
2996 gCws->fNewColors[i] = xcol[i].pixel;
2997
2998 delete [] xcol;
2999}
3000
3001////////////////////////////////////////////////////////////////////////////////
3002/// Returns index in orgcolors (and fNewColors) for pixel.
3003
3004Int_t TGX11::FindColor(ULong_t pixel, ULong_t *orgcolors, Int_t ncolors)
3005{
3006 for (int i = 0; i < ncolors; i++)
3007 if (pixel == orgcolors[i]) return i;
3008
3009 Error("FindColor", "did not find color, should never happen!");
3010
3011 return 0;
3012}
3013
3014////////////////////////////////////////////////////////////////////////////////
3015/// Set color intensities for given color index.
3016///
3017/// \param [in] cindex : color index
3018/// \param [in] r,g,b : red, green, blue intensities between 0.0 and 1.0
3019
3020void TGX11::SetRGB(int cindex, float r, float g, float b)
3021{
3022 if (fColormap) {
3023 RXColor xcol;
3024 xcol.red = (UShort_t)(r * kBIGGEST_RGB_VALUE);
3025 xcol.green = (UShort_t)(g * kBIGGEST_RGB_VALUE);
3026 xcol.blue = (UShort_t)(b * kBIGGEST_RGB_VALUE);
3027 xcol.flags = DoRed | DoGreen | DoBlue;
3028 XColor_t &col = GetColor(cindex);
3029 if (col.fDefined) {
3030 // if color is already defined with same rgb just return
3031 if (col.fRed == xcol.red && col.fGreen == xcol.green &&
3032 col.fBlue == xcol.blue)
3033 return;
3034 col.fDefined = kFALSE;
3035 if (fRedDiv == -1)
3036 XFreeColors((Display*)fDisplay, fColormap, &col.fPixel, 1, 0);
3037 }
3038 if (AllocColor(fColormap, &xcol)) {
3039 col.fDefined = kTRUE;
3040 col.fPixel = xcol.pixel;
3041 col.fRed = xcol.red;
3042 col.fGreen = xcol.green;
3043 col.fBlue = xcol.blue;
3044 }
3045 }
3046}
3047
3048////////////////////////////////////////////////////////////////////////////////
3049/// Set text alignment.
3050///
3051/// \param [in] talign text alignment
3052
3054{
3055 Int_t txalh = talign/10;
3056 Int_t txalv = talign%10;
3057 fTextAlignH = txalh;
3058 fTextAlignV = txalv;
3059
3060 switch (txalh) {
3061
3062 case 0 :
3063 case 1 :
3064 switch (txalv) { //left
3065 case 1 :
3066 fTextAlign = 7; //bottom
3067 break;
3068 case 2 :
3069 fTextAlign = 4; //center
3070 break;
3071 case 3 :
3072 fTextAlign = 1; //top
3073 break;
3074 }
3075 break;
3076 case 2 :
3077 switch (txalv) { //center
3078 case 1 :
3079 fTextAlign = 8; //bottom
3080 break;
3081 case 2 :
3082 fTextAlign = 5; //center
3083 break;
3084 case 3 :
3085 fTextAlign = 2; //top
3086 break;
3087 }
3088 break;
3089 case 3 :
3090 switch (txalv) { //right
3091 case 1 :
3092 fTextAlign = 9; //bottom
3093 break;
3094 case 2 :
3095 fTextAlign = 6; //center
3096 break;
3097 case 3 :
3098 fTextAlign = 3; //top
3099 break;
3100 }
3101 break;
3102 }
3103
3105}
3106
3107////////////////////////////////////////////////////////////////////////////////
3108/// Set color index for text.
3109
3111{
3112 if (cindex < 0) return;
3113
3114 TAttText::SetTextColor(cindex);
3115
3116 SetColor(gGCtext, Int_t(cindex));
3117
3118 XGCValues values;
3119 if (XGetGCValues((Display*)fDisplay, *gGCtext, GCForeground | GCBackground, &values)) {
3120 XSetForeground( (Display*)fDisplay, *gGCinvt, values.background );
3121 XSetBackground( (Display*)fDisplay, *gGCinvt, values.foreground );
3122 } else {
3123 Error("SetTextColor", "cannot get GC values");
3124 }
3125 XSetBackground((Display*)fDisplay, *gGCtext, GetColor(0).fPixel);
3126}
3127
3128////////////////////////////////////////////////////////////////////////////////
3129/// Set text font to specified name.
3130///
3131/// \param [in] fontname font name
3132/// \param [in] mode loading flag
3133/// - mode=0 search if the font exist (kCheck)
3134/// - mode=1 search the font and load it if it exists (kLoad)
3135///
3136/// Set text font to specified name. This function returns 0 if
3137/// the specified font is found, 1 if not.
3138
3140{
3141 char **fontlist;
3142 int fontcount;
3143 int i;
3144
3145 if (mode == kLoad) {
3146 for (i = 0; i < kMAXFONT; i++) {
3147 if (strcmp(fontname, gFont[i].name) == 0) {
3148 gTextFont = gFont[i].id;
3149 XSetFont((Display*)fDisplay, *gGCtext, gTextFont->fid);
3150 XSetFont((Display*)fDisplay, *gGCinvt, gTextFont->fid);
3151 return 0;
3152 }
3153 }
3154 }
3155
3156 fontlist = XListFonts((Display*)fDisplay, fontname, 1, &fontcount);
3157
3158 if (fontlist && fontcount != 0) {
3159 if (mode == kLoad) {
3160 if (gFont[gCurrentFontNumber].id)
3161 XFreeFont((Display*)fDisplay, gFont[gCurrentFontNumber].id);
3162 gTextFont = XLoadQueryFont((Display*)fDisplay, fontlist[0]);
3163 XSetFont((Display*)fDisplay, *gGCtext, gTextFont->fid);
3164 XSetFont((Display*)fDisplay, *gGCinvt, gTextFont->fid);
3166 strlcpy(gFont[gCurrentFontNumber].name,fontname,80);
3169 }
3170 XFreeFontNames(fontlist);
3171 return 0;
3172 } else {
3173 return 1;
3174 }
3175}
3176
3177////////////////////////////////////////////////////////////////////////////////
3178/// Set current text font number.
3179
3181{
3182 fTextFont = fontnumber;
3183}
3184
3185////////////////////////////////////////////////////////////////////////////////
3186/// Set current text size.
3187
3189{
3190 fTextSize = textsize;
3191}
3192
3193////////////////////////////////////////////////////////////////////////////////
3194/// Set synchronisation on or off.
3195///
3196/// \param [in] mode : synchronisation on/off
3197/// - mode=1 on
3198/// - mode<>0 off
3199
3200void TGX11::Sync(int mode)
3201{
3202 switch (mode) {
3203
3204 case 1 :
3205 XSynchronize((Display*)fDisplay,1);
3206 break;
3207
3208 default:
3209 XSynchronize((Display*)fDisplay,0);
3210 break;
3211 }
3212}
3213
3214////////////////////////////////////////////////////////////////////////////////
3215/// Update display.
3216///
3217/// \param [in] mode : (1) update (0) sync
3218///
3219/// Synchronise client and server once (not permanent).
3220/// Copy the pixmap gCws->fDrawing on the window gCws->fWindow
3221/// if the double buffer is on.
3222
3224{
3225 if (gCws->fDoubleBuffer) {
3226 XCopyArea((Display*)fDisplay, gCws->fDrawing, gCws->fWindow,
3227 *gGCpxmp, 0, 0, gCws->fWidth, gCws->fHeight, 0, 0);
3228 }
3229 if (mode == 1) {
3230 XFlush((Display*)fDisplay);
3231 } else {
3232 XSync((Display*)fDisplay, False);
3233 }
3234}
3235
3236////////////////////////////////////////////////////////////////////////////////
3237/// Set pointer position.
3238///
3239/// \param [in] ix New X coordinate of pointer
3240/// \param [in] iy New Y coordinate of pointer
3241/// \param [in] id Window identifier
3242///
3243/// Coordinates are relative to the origin of the window id
3244/// or to the origin of the current window if id == 0.
3245
3247{
3248 if (!id) {
3249 // Causes problems when calling ProcessEvents()... BadWindow
3250 //XWarpPointer((Display*)fDisplay, None, gCws->fWindow, 0, 0, 0, 0, ix, iy);
3251 } else {
3252 XWarpPointer((Display*)fDisplay, None, (Window) id, 0, 0, 0, 0, ix, iy);
3253 }
3254}
3255
3256////////////////////////////////////////////////////////////////////////////////
3257/// Write the pixmap wid in the bitmap file pxname.
3258///
3259/// \param [in] wid : Pixmap address
3260/// \param [in] w,h : Width and height of the pixmap.
3261/// \param [in] pxname : pixmap name
3262
3263void TGX11::WritePixmap(int wid, unsigned int w, unsigned int h, char *pxname)
3264{
3265 unsigned int wval, hval;
3266 wval = w;
3267 hval = h;
3268
3269 gTws = &fWindows[wid];
3270 XWriteBitmapFile((Display*)fDisplay, pxname, gTws->fDrawing, wval, hval, -1, -1);
3271}
3272
3273
3274//
3275// Functions for GIFencode()
3276//
3277
3278static FILE *gOut; // output unit used WriteGIF and PutByte
3279static XImage *gXimage = 0; // image used in WriteGIF and GetPixel
3280
3281extern "C" {
3282 int GIFquantize(UInt_t width, UInt_t height, Int_t *ncol, Byte_t *red, Byte_t *green,
3283 Byte_t *blue, Byte_t *outputBuf, Byte_t *outputCmap);
3284 long GIFencode(int Width, int Height, Int_t Ncol, Byte_t R[], Byte_t G[], Byte_t B[], Byte_t ScLine[],
3285 void (*get_scline) (int, int, Byte_t *), void (*pb)(Byte_t));
3286 int GIFdecode(Byte_t *gifArr, Byte_t *pixArr, int *Width, int *Height, int *Ncols, Byte_t *R, Byte_t *G, Byte_t *B);
3287 int GIFinfo(Byte_t *gifArr, int *Width, int *Height, int *Ncols);
3288}
3289
3290////////////////////////////////////////////////////////////////////////////////
3291/// Get pixels in line y and put in array scline.
3292
3293static void GetPixel(int y, int width, Byte_t *scline)
3294{
3295 for (int i = 0; i < width; i++)
3296 scline[i] = Byte_t(XGetPixel(gXimage, i, y));
3297}
3298
3299////////////////////////////////////////////////////////////////////////////////
3300/// Put byte b in output stream.
3301
3302static void PutByte(Byte_t b)
3303{
3304 if (ferror(gOut) == 0) fputc(b, gOut);
3305}
3306
3307////////////////////////////////////////////////////////////////////////////////
3308/// Returns in R G B the ncol colors of the palette used by the image.
3309/// The image pixels are changed to index values in these R G B arrays.
3310/// This produces a colormap with only the used colors (so even on displays
3311/// with more than 8 planes we will be able to create GIF's when the image
3312/// contains no more than 256 different colors). If it does contain more
3313/// colors we will have to use GIFquantize to reduce the number of colors.
3314/// The R G B arrays must be deleted by the caller.
3315
3316void TGX11::ImgPickPalette(RXImage *image, Int_t &ncol, Int_t *&R, Int_t *&G, Int_t *&B)
3317{
3318 ULong_t *orgcolors = 0;
3319 Int_t maxcolors = 0, ncolors = 0;
3320
3321 // collect different image colors
3322 int x, y;
3323 for (x = 0; x < (int) gCws->fWidth; x++) {
3324 for (y = 0; y < (int) gCws->fHeight; y++) {
3325 ULong_t pixel = XGetPixel(image, x, y);
3326 CollectImageColors(pixel, orgcolors, ncolors, maxcolors);
3327 }
3328 }
3329
3330 // get RGB values belonging to pixels
3331 RXColor *xcol = new RXColor[ncolors];
3332
3333 int i;
3334 for (i = 0; i < ncolors; i++) {
3335 xcol[i].pixel = orgcolors[i];
3336 xcol[i].red = xcol[i].green = xcol[i].blue = 0;
3337 xcol[i].flags = DoRed | DoGreen | DoBlue;
3338 }
3339 QueryColors(fColormap, xcol, ncolors);
3340
3341 // create RGB arrays and store RGB's for each color and set number of colors
3342 // (space must be delete by caller)
3343 R = new Int_t[ncolors];
3344 G = new Int_t[ncolors];
3345 B = new Int_t[ncolors];
3346
3347 for (i = 0; i < ncolors; i++) {
3348 R[i] = xcol[i].red;
3349 G[i] = xcol[i].green;
3350 B[i] = xcol[i].blue;
3351 }
3352 ncol = ncolors;
3353
3354 // update image with indices (pixels) into the new RGB colormap
3355 for (x = 0; x < (int) gCws->fWidth; x++) {
3356 for (y = 0; y < (int) gCws->fHeight; y++) {
3357 ULong_t pixel = XGetPixel(image, x, y);
3358 Int_t idx = FindColor(pixel, orgcolors, ncolors);
3359 XPutPixel(image, x, y, idx);
3360 }
3361 }
3362
3363 // cleanup
3364 delete [] xcol;
3365 ::operator delete(orgcolors);
3366}
3367
3368////////////////////////////////////////////////////////////////////////////////
3369/// Writes the current window into GIF file. Returns 1 in case of success,
3370/// 0 otherwise.
3371
3373{
3374 Byte_t scline[2000], r[256], b[256], g[256];
3375 Int_t *red, *green, *blue;
3376 Int_t ncol, maxcol, i;
3377
3378 if (gXimage) {
3379 XDestroyImage(gXimage);
3380 gXimage = 0;
3381 }
3382
3383 gXimage = XGetImage((Display*)fDisplay, gCws->fDrawing, 0, 0,
3384 gCws->fWidth, gCws->fHeight,
3385 AllPlanes, ZPixmap);
3386
3387 ImgPickPalette((RXImage*)gXimage, ncol, red, green, blue);
3388
3389 if (ncol > 256) {
3390 //GIFquantize(...);
3391 Error("WriteGIF", "Cannot create GIF of image containing more than 256 colors. Try in batch mode.");
3392 delete [] red;
3393 delete [] green;
3394 delete [] blue;
3395 return 0;
3396 }
3397
3398 maxcol = 0;
3399 for (i = 0; i < ncol; i++) {
3400 if (maxcol < red[i] ) maxcol = red[i];
3401 if (maxcol < green[i] ) maxcol = green[i];
3402 if (maxcol < blue[i] ) maxcol = blue[i];
3403 r[i] = 0;
3404 g[i] = 0;
3405 b[i] = 0;
3406 }
3407 if (maxcol != 0) {
3408 for (i = 0; i < ncol; i++) {
3409 r[i] = red[i] * 255/maxcol;
3410 g[i] = green[i] * 255/maxcol;
3411 b[i] = blue[i] * 255/maxcol;
3412 }
3413 }
3414
3415 gOut = fopen(name, "w+");
3416
3417 if (gOut) {
3418 GIFencode(gCws->fWidth, gCws->fHeight,
3419 ncol, r, g, b, scline, ::GetPixel, PutByte);
3420 fclose(gOut);
3421 i = 1;
3422 } else {
3423 Error("WriteGIF","cannot write file: %s",name);
3424 i = 0;
3425 }
3426 delete [] red;
3427 delete [] green;
3428 delete [] blue;
3429 return i;
3430}
3431
3432////////////////////////////////////////////////////////////////////////////////
3433/// Draw image.
3434
3435void TGX11::PutImage(int offset,int itran,int x0,int y0,int nx,int ny,int xmin,
3436 int ymin,int xmax,int ymax, unsigned char *image,Drawable_t wid)
3437{
3438 const int maxSegment = 20;
3439 int i, n, x, y, xcur, x1, x2, y1, y2;
3440 unsigned char *jimg, *jbase, icol;
3441 int nlines[256];
3442 XSegment lines[256][maxSegment];
3443 Drawable_t id;
3444
3445 if (wid) {
3446 id = wid;
3447 } else {
3448 id = gCws->fDrawing;
3449 }
3450
3451 for (i = 0; i < 256; i++) nlines[i] = 0;
3452
3453 x1 = x0 + xmin; y1 = y0 + ny - ymax - 1;
3454 x2 = x0 + xmax; y2 = y0 + ny - ymin - 1;
3455 jbase = image + (ymin-1)*nx + xmin;
3456
3457 for (y = y2; y >= y1; y--) {
3458 xcur = x1; jbase += nx;
3459 for (jimg = jbase, icol = *jimg++, x = x1+1; x <= x2; jimg++, x++) {
3460 if (icol != *jimg) {
3461 if (icol != itran) {
3462 n = nlines[icol]++;
3463 lines[icol][n].x1 = xcur; lines[icol][n].y1 = y;
3464 lines[icol][n].x2 = x-1; lines[icol][n].y2 = y;
3465 if (nlines[icol] == maxSegment) {
3466 SetColor(gGCline,(int)icol+offset);
3467 XDrawSegments((Display*)fDisplay,id,*gGCline,&lines[icol][0],
3468 maxSegment);
3469 nlines[icol] = 0;
3470 }
3471 }
3472 icol = *jimg; xcur = x;
3473 }
3474 }
3475 if (icol != itran) {
3476 n = nlines[icol]++;
3477 lines[icol][n].x1 = xcur; lines[icol][n].y1 = y;
3478 lines[icol][n].x2 = x-1; lines[icol][n].y2 = y;
3479 if (nlines[icol] == maxSegment) {
3480 SetColor(gGCline,(int)icol+offset);
3481 XDrawSegments((Display*)fDisplay,id,*gGCline,&lines[icol][0],
3482 maxSegment);
3483 nlines[icol] = 0;
3484 }
3485 }
3486 }
3487
3488 for (i = 0; i < 256; i++) {
3489 if (nlines[i] != 0) {
3490 SetColor(gGCline,i+offset);
3491 XDrawSegments((Display*)fDisplay,id,*gGCline,&lines[i][0],nlines[i]);
3492 }
3493 }
3494}
3495
3496////////////////////////////////////////////////////////////////////////////////
3497/// If id is NULL - loads the specified gif file at position [x0,y0] in the
3498/// current window. Otherwise creates pixmap from gif file
3499
3500Pixmap_t TGX11::ReadGIF(int x0, int y0, const char *file, Window_t id)
3501{
3502 FILE *fd;
3503 Seek_t filesize = 0;
3504 unsigned char *gifArr, *pixArr, red[256], green[256], blue[256], *j1, *j2, icol;
3505 int i, j, k, width, height, ncolor, irep, offset;
3506 float rr, gg, bb;
3507 Pixmap_t pic = 0;
3508
3509 fd = fopen(file, "r");
3510 if (!fd) {
3511 Error("ReadGIF", "unable to open GIF file");
3512 return pic;
3513 }
3514
3515 fseek(fd, 0L, 2);
3516 long ft = ftell(fd);
3517 if (ft <=0) {
3518 Error("ReadGIF", "unable to open GIF file");
3519 fclose(fd);
3520 return pic;
3521 } else {
3522 filesize = Seek_t(ft);
3523 }
3524 fseek(fd, 0L, 0);
3525
3526 if (!(gifArr = (unsigned char *) calloc(filesize+256,1))) {
3527 Error("ReadGIF", "unable to allocate array for gif");
3528 fclose(fd);
3529 return pic;
3530 }
3531
3532 if (fread(gifArr, filesize, 1, fd) != 1) {
3533 Error("ReadGIF", "GIF file read failed");
3534 free(gifArr);
3535 fclose(fd);
3536 return pic;
3537 }
3538 fclose(fd);
3539
3540 irep = GIFinfo(gifArr, &width, &height, &ncolor);
3541 if (irep != 0) {
3542 free(gifArr);
3543 return pic;
3544 }
3545
3546 if (!(pixArr = (unsigned char *) calloc((width*height),1))) {
3547 Error("ReadGIF", "unable to allocate array for image");
3548 free(gifArr);
3549 return pic;
3550 }
3551
3552 irep = GIFdecode(gifArr, pixArr, &width, &height, &ncolor, red, green, blue);
3553 if (irep != 0) {
3554 free(gifArr);
3555 free(pixArr);
3556 return pic;
3557 }
3558
3559 // S E T P A L E T T E
3560
3561 offset = 8;
3562
3563 for (i = 0; i < ncolor; i++) {
3564 rr = red[i]/255.;
3565 gg = green[i]/255.;
3566 bb = blue[i]/255.;
3567 j = i+offset;
3568 SetRGB(j,rr,gg,bb);
3569 }
3570
3571 // O U T P U T I M A G E
3572
3573 for (i = 1; i <= height/2; i++) {
3574 j1 = pixArr + (i-1)*width;
3575 j2 = pixArr + (height-i)*width;
3576 for (k = 0; k < width; k++) {
3577 icol = *j1; *j1++ = *j2; *j2++ = icol;
3578 }
3579 }
3580 if (id) pic = CreatePixmap(id, width, height);
3581 PutImage(offset,-1,x0,y0,width,height,0,0,width-1,height-1,pixArr,pic);
3582
3583 free(gifArr);
3584 free(pixArr);
3585
3586 if (pic)
3587 return pic;
3588 else if (gCws->fDrawing)
3589 return (Pixmap_t)gCws->fDrawing;
3590 return 0;
3591}
3592
3593////////////////////////////////////////////////////////////////////////////////
3594/// Returns an array of pixels created from a part of drawable (defined by x, y, w, h)
3595/// in format:
3596/// `b1, g1, r1, 0, b2, g2, r2, 0 ... bn, gn, rn, 0 ..`
3597///
3598/// Pixels are numbered from left to right and from top to bottom.
3599/// By default all pixels from the whole drawable are returned.
3600///
3601/// Note that return array is 32-bit aligned
3602
3603unsigned char *TGX11::GetColorBits(Drawable_t /*wid*/, Int_t /*x*/, Int_t /*y*/,
3604 UInt_t /*w*/, UInt_t /*h*/)
3605{
3606 return 0;
3607}
3608
3609////////////////////////////////////////////////////////////////////////////////
3610/// create pixmap from RGB data. RGB data is in format :
3611/// b1, g1, r1, 0, b2, g2, r2, 0 ... bn, gn, rn, 0 ..
3612///
3613/// Pixels are numbered from left to right and from top to bottom.
3614/// Note that data must be 32-bit aligned
3615
3616Pixmap_t TGX11::CreatePixmapFromData(unsigned char * /*bits*/, UInt_t /*width*/,
3617 UInt_t /*height*/)
3618{
3619 return (Pixmap_t)0;
3620}
3621
3622////////////////////////////////////////////////////////////////////////////////
3623/// Register pixmap created by gVirtualGL
3624///
3625/// \param [in] pixid Pixmap identifier
3626/// \param [in] w,h Width and height of the pixmap
3627///
3628/// register new pixmap
3629
3631{
3632 Int_t wid = 0;
3633
3634 // Select next free window number
3635 for (; wid < fMaxNumberOfWindows; ++wid)
3636 if (!fWindows[wid].fOpen)
3637 break;
3638
3639 if (wid == fMaxNumberOfWindows) {
3640 Int_t newsize = fMaxNumberOfWindows + 10;
3641 fWindows = (XWindow_t*) TStorage::ReAlloc(
3642 fWindows, newsize * sizeof(XWindow_t),
3643 fMaxNumberOfWindows*sizeof(XWindow_t)
3644 );
3645
3646 for (Int_t i = fMaxNumberOfWindows; i < newsize; ++i)
3647 fWindows[i].fOpen = 0;
3648
3649 fMaxNumberOfWindows = newsize;
3650 }
3651
3652 fWindows[wid].fOpen = 1;
3653 gCws = fWindows + wid;
3654 gCws->fWindow = pixid;
3655 gCws->fDrawing = gCws->fWindow;
3656 gCws->fBuffer = 0;
3657 gCws->fDoubleBuffer = 0;
3658 gCws->fIsPixmap = 1;
3659 gCws->fClip = 0;
3660 gCws->fWidth = w;
3661 gCws->fHeight = h;
3662 gCws->fNewColors = 0;
3663 gCws->fShared = kFALSE;
3664
3665 return wid;
3666}
3667
3668////////////////////////////////////////////////////////////////////////////////
3669/// Returns 1 if window system server supports extension given by the
3670/// argument, returns 0 in case extension is not supported and returns -1
3671/// in case of error (like server not initialized).
3672/// Examples:
3673/// - "Apple-WM" - does server run on MacOS X;
3674/// - "XINERAMA" - does server support Xinerama.
3675/// See also the output of xdpyinfo.
3676
3677Int_t TGX11::SupportsExtension(const char *ext) const
3678{
3679 Int_t major_opcode, first_event, first_error;
3680 if (!(Display*)fDisplay)
3681 return -1;
3682 return XQueryExtension((Display*)fDisplay, ext, &major_opcode, &first_event, &first_error);
3683}
Handle_t Pixmap_t
Definition: GuiTypes.h:29
Handle_t Drawable_t
Definition: GuiTypes.h:30
Handle_t Window_t
Definition: GuiTypes.h:28
ROOT::R::TRInterface & r
Definition: Object.C:4
#define b(i)
Definition: RSha256.hxx:100
#define c(i)
Definition: RSha256.hxx:101
#define g(i)
Definition: RSha256.hxx:105
#define h(i)
Definition: RSha256.hxx:106
#define R(a, b, c, d, e, f, g, h, i)
Definition: RSha256.hxx:110
const unsigned char gStipples[26][32]
Definition: RStipples.h:26
static const double x2[5]
static const double x1[5]
unsigned short UShort_t
Definition: RtypesCore.h:36
unsigned char Byte_t
Definition: RtypesCore.h:60
int Int_t
Definition: RtypesCore.h:41
const size_t kBitsPerByte
Definition: RtypesCore.h:110
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
int Seek_t
Definition: RtypesCore.h:49
unsigned long ULong_t
Definition: RtypesCore.h:51
long Long_t
Definition: RtypesCore.h:50
short Width_t
Definition: RtypesCore.h:78
bool Bool_t
Definition: RtypesCore.h:59
short Font_t
Definition: RtypesCore.h:75
short Short_t
Definition: RtypesCore.h:35
short Color_t
Definition: RtypesCore.h:79
long long Long64_t
Definition: RtypesCore.h:69
short Style_t
Definition: RtypesCore.h:76
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
include TDocParser_001 C image html pict1_TDocParser_001 png width
Definition: TDocParser.cxx:121
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
unsigned long KeySym
Definition: TGWin32.h:53
XPoint * XRotTextExtents(Display *, XFontStruct *, float, int, int, char *, int)
Calculate the bounding box some text will have when painted.
Definition: Rotated.cxx:1350
static Int_t gFillHollow
Definition: TGX11.cxx:100
static FILE * gOut
Definition: TGX11.cxx:3278
float XRotVersion(char *, int)
Return version/copyright information.
Definition: Rotated.cxx:238
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)
static ULong_t gKeybdMask
Definition: TGX11.cxx:144
void XRotSetMagnification(float)
Set the font magnification factor for all subsequent operations.
Definition: Rotated.cxx:248
static int gCapStyle
Definition: TGX11.cxx:130
static GC * gGCfill
Definition: TGX11.cxx:92
static GC gGCecho
Definition: TGX11.cxx:98
XFontStruct * id
Definition: TGX11.cxx:108
static GC * gGCinvt
Definition: TGX11.cxx:94
static void GetPixel(int y, int width, Byte_t *scline)
Get pixels in line y and put in array scline.
Definition: TGX11.cxx:3293
static Pixmap gFillPattern
Definition: TGX11.cxx:101
static struct @56 gMarker
static Cursor gNullCursor
Definition: TGX11.cxx:154
char name[80]
Definition: TGX11.cxx:109
static XWindow_t * gTws
Definition: TGX11.cxx:81
const int kMAXGC
Definition: TGX11.cxx:88
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
const Int_t kMAXFONT
Definition: TGX11.cxx:106
static int gLineStyle
Definition: TGX11.cxx:129
const char null_cursor_bits[]
Definition: TGX11.cxx:150
int XRotDrawString(Display *, XFontStruct *, float, Drawable, GC, int, int, char *)
A front end to XRotPaintAlignedString: -no alignment, no background.
Definition: Rotated.cxx:292
int n
Definition: TGX11.cxx:121
static char gDashList[10]
Definition: TGX11.cxx:132
static int gDashOffset
Definition: TGX11.cxx:134
const Int_t kBIGGEST_RGB_VALUE
Definition: TGX11.cxx:83
const Int_t kMAXMK
Definition: TGX11.cxx:118
static void PutByte(Byte_t b)
Put byte b in output stream.
Definition: TGX11.cxx:3302
static GC * gGCpxmp
Definition: TGX11.cxx:96
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))
static GC * gGCline
Definition: TGX11.cxx:90
int XRotDrawAlignedImageString(Display *, XFontStruct *, float, Drawable, GC, int, int, char *, int)
A front end to XRotPaintAlignedString: -does alignment, paints background.
Definition: Rotated.cxx:325
static ULong_t gMouseMask
Definition: TGX11.cxx:140
static Int_t gCurrentFontNumber
Definition: TGX11.cxx:113
static int gJoinStyle
Definition: TGX11.cxx:131
static GC gGClist[kMAXGC]
Definition: TGX11.cxx:89
static int gDashLength
Definition: TGX11.cxx:133
static GC * gGCdash
Definition: TGX11.cxx:95
static GC * gGCmark
Definition: TGX11.cxx:91
int type
Definition: TGX11.cxx:120
static GC * gGCtext
Definition: TGX11.cxx:93
int XRotDrawAlignedString(Display *, XFontStruct *, float, Drawable, GC, int, int, char *, int)
A front end to XRotPaintAlignedString: -does alignment, no background.
Definition: Rotated.cxx:314
int XRotDrawImageString(Display *, XFontStruct *, float, Drawable, GC, int, int, char *)
A front end to XRotPaintAlignedString: -no alignment, paints background.
Definition: Rotated.cxx:303
static int gDashSize
Definition: TGX11.cxx:135
static int gLineWidth
Definition: TGX11.cxx:128
static XImage * gXimage
Definition: TGX11.cxx:3279
XPoint xy[kMAXMK]
Definition: TGX11.cxx:122
static struct @55 gFont[kMAXFONT]
static XFontStruct * gTextFont
Definition: TGX11.cxx:112
void XRotSetBoundingBoxPad(int)
Set the padding used when calculating bounding boxes.
Definition: Rotated.cxx:257
static Int_t DummyX11ErrorHandler(Display *, XErrorEvent *)
Dummy error handler for X11. Used by FindUsableVisual().
Definition: TGX11.cxx:834
static XWindow_t * gCws
Definition: TGX11.cxx:80
int GIFinfo(Byte_t *gifArr, int *Width, int *Height, int *Ncols)
Definition: gifdecode.c:80
XID Colormap
Definition: TGX11.h:38
XID Window
Definition: TGX11.h:39
XID Drawable
Definition: TGX11.h:36
XID Cursor
Definition: TGX11.h:37
float xmin
Definition: THbookFile.cxx:93
float ymin
Definition: THbookFile.cxx:93
float xmax
Definition: THbookFile.cxx:93
float ymax
Definition: THbookFile.cxx:93
const Int_t kNMAX
#define gROOT
Definition: TROOT.h:414
void Printf(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition: TStyle.h:406
ECursor
Definition: TVirtualX.h:44
@ kRightSide
Definition: TVirtualX.h:45
@ kBottomSide
Definition: TVirtualX.h:45
@ kArrowRight
Definition: TVirtualX.h:47
@ kTopLeft
Definition: TVirtualX.h:44
@ kBottomRight
Definition: TVirtualX.h:44
@ kArrowVer
Definition: TVirtualX.h:46
@ kCaret
Definition: TVirtualX.h:47
@ kTopSide
Definition: TVirtualX.h:45
@ kLeftSide
Definition: TVirtualX.h:45
@ kWatch
Definition: TVirtualX.h:47
@ kMove
Definition: TVirtualX.h:46
@ kTopRight
Definition: TVirtualX.h:44
@ kBottomLeft
Definition: TVirtualX.h:44
@ kHand
Definition: TVirtualX.h:46
@ kCross
Definition: TVirtualX.h:46
@ kRotate
Definition: TVirtualX.h:46
@ kNoDrop
Definition: TVirtualX.h:47
@ kArrowHor
Definition: TVirtualX.h:46
@ kPointer
Definition: TVirtualX.h:47
const int kNumCursors
Definition: TVirtualX.h:43
#define free
Definition: civetweb.c:1539
#define calloc
Definition: civetweb.c:1537
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
Style_t fFillStyle
Fill area style.
Definition: TAttFill.h:23
Color_t fFillColor
Fill area color.
Definition: TAttFill.h:22
Width_t fLineWidth
Line width.
Definition: TAttLine.h:23
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
Style_t fLineStyle
Line style.
Definition: TAttLine.h:22
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition: TAttMarker.h:38
Size_t fMarkerSize
Marker size.
Definition: TAttMarker.h:24
Style_t fMarkerStyle
Marker style.
Definition: TAttMarker.h:23
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition: TAttText.h:41
Float_t fTextAngle
Text angle.
Definition: TAttText.h:21
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
Definition: TAttText.h:43
Font_t fTextFont
Text font.
Definition: TAttText.h:25
Float_t fTextSize
Text size.
Definition: TAttText.h:22
The color creation and management class.
Definition: TColor.h:19
Float_t GetRed() const
Definition: TColor.h:57
Float_t GetBlue() const
Definition: TColor.h:59
Float_t GetGreen() const
Definition: TColor.h:58
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
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:411
This class stores a (key,value) pair using an external hash.
Definition: TExMap.h:33
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:87
Long64_t GetValue(ULong64_t hash, Long64_t key)
Return the value belonging to specified key and hash value.
Definition: TExMap.cxx:173
This class is the basic interface to the X11 (Xlib) graphics system.
Definition: TGX11.h:83
void * fDisplay
Pointer to display.
Definition: TGX11.h:128
void QueryPointer(Int_t &ix, Int_t &iy)
Query pointer position.
Definition: TGX11.cxx:1449
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:2959
Colormap fColormap
Default colormap, 0 if b/w.
Definition: TGX11.h:132
virtual void GetTextExtent(UInt_t &w, UInt_t &h, char *mess)
Return the size of a character string.
Definition: TGX11.cxx:1043
Int_t fScreenNumber
Screen number.
Definition: TGX11.h:135
void SetDoubleBufferOFF()
Turn double buffer mode off.
Definition: TGX11.cxx:2119
void SetTextColor(Color_t cindex)
Set color index for text.
Definition: TGX11.cxx:3110
void SelectWindow(Int_t wid)
Select window to which subsequent output is directed.
Definition: TGX11.cxx:1953
void DrawPolyLine(Int_t n, TPoint *xy)
Draw a line through all points.
Definition: TGX11.cxx:619
void SetLineType(Int_t n, Int_t *dash)
Set line type.
Definition: TGX11.cxx:2292
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:2934
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:1077
ULong_t fWhitePixel
Value of white pixel in colormap.
Definition: TGX11.h:134
Cursor fCursors[kNumCursors]
List of cursors.
Definition: TGX11.h:89
Bool_t AllocColor(Colormap cmap, RXColor *color)
Allocate color in colormap.
Definition: TGX11.cxx:361
Int_t fTextAlignV
Text Alignment Vertical.
Definition: TGX11.h:137
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
Int_t fBlueShift
Bits to left shift blue.
Definition: TGX11.h:148
void ClosePixmap()
Delete current pixmap.
Definition: TGX11.cxx:434
void SetDoubleBufferON()
Turn double buffer mode on.
Definition: TGX11.cxx:2129
void GetCharacterUp(Float_t &chupx, Float_t &chupy)
Return character up vector.
Definition: TGX11.cxx:894
void Warp(Int_t ix, Int_t iy, Window_t id=0)
Set pointer position.
Definition: TGX11.cxx:3246
void SetTextAlign(Short_t talign=11)
Set text alignment.
Definition: TGX11.cxx:3053
void RescaleWindow(Int_t wid, UInt_t w, UInt_t h)
Rescale the window wid.
Definition: TGX11.cxx:1836
Window_t GetWindowID(Int_t wid)
Return the X11 window identifier.
Definition: TGX11.cxx:1063
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
void SetCursor(Int_t win, ECursor cursor)
Set the cursor.
Definition: TGX11.cxx:2071
void Sync(Int_t mode)
Set synchronisation on or off.
Definition: TGX11.cxx:3200
void * GetGC(Int_t which) const
Return desired Graphics Context ("which" maps directly on gGCList[]).
Definition: TGX11.cxx:926
void MoveWindow(Int_t wid, Int_t x, Int_t y)
Move the window wid.
Definition: TGX11.cxx:1075
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:3603
void SetMarkerSize(Float_t markersize)
Set marker size index.
Definition: TGX11.cxx:2390
void SetDrawMode(EDrawMode mode)
Set the drawing mode.
Definition: TGX11.cxx:2154
Int_t AddPixmap(ULong_t pixid, UInt_t w, UInt_t h)
Register pixmap created by gVirtualGL.
Definition: TGX11.cxx:3630
Bool_t fHasXft
True when XftFonts are used.
Definition: TGX11.h:150
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:3263
void DrawBox(Int_t x1, Int_t y1, Int_t x2, Int_t y2, EBoxMode mode)
Draw a box.
Definition: TGX11.cxx:520
void ClearPixmap(Drawable *pix)
Clear the pixmap pix.
Definition: TGX11.cxx:402
Float_t fTextMagnitude
Text Magnitude.
Definition: TGX11.h:141
void SetCharacterUp(Float_t chupx, Float_t chupy)
Set character up vector.
Definition: TGX11.cxx:1978
Drawable fRootWin
Root window used as parent of all windows.
Definition: TGX11.h:130
void SetMarkerStyle(Style_t markerstyle)
Set marker style.
Definition: TGX11.cxx:2430
virtual ~TGX11()
Destructor.
Definition: TGX11.cxx:319
void DrawFillArea(Int_t n, TPoint *xy)
Fill area described by polygon.
Definition: TGX11.cxx:584
void SetInput(Int_t inp)
Set input on or off.
Definition: TGX11.cxx:2252
void RemoveWindow(ULong_t qwid)
Remove a window created by Qt (like CloseWindow1()).
Definition: TGX11.cxx:1417
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
Int_t fTextAlignH
Text Alignment Horizontal.
Definition: TGX11.h:136
void * fXEvent
Current native (X11) event.
Definition: TGX11.h:90
ULong_t GetPixel(Color_t cindex)
Return pixel value associated to specified ROOT color number.
Definition: TGX11.cxx:999
Int_t fGreenShift
Bits to left shift green.
Definition: TGX11.h:147
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
void SetOpacity(Int_t percent)
Set opacity of a window.
Definition: TGX11.cxx:2869
void SetFillColor(Color_t cindex)
Set color index for fill areas.
Definition: TGX11.cxx:2178
Pixmap_t CreatePixmapFromData(unsigned char *bits, UInt_t width, UInt_t height)
create pixmap from RGB data.
Definition: TGX11.cxx:3616
Int_t InitWindow(ULong_t window)
Open window and return window number.
Definition: TGX11.cxx:1296
void ClearWindow()
Clear current window.
Definition: TGX11.cxx:417
Int_t WriteGIF(char *name)
Writes the current window into GIF file.
Definition: TGX11.cxx:3372
XColor_t & GetColor(Int_t cid)
Return reference to internal color structure associated to color index cid.
Definition: TGX11.cxx:904
Int_t fBlueDiv
Blue value divider.
Definition: TGX11.h:145
void CopyWindowtoPixmap(Drawable *pix, Int_t xpos, Int_t ypos)
Copy area of current window in the pixmap pix.
Definition: TGX11.cxx:503
void SetLineStyle(Style_t linestyle)
Set line style.
Definition: TGX11.cxx:2318
Drawable fVisRootWin
Root window with fVisual to be used to create GC's and XImages.
Definition: TGX11.h:131
void GetPlanes(Int_t &nplanes)
Get maximum number of planes.
Definition: TGX11.cxx:1014
void SetMarkerColor(Color_t cindex)
Set color index for markers.
Definition: TGX11.cxx:2376
TExMap * fColors
Hash list of colors.
Definition: TGX11.h:88
Int_t fTextAlign
Text alignment (set in SetTextAlign)
Definition: TGX11.h:138
Window_t GetCurrentWindow() const
Return current window pointer. Protected method used by TGX11TTF.
Definition: TGX11.cxx:917
void SetMarkerType(Int_t type, Int_t n, RXPoint *xy)
Set marker type.
Definition: TGX11.cxx:2415
Int_t fRedDiv
Red value divider, -1 if no TrueColor visual.
Definition: TGX11.h:143
Int_t fDepth
Number of color planes.
Definition: TGX11.h:142
void ResizeWindow(Int_t wid)
Resize the current window if necessary.
Definition: TGX11.cxx:1914
void CloseWindow()
Delete current window.
Definition: TGX11.cxx:442
void CloseWindow1()
Delete current window.
Definition: TGX11.cxx:456
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:3677
ULong_t fBlackPixel
Value of black pixel in colormap.
Definition: TGX11.h:133
const char * DisplayName(const char *dpyName=0)
Return hostname on which the display is opened.
Definition: TGX11.cxx:991
Float_t fCharacterUpX
Character Up vector along X.
Definition: TGX11.h:139
Int_t fGreenDiv
Green value divider.
Definition: TGX11.h:144
Int_t RequestLocator(Int_t mode, Int_t ctyp, Int_t &x, Int_t &y)
Request Locator position.
Definition: TGX11.cxx:1500
void UpdateWindow(Int_t mode)
Update display.
Definition: TGX11.cxx:3223
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
TGX11()
Default constructor.
Definition: TGX11.cxx:168
Bool_t Init(void *display)
Initialize X11 system. Returns kFALSE in case of failure.
Definition: TGX11.cxx:337
void DrawLine(Int_t x1, Int_t y1, Int_t x2, Int_t y2)
Draw a line.
Definition: TGX11.cxx:603
Int_t OpenPixmap(UInt_t w, UInt_t h)
Open a new pixmap.
Definition: TGX11.cxx:1238
Int_t fRedShift
Bits to left shift red, -1 if no TrueColor visual.
Definition: TGX11.h:146
virtual void SetTextSize(Float_t textsize)
Set current text size.
Definition: TGX11.cxx:3188
Int_t OpenDisplay(void *display)
Open the display. Return -1 if the opening fails, 0 when ok.
Definition: TGX11.cxx:1086
Int_t ResizePixmap(Int_t wid, UInt_t w, UInt_t h)
Resize a pixmap.
Definition: TGX11.cxx:1870
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
void RemovePixmap(Drawable *pix)
Remove the pixmap pix.
Definition: TGX11.cxx:1467
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
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:3500
Int_t fMaxNumberOfWindows
Maximum number of windows.
Definition: TGX11.h:86
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:3316
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
Int_t FindColor(ULong_t pixel, ULong_t *orgcolors, Int_t ncolors)
Returns index in orgcolors (and fNewColors) for pixel.
Definition: TGX11.cxx:3004
void SetFillStyleIndex(Int_t style, Int_t fasi)
Set fill area style index.
Definition: TGX11.cxx:2209
RVisual * fVisual
Pointer to visual used by all windows.
Definition: TGX11.h:129
void SetClipOFF(Int_t wid)
Turn off the clipping for the window wid.
Definition: TGX11.cxx:1999
virtual Int_t SetTextFont(char *fontname, ETextSetMode mode)
Set text font to specified name.
Definition: TGX11.cxx:3139
void SetFillStyle(Style_t style)
Set fill area style.
Definition: TGX11.cxx:2197
void SetLineWidth(Width_t width)
Set line width.
Definition: TGX11.cxx:2357
XWindow_t * fWindows
List of windows.
Definition: TGX11.h:87
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:3435
void FindBestVisual()
Find best visual, i.e.
Definition: TGX11.cxx:775
void SetRGB(Int_t cindex, Float_t r, Float_t g, Float_t b)
Set color intensities for given color index.
Definition: TGX11.cxx:3020
void SetColor(void *gc, Int_t ci)
Set the foreground color in GC.
Definition: TGX11.cxx:2038
void SetDoubleBuffer(Int_t wid, Int_t mode)
Set the double buffer on/off on window wid.
Definition: TGX11.cxx:2086
void SetLineColor(Color_t cindex)
Set color index for lines.
Definition: TGX11.cxx:2271
void GetRGB(Int_t index, Float_t &r, Float_t &g, Float_t &b)
Get rgb values for color "index".
Definition: TGX11.cxx:1022
Int_t GetDoubleBuffer(Int_t wid)
Query the double buffer value for the window wid.
Definition: TGX11.cxx:938
Float_t fCharacterUpY
Character Up vector along Y.
Definition: TGX11.h:140
Bool_t fHasTTFonts
True when TrueType fonts are used.
Definition: TGX11.h:149
void DrawPolyMarker(Int_t n, TPoint *xy)
Draw n markers with the current attributes at position x, y.
Definition: TGX11.cxx:671
Int_t RequestString(Int_t x, Int_t y, char *text)
Request a string.
Definition: TGX11.cxx:1678
An array of TObjects.
Definition: TObjArray.h:37
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:522
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
Collectable string class.
Definition: TObjString.h:28
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
Definition: TPoint.h:31
static void * Alloc(size_t size)
Allocate a block of memory, that later can be resized using TStorage::ReAlloc().
Definition: TStorage.cxx:152
static void * ReAlloc(void *vp, size_t size)
Reallocate (i.e.
Definition: TStorage.cxx:183
static void Dealloc(void *ptr)
De-allocate block of memory, that was allocated via TStorage::Alloc().
Definition: TStorage.cxx:170
Basic string class.
Definition: TString.h:131
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2197
const char * GetLineStyleString(Int_t i=1) const
Return line style string (used by PostScript).
Definition: TStyle.cxx:970
Semi-Abstract base class defining a generic interface to the underlying, low level,...
Definition: TVirtualX.h:53
EDrawMode fDrawMode
Definition: TVirtualX.h:62
TPaveText * pt
TText * text
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
#define G(x, y, z)
static double B[]
static constexpr double L
Double_t ACos(Double_t)
Definition: TMath.h:656
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:212
Double_t Sqrt(Double_t x)
Definition: TMath.h:679
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
constexpr Double_t Pi()
Definition: TMath.h:38
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
Definition: file.py:1
const char * False
const char * True
Description of a X11 color.
Definition: TGWin32.h:59
Bool_t fDefined
true if pixel value is defined
Definition: TGWin32.h:61
UShort_t fBlue
blue value
Definition: TGX11.h:75
UShort_t fRed
red value in range [0,kBIGGEST_RGB_VALUE]
Definition: TGX11.h:73
UShort_t fGreen
green value
Definition: TGX11.h:74
ULong_t fPixel
color pixel value
Definition: TGX11.h:72
TCanvas * style()
Definition: style.C:1
auto * m
Definition: textangle.C:8
#define org(otri, vertexptr)
Definition: triangle.c:1037