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