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-2007 Daniel A. Steffen <das@users.sourceforge.net> 9 * 10 * See the file "license.terms" for information on usage and redistribution 11 * of this file, and for a DISCLAIMER OF ALL WARRANTIES. 12 * 13 * RCS: @(#) $Id: xgc.c,v 1.6.2.6 2007/11/09 06:26:57 das Exp $ 14 */ 15 16#include <tkInt.h> 17 18#if !defined(MAC_TCL) && !defined(MAC_OSX_TK) 19# include <X11/Xlib.h> 20#endif 21#ifdef MAC_TCL 22# include <Xlib.h> 23# include <X.h> 24# define Cursor XCursor 25# define Region XRegion 26#endif 27#ifdef MAC_OSX_TK 28# include <tkMacOSXInt.h> 29# include <X11/Xlib.h> 30# include <X11/X.h> 31# define Cursor XCursor 32# define Region XRegion 33#endif 34 35 36/* 37 *---------------------------------------------------------------------- 38 * 39 * AllocClipMask -- 40 * 41 * Static helper proc to allocate new or clear existing TkpClipMask. 42 * 43 * Results: 44 * Returns ptr to the new/cleared TkpClipMask. 45 * 46 * Side effects: 47 * None. 48 * 49 *---------------------------------------------------------------------- 50 */ 51 52static TkpClipMask *AllocClipMask(GC gc) { 53 TkpClipMask *clip_mask = (TkpClipMask*) gc->clip_mask; 54 55 if (clip_mask == None) { 56 clip_mask = (TkpClipMask*) ckalloc(sizeof(TkpClipMask)); 57 gc->clip_mask = (Pixmap) clip_mask; 58#ifdef MAC_OSX_TK 59 } else if (clip_mask->type == TKP_CLIP_REGION) { 60 TkpReleaseRegion(clip_mask->value.region); 61#endif 62 } 63 return clip_mask; 64} 65 66/* 67 *---------------------------------------------------------------------- 68 * 69 * FreeClipMask -- 70 * 71 * Static helper proc to free TkpClipMask. 72 * 73 * Results: 74 * None. 75 * 76 * Side effects: 77 * None. 78 * 79 *---------------------------------------------------------------------- 80 */ 81 82static void FreeClipMask(GC gc) { 83 if (gc->clip_mask != None) { 84#ifdef MAC_OSX_TK 85 if (((TkpClipMask*) gc->clip_mask)->type == TKP_CLIP_REGION) { 86 TkpReleaseRegion(((TkpClipMask*) gc->clip_mask)->value.region); 87 } 88#endif 89 ckfree((char*) gc->clip_mask); 90 gc->clip_mask = None; 91 } 92} 93 94/* 95 *---------------------------------------------------------------------- 96 * 97 * XCreateGC -- 98 * 99 * Allocate a new GC, and initialize the specified fields. 100 * 101 * Results: 102 * Returns a newly allocated GC. 103 * 104 * Side effects: 105 * None. 106 * 107 *---------------------------------------------------------------------- 108 */ 109 110GC 111XCreateGC(display, d, mask, values) 112 Display* display; 113 Drawable d; 114 unsigned long mask; 115 XGCValues* values; 116{ 117 GC gp; 118 119/* 120 * In order to have room for a dash list, MAX_DASH_LIST_SIZE extra chars are 121 * defined, which is invisible from the outside. The list is assumed to end 122 * with a 0-char, so this must be set explicitely during initialization. 123 */ 124 125#define MAX_DASH_LIST_SIZE 10 126 127 gp = (XGCValues *)ckalloc(sizeof(XGCValues) + MAX_DASH_LIST_SIZE); 128 if (!gp) { 129 return None; 130 } 131 132 gp->function = (mask & GCFunction) ?values->function :GXcopy; 133 gp->plane_mask = (mask & GCPlaneMask) ?values->plane_mask :~0; 134 gp->foreground = (mask & GCForeground) ?values->foreground : 135 BlackPixelOfScreen(DefaultScreenOfDisplay(display)); 136 gp->background = (mask & GCBackground) ?values->background : 137 WhitePixelOfScreen(DefaultScreenOfDisplay(display)); 138 gp->line_width = (mask & GCLineWidth) ?values->line_width :1; 139 gp->line_style = (mask & GCLineStyle) ?values->line_style :LineSolid; 140 gp->cap_style = (mask & GCCapStyle) ?values->cap_style :0; 141 gp->join_style = (mask & GCJoinStyle) ?values->join_style :0; 142 gp->fill_style = (mask & GCFillStyle) ?values->fill_style :FillSolid; 143 gp->fill_rule = (mask & GCFillRule) ?values->fill_rule :WindingRule; 144 gp->arc_mode = (mask & GCArcMode) ?values->arc_mode :ArcPieSlice; 145 gp->tile = (mask & GCTile) ?values->tile :None; 146 gp->stipple = (mask & GCStipple) ?values->stipple :None; 147 gp->ts_x_origin = (mask & GCTileStipXOrigin) ?values->ts_x_origin:0; 148 gp->ts_y_origin = (mask & GCTileStipYOrigin) ?values->ts_y_origin:0; 149 gp->font = (mask & GCFont) ?values->font :None; 150 gp->subwindow_mode = (mask & GCSubwindowMode)?values->subwindow_mode:ClipByChildren; 151 gp->graphics_exposures = (mask & GCGraphicsExposures)?values->graphics_exposures:True; 152 gp->clip_x_origin = (mask & GCClipXOrigin) ?values->clip_x_origin :0; 153 gp->clip_y_origin = (mask & GCClipYOrigin) ?values->clip_y_origin :0; 154 gp->dash_offset = (mask & GCDashOffset) ?values->dash_offset :0; 155 gp->dashes = (mask & GCDashList) ?values->dashes :4; 156 (&(gp->dashes))[1] = 0; 157 158 gp->clip_mask = None; 159 if (mask & GCClipMask) { 160 TkpClipMask *clip_mask = AllocClipMask(gp); 161 162 clip_mask->type = TKP_CLIP_PIXMAP; 163 clip_mask->value.pixmap = values->clip_mask; 164 } 165 166 return gp; 167} 168 169/* 170 *---------------------------------------------------------------------- 171 * 172 * XChangeGC -- 173 * 174 * Changes the GC components specified by valuemask for the 175 * specified GC. 176 * 177 * Results: 178 * None. 179 * 180 * Side effects: 181 * Updates the specified GC. 182 * 183 *---------------------------------------------------------------------- 184 */ 185 186void 187XChangeGC(d, gc, mask, values) 188 Display * d; 189 GC gc; 190 unsigned long mask; 191 XGCValues *values; 192{ 193 if (mask & GCFunction) { gc->function = values->function; } 194 if (mask & GCPlaneMask) { gc->plane_mask = values->plane_mask; } 195 if (mask & GCForeground) { gc->foreground = values->foreground; } 196 if (mask & GCBackground) { gc->background = values->background; } 197 if (mask & GCLineWidth) { gc->line_width = values->line_width; } 198 if (mask & GCLineStyle) { gc->line_style = values->line_style; } 199 if (mask & GCCapStyle) { gc->cap_style = values->cap_style; } 200 if (mask & GCJoinStyle) { gc->join_style = values->join_style; } 201 if (mask & GCFillStyle) { gc->fill_style = values->fill_style; } 202 if (mask & GCFillRule) { gc->fill_rule = values->fill_rule; } 203 if (mask & GCArcMode) { gc->arc_mode = values->arc_mode; } 204 if (mask & GCTile) { gc->tile = values->tile; } 205 if (mask & GCStipple) { gc->stipple = values->stipple; } 206 if (mask & GCTileStipXOrigin) { gc->ts_x_origin = values->ts_x_origin; } 207 if (mask & GCTileStipYOrigin) { gc->ts_y_origin = values->ts_y_origin; } 208 if (mask & GCFont) { gc->font = values->font; } 209 if (mask & GCSubwindowMode) { gc->subwindow_mode = values->subwindow_mode; } 210 if (mask & GCGraphicsExposures) { gc->graphics_exposures = values->graphics_exposures; } 211 if (mask & GCClipXOrigin) { gc->clip_x_origin = values->clip_x_origin; } 212 if (mask & GCClipYOrigin) { gc->clip_y_origin = values->clip_y_origin; } 213 if (mask & GCClipMask) { XSetClipMask(d, gc, values->clip_mask); } 214 if (mask & GCDashOffset) { gc->dash_offset = values->dash_offset; } 215 if (mask & GCDashList) { gc->dashes = values->dashes; (&(gc->dashes))[1] = 0;} 216} 217 218/* 219 *---------------------------------------------------------------------- 220 * 221 * XFreeGC -- 222 * 223 * Deallocates the specified graphics context. 224 * 225 * Results: 226 * None. 227 * 228 * Side effects: 229 * None. 230 * 231 *---------------------------------------------------------------------- 232 */ 233 234void XFreeGC(d, gc) 235 Display * d; 236 GC gc; 237{ 238 if (gc != None) { 239 FreeClipMask(gc); 240 ckfree((char *) gc); 241 } 242} 243 244/* 245 *---------------------------------------------------------------------- 246 * 247 * XSetForeground, etc. -- 248 * 249 * The following functions are simply accessor functions for 250 * the GC slots. 251 * 252 * Results: 253 * None. 254 * 255 * Side effects: 256 * Each function sets some slot in the GC. 257 * 258 *---------------------------------------------------------------------- 259 */ 260 261void 262XSetForeground(display, gc, foreground) 263 Display *display; 264 GC gc; 265 unsigned long foreground; 266{ 267 gc->foreground = foreground; 268} 269 270void 271XSetBackground(display, gc, background) 272 Display *display; 273 GC gc; 274 unsigned long background; 275{ 276 gc->background = background; 277} 278 279void 280XSetDashes(display, gc, dash_offset, dash_list, n) 281 Display* display; 282 GC gc; 283 int dash_offset; 284 _Xconst char* dash_list; 285 int n; 286{ 287 char *p = &(gc->dashes); 288 289#ifdef TkWinDeleteBrush 290 TkWinDeleteBrush(gc->fgBrush); 291 TkWinDeletePen(gc->fgPen); 292 TkWinDeleteBrush(gc->bgBrush); 293 TkWinDeletePen(gc->fgExtPen); 294#endif 295 gc->dash_offset = dash_offset; 296 if (n > MAX_DASH_LIST_SIZE) n = MAX_DASH_LIST_SIZE; 297 while (n-- > 0) { 298 *p++ = *dash_list++; 299 } 300 *p = 0; 301} 302 303void 304XSetFunction(display, gc, function) 305 Display *display; 306 GC gc; 307 int function; 308{ 309 gc->function = function; 310} 311 312void 313XSetFillRule(display, gc, fill_rule) 314 Display *display; 315 GC gc; 316 int fill_rule; 317{ 318 gc->fill_rule = fill_rule; 319} 320 321void 322XSetFillStyle(display, gc, fill_style) 323 Display *display; 324 GC gc; 325 int fill_style; 326{ 327 gc->fill_style = fill_style; 328} 329 330void 331XSetTSOrigin(display, gc, x, y) 332 Display *display; 333 GC gc; 334 int x, y; 335{ 336 gc->ts_x_origin = x; 337 gc->ts_y_origin = y; 338} 339 340void 341XSetFont(display, gc, font) 342 Display *display; 343 GC gc; 344 Font font; 345{ 346 gc->font = font; 347} 348 349void 350XSetArcMode(display, gc, arc_mode) 351 Display *display; 352 GC gc; 353 int arc_mode; 354{ 355 gc->arc_mode = arc_mode; 356} 357 358void 359XSetStipple(display, gc, stipple) 360 Display *display; 361 GC gc; 362 Pixmap stipple; 363{ 364 gc->stipple = stipple; 365} 366 367void 368XSetLineAttributes(display, gc, line_width, line_style, cap_style, 369 join_style) 370 Display *display; 371 GC gc; 372 unsigned int line_width; 373 int line_style; 374 int cap_style; 375 int join_style; 376{ 377 gc->line_width = line_width; 378 gc->line_style = line_style; 379 gc->cap_style = cap_style; 380 gc->join_style = join_style; 381} 382 383void 384XSetClipOrigin(display, gc, clip_x_origin, clip_y_origin) 385 Display* display; 386 GC gc; 387 int clip_x_origin; 388 int clip_y_origin; 389{ 390 gc->clip_x_origin = clip_x_origin; 391 gc->clip_y_origin = clip_y_origin; 392} 393 394/* 395 *---------------------------------------------------------------------- 396 * 397 * TkSetRegion, XSetClipMask -- 398 * 399 * Sets the clipping region/pixmap for a GC. 400 * 401 * Note that unlike the Xlib equivalent, it is not safe to delete the 402 * region after setting it into the GC (except on Mac OS X). The only 403 * uses of TkSetRegion are currently in DisplayFrame and in 404 * ImgPhotoDisplay, which use the GC immediately. 405 * 406 * Results: 407 * None. 408 * 409 * Side effects: 410 * Allocates or dealloates a TkpClipMask. 411 * 412 *---------------------------------------------------------------------- 413 */ 414 415void 416TkSetRegion(display, gc, r) 417 Display* display; 418 GC gc; 419 TkRegion r; 420{ 421 if (r == None) { 422 FreeClipMask(gc); 423 } else { 424 TkpClipMask *clip_mask = AllocClipMask(gc); 425 426 clip_mask->type = TKP_CLIP_REGION; 427 clip_mask->value.region = r; 428#ifdef MAC_OSX_TK 429 TkpRetainRegion(r); 430#endif 431 } 432} 433 434void 435XSetClipMask(display, gc, pixmap) 436 Display* display; 437 GC gc; 438 Pixmap pixmap; 439{ 440 if (pixmap == None) { 441 FreeClipMask(gc); 442 } else { 443 TkpClipMask *clip_mask = AllocClipMask(gc); 444 445 clip_mask->type = TKP_CLIP_PIXMAP; 446 clip_mask->value.pixmap = pixmap; 447 } 448} 449 450/* 451 * Some additional dummy functions (hopefully implemented soon). 452 */ 453 454#if 0 455Cursor 456XCreateFontCursor(display, shape) 457 Display* display; 458 unsigned int shape; 459{ 460 return (Cursor) 0; 461} 462 463void 464XDrawImageString(display, d, gc, x, y, string, length) 465 Display* display; 466 Drawable d; 467 GC gc; 468 int x; 469 int y; 470 _Xconst char* string; 471 int length; 472{ 473} 474#endif 475 476void 477XDrawPoint(display, d, gc, x, y) 478 Display* display; 479 Drawable d; 480 GC gc; 481 int x; 482 int y; 483{ 484 XDrawLine(display, d, gc, x, y, x, y); 485} 486 487void 488XDrawPoints(display, d, gc, points, npoints, mode) 489 Display* display; 490 Drawable d; 491 GC gc; 492 XPoint* points; 493 int npoints; 494 int mode; 495{ 496 int i; 497 498 for (i=0; i<npoints; i++) { 499 XDrawPoint(display, d, gc, points[i].x, points[i].y); 500 } 501} 502 503#if !defined(MAC_TCL) && !defined(MAC_OSX_TK) 504void 505XDrawSegments(display, d, gc, segments, nsegments) 506 Display* display; 507 Drawable d; 508 GC gc; 509 XSegment* segments; 510 int nsegments; 511{ 512} 513#endif 514 515#if 0 516char * 517XFetchBuffer(display, nbytes_return, buffer) 518 Display* display; 519 int* nbytes_return; 520 int buffer; 521{ 522 return (char *) 0; 523} 524 525Status XFetchName(display, w, window_name_return) 526 Display* display; 527 Window w; 528 char** window_name_return; 529{ 530 return (Status) 0; 531} 532 533Atom *XListProperties(display, w, num_prop_return) 534 Display* display; 535 Window w; 536 int* num_prop_return; 537{ 538 return (Atom *) 0; 539} 540 541void 542XMapRaised(display, w) 543 Display* display; 544 Window w; 545{ 546} 547 548void 549XPutImage(display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height) 550 Display* display; 551 Drawable d; 552 GC gc; 553 XImage* image; 554 int src_x; 555 int src_y; 556 int dest_x; 557 int dest_y; 558 unsigned int width; 559 unsigned int height; 560{ 561} 562 563void 564XQueryTextExtents(display, font_ID, string, nchars, direction_return, 565 font_ascent_return, font_descent_return, overall_return) 566 Display* display; 567 XID font_ID; 568 _Xconst char* string; 569 int nchars; 570 int* direction_return; 571 int* font_ascent_return; 572 int* font_descent_return; 573 XCharStruct* overall_return; 574{ 575} 576 577void 578XReparentWindow(display, w, parent, x, y) 579 Display* display; 580 Window w; 581 Window parent; 582 int x; 583 int y; 584{ 585} 586 587void 588XRotateBuffers(display, rotate) 589 Display* display; 590 int rotate; 591{ 592} 593 594void 595XStoreBuffer(display, bytes, nbytes, buffer) 596 Display* display; 597 _Xconst char* bytes; 598 int nbytes; 599 int buffer; 600{ 601} 602 603void 604XUndefineCursor(display, w) 605 Display* display; 606 Window w; 607{ 608} 609#endif 610