1 /*
2 * xgc.c --
3 *
4 * This file contains generic routines for manipulating X graphics
5 * contexts.
6 *
7 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
8 * Copyright (c) 2002-2009 Daniel A. Steffen <das@users.sourceforge.net>
9 * Copyright 2008-2009, Apple Inc.
10 *
11 * See the file "license.terms" for information on usage and redistribution of
12 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 */
14
15 #include "tkInt.h"
16 #include <X11/Xlib.h>
17 #if defined(MAC_OSX_TK)
18 # define Cursor XCursor
19 # define Region XRegion
20 #endif
21
22 #undef TkSetRegion
23
24 #define MAX_DASH_LIST_SIZE 10
25 typedef struct {
26 XGCValues gc;
27 char dash[MAX_DASH_LIST_SIZE];
28 } XGCValuesWithDash;
29
30 /*
31 *----------------------------------------------------------------------
32 *
33 * AllocClipMask --
34 *
35 * Static helper proc to allocate new or clear existing TkpClipMask.
36 *
37 * Results:
38 * Returns ptr to the new/cleared TkpClipMask.
39 *
40 * Side effects:
41 * None.
42 *
43 *----------------------------------------------------------------------
44 */
45
AllocClipMask(GC gc)46 static TkpClipMask *AllocClipMask(GC gc) {
47 TkpClipMask *clip_mask = (TkpClipMask*) gc->clip_mask;
48
49 if (clip_mask == NULL) {
50 clip_mask = (TkpClipMask *)ckalloc(sizeof(TkpClipMask));
51 gc->clip_mask = (Pixmap) clip_mask;
52 }
53 return clip_mask;
54 }
55
56 /*
57 *----------------------------------------------------------------------
58 *
59 * FreeClipMask --
60 *
61 * Static helper proc to free TkpClipMask.
62 *
63 * Results:
64 * None.
65 *
66 * Side effects:
67 * None.
68 *
69 *----------------------------------------------------------------------
70 */
71
FreeClipMask(GC gc)72 static void FreeClipMask(GC gc) {
73 if (gc->clip_mask != None) {
74 ckfree((char *)gc->clip_mask);
75 gc->clip_mask = None;
76 }
77 }
78
79 /*
80 *----------------------------------------------------------------------
81 *
82 * XCreateGC --
83 *
84 * Allocate a new GC, and initialize the specified fields.
85 *
86 * Results:
87 * Returns a newly allocated GC.
88 *
89 * Side effects:
90 * None.
91 *
92 *----------------------------------------------------------------------
93 */
94
95 GC
XCreateGC(Display * display,Drawable d,unsigned long mask,XGCValues * values)96 XCreateGC(
97 Display *display,
98 Drawable d,
99 unsigned long mask,
100 XGCValues *values)
101 {
102 GC gp;
103 (void)d;
104
105 /*
106 * In order to have room for a dash list, MAX_DASH_LIST_SIZE extra chars
107 * are defined, which is invisible from the outside. The list is assumed
108 * to end with a 0-char, so this must be set explicitly during
109 * initialization.
110 */
111
112 gp = (GC)ckalloc(sizeof(XGCValuesWithDash));
113 if (!gp) {
114 return NULL;
115 }
116
117 #define InitField(name,maskbit,default) \
118 (gp->name = (mask & (maskbit)) ? values->name : (default))
119
120 InitField(function, GCFunction, GXcopy);
121 InitField(plane_mask, GCPlaneMask, (unsigned long)(~0));
122 InitField(foreground, GCForeground,
123 BlackPixelOfScreen(DefaultScreenOfDisplay(display)));
124 InitField(background, GCBackground,
125 WhitePixelOfScreen(DefaultScreenOfDisplay(display)));
126 InitField(line_width, GCLineWidth, 1);
127 InitField(line_style, GCLineStyle, LineSolid);
128 InitField(cap_style, GCCapStyle, 0);
129 InitField(join_style, GCJoinStyle, 0);
130 InitField(fill_style, GCFillStyle, FillSolid);
131 InitField(fill_rule, GCFillRule, WindingRule);
132 InitField(arc_mode, GCArcMode, ArcPieSlice);
133 InitField(tile, GCTile, 0);
134 InitField(stipple, GCStipple, 0);
135 InitField(ts_x_origin, GCTileStipXOrigin, 0);
136 InitField(ts_y_origin, GCTileStipYOrigin, 0);
137 InitField(font, GCFont, 0);
138 InitField(subwindow_mode, GCSubwindowMode, ClipByChildren);
139 InitField(graphics_exposures, GCGraphicsExposures, True);
140 InitField(clip_x_origin, GCClipXOrigin, 0);
141 InitField(clip_y_origin, GCClipYOrigin, 0);
142 InitField(dash_offset, GCDashOffset, 0);
143 InitField(dashes, GCDashList, 4);
144 (&(gp->dashes))[1] = 0;
145
146 gp->clip_mask = None;
147 if (mask & GCClipMask) {
148 TkpClipMask *clip_mask = AllocClipMask(gp);
149
150 clip_mask->type = TKP_CLIP_PIXMAP;
151 clip_mask->value.pixmap = values->clip_mask;
152 }
153 return gp;
154 }
155
156 /*
157 *----------------------------------------------------------------------
158 *
159 * XChangeGC --
160 *
161 * Changes the GC components specified by valuemask for the specified GC.
162 *
163 * Results:
164 * None.
165 *
166 * Side effects:
167 * Updates the specified GC.
168 *
169 *----------------------------------------------------------------------
170 */
171
172 int
XChangeGC(Display * d,GC gc,unsigned long mask,XGCValues * values)173 XChangeGC(
174 Display *d,
175 GC gc,
176 unsigned long mask,
177 XGCValues *values)
178 {
179 #define ModifyField(name,maskbit) \
180 if (mask & (maskbit)) { gc->name = values->name; }
181
182 ModifyField(function, GCFunction);
183 ModifyField(plane_mask, GCPlaneMask);
184 ModifyField(foreground, GCForeground);
185 ModifyField(background, GCBackground);
186 ModifyField(line_width, GCLineWidth);
187 ModifyField(line_style, GCLineStyle);
188 ModifyField(cap_style, GCCapStyle);
189 ModifyField(join_style, GCJoinStyle);
190 ModifyField(fill_style, GCFillStyle);
191 ModifyField(fill_rule, GCFillRule);
192 ModifyField(arc_mode, GCArcMode);
193 ModifyField(tile, GCTile);
194 ModifyField(stipple, GCStipple);
195 ModifyField(ts_x_origin, GCTileStipXOrigin);
196 ModifyField(ts_y_origin, GCTileStipYOrigin);
197 ModifyField(font, GCFont);
198 ModifyField(subwindow_mode, GCSubwindowMode);
199 ModifyField(graphics_exposures, GCGraphicsExposures);
200 ModifyField(clip_x_origin, GCClipXOrigin);
201 ModifyField(clip_y_origin, GCClipYOrigin);
202 ModifyField(dash_offset, GCDashOffset);
203 if (mask & GCClipMask) {
204 XSetClipMask(d, gc, values->clip_mask);
205 }
206 if (mask & GCDashList) {
207 gc->dashes = values->dashes;
208 (&(gc->dashes))[1] = 0;
209 }
210 return Success;
211 }
212
213 /*
214 *----------------------------------------------------------------------
215 *
216 * XFreeGC --
217 *
218 * Deallocates the specified graphics context.
219 *
220 * Results:
221 * None.
222 *
223 * Side effects:
224 * None.
225 *
226 *----------------------------------------------------------------------
227 */
228
XFreeGC(Display * d,GC gc)229 int XFreeGC(
230 Display *d,
231 GC gc)
232 {
233 (void)d;
234
235 if (gc != NULL) {
236 FreeClipMask(gc);
237 ckfree(gc);
238 }
239 return Success;
240 }
241
242 /*
243 *----------------------------------------------------------------------
244 *
245 * XSetForeground, etc. --
246 *
247 * The following functions are simply accessor functions for the GC
248 * slots.
249 *
250 * Results:
251 * None.
252 *
253 * Side effects:
254 * Each function sets some slot in the GC.
255 *
256 *----------------------------------------------------------------------
257 */
258
259 int
XSetForeground(Display * display,GC gc,unsigned long foreground)260 XSetForeground(
261 Display *display,
262 GC gc,
263 unsigned long foreground)
264 {
265 (void)display;
266
267 gc->foreground = foreground;
268 return Success;
269 }
270
271 int
XSetBackground(Display * display,GC gc,unsigned long background)272 XSetBackground(
273 Display *display,
274 GC gc,
275 unsigned long background)
276 {
277 (void)display;
278
279 gc->background = background;
280 return Success;
281 }
282
283 int
XSetDashes(Display * display,GC gc,int dash_offset,_Xconst char * dash_list,int n)284 XSetDashes(
285 Display *display,
286 GC gc,
287 int dash_offset,
288 _Xconst char *dash_list,
289 int n)
290 {
291 char *p = &(gc->dashes);
292 (void)display;
293
294 #ifdef TkWinDeleteBrush
295 TkWinDeleteBrush(gc->fgBrush);
296 TkWinDeletePen(gc->fgPen);
297 TkWinDeleteBrush(gc->bgBrush);
298 TkWinDeletePen(gc->fgExtPen);
299 #endif
300 gc->dash_offset = dash_offset;
301 if (n > MAX_DASH_LIST_SIZE) n = MAX_DASH_LIST_SIZE;
302 while (n-- > 0) {
303 *p++ = *dash_list++;
304 }
305 *p = 0;
306 return Success;
307 }
308
309 int
XSetFunction(Display * display,GC gc,int function)310 XSetFunction(
311 Display *display,
312 GC gc,
313 int function)
314 {
315 (void)display;
316
317 gc->function = function;
318 return Success;
319 }
320
321 int
XSetFillRule(Display * display,GC gc,int fill_rule)322 XSetFillRule(
323 Display *display,
324 GC gc,
325 int fill_rule)
326 {
327 (void)display;
328
329 gc->fill_rule = fill_rule;
330 return Success;
331 }
332
333 int
XSetFillStyle(Display * display,GC gc,int fill_style)334 XSetFillStyle(
335 Display *display,
336 GC gc,
337 int fill_style)
338 {
339 (void)display;
340
341 gc->fill_style = fill_style;
342 return Success;
343 }
344
345 int
XSetTSOrigin(Display * display,GC gc,int x,int y)346 XSetTSOrigin(
347 Display *display,
348 GC gc,
349 int x, int y)
350 {
351 (void)display;
352
353 gc->ts_x_origin = x;
354 gc->ts_y_origin = y;
355 return Success;
356 }
357
358 int
XSetFont(Display * display,GC gc,Font font)359 XSetFont(
360 Display *display,
361 GC gc,
362 Font font)
363 {
364 (void)display;
365
366 gc->font = font;
367 return Success;
368 }
369
370 int
XSetArcMode(Display * display,GC gc,int arc_mode)371 XSetArcMode(
372 Display *display,
373 GC gc,
374 int arc_mode)
375 {
376 (void)display;
377
378 gc->arc_mode = arc_mode;
379 return Success;
380 }
381
382 int
XSetStipple(Display * display,GC gc,Pixmap stipple)383 XSetStipple(
384 Display *display,
385 GC gc,
386 Pixmap stipple)
387 {
388 (void)display;
389
390 gc->stipple = stipple;
391 return Success;
392 }
393
394 int
XSetLineAttributes(Display * display,GC gc,unsigned int line_width,int line_style,int cap_style,int join_style)395 XSetLineAttributes(
396 Display *display,
397 GC gc,
398 unsigned int line_width,
399 int line_style,
400 int cap_style,
401 int join_style)
402 {
403 (void)display;
404
405 gc->line_width = line_width;
406 gc->line_style = line_style;
407 gc->cap_style = cap_style;
408 gc->join_style = join_style;
409 return Success;
410 }
411
412 int
XSetClipOrigin(Display * display,GC gc,int clip_x_origin,int clip_y_origin)413 XSetClipOrigin(
414 Display *display,
415 GC gc,
416 int clip_x_origin,
417 int clip_y_origin)
418 {
419 (void)display;
420
421 gc->clip_x_origin = clip_x_origin;
422 gc->clip_y_origin = clip_y_origin;
423 return Success;
424 }
425
426 /*
427 *----------------------------------------------------------------------
428 *
429 * TkSetRegion, XSetClipMask --
430 *
431 * Sets the clipping region/pixmap for a GC.
432 *
433 * Note that unlike the Xlib equivalent, it is not safe to delete the
434 * region after setting it into the GC (except on Mac OS X). The only
435 * uses of TkSetRegion are currently in DisplayFrame and in
436 * ImgPhotoDisplay, which use the GC immediately.
437 *
438 * Results:
439 * None.
440 *
441 * Side effects:
442 * Allocates or deallocates a TkpClipMask.
443 *
444 *----------------------------------------------------------------------
445 */
446
447 int
TkSetRegion(Display * display,GC gc,TkRegion r)448 TkSetRegion(
449 Display *display,
450 GC gc,
451 TkRegion r)
452 {
453 (void)display;
454
455 if (r == NULL) {
456 Tcl_Panic("must not pass NULL to TkSetRegion for compatibility with X11; use XSetClipMask instead");
457 } else {
458 TkpClipMask *clip_mask = AllocClipMask(gc);
459
460 clip_mask->type = TKP_CLIP_REGION;
461 clip_mask->value.region = r;
462 }
463 return Success;
464 }
465
466 int
XSetClipMask(Display * display,GC gc,Pixmap pixmap)467 XSetClipMask(
468 Display *display,
469 GC gc,
470 Pixmap pixmap)
471 {
472 (void)display;
473
474 if (pixmap == None) {
475 FreeClipMask(gc);
476 } else {
477 TkpClipMask *clip_mask = AllocClipMask(gc);
478
479 clip_mask->type = TKP_CLIP_PIXMAP;
480 clip_mask->value.pixmap = pixmap;
481 }
482 return Success;
483 }
484
485 /*
486 * Some additional dummy functions (hopefully implemented soon).
487 */
488
489 #if 0
490 Cursor
491 XCreateFontCursor(
492 Display *display,
493 unsigned int shape)
494 {
495 return (Cursor) 0;
496 }
497
498 void
499 XDrawImageString(
500 Display *display,
501 Drawable d,
502 GC gc,
503 int x,
504 int y,
505 _Xconst char *string,
506 int length)
507 {
508 }
509 #endif
510
511 int
XDrawPoint(Display * display,Drawable d,GC gc,int x,int y)512 XDrawPoint(
513 Display *display,
514 Drawable d,
515 GC gc,
516 int x,
517 int y)
518 {
519 return XDrawLine(display, d, gc, x, y, x, y);
520 }
521
522 int
XDrawPoints(Display * display,Drawable d,GC gc,XPoint * points,int npoints,int mode)523 XDrawPoints(
524 Display *display,
525 Drawable d,
526 GC gc,
527 XPoint *points,
528 int npoints,
529 int mode)
530 {
531 int res = Success;
532 (void)mode;
533
534 while (npoints-- > 0) {
535 res = XDrawLine(display, d, gc,
536 points[0].x, points[0].y, points[0].x, points[0].y);
537 if (res != Success) break;
538 ++points;
539 }
540 return res;
541 }
542
543 #if !defined(MAC_OSX_TK)
544 int
XDrawSegments(Display * display,Drawable d,GC gc,XSegment * segments,int nsegments)545 XDrawSegments(
546 Display *display,
547 Drawable d,
548 GC gc,
549 XSegment *segments,
550 int nsegments)
551 {
552 (void)display;
553 (void)d;
554 (void)gc;
555 (void)segments;
556 (void)nsegments;
557
558 return BadDrawable;
559 }
560 #endif
561
562 #if 0
563 char *
564 XFetchBuffer(
565 Display *display,
566 int *nbytes_return,
567 int buffer)
568 {
569 (void)display;
570 (void)nbytes_return;
571 (void)buffer;
572
573 return (char *) 0;
574 }
575
576 Status
577 XFetchName(
578 Display *display,
579 Window w,
580 char **window_name_return)
581 {
582 (void)display;
583 (void)w;
584 (void)window_name_return;
585
586 return Success;
587 }
588
589 Atom *
590 XListProperties(
591 Display* display,
592 Window w,
593 int *num_prop_return)
594 {
595 (void)display;
596 (void)w;
597 (void)num_prop_return;
598
599 return (Atom *) 0;
600 }
601
602 int
603 XMapRaised(
604 Display *display,
605 Window w)
606 {
607 (void)display;
608 (void)w;
609
610 return Success;
611 }
612
613 int
614 XQueryTextExtents(
615 Display *display,
616 XID font_ID,
617 _Xconst char *string,
618 int nchars,
619 int *direction_return,
620 int *font_ascent_return,
621 int *font_descent_return,
622 XCharStruct *overall_return)
623 {
624 (void)display;
625 (void)font_ID;
626 (void)string;
627 (void)nchars;
628 (void)direction_return;
629 (void)font_ascent_return;
630 (void)font_descent_return;
631 (void)overall_return;
632
633 return Success;
634 }
635
636 int
637 XReparentWindow(
638 Display *display,
639 Window w,
640 Window parent,
641 int x,
642 int y)
643 {
644 (void)display;
645 (void)w;
646 (void)parent;
647 (void)x;
648 (void)y;
649
650 return BadWindow;
651 }
652
653 int
654 XUndefineCursor(
655 Display *display,
656 Window w)
657 {
658 (void)display;
659 (void)w;
660
661 return Success;
662 }
663
664 XVaNestedList
665 XVaCreateNestedList(
666 int unused, ...)
667 {
668 (void)unused;
669 return NULL;
670 }
671
672 char *
673 XSetICValues(
674 XIC xic, ...)
675 {
676 (void)xic;
677 return NULL;
678 }
679
680 char *
681 XGetICValues(
682 XIC xic, ...)
683 {
684 (void)xic;
685 return NULL;
686 }
687
688 void
689 XSetICFocus(
690 XIC xic)
691 {
692 (void)xic;
693 }
694
695 Window
696 XCreateWindow(
697 Display *display,
698 Window parent,
699 int x,
700 int y,
701 unsigned int width,
702 unsigned int height,
703 unsigned int border_width,
704 int depth,
705 unsigned int clazz,
706 Visual *visual,
707 unsigned long value_mask,
708 XSetWindowAttributes *attributes)
709 {
710 (void)display;
711 (void)parent;
712 (void)x;
713 (void)y;
714 (void)width;
715 (void)height;
716 (void)border_width;
717 (void)depth;
718 (void)clazz;
719 (void)visual;
720 (void)value_mask;
721 (void)attributes;
722
723 return 0;
724 }
725
726 int
727 XPointInRegion(
728 Region rgn,
729 int x,
730 int y)
731 {
732 (void)rgn;
733 (void)x;
734 (void)y;
735
736 return 0;
737 }
738
739 int
740 XUnionRegion(
741 Region srca,
742 Region srcb,
743 Region dr_return)
744 {
745 (void)srca;
746 (void)srcb;
747 (void)dr_return;
748
749 return 0;
750 }
751
752 Region
753 XPolygonRegion(
754 XPoint *pts,
755 int n,
756 int rule)
757 {
758 (void)pts;
759 (void)n;
760 (void)rule;
761
762 return 0;
763 }
764 #endif
765
766 void
XDestroyIC(XIC ic)767 XDestroyIC(
768 XIC ic)
769 {
770 (void)ic;
771 }
772
773 Cursor
XCreatePixmapCursor(Display * display,Pixmap source,Pixmap mask,XColor * foreground_color,XColor * background_color,unsigned int x,unsigned int y)774 XCreatePixmapCursor(
775 Display *display,
776 Pixmap source,
777 Pixmap mask,
778 XColor *foreground_color,
779 XColor *background_color,
780 unsigned int x,
781 unsigned int y)
782 {
783 (void)display;
784 (void)source;
785 (void)mask;
786 (void)foreground_color;
787 (void)background_color;
788 (void)x;
789 (void)y;
790
791 return (Cursor) NULL;
792 }
793
794 Cursor
XCreateGlyphCursor(Display * display,Font source_font,Font mask_font,unsigned int source_char,unsigned int mask_char,XColor _Xconst * foreground_color,XColor _Xconst * background_color)795 XCreateGlyphCursor(
796 Display *display,
797 Font source_font,
798 Font mask_font,
799 unsigned int source_char,
800 unsigned int mask_char,
801 XColor _Xconst *foreground_color,
802 XColor _Xconst *background_color)
803 {
804 (void)display;
805 (void)source_font;
806 (void)mask_font;
807 (void)source_char;
808 (void)mask_char;
809 (void)foreground_color;
810 (void)background_color;
811
812 return (Cursor) NULL;
813 }
814
815 #if 0
816 XFontSet
817 XCreateFontSet(
818 Display *display /* display */,
819 _Xconst char *base_font_name_list /* base_font_name_list */,
820 char ***missing_charset_list /* missing_charset_list */,
821 int *missing_charset_count /* missing_charset_count */,
822 char **def_string /* def_string */
823 ) {
824 (void)display;
825 (void)base_font_name_list;
826 (void)missing_charset_list;
827 (void)missing_charset_count;
828 (void)def_string;
829
830 return (XFontSet)0;
831 }
832
833 void
834 XFreeFontSet(
835 Display *display, /* display */
836 XFontSet fontset /* font_set */
837 ) {
838 (void)display;
839 (void)fontset;
840 }
841
842 void
843 XFreeStringList(
844 char **list /* list */
845 ) {
846 (void)list;
847 }
848
849 Status
850 XCloseIM(
851 XIM im /* im */
852 ) {
853 (void)im;
854
855 return Success;
856 }
857
858 Bool
859 XRegisterIMInstantiateCallback(
860 Display *dpy /* dpy */,
861 struct _XrmHashBucketRec *rdb /* rdb */,
862 char *res_name /* res_name */,
863 char *res_class /* res_class */,
864 XIDProc callback /* callback */,
865 XPointer client_data /* client_data */
866 ) {
867 (void)dpy;
868 (void)rdb;
869 (void)res_name;
870 (void)res_class;
871 (void)callback;
872 (void)client_data;
873
874 return False;
875 }
876
877 Bool
878 XUnregisterIMInstantiateCallback(
879 Display *dpy /* dpy */,
880 struct _XrmHashBucketRec *rdb /* rdb */,
881 char *res_name /* res_name */,
882 char *res_class /* res_class */,
883 XIDProc callback /* callback */,
884 XPointer client_data /* client_data */
885 ) {
886 (void)dpy;
887 (void)rdb;
888 (void)res_name;
889 (void)res_class;
890 (void)callback;
891 (void)client_data;
892
893 return False;
894 }
895
896 char *
897 XSetLocaleModifiers(
898 const char *modifier_list /* modifier_list */
899 ) {
900 (void)modifier_list;
901
902 return NULL;
903 }
904
905 XIM XOpenIM(
906 Display *dpy /* dpy */,
907 struct _XrmHashBucketRec *rdb /* rdb */,
908 char *res_name /* res_name */,
909 char *res_class /* res_class */
910 ) {
911 (void)dpy;
912 (void)rdb;
913 (void)res_name;
914 (void)res_class;
915
916 return NULL;
917 }
918
919 char *
920 XGetIMValues(
921 XIM im /* im */, ...
922 ) {
923 (void)im;
924
925 return NULL;
926 }
927
928 char *
929 XSetIMValues(
930 XIM im /* im */, ...
931 ) {
932 (void)im;
933
934 return NULL;
935 }
936 #endif
937
938 /*
939 * Local Variables:
940 * mode: c
941 * c-basic-offset: 4
942 * fill-column: 78
943 * End:
944 */
945