X11workbench Toolkit  1.0
graphical_api.c
Go to the documentation of this file.
1 // //
3 // _ _ _ _ //
4 // __ _ _ __ __ _ _ __ | |__ (_) ___ __ _ | | __ _ _ __ (_) ___ //
5 // / _` || '__|/ _` || '_ \ | '_ \ | | / __|/ _` || | / _` || '_ \ | | / __| //
6 // | (_| || | | (_| || |_) || | | || || (__| (_| || | | (_| || |_) || | _| (__ //
7 // \__, ||_| \__,_|| .__/ |_| |_||_| \___|\__,_||_|_____\__,_|| .__/ |_|(_)\___| //
8 // |___/ |_| |_____| |_| //
9 // //
10 // //
11 // Graphical API 'wrapper' functions, an X11-style API for cross-platform //
12 // //
14 
15 /*****************************************************************************
16 
17  X11workbench - X11 programmer's 'work bench' application and toolkit
18  Copyright (c) 2010-2019 by Bob Frazier (aka 'Big Bad Bombastic Bob')
19 
20 
21  DISCLAIMER: The X11workbench application and toolkit software are supplied
22  'as-is', with no warranties, either implied or explicit.
23  Any claims to alleged functionality or features should be
24  considered 'preliminary', and might not function as advertised.
25 
26  MIT-like license:
27 
28  There is no restriction as to what you can do with this software, so long
29  as you include the above copyright notice and DISCLAIMER for any distributed
30  work that is equal to or derived from this one, along with this paragraph
31  that explains the terms of the license if the source is also being made
32  available. A "derived work" describes a work that uses a significant portion
33  of the source files or algorithms that are included with this one.
34  Specifically excluded from this are files that were generated by the software,
35  or anything that is included with the software that is part of another package
36  (such as files that were created or added during the 'configure' process).
37  Specifically included is the use of part or all of any of the X11 workbench
38  toolkit source or header files in your distributed application. If you do not
39  ship the source, the above copyright statement is still required to be placed
40  in a reasonably prominent place, such as documentation, splash screens, and/or
41  'about the application' dialog boxes.
42 
43  Use and distribution are in accordance with GPL, LGPL, and/or the above
44  MIT-like license. See COPYING and README files for more information.
45 
46 
47  Additional information at http://sourceforge.net/projects/X11workbench
48 
49 ******************************************************************************/
50 
51 
60 #include <stdio.h>
61 #include <stdlib.h>
62 #include <stdarg.h>
63 #include <limits.h>
64 #include <unistd.h>
65 #include <memory.h>
66 #include <string.h>
67 #include <strings.h>
68 #include <signal.h>
69 #include <time.h>
70 #include <fcntl.h>
71 #include <errno.h>
72 #include <sys/time.h> // for 'gettimeofday'
73 
74 // TODO: determine if pthread is available, optionally use for timers
75 #include <pthread.h> /* currently required */
76 
77 #include <X11/cursorfont.h>
78 #ifndef XK_Delete /* moslty for interix */
79 #define XK_MISCELLANY /* mostly for interix */
80 #include <X11/keysymdef.h> // some platforms don't automatically include this with X headers
81 #endif // XK_Delete
82 
83 #include "window_helper.h" /* contains definitions for functions implemented here */
84 #include "pixmap_helper.h"
85 #include "conf_help.h"
86 
87 
88 static XImage *__internalGetClipImage(WBGC hGC)
89 {
90 XImage *pRval = NULL;
91 Display *display = hGC->display;
92 const XGCValues *pGCValues = &(hGC->values);
93 
94 
95  if(pGCValues->clip_mask != None)
96  {
97  Window winRoot = None;
98  int iX0=0, iY0=0;
99  unsigned int iWidth0=0, iHeight0=0, iBorder;
100  unsigned int uiDepth = 0;
101 
102  // create a pixmap from the clip mask
103  // TODO: cache all of this someplace?
104 
106  XGetGeometry(display, pGCValues->clip_mask, &winRoot, &iX0, &iY0, &iWidth0, &iHeight0, &iBorder, &uiDepth);
108 
109  // clip region will translate into 1-plane XYPixmap, from a 1-plane Pixmap
110  // hopefully this is a REALLY FAST EFFICIENT process. Otherwise, this could suck for performance.
111 
112  // TODO: wrap the 'GC' as a WB_GC and cache a few things *LIKE* the clip region as an XImage
113  // This might actually work out better since I'd be avoiding a few arcane things and focusing
114  // on providing a way to do graphics operations compatible with WIN32
115 
116  pRval = WBXGetImage(display, pGCValues->clip_mask, 0, 0, iWidth0, iHeight0, 1, XYPixmap);
117  }
118 
119  return pRval;
120 }
121 
122 
123 
124 int WBDrawPoint(Display *display, Drawable d, WBGC gc, int x, int y)
125 {
126 int iRval;
127 
128 #ifdef WIN32
129 #error not ready for WIN32 yet
130 #else // WIN32
131 
132 XImage *pImage;
133 
134  if(!display)
135  {
136  display = WBGetWindowDisplay((Window)d);
137  }
138 
139  // if it's a window, I'll get its XImage. If NULL, do it the old way
140 
141  pImage = WBGetWindowImage(display, d);
142 
143  if(!pImage)
144  {
146  iRval = XDrawPoint(display, d, gc->gc, x, y);
148  }
149  else
150  {
151  iRval = WBXDrawPoint(pImage, gc, x, y);
152  }
153 
154 #endif // WIN32
155 
156  return iRval;
157 }
158 
159 
160 int WBDrawPoints(Display *display, Drawable d, WBGC gc, XPoint *points,
161  int npoints, int mode)
162 {
163 int iRval;
164 
165 #ifdef WIN32
166 #error not ready for WIN32 yet
167 #else // WIN32
168 
169 XImage *pImage;
170 
171  if(!display)
172  {
173  display = WBGetWindowDisplay((Window)d);
174  }
175 
176  // if it's a window, I'll get its XImage. If NULL, do it the old way
177 
178  pImage = WBGetWindowImage(display, d);
179 
180  if(!pImage)
181  {
183  iRval = XDrawPoints(display, d, gc->gc, points, npoints, mode);
185  }
186  else
187  {
188  iRval = WBXDrawPoints(pImage, gc, points, npoints, mode);
189  }
190 
191 #endif // WIN32
192 
193  return iRval;
194 }
195 
196 
197 int WBDrawLine(Display *display, Drawable d, WBGC gc,
198  int x1, int y1, int x2, int y2)
199 {
200 int iRval;
201 
202 #ifdef WIN32
203 #error not ready for WIN32 yet
204 #else // WIN32
205 
206 XImage *pImage;
207 
208  if(!display)
209  {
210  display = WBGetWindowDisplay((Window)d);
211  }
212 
213  // if it's a window, I'll get its XImage. If NULL, do it the old way
214 
215  pImage = WBGetWindowImage(display, d);
216 
217  if(!pImage)
218  {
220  iRval = XDrawLine(display, d, gc->gc, x1, y1, x2, y2);
222  }
223  else
224  {
225  iRval = WBXDrawLine(pImage, gc, x1, y1, x2, y2);
226  }
227 
228 #endif // WIN32
229 
230  return iRval;
231 }
232 
233 
234 int WBDrawLines(Display *display, Drawable d, WBGC gc, XPoint *points,
235  int npoints, int mode)
236 {
237 int iRval;
238 
239 #ifdef WIN32
240 #error not ready for WIN32 yet
241 #else // WIN32
242 
243 XImage *pImage;
244 
245  if(!display)
246  {
247  display = WBGetWindowDisplay((Window)d);
248  }
249 
250  // if it's a window, I'll get its XImage. If NULL, do it the old way
251 
252  pImage = WBGetWindowImage(display, d);
253 
254  if(!pImage)
255  {
257  iRval = XDrawLines(display, d, gc->gc, points, npoints, mode);
259  }
260  else
261  {
262  iRval = WBXDrawLines(pImage, gc, points, npoints, mode);
263  }
264 
265 #endif // WIN32
266 
267  return iRval;
268 }
269 
270 
271 int WBDrawRectangle(Display *display, Drawable d, WBGC gc, int x, int y,
272  unsigned int width, unsigned int height)
273 {
274 int iRval;
275 
276 #ifdef WIN32
277 #error not ready for WIN32 yet
278 #else // WIN32
279 
280 XImage *pImage;
281 
282  if(!display)
283  {
284  display = WBGetWindowDisplay((Window)d);
285  }
286 
287  // if it's a window, I'll get its XImage. If NULL, do it the old way
288 
289  pImage = WBGetWindowImage(display, d);
290 
291  if(!pImage)
292  {
294  iRval = XDrawRectangle(display, d, gc->gc, x, y, width, height);
296  }
297  else
298  {
299  iRval = WBXDrawRectangle(pImage, gc, x, y, width, height);
300  }
301 
302 #endif // WIN32
303 
304  return iRval;
305 }
306 
307 
308 int WBFillRectangle(Display *display, Drawable d, WBGC gc, int x, int y,
309  unsigned int width, unsigned int height)
310 {
311 int iRval;
312 
313 #ifdef WIN32
314 #error not ready for WIN32 yet
315 #else // WIN32
316 
317 XImage *pImage;
318 
319  if(!display)
320  {
321  display = WBGetWindowDisplay((Window)d);
322  }
323 
324  // if it's a window, I'll get its XImage. If NULL, do it the old way
325 
326  pImage = WBGetWindowImage(display, d);
327 
328  if(!pImage)
329  {
331  iRval = XFillRectangle(display, d, gc->gc, x, y, width, height);
333  }
334  else
335  {
336  iRval = WBXFillRectangle(pImage, gc, x, y, width, height);
337  }
338 
339 #endif // WIN32
340 
341  return iRval;
342 }
343 
344 
345 int WBDrawArc(Display *display, Drawable d, WBGC gc, int x, int y,
346  unsigned int width, unsigned int height,
347  int angle1, int angle2)
348 {
349 int iRval;
350 
351 #ifdef WIN32
352 #error not ready for WIN32 yet
353 #else // WIN32
354 
355 XImage *pImage;
356 
357  if(!display)
358  {
359  display = WBGetWindowDisplay((Window)d);
360  }
361 
362  // if it's a window, I'll get its XImage. If NULL, do it the old way
363 
364  pImage = WBGetWindowImage(display, d);
365 
366  if(!pImage)
367  {
369  iRval = XDrawArc(display, d, gc->gc, x, y, width, height, angle1, angle2);
371  }
372  else
373  {
374  iRval = WBXDrawArc(pImage, gc, x, y, width, height, angle1, angle2);
375  }
376 
377 #endif // WIN32
378 
379  return iRval;
380 }
381 
382 
383 int WBFillArc(Display *display, Drawable d, WBGC gc, int x, int y,
384  unsigned int width, unsigned int height,
385  int angle1, int angle2)
386 {
387 int iRval;
388 
389 #ifdef WIN32
390 #error not ready for WIN32 yet
391 #else // WIN32
392 
393 XImage *pImage;
394 
395  if(!display)
396  {
397  display = WBGetWindowDisplay((Window)d);
398  }
399 
400  // if it's a window, I'll get its XImage. If NULL, do it the old way
401 
402  pImage = WBGetWindowImage(display, d);
403 
404  if(!pImage)
405  {
407  iRval = XFillArc(display, d, gc->gc, x, y, width, height, angle1, angle2);
409  }
410  else
411  {
412  iRval = WBXFillArc(pImage, gc, x, y, width, height, angle1, angle2);
413  }
414 
415 #endif // WIN32
416 
417  return iRval;
418 }
419 
420 
421 int WBFillPolygon(Display *display, Drawable d, WBGC gc, XPoint *points,
422  int npoints, int shape, int mode)
423 {
424 int iRval;
425 
426 #ifdef WIN32
427 #error not ready for WIN32 yet
428 #else // WIN32
429 
430 XImage *pImage;
431 
432  if(!display)
433  {
434  display = WBGetWindowDisplay((Window)d);
435  }
436 
437  // if it's a window, I'll get its XImage. If NULL, do it the old way
438 
439  pImage = WBGetWindowImage(display, d);
440 
441  if(!pImage)
442  {
444  iRval = XFillPolygon(display, d, gc->gc, points, npoints, shape, mode);
446  }
447  else
448  {
449  iRval = WBXFillPolygon(pImage, gc, points, npoints, shape, mode);
450  }
451 
452 #endif // WIN32
453 
454  return iRval;
455 }
456 
457 
458 int WBDrawString(Display *display, Drawable d, WBGC gc, int x, int y,
459  const char *string, int length)
460 {
461 int iRval = 0;
462 
463 #ifdef WIN32
464 #error not ready for WIN32 yet
465 #else // WIN32
466 
467 XImage *pImage;
468 
469  // if it's a window, I'll get its XImage. If NULL, do it the old way
470 
471  pImage = WBGetWindowImage(display, d);
472 
473  if(!display)
474  {
475  display = WBGetWindowDisplay((Window)d);
476  }
477 
478  if(!pImage)
479  {
480  char *pTemp;
481 
482  pTemp = WBAlloc(length + 1);
483  if(!pTemp)
484  {
485  return -1;
486  }
487 
488  memcpy(pTemp, string, length);
489  pTemp[length] = 0;
490 
491  // for now do this - but I should make it a call to DTDrawString instead
492 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
493  if(gc->pFont && gc->pFont->pxftFont)
494  {
495  iRval = 0; // for now
496 #warning TODO: IMPLEMENT THIS PART for Xft FONTS
497  }
498  else
499 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
500  if(gc->pFont && gc->pFont->fsFont)
501  {
502  WB_DEBUG_PRINT(DebugLevel_Verbose | DebugSubSystem_DrawText,
503  "%s.%d using WB_DRAW_STRING for \"%-.*s\" color=#%08lxH bkgnd=#%08lxH\n",
504  __FUNCTION__, __LINE__, length, pTemp,
506 
508  WB_DRAW_STRING(display, d, gc->pFont->fsFont, gc->gc, x, y, pTemp, length);
510  iRval = length; // assume it worked
511  }
512  else // using legacy X11 fonts
513  {
514  if(gc->pFont && gc->pFont->pFontStruct && gc->pFont->pFontStruct->fid != None)
515  {
516  // if GC font is not this one, assign it to this one
517  if(!gc->pFont || gc->values.font != gc->pFont->pFontStruct->fid)
518  {
520  XChangeGC(gc->display, gc->gc, GCFont, &(gc->values));
521  XGetGCValues(gc->display, gc->gc,
522  (GCAll & ~(GCClipMask | GCDashList)), // clip mask and dash mask can't be requested
523  &(gc->values)); // query them all to snapshot them
525  }
526  }
527 
528  WB_DEBUG_PRINT(DebugLevel_Verbose | DebugSubSystem_DrawText,
529  "%s.%d using XDrawString for \"%-.*s\" color=#%08lxH bkgnd=#%08lxH\n",
530  __FUNCTION__, __LINE__, length, pTemp,
532 
534  iRval = XDrawString(display, d, gc->gc, x, y, pTemp, length);
536  }
537 
538  WBFree(pTemp);
539  }
540  else
541  {
542  iRval = WBXDrawString(pImage, gc->pFont, gc, x, y, string, length);
543  // NOTE: does not update immediately, but after you 'end paint'
544  }
545 
546 #endif // WIN32
547 
548  return iRval;
549 }
550 
551 
552 
553 
554 
556 // ____ _ _ ____ _ _ //
557 // / ___| _ __ __ _ _ __ | |__ (_) ___ ___ / ___| ___ _ __ | |_ ___ __ __| |_ //
558 // | | _ | '__|/ _` || '_ \ | '_ \ | | / __|/ __| | | / _ \ | '_ \ | __|/ _ \\ \/ /| __| //
559 // | |_| || | | (_| || |_) || | | || || (__ \__ \ | |___| (_) || | | || |_| __/ > < | |_ //
560 // \____||_| \__,_|| .__/ |_| |_||_| \___||___/ \____|\___/ |_| |_| \__|\___|/_/\_\ \__| //
561 // |_| //
563 
564 
565 WBGC WBCreateGC(Display *pDisplay, Drawable dw, unsigned long valuemask,
566  const XGCValues *values)
567 {
568 WBGC pRval;
569 
570 
571  pRval = (WBGC)WBAlloc(sizeof(*pRval)); // WBGC is a pointer, don't use 'sizeof' on that!!!
572  if(!pRval)
573  {
574  return NULL;
575  }
576 
577  if(!pDisplay)
578  {
579  pDisplay = WBGetDefaultDisplay();
580  }
581 
582  if(dw == None)
583  {
584  dw = WBGetHiddenHelperWindow(); // basically I need to have something valid for a Drawable
585  }
586 
587  memset(pRval, 0, sizeof(*pRval));
588 
589  // TEMPORARILY, use 'pRval->values' to cache what I have in 'values' becauswe it's read-only
590  if(valuemask && values)
591  {
592  memcpy(&(pRval->values), values, sizeof(pRval->values));
593  }
594 
595  pRval->display = pDisplay;
596  pRval->dw = dw;
597 
599  // if 'values' is NULL, pass NULL; otherwise, address to pRval->values
600  pRval->gc = XCreateGC(pDisplay, dw, valuemask, valuemask && values ? &(pRval->values) : NULL);
602 
603  if(pRval->gc == None)
604  {
605  WBFree(pRval);
606  return NULL;
607  }
608 
609  // now re-get 'values' structure based on what was assigned...
610  memset(&(pRval->values), 0, sizeof(pRval->values)); // must do this first
611 
613  XGetGCValues(pDisplay, pRval->gc,
614  (GCAll & ~(GCClipMask | GCDashList)), // clip mask and dash mask can't be requested
615  &(pRval->values)); // query them all to snapshot them
617 
618  // From the 'man' page: an invalid resource ID (with one or more of the three most significant
619  // bits set to 1) will be returned for GCFont, GCTile, and GCStipple if the
620  // component has never been explicitly set by the client.
621 
622  if((CARD32)pRval->values.font & 0xe0000000) // not valid?
623  {
624  pRval->values.font = None;
625  }
626 
627  if((CARD32)pRval->values.tile & 0xe0000000) // not valid?
628  {
629  pRval->values.tile = None;
630  }
631 
632  if((CARD32)pRval->values.stipple & 0xe0000000) // not valid?
633  {
634  pRval->values.stipple = None;
635  }
636 
637  // NOTE: this really shouldn't be affected, but...
638  if((CARD32)pRval->values.clip_mask & 0xe0000000) // not valid?
639  {
640  WB_ERROR_PRINT("ERROR - %s - hGCDest->values.clip_mask not valid, %d (%08xH)\n",
641  __FUNCTION__, (int)pRval->values.clip_mask, (int)pRval->values.clip_mask);
642 
643  pRval->values.clip_mask = None;
644  }
645 
646 
647  // if the original 'values' had a valid clip mask, make a copy of it
648 
649  if(values && (valuemask & GCClipMask) && values->clip_mask != None)
650  {
651  if(values->clip_mask & 0xe0000000) // not valid?
652  {
653  WB_ERROR_PRINT("ERROR - %s - values 'clip_mask' not valid, %d (%08xH)\n",
654  __FUNCTION__, (int)values->clip_mask, (int)values->clip_mask);
655 
656  pRval->values.clip_mask = None;
657  }
658  else
659  {
660  // TODO: is this really the right way to do it??? should I make a copy instead?
661  pRval->values.clip_mask = values->clip_mask; // make a copy
662 
663  // I am setting a clip mask, so cache it as an XImage
664 
665  pRval->clip_image = __internalGetClipImage(pRval);
666 
667  pRval->values.clip_mask = None; // don't share the old clip mask between WBGC's
668 
669  // TODO: should I create a region from it?
670  }
671  }
672 
673  return pRval;
674 }
675 
676 int WBChangeGC(WBGC hGC, unsigned long valuemask,
677  const XGCValues *values)
678 {
679 int iRval;
680 XGCValues valtemp;
681 
682  // if I'm changing something that has a cache, destroy the old one
683  // or the same thing if I can't actually read the value like GCDash, GC
684 
685  if(valuemask & GCDashList)
686  {
687  hGC->values.dashes = values->dashes;
688  }
689 
690  if(valuemask & GCFont)
691  {
692 // if(hGC->pFont && (!values || values->font != hGC->values.font))
693 // {
694 // BEGIN_XCALL_DEBUG_WRAPPER
695 // XFreeFontInfo(NULL, hGC->pFont, 1);
696 // END_XCALL_DEBUG_WRAPPER
697 //
698 // hGC->pFont = NULL;
699 // }
700 // if(hGC->fontset != None && (!values || values->font != hGC->values.font))
701 // {
702 // BEGIN_XCALL_DEBUG_WRAPPER
703 // XFreeFontSet(hGC->display, hGC->fontset);
704 // END_XCALL_DEBUG_WRAPPER
705 //
706 // hGC->fontset = None;
707 // }
708  }
709 
710  if(valuemask & GCTile)
711  {
712  if(hGC->tile_image && (!values || values->tile != hGC->values.tile))
713  {
715  XDestroyImage(hGC->tile_image);
717 
718  hGC->tile_image = NULL;
719  }
720  }
721 
722  if(valuemask & GCStipple)
723  {
724  if(hGC->stip_image && (!values || values->stipple != hGC->values.stipple))
725  {
727  XDestroyImage(hGC->stip_image);
729 
730  hGC->stip_image = NULL;
731  }
732  }
733 
734  // NOTE: the clip mask in this case is related to the clip region, and so if I
735  // change the clip region I should update the clip mask, since that's what
736  // the X server will be doing. SO 'vice versa' if using this function call
737  // meaning I may have to 'nuke out' some kind of clip region??? Yeah that
738  // wouldn't be good, so maybe just free the thing...
739 
740  if(valuemask & GCClipMask)
741  {
742  // NOTE: GCClipMask and GCDashList can't be requested but can be changed with this call
743  // when using the XChangeGC call...
744 
745 #warning if I am NOT making a copy and assign anyway, will the ref count be messed up???
746 
747  if(hGC->values.clip_mask != None)
748  {
750  XFreePixmap(hGC->display, hGC->values.clip_mask);
752 
753  hGC->values.clip_mask = None;
754  }
755 
756  if(hGC->clip_image && (!values || values->clip_mask != hGC->values.clip_mask))
757  {
759  XDestroyImage(hGC->clip_image);
761 
762  hGC->clip_image = NULL;
763  }
764 
765  if(hGC->clip_rgn != None)
766  {
768  XDestroyRegion(hGC->clip_rgn);
770 
771  hGC->clip_rgn = None;
772  }
773  }
774 
775  // make the changes, then query the results [this is the simpler way]
776  // later, do I want to re-cache important things at this time, or wait
777  // until I actually NEED them? For now, I wait.
778 
779  memcpy(&valtemp, values, sizeof(valtemp)); // because 'values' is a const pointer
780 
782  iRval = XChangeGC(hGC->display, hGC->gc, valuemask, &valtemp);
783  XGetGCValues(hGC->display, hGC->gc,
784  (GCAll & ~(GCClipMask | GCDashList)), // clip mask and dash mask can't be requested
785  &(hGC->values)); // query them all to snapshot them
787 
788  // From the 'man' page: an invalid resource ID (with one or more of the three most significant
789  // bits set to 1) will be returned for GCFont, GCTile, and GCStipple if the
790  // component has never been explicitly set by the client.
791 
792  if((CARD32)hGC->values.font & 0xe0000000) // not valid?
793  {
794  hGC->values.font = None;
795  }
796 
797  if((CARD32)hGC->values.tile & 0xe0000000) // not valid?
798  {
799  hGC->values.tile = None;
800  }
801 
802  if((CARD32)hGC->values.stipple & 0xe0000000) // not valid?
803  {
804  hGC->values.stipple = None;
805  }
806 
807  // NOTE: this really shouldn't be affected, but...
808  if((CARD32)hGC->values.clip_mask & 0xe0000000) // not valid?
809  {
810  WB_ERROR_PRINT("ERROR - %s - hGCDest->values.clip_mask not valid, %d (%08xH)\n",
811  __FUNCTION__, (int)hGC->values.clip_mask, (int)hGC->values.clip_mask);
812 
813  hGC->values.clip_mask = None;
814  }
815 
816  if(valuemask & GCClipMask) // ONLY if this flag is assigned
817  {
818 // if(values->clip_mask != None)// && hGC->values.clip_mask != values->clip_mask)
819 // {
820 // WB_WARN_PRINT("WARNING - %s - calling PXM_CopyPixmap on %d (%08xH), %d (%08xH)\n", __FUNCTION__, (int)hGC->dw, (int)hGC->dw, (int)values->clip_mask, (int)values->clip_mask);
821 // // TODO: should I really be doing this ???
822 // hGC->values.clip_mask = PXM_CopyPixmap(hGC->display, hGC->dw, values->clip_mask);
823 // }
824 
825  // I am setting a clip mask, so cache it as an XImage
826 
827  hGC->clip_image = __internalGetClipImage(hGC);
828  }
829 
830  return iRval;
831 }
832 
833 Status WBGetGCValues(WBGC hGC, unsigned long valuemask,
834  XGCValues *values)
835 {
836 Status rval;
837 
838  // for now, just do this. later, use my cached copy as much as I can
839 
840 
841  // clean up the cached stuff
842 
843  if(valuemask & GCClipMask)
844  {
845  if(values->clip_mask != None)
846  {
848  XFreePixmap(hGC->display, values->clip_mask);
850 
851  values->clip_mask = None;
852  }
853  }
854 
855  if(valuemask & GCDashList)
856  {
857  // TODO: cache dash ?
858  }
859 
861  rval = XGetGCValues(hGC->display, hGC->gc, // a safe way to do this
862  valuemask, values);
864 
865  if((CARD32)values->font & 0xe0000000) // not valid?
866  {
867  values->font = None;
868  }
869 
870  if((CARD32)values->tile & 0xe0000000) // not valid?
871  {
872  values->tile = None;
873  }
874 
875  if((CARD32)values->stipple & 0xe0000000) // not valid?
876  {
877  values->stipple = None;
878  }
879 
880  // NOTE: this really shouldn't be affected, but...
881  if((CARD32)values->clip_mask & 0xe0000000) // not valid?
882  {
883  WB_ERROR_PRINT("ERROR - %s - values->clip_mask not valid, %d (%08xH)\n",
884  __FUNCTION__, (int)values->clip_mask, (int)values->clip_mask);
885 
886  values->clip_mask = None;
887  }
888  else if(values->clip_mask & 0xffffffffe0000000LL)
889  {
890  WB_ERROR_PRINT("ERROR ERROR !!! - %s - values->clip_mask not valid, %d (%08xH)\n",
891  __FUNCTION__, (int)values->clip_mask, (int)values->clip_mask);
892 
893  values->clip_mask = None;
894  }
895 
896  if(valuemask & GCDashList)
897  {
898  // TODO: cache dash ?
899  values->dashes = hGC->values.dashes; // for now, assuming it's valid
900  }
901 
902  return rval;
903 }
904 
906 {
907 WBGC pRval;
908 int iRet;
909 
910  // this will make a complete copy of the original GC, including
911  // any cached elements. By doing it this way I can do whatever I
912  // want to with the copy and not have leaks nor use-after-free,
913  // while preserving as much performance as I can
914 
915  if(!hGCOrig || hGCOrig->gc == None)
916  {
917  WB_ERROR_PRINT("ERROR - %s - invalid source WBGC\n", __FUNCTION__);
918  return NULL; // not valid
919  }
920 
921  if(hGCOrig->dw == None)
922  {
923  WB_ERROR_PRINT("ERROR - %s - invalid (NULL) drawable in source WBGC\n", __FUNCTION__);
924  return NULL;
925  }
926 
927  pRval = (WBGC)WBAlloc(sizeof(*pRval)); // WBGC is a pointer, don't use 'sizeof' on that!!!
928  if(!pRval)
929  {
930  return NULL;
931  }
932 
933  memset(pRval, 0, sizeof(*pRval));
934 
935  pRval->display = hGCOrig->display;
936  pRval->dw = hGCOrig->dw;
937 
938 
940  pRval->gc = XCreateGC(pRval->display, pRval->dw, 0, NULL);
942 
943  if(pRval->gc == None)
944  {
945  WBFree(pRval);
946  return NULL;
947  }
948 
949 
950 // WB_WARN_PRINT("TEMPORARY: %s - calling WBCopyGC2()\n", __FUNCTION__);
951  iRet = WBCopyGC2(hGCOrig, GCAll, pRval);
952 
953  // TODO: test iRet for success
954 
955  return pRval;
956 }
957 
958 int WBCopyGC2(WBGC hGCOrig, unsigned long valuemask, WBGC hGCDest)
959 {
960 int iRet;
961 
962  if(!hGCOrig || !hGCDest || hGCOrig->gc == None || hGCDest->gc == None)
963  {
964  return -1;
965  }
966 
968  iRet = XCopyGC(hGCOrig->display, hGCOrig->gc, valuemask, hGCDest->gc);
970 
971  // TODO: check 'iRet' value which is poorly documented in the 'man' page
972 
973 
974  // clean up the cached stuff
975 
976  if(valuemask & GCFont)
977  {
978  if(hGCDest->pFont)
979  {
980  WBFreeFont(hGCDest->display, hGCDest->pFont);
981 // BEGIN_XCALL_DEBUG_WRAPPER
982 // XFreeFontInfo(NULL, hGCDest->pFont, 1); // just the one; does not unload the font
983 // END_XCALL_DEBUG_WRAPPER
984 
985  hGCDest->pFont = NULL;
986  }
987 // if(hGCDest->fontset != None)
988 // {
989 // BEGIN_XCALL_DEBUG_WRAPPER
990 // XFreeFontSet(hGCDest->display, hGCDest->fontset);
991 // END_XCALL_DEBUG_WRAPPER
992 //
993 // hGCDest->fontset = None;
994 // }
995  }
996 
997  if(valuemask & GCTile)
998  {
999  if(hGCDest->tile_image)
1000  {
1001  WBXDestroyImage(hGCDest->tile_image);
1002  hGCDest->tile_image = NULL;
1003  }
1004  }
1005 
1006  if(valuemask & GCStipple)
1007  {
1008  if(hGCDest->stip_image)
1009  {
1010  WBXDestroyImage(hGCDest->stip_image);
1011  hGCDest->stip_image = NULL;
1012  }
1013  }
1014 
1015  if(valuemask & GCClipMask)
1016  {
1017  if(hGCDest->values.clip_mask != None)
1018  {
1019  // TODO: do I need to do this??
1020 // BEGIN_XCALL_DEBUG_WRAPPER
1021 // XFreePixmap(hGCDest->display, hGCDest->values.clip_mask);
1022 // END_XCALL_DEBUG_WRAPPER
1023 //
1024 // hGCDest->values.clip_mask = None;
1025  }
1026 
1027  if(hGCDest->clip_image)
1028  {
1029  WBXDestroyImage(hGCDest->clip_image);
1030  hGCDest->clip_image = NULL;
1031  }
1032 
1033  if(hGCDest->clip_rgn)
1034  {
1036  XDestroyRegion(hGCDest->clip_rgn);
1038 
1039  hGCDest->clip_rgn = None;
1040  }
1041  }
1042 
1043  if(valuemask & GCDashList)
1044  {
1045  // TODO: cache dash ?
1046  }
1047 
1048 
1050  XGetGCValues(hGCDest->display, hGCDest->gc, // a safe way to do this
1051  (GCAll & ~(GCClipMask | GCDashList)), // clip mask and dash mask can't be requested
1052  &(hGCDest->values)); // query them all to snapshot them
1054 
1055  // From the 'man' page: an invalid resource ID (with one or more of the three most significant
1056  // bits set to 1) will be returned for GCFont, GCTile, and GCStipple if the
1057  // component has never been explicitly set by the client.
1058 
1059 // if((CARD32)hGCDest->values.font & 0xe0000000) // not valid?
1060 // {
1061 // hGCDest->values.font = None;
1062 // }
1063 
1064  if((CARD32)hGCDest->values.tile & 0xe0000000) // not valid?
1065  {
1066  hGCDest->values.tile = None;
1067  }
1068 
1069  if((CARD32)hGCDest->values.stipple & 0xe0000000) // not valid?
1070  {
1071  hGCDest->values.stipple = None;
1072  }
1073 
1074  // NOTE: this really shouldn't be affected, but...
1075  if((CARD32)hGCDest->values.clip_mask & 0xe0000000) // not valid?
1076  {
1077  WB_ERROR_PRINT("ERROR - %s - hGCDest->values.clip_mask not valid, %d (%08xH)\n",
1078  __FUNCTION__, (int)hGCDest->values.clip_mask, (int)hGCDest->values.clip_mask);
1079  }
1080  else if(hGCDest->values.clip_mask & 0xffffffffe0000000LL)
1081  {
1082  WB_ERROR_PRINT("ERROR ERROR !!! - %s - hGCDest->values.clip_mask not valid, %d (%08xH)\n",
1083  __FUNCTION__, (int)hGCDest->values.clip_mask, (int)hGCDest->values.clip_mask);
1084  }
1085 
1086 
1087  // make copies of all of the cached things
1088 
1089 
1090  // tile, stipple, clip_mask, dashes
1091 
1092  if(hGCOrig->values.dashes != 0)
1093  {
1094  // TODO: anything more??
1095  hGCDest->values.dashes = hGCOrig->values.dashes;
1096  }
1097 
1098  // NOTE: these are being 'fudged' a bit and it's really a cached version.
1099  if(valuemask & GCClipMask)
1100  {
1101  // TODO: do I need to do this???
1102 // if(hGCOrig->values.clip_mask != None)
1103 // {
1104 // WB_WARN_PRINT("WARNING - %s - calling PXM_CopyPixmap on %d (%08xH), %d (%08xH)\n", __FUNCTION__, (int)hGCOrig->dw, (int)hGCOrig->dw, (int)hGCOrig->values.clip_mask, (int)hGCOrig->values.clip_mask);
1105 // hGCDest->values.clip_mask = PXM_CopyPixmap(hGCDest->display, hGCOrig->dw,
1106 // hGCOrig->values.clip_mask);
1107 // }
1108 
1109  if(hGCOrig->clip_rgn)
1110  {
1111  hGCDest->clip_rgn = WBCopyRegion(hGCOrig->clip_rgn);
1112  }
1113 
1114  if(hGCOrig->clip_image)
1115  {
1116  hGCDest->clip_image = WBXCopyImage(hGCDest->display, hGCOrig->clip_image);
1117  }
1118  }
1119 
1120  if(valuemask & GCTile)
1121  {
1122 // if(hGCOrig->values.tile != None)
1123 // {
1124 // hGCDest->values.tile = PXM_CopyPixmap(hGCOrig->values.tile);
1125 // }
1126 
1127  if(hGCOrig->tile_image)
1128  {
1129  hGCDest->tile_image = WBXCopyImage(hGCDest->display, hGCOrig->tile_image);
1130  }
1131  }
1132 
1133  if(valuemask & GCStipple)
1134  {
1135 // if(hGCOrig->values.stipple != None)
1136 // {
1137 // hGCDest->values.stipple = PXM_CopyPixmap(hGCOrig->values.stipple);
1138 // }
1139 
1140  if(hGCOrig->stip_image)
1141  {
1142  hGCDest->stip_image = WBXCopyImage(hGCDest->display, hGCOrig->stip_image);
1143  }
1144  }
1145 
1146  if(valuemask & GCFont)
1147  {
1148  if(hGCOrig->pFont)
1149  {
1150  hGCDest->pFont = WBCopyFont(hGCDest->display, hGCOrig->pFont);
1151  }
1152 
1153 // if(hGCOrig->fontset != None)
1154 // {
1155 // hGCDest->fontset = WBCopyModifyFontSet(hGCDest->display, hGCOrig->fontset, 0, 0);
1156 // }
1157  }
1158 
1159  return iRet;
1160 }
1161 
1162 WBGC WBCopyDrawableGC(Display *pDisplay, Drawable dw, WBGC hGCOrig)
1163 {
1164 WBGC pRval;
1165 int iRet;
1166 
1167  // this will make a complete copy of the original GC, including
1168  // any cached elements. By doing it this way I can do whatever I
1169  // want to with the copy and not have leaks nor use-after-free,
1170  // while preserving as much performance as I can
1171 
1172  if(!hGCOrig || hGCOrig->gc == None)
1173  {
1174  return NULL; // not valid
1175  }
1176 
1177  if(pDisplay == NULL)
1178  {
1179  pDisplay = hGCOrig->display;
1180  }
1181 
1182  if(dw == None)
1183  {
1184  dw = hGCOrig->dw;
1185  }
1186 
1187  pRval = (WBGC)WBAlloc(sizeof(*pRval)); // WBGC is a pointer, don't use 'sizeof' on that!!!
1188  if(!pRval)
1189  {
1190  return NULL;
1191  }
1192 
1193  memset(pRval, 0, sizeof(*pRval));
1194 
1195  pRval->display = pDisplay;
1196  pRval->dw = dw;
1197 
1198  // TODO: handle different 'pDisplay' etc.
1199 
1201  pRval->gc = XCreateGC(pDisplay, dw, 0, NULL);
1203 
1204  if(pRval->gc == None)
1205  {
1206  WBFree(pRval);
1207  return NULL;
1208  }
1209 
1210 // WB_WARN_PRINT("TEMPORARY: %s - calling WBCopyGC2()\n", __FUNCTION__);
1211  iRet = WBCopyGC2(hGCOrig, GCAll, pRval);
1212 
1213  // TODO: test iRval for success
1214 
1215  return pRval;
1216 }
1217 
1218 void WBFreeGC(WBGC hGC)
1219 {
1220  if(!hGC) // TODO: other validity tests??
1221  {
1222  return;
1223  }
1224 
1225  // delete all of the cached things, and 'clip_mask' (if any)
1226 
1227  if(hGC->values.clip_mask != None)
1228  {
1230  // TODO: do I need to do this ???
1231  XFreePixmap(hGC->display, hGC->values.clip_mask);
1233 
1234  hGC->values.clip_mask = None;
1235  }
1236 
1237  if(hGC->clip_rgn)
1238  {
1240  XDestroyRegion(hGC->clip_rgn);
1242 
1243  hGC->clip_rgn = None;
1244  }
1245 
1246  if(hGC->pFont)
1247  {
1248 // BEGIN_XCALL_DEBUG_WRAPPER
1249 // XFreeFontInfo(NULL, hGC->pFont, 1); // just the one; does not unload the font
1250 // END_XCALL_DEBUG_WRAPPER
1251 
1252  WBFreeFont(hGC->display, hGC->pFont);
1253  hGC->pFont = NULL;
1254  }
1255 
1256 // if(hGC->fontset != None)
1257 // {
1258 // BEGIN_XCALL_DEBUG_WRAPPER
1259 // XFreeFontSet(hGC->display, hGC->fontset);
1260 // END_XCALL_DEBUG_WRAPPER
1261 //
1262 // hGC->fontset = None;
1263 // }
1264 
1265  if(hGC->clip_image)
1266  {
1268  hGC->clip_image = NULL;
1269  }
1270 
1271  if(hGC->tile_image)
1272  {
1274  hGC->tile_image = NULL;
1275  }
1276 
1277  if(hGC->stip_image)
1278  {
1280  hGC->stip_image = NULL;
1281  }
1282 
1283  // free the actual GC and the allocated memory
1284 
1285  XFreeGC(hGC->display, hGC->gc);
1286  hGC->gc = None;
1287 
1288  WBFree(hGC); // free the allocated RAM for the struct and I'm done
1289 }
1290 
1291 GContext WBGContextFromGC(WBGC hGC)
1292 {
1293 GContext rval;
1294 
1295  // for now, just do this. later, use my cached copy
1296 
1298  rval = XGContextFromGC(hGC->gc);
1300 
1301  return rval;
1302 }
1303 
1305 {
1306  if(!gc)
1307  {
1308  return NULL;
1309  }
1310 
1311  return gc->pFont; // just return the value as-is (as WB_FONTC)
1312 }
1313 
1314 WB_FONT WBGetGCFont(Display *pDisplay, WBGC gc)
1315 {
1316 //XFontStruct *pF, *pRval;
1317 
1318 
1319  if(!pDisplay)
1320  {
1321  pDisplay = WBGetDefaultDisplay();
1322  }
1323 
1324  if(!gc)
1325  {
1326  return NULL;
1327  }
1328 
1329  if(gc->pFont)
1330  {
1331  return WBCopyFont(gc->display, gc->pFont); // return copy of it
1332  }
1333 
1334  return NULL;
1335 #if 0
1336  pRval = NULL;
1337 
1339  pF = XQueryFont(pDisplay, gc->values.font);
1340 
1341  if(pF)
1342  {
1343  unsigned long lName = 0;
1344  if(XGetFontProperty(pF, XA_FONT, &lName)) // grab font name, which I'll use to load it
1345  {
1346  char *pName = WBGetAtomName(WBGetDefaultDisplay(), (Atom)lName);
1347  if(pName)
1348  {
1349  gc->pFont = XLoadQueryFont(pDisplay, pName); // saved cached value, now owned by the WBGC
1350  if(gc->pFont) // font was loaded properly
1351  {
1352  pRval = WBCopyFont(gc->pFont);
1353  }
1354 
1355  WBFree(pName);
1356  }
1357  }
1358 
1359  XFreeFontInfo(NULL, pF, 1); // to JUST free "the info" (required for XQueryFont)
1360  // NOTE: do not assign NULL to pF here, it's a flag below
1361  }
1363 
1364  if(!pRval)
1365  {
1366  pRval = WBCopyFont(WBGetDefaultFont());
1367  }
1368 
1369  return pRval; // caller must delete this using XFreeFont()
1370 #endif // 0
1371 }
1372 
1373 //XFontSet WBGetGCFontSet(Display *pDisplay, WBGC gc)
1374 //{
1375 //#warning implement this
1376 //
1377 // return None; // for now...
1378 //}
1379 
1380 
1381 
1382 int WBSetRegion(WBGC hGC, Region rgnClip)
1383 {
1384 int iRet;
1385 
1386 
1388  iRet = XSetRegion(hGC->display, hGC->gc, rgnClip);
1390 
1391  if(hGC->clip_image)
1392  {
1394  hGC->clip_image = NULL;
1395  }
1396 
1397  if(hGC->values.clip_mask != None)
1398  {
1400  // TODO: do I need to do this ???
1401  XFreePixmap(hGC->display, hGC->values.clip_mask);
1403 
1404  hGC->values.clip_mask = None;
1405  }
1406 
1407  if(hGC->clip_rgn)
1408  {
1410  XDestroyRegion(hGC->clip_rgn);
1412  }
1413 
1414  if(rgnClip != None)
1415  {
1416  hGC->clip_rgn = WBCopyRegion(rgnClip); // cache a copy of it
1417  }
1418 
1419  return iRet;
1420 }
1421 
1422 int WBSetClipOrigin(WBGC hGC, int clip_x_origin, int clip_y_origin)
1423 {
1424 int iRet;
1425 
1427  iRet = XSetClipOrigin(hGC->display, hGC->gc, clip_x_origin, clip_y_origin);
1429 
1430  hGC->values.clip_x_origin = clip_x_origin;
1431  hGC->values.clip_y_origin = clip_y_origin;
1432 
1433  return iRet;
1434 }
1435 
1436 int WBSetClipMask(WBGC hGC, Pixmap pixmap)
1437 {
1438 int iRet;
1439 
1441  iRet = XSetClipMask(hGC->display, hGC->gc, pixmap);
1443 
1444  hGC->values.clip_mask = PXM_CopyPixmap(hGC->display, hGC->dw, pixmap); // TODO: do I make a copy or just use this as-is ?
1445 
1446  if(hGC->clip_rgn)
1447  {
1449  XDestroyRegion(hGC->clip_rgn);
1451 
1452  hGC->clip_rgn = None;
1453  }
1454 
1455  if(hGC->clip_image)
1456  {
1458  hGC->clip_image = NULL;
1459  }
1460 
1461  return iRet;
1462 }
1463 
1464 int WBSetFunction(WBGC hGC, int function)
1465 {
1466 int iRet;
1467 
1469  iRet = XSetFunction(hGC->display, hGC->gc, function);
1471 
1472  hGC->values.function = function;
1473 
1474  return iRet;
1475 }
1476 
1477 int WBSetForeground(WBGC hGC, unsigned long foreground)
1478 {
1479 int iRet;
1480 
1482  iRet = XSetForeground(hGC->display, hGC->gc, foreground);
1484 
1485  hGC->values.foreground = foreground;
1486 
1487  return iRet;
1488 }
1489 
1490 int WBSetBackground(WBGC hGC, unsigned long background)
1491 {
1492 int iRet;
1493 
1495  iRet = XSetBackground(hGC->display, hGC->gc, background);
1497 
1498  hGC->values.background = background;
1499 
1500  return iRet;
1501 }
1502 
1503 int WBSetFont(WBGC hGC, WB_FONTC pFont)
1504 {
1505 int iRet = 0;
1506 WB_FONT pNewFont;
1507 
1508 
1509  if(pFont)
1510  {
1511  pNewFont = WBCopyFont(hGC->display, pFont);
1512 
1513  if(!pNewFont) // copy failed
1514  {
1515  return -1;
1516  }
1517  }
1518  else
1519  {
1520  pNewFont = NULL;
1521  }
1522 
1523  iRet = WBSetFontNoCopy(hGC, pNewFont);
1524  if(iRet && pNewFont) // an error, no assignment made
1525  {
1526  WBFreeFont(hGC->display, pNewFont); // free the copy
1527  }
1528 
1529  return iRet;
1530 }
1531 
1533 {
1534 int iRet = 0;
1535 
1536 
1537  if(pFont && pFont->pFontStruct &&
1538  pFont->pFontStruct->fid != hGC->values.font)
1539  {
1541  iRet = XSetFont(hGC->display, hGC->gc, pFont->pFontStruct->fid);
1543 
1544  hGC->values.font = pFont->pFontStruct->fid; // updated (TODO set mask as well?)
1545  }
1546 
1547  if(hGC->pFont)
1548  {
1549  WBFreeFont(hGC->display, hGC->pFont);
1550  hGC->pFont = NULL;
1551  }
1552 
1553 #warning verify that XSetFont returns a zero on success and then enable this check
1554  if( pFont)
1555  {
1556  hGC->pFont = pFont;
1557 
1558 #warning verify that XSetFont returns a zero on success and then remove this next line
1559  iRet = 0;
1560  }
1561 
1562  return iRet;
1563 }
1564 
1565 int WBSetLineAttributes(WBGC hGC, unsigned int line_width,
1566  int line_style, int cap_style, int join_style)
1567 {
1568 int iRet;
1569 
1571  iRet = XSetLineAttributes(hGC->display, hGC->gc, line_width, line_style, cap_style, join_style);
1573 
1574  hGC->values.line_width = line_width;
1575  hGC->values.line_style = line_style;
1576  hGC->values.cap_style = cap_style;
1577  hGC->values.join_style = join_style;
1578 
1579  return iRet;
1580 }
1581 
1582 int WBSetDashes(WBGC hGC, int dash_offset, const char dash_list[], int n)
1583 {
1584 int iRet;
1585 char *pDashList;
1586 char c1 = 0;
1587 
1588  if(n > 0)
1589  {
1590  pDashList = WBAlloc(n + 1);
1591 
1592  if(!pDashList)
1593  {
1594  return -1;
1595  }
1596 
1597  memcpy(pDashList, dash_list, n);
1598  }
1599  else
1600  {
1601  pDashList = &c1;
1602  }
1603 
1605  iRet = XSetDashes(hGC->display, hGC->gc, dash_offset, pDashList, n);
1607 
1608  if(pDashList != &c1)
1609  {
1610  WBFree(pDashList);
1611  }
1612 
1613  // TODO: cache the value, remove previous cached values
1614 
1615  return iRet;
1616 }
1617 
GC gc
the associated 'GC'
XImage * clip_image
cached XImage for the GC, for 'clip mask'
int WBDrawPoints(Display *display, Drawable d, WBGC gc, XPoint *points, int npoints, int mode)
Wrapper for XDrawPoints()
int WBXDrawArc(XImage *pImage, WBGC hGC, int x, int y, unsigned int width, unsigned int height, int angle1, int angle2)
XImage version for XDrawArc()
XImage * tile_image
cached XImage for the GC, for 'tile'
int WBChangeGC(WBGC hGC, unsigned long valuemask, const XGCValues *values)
Change a WBGC, a wrapper for XChangeGC()
'window helper' main header file for the X11workbench Toolkit API
Display * display
the Display associated with the WBGC (NULL implies 'Default Display')
int WBDrawLine(Display *display, Drawable d, WBGC gc, int x1, int y1, int x2, int y2)
Wrapper for XDrawLines()
void WBFreeFont(Display *pDisplay, WB_FONT pFont)
free a WB_FONT that was created using one of the WBFont APIs
Definition: font_helper.c:250
#define WB_DEBUG_PRINT(L,...)
Preferred method of implementing conditional debug output.
Definition: debug_helper.h:364
int WBXFillPolygon(XImage *pImage, WBGC hGC, XPoint *points, int npoints, int shape, int mode)
XImage version for XFillPolygon()
int WBSetLineAttributes(WBGC hGC, unsigned int line_width, int line_style, int cap_style, int join_style)
Assign font to a WBGC, a wrapper for XSetLineAttributes()
XImage * WBGetWindowImage(Display *pDisplay, Window wID)
Obtain an XImage for the entire window.
WB_FONT WBCopyFont(Display *pDisplay, WB_FONTC pOldFont)
make a copy of an existing font (best when assigning to a window)
Definition: font_helper.c:168
int WBDrawPoint(Display *display, Drawable d, WBGC gc, int x, int y)
Wrapper for XDrawPoint()
static __inline__ unsigned long WBGetForeground(WBGC hGC)
Get the (cached) foreground color for a WBGC.
int WBXDrawRectangle(XImage *pImage, WBGC hGC, int x, int y, unsigned int width, unsigned int height)
XImage version for XDrawRectangle()
Drawable dw
the Drawable for which this WBGC was created (None implies default Window)
XImage * stip_image
cached XImage for the GC, for 'stipple'
int WBFillPolygon(Display *display, Drawable d, WBGC gc, XPoint *points, int npoints, int shape, int mode)
Wrapper for XFillPolygon()
WB_FONT pFont
cached default font
static __inline__ Display * WBGetDefaultDisplay(void)
Returns the default Display.
'configuration helper' main header file for the X11 Work Bench Toolkit API
int WBXFillRectangle(XImage *pImage, WBGC hGC, int x, int y, unsigned int width, unsigned int height)
XImage version for XFillRectangle()
Region WBCopyRegion(Region rgnSource)
Simple utility to copy a region.
#define GCAll
A bit mask for ALL GC properties (used when copying a GC)
int WBSetFont(WBGC hGC, WB_FONTC pFont)
Assign font to a WBGC, a wrapper for XSetFont()
int WBDrawString(Display *display, Drawable d, WBGC gc, int x, int y, const char *string, int length)
wrapper for XDrawString()
int WBXDrawLine(XImage *pImage, WBGC hGC, int x1, int y1, int x2, int y2)
XImage version for XDrawLines()
XImage * WBXCopyImage(Display *pDisplay, XImage *pImage)
Make a copy of an XImage.
int WBSetForeground(WBGC hGC, unsigned long foreground)
Assign foreground color, a wrapper for XSetForeground()
int WBDrawArc(Display *display, Drawable d, WBGC gc, int x, int y, unsigned int width, unsigned int height, int angle1, int angle2)
Wrapper for XDrawArc()
int WBDrawRectangle(Display *display, Drawable d, WBGC gc, int x, int y, unsigned int width, unsigned int height)
Wrapper for XDrawRectangle()
int WBDrawLines(Display *display, Drawable d, WBGC gc, XPoint *points, int npoints, int mode)
Wrapper for XDrawLine()
void * WBAlloc(int nSize)
High performance memory sub-allocator 'allocate'.
#define END_XCALL_DEBUG_WRAPPER
wrapper macro for calls into the X11 library. This macro follows the call(s)
GContext WBGContextFromGC(WBGC hGC)
Free resources for a WBGC, wrapper for XGContextFromGC()
int WBSetFontNoCopy(WBGC hGC, WB_FONT pFont)
Assign font to a WBGC, a wrapper for XSetFont()
int WBSetRegion(WBGC hGC, Region rgnClip)
Assign clipping region, wrapper for XSetRegion()
int WBXDrawPoint(XImage *pImage, WBGC hGC, int x, int y)
XImage version for XDrawPoint()
int WBXDrawString(XImage *pImage, WB_FONTC pFont, WBGC hGC, int x, int y, const char *string, int length)
XImage version for XDrawString() or DTDrawString()
WBGC WBCopyGC(WBGC hGCOrig)
makes a copy of a WBGC, a more sensible wrapper for XCopyGC()
int WBFillArc(Display *display, Drawable d, WBGC gc, int x, int y, unsigned int width, unsigned int height, int angle1, int angle2)
Wrapper for XFillArc()
#define WB_ERROR_PRINT(...)
Preferred method of implementing an 'error level' debug message for all subsystems.
Definition: debug_helper.h:474
Window WBGetHiddenHelperWindow(void)
Returns a special 'hidden' window used for information purposes.
int WBXDrawPoints(XImage *pImage, WBGC hGC, XPoint *points, int npoints, int mode)
XImage version for XDrawPoints()
void WBFree(void *pBuf)
High performance memory sub-allocator 'free'.
XGCValues values
cached XGCValues for the GC
WBGC WBCreateGC(Display *pDisplay, Drawable dw, unsigned long valuemask, const XGCValues *values)
Creates a WBGC, wrapper for XCreateGC()
#define WB_DRAW_STRING
Definition: font_helper.h:101
int WBCopyGC2(WBGC hGCOrig, unsigned long valuemask, WBGC hGCDest)
makes a copy of a WBGC, a wrapper for XCopyGC()
int WBSetClipMask(WBGC hGC, Pixmap pixmap)
Set clip mask, a wrapper for XSetClipMask()
static __inline__ unsigned long WBGetBackground(WBGC hGC)
Get the (cached) background color for a WBGC.
XImage * WBXGetImage(Display *pDisplay, Drawable dw, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, int format)
Read contents of a Drawable onto an XImage.
XFontSet fsFont
legacy 'XFontSet' for X11 raster fonts (UTF-8)
Definition: font_helper.h:168
WB_FONT WBGetGCFont(Display *pDisplay, WBGC gc)
return a copy of the WB_FONT object that was assigned to a WBGC
int WBXDestroyImage(XImage *pImage)
Destroy an XImage - call this instead of XDestroyImage()
XFontStruct * pFontStruct
legacy 'XFontStruct' for X11 raster fonts
Definition: font_helper.h:167
int WBSetClipOrigin(WBGC hGC, int clip_x_origin, int clip_y_origin)
Set clip origin, a wrapper for XSetClipOrigin()
Display * WBGetWindowDisplay(Window wID)
returns the Display associated with a window
void WBFreeGC(WBGC hGC)
Free resources for a WBGC, wrapper for XFreeGC()
Status WBGetGCValues(WBGC hGC, unsigned long valuemask, XGCValues *values)
Change a WBGC, a wrapper for XGetGCValues()
#define BEGIN_XCALL_DEBUG_WRAPPER
wrapper macro for calls into the X11 library. This macro precedes the call(s)
struct s_WBGC * WBGC
internal wrapper struct for GC with local cache
WBGC WBCopyDrawableGC(Display *pDisplay, Drawable dw, WBGC hGCOrig)
makes a copy of the specified WBGC for the desired 'Drawable'
Region clip_rgn
clipping region (or None to use clip_image) - owned by the object
int WBXDrawLines(XImage *pImage, WBGC hGC, XPoint *points, int npoints, int mode)
XImage version for XDrawLine()
int WBFillRectangle(Display *display, Drawable d, WBGC gc, int x, int y, unsigned int width, unsigned int height)
Wrapper for XFillRectangle()
char * WBGetAtomName(Display *pDisplay, Atom aAtom)
Lookup and/or allocate an internal Atom for a named string.
int WBSetBackground(WBGC hGC, unsigned long background)
Assign background color, a wrapper for XSetBackground()
An allocated structure containing XFontStruct, XFontInfo, and XftFont [as applicable] for a specified...
Definition: font_helper.h:152
internal wrapper struct for GC with local cache
int WBSetDashes(WBGC hGC, int dash_offset, const char dash_list[], int n)
Assign font to a WBGC, a wrapper for XSetFont()
Pixmap PXM_CopyPixmap(Display *pDisplay, Drawable dw, Pixmap pxSource)
Copy a pixmap for the specified Display and Drawable.
int WBXFillArc(XImage *pImage, WBGC hGC, int x, int y, unsigned int width, unsigned int height, int angle1, int angle2)
XImage version for XFillArc()
int WBSetFunction(WBGC hGC, int function)
Set the 'function' for the WBGC, a wrapper for XSetFunction()
WB_FONTC WBQueryGCFont(WBGC gc)
return the WB_FONTC object that was assigned to a WBGC
WB_FONTC WBGetDefaultFont(void)
Returns a pointer to the default font WB_FONT for the default display. This is a shared resource; do ...