2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /*******************************************************************************
27 ** $XConsortium: graphics.c /main/3 1995/11/03 10:27:52 rswiston $
29 ** RESTRICTED CONFIDENTIAL INFORMATION:
31 ** The information in this document is subject to special
32 ** restrictions in a confidential disclosure agreement between
33 ** HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
34 ** document outside HP, IBM, Sun, USL, SCO, or Univel without
35 ** Sun's specific written approval. This document and all copies
36 ** and derivative works thereof must be returned or destroyed at
39 ** Copyright 1993 Sun Microsystems, Inc. All rights reserved.
41 *******************************************************************************/
44 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
45 * (c) Copyright 1993, 1994 International Business Machines Corp. *
46 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
47 * (c) Copyright 1993, 1994 Novell, Inc. *
51 static char sccsid[] = "@(#)graphics.c 1.23 94/11/29 Copyr 1994 Sun Microsystems, Inc.";
54 #include <EUSCompat.h>
57 #if !defined(CSRG_BASED)
58 #include <sys/sysmacros.h>
60 #include <sys/param.h> /* MAXPATHLEN defined here */
62 #include <sys/utsname.h> /* SYS_NMLN */
71 #include <sys/resource.h>
73 #include <netinet/in.h>
75 #include <Xm/DrawingA.h>
77 #include <Xm/RowColumn.h>
78 #include <Xm/ManagerP.h>
79 #include <Xm/GadgetP.h>
83 #include "datefield.h"
97 #include "dayglance.h"
98 #include "yearglance.h"
99 #include "weekglance.h"
101 #include "calendar.h"
111 #include "monthglance.h"
114 #define gray_data_75_width 8
115 #define gray_data_75_height 8
116 #define gray_data_50_width 8
117 #define gray_data_50_height 8
118 #define gray_data_25_width 8
119 #define gray_data_25_height 8
120 #define black_data_width 8
121 #define black_data_height 8
123 #define solid_list_length 2
124 #define short_dotted_list_length 2
125 #define dotted_list_length 2
126 #define dot_dashed_list_length 4
127 #define short_dashed_list_length 2
128 #define long_dashed_list_length 2
129 #define odd_dashed_list_length 3
130 static unsigned char black_data[] = {
140 static unsigned char gray_data_75[] = {
151 static unsigned char gray_data_50[] = {
162 static unsigned char gray_data_25[] = {
173 static Pixmap black_data_pixmap = NULL;
174 static Pixmap gray_data_75_pixmap = NULL;
175 static Pixmap gray_data_50_pixmap = NULL;
176 static Pixmap gray_data_25_pixmap = NULL;
178 static unsigned char solid[solid_list_length] = {1, 0};
179 static unsigned char short_dotted[short_dotted_list_length] = {1, 1};
180 static unsigned char dotted[dotted_list_length] = {3, 1};
181 static unsigned char dot_dashed[dot_dashed_list_length] = {3, 4, 3, 1};
182 static unsigned char short_dashed[short_dashed_list_length] = {4, 4};
183 static unsigned char long_dashed[long_dashed_list_length] = {4, 7};
184 static unsigned char odd_dashed[odd_dashed_list_length] = {1, 2, 3};
186 static unsigned char *dash_list[] = {
197 gr_clear_area(new_XContext *xc, int x, int y, Dimension w, Dimension h) {
199 XFillRectangle(xc->display, xc->xid, xc->clear_gc, x, y, w, h);
201 XClearArea(xc->display, xc->xid, x, y, w, h, False);
206 gr_clear_box (new_XContext *xc, int x, int y, int w, int h) {
208 x+=1; y+=1; w-=1; h-=1;
210 XFillRectangle(xc->display, xc->xid, xc->clear_gc, x, y, w, h);
212 XClearArea(xc->display, xc->xid, x, y, w, h, False);
217 gr_make_grayshade(new_XContext *xc, int x, int y, int w, int h, int shade) {
219 XColor colorcell_del, rgb_db_ref;
221 XSetForeground((Display*)xc->display, (GC)xc->gc, (unsigned long)xc->colorcell_del[shade].pixel);
223 XSetFillStyle(xc->display, xc->gc, FillSolid);
224 XFillRectangle(xc->display, xc->xid, xc->gc, x, y, w, h);
228 gr_make_gray(new_XContext *xc, int x, int y, int w, int h, int percent) {
230 /* Set up gray stipple */
233 XSetStipple(xc->display, xc->gc, gray_data_25_pixmap);
236 XSetStipple(xc->display, xc->gc, gray_data_50_pixmap);
239 XSetStipple(xc->display, xc->gc, gray_data_75_pixmap);
242 XSetStipple(xc->display, xc->gc, gray_data_25_pixmap);
246 XSetForeground(xc->display, xc->gc, xc->foreground);
247 XSetFillStyle(xc->display, xc->gc, FillOpaqueStippled);
248 XFillRectangle(xc->display, xc->xid, xc->gc, x, y, w, h);
252 gr_make_rgbcolor(new_XContext *xc, Colormap cms, int x, int y, int w, int h,
253 int r, int g, int b) {
255 XColor colorcell_del;
257 colorcell_del.red = (unsigned short)(r<<8);
258 colorcell_del.green = (unsigned short)(g<<8);
259 colorcell_del.blue = (unsigned short)(b<<8);
260 XAllocColor(xc->display, cms, &colorcell_del);
262 XSetForeground((Display*)xc->display, (GC)xc->gc,
263 (unsigned long)colorcell_del.pixel);
264 XSetFillStyle(xc->display, xc->gc, FillSolid);
265 XFillRectangle(xc->display, xc->xid, xc->gc, x, y, w, h);
269 gr_nchars(int area, char *str, Cal_Font *font) {
274 int len = cm_strlen(str);
277 CalTextExtents(font, str, len, &nop, &nop, &width, &nop);
281 for (i=0; i<len; i++) {
283 buf = (char *)cm_mbchar(str);
286 buf = (char *)cm_mbchar((char *)NULL);
289 CalTextExtents(font, buf, l, &nop, &nop, &width, &nop);
292 n += mblen(buf, MB_LEN_MAX);
310 XColor colorcell_del, rgb_db_ref;
317 XGetGCValues(xc->display, xc->gc,
318 GCForeground|GCFillStyle, xc->gcvals);
320 pixel = xc->colorcell_del[RED].pixel;
327 XSetForeground((Display*)xc->display, (GC)xc->gc, pixel);
328 XSetFillStyle(xc->display, xc->gc, FillSolid);
330 for (;thickness > 0; thickness--) {
331 XDrawRectangle(xc->display, xc->xid, xc->gc, x, y, w, h);
348 for (;thickness > 0; thickness--) {
349 XDrawRectangle(xc->display, xc->xid, xc->clear_gc, x, y, w, h);
355 /* given an area of a certain length (in pixels), compute
356 where to lay down a string such that it's centered */
359 gr_center(int area, char *str, Cal_Font *font) {
361 int i, strl, l, w, first = 1;
366 strl = cm_strlen(str);
367 for (i=0; i<strl; i++) {
369 buf = (char*)cm_mbchar(str);
372 buf = (char*)cm_mbchar((char *)NULL);
375 CalTextExtents(font, buf, l, &nop, &nop, &width, &nop);
378 return ((area - w)/2);
382 gr_text(new_XContext *xc, int x, int y, Cal_Font *font, char *str,
385 int len = cm_strlen(str);
387 XRectangle overall_ink_return;
390 CalTextExtents(font, str, len, &x2, &y2, &w, &h);
392 overall_ink_return.x = x2 + rect->x;
393 overall_ink_return.y = y2 + rect->y;
394 overall_ink_return.width = w;
395 overall_ink_return.height = h;
397 if (!myrect_intersectsrect(rect, &overall_ink_return))
400 CalDrawString(xc->display, xc->xid, font, xc->draw_gc, x, y,
401 str, cm_strlen(str));
405 gr_text_rgb(new_XContext *xc, int x, int y, Cal_Font *font, char *str,
406 Pixel shade, Colormap cms, XRectangle *rect) {
408 XRectangle overall_ink_return;
412 CalTextExtents(font, str, cm_strlen(str), &x2, &y2, &w, &h);
414 overall_ink_return.x = x2 + rect->x;
415 overall_ink_return.y = y2 + rect->y;
416 overall_ink_return.width = w;
417 overall_ink_return.height = h;
419 if (!myrect_intersectsrect(rect, &overall_ink_return))
423 XSetForeground((Display*)xc->display, (GC)xc->gc,
424 (unsigned long)shade);
426 CalDrawString(xc->display, xc->xid, font, xc->gc, x, y,
427 str, cm_strlen(str));
431 gr_draw_line(new_XContext *xc, int x1, int y1, int x2, int y2,
432 GR_Line_Style style, XRectangle *rect) {
441 gr_rect.width = x2-x1;
442 gr_rect.height = y2-y1;
444 if (!myrect_intersectsrect(rect, &gr_rect))
447 if (style==gr_solid) {
448 XDrawLine(xc->display, xc->xid, xc->draw_gc, x1, y1, x2,
452 /* Set up and paint */
453 XSetForeground(xc->display, xc->gc, xc->foreground);
454 XSetDashes(xc->display, xc->gc, dash_offset,
455 (char *)dash_list[style],
456 short_dotted_list_length);
457 XSetLineAttributes(xc->display, xc->gc, 0,
458 LineOnOffDash, CapNotLast, JoinMiter);
459 XDrawLine(xc->display, xc->xid, xc->gc, x1, y1, x2, y2);
465 gr_draw_box(new_XContext *xc, int x, int y, int w, int h, XRectangle *rect) {
475 if (!myrect_intersectsrect(rect, &gr_rect))
478 XDrawRectangle(xc->display, xc->xid, xc->draw_gc, x, y, w, h);
482 gr_draw_glyph(new_XContext *src_xc, new_XContext *dst_xc, Pixmap pixmap,
483 int x, int y, int w, int h) {
485 XSetStipple(src_xc->display, src_xc->gc, pixmap);
486 XSetTSOrigin(src_xc->display, src_xc->gc, x, y);
487 XFillRectangle(src_xc->display, dst_xc->xid, src_xc->gc, x, y, w, h);
491 saturate(XColor *xclr)
496 n = MAX(xclr->red, xclr->green);
497 n = MAX(n, xclr->blue);
509 * Allocate and initialize an XContext
512 gr_create_xcontext(Calendar *c, Widget widget, GR_depth depth, XtAppContext app)
517 XGCValues gc_vals, tmp_vals;
522 /* X Drawing Stuff */
523 if ((xc = (new_XContext *) ckalloc(sizeof(new_XContext))) == NULL)
526 xc->display = (Display *) XtDisplay(widget);
529 if (depth == gr_mono) {
532 xc->hilight_color = 1;
534 XtVaGetValues(widget,
535 XmNbackground, &xc->background,
536 XmNforeground, &xc->foreground,
539 * XXX EEEEEEK! We use a private interface to get the
540 * hilight color. We do this because there is no public
543 hilight_gc = XmParentHighlightGC(widget);
544 XGetGCValues(xc->display, hilight_gc, GCForeground, &tmp_vals);
545 xc->hilight_color = tmp_vals.foreground;
548 xc->xid = XtWindowOfObject(widget);
549 xc->screen_depth = DefaultDepthOfScreen(XtScreen(widget));
552 * Create general purpose gc. This gc is changed as needed by
553 * the drawing routines.
555 xc->gcvals = (XGCValues *) ckalloc(sizeof(XGCValues));
556 xc->gcvals->foreground = xc->foreground;
557 xc->gcvals->background = xc->background;
559 xc->gcvals->fill_style = FillOpaqueStippled;
563 GCForeground|GCBackground|GCFillStyle,
567 * Specialized GCs. We create a couple of specialized GCs to increase
568 * the speed of common operations. This way we don't need to change
569 * the GC for every operation.
572 /* GC used for clearing */
573 gc_vals.foreground = xc->background;
574 xc->clear_gc = XCreateGC(xc->display, xc->xid, GCForeground, &gc_vals);
576 /* Create GC used for inverting */
577 gc_vals.foreground = xc->background;
578 gc_vals.function = GXinvert;
579 xc->invert_gc = XCreateGC(xc->display, xc->xid,
580 GCForeground | GCFunction, &gc_vals);
581 XSetSubwindowMode(xc->display, xc->invert_gc, IncludeInferiors);
583 /* Create GC used for drawing */
584 gc_vals.function = GXcopy;
585 gc_vals.foreground = xc->foreground;
586 xc->draw_gc = XCreateGC(xc->display, xc->xid, GCForeground | GCFunction,
588 XSetLineAttributes(xc->display, xc->draw_gc, 0,
589 LineSolid, CapNotLast, JoinMiter);
596 * Set the clip mask for all gcs the graphics package uses
600 gr_set_clip_rectangles(new_XContext *xc, int x, int y, XRectangle *rectangles,
601 int n, int ordering) {
603 XSetClipRectangles(xc->display, xc->gc, x, y, rectangles, n, ordering);
604 XSetClipRectangles(xc->display, xc->draw_gc,
605 x, y, rectangles, n, ordering);
606 XSetClipRectangles(xc->display, xc->clear_gc,
607 x, y, rectangles, n, ordering);
608 XSetClipRectangles(xc->display, xc->invert_gc,
609 x, y, rectangles, n, ordering);
614 gr_clear_clip_rectangles(new_XContext *xc) {
616 XSetClipMask(xc->display, xc->gc, None);
617 XSetClipMask(xc->display, xc->draw_gc, None);
618 XSetClipMask(xc->display, xc->clear_gc, None);
619 XSetClipMask(xc->display, xc->invert_gc, None);
623 gr_create_stipple(new_XContext *xc, unsigned char *data, int datawidth, int dataheight,
624 Pixmap *stipple, unsigned int *width, unsigned int *height) {
629 if ((*stipple = XCreateBitmapFromData(xc->display,
631 /* RootWindow(xc->display, DefaultScreen(xc->display)), */
632 (char *)data, datawidth, dataheight)) == NULL) {
637 *height = dataheight;
643 gr_init(new_XContext *xc, Widget canvas) {
645 unsigned int width, height;
649 Display *dpy = XtDisplay(canvas);
650 int scr = DefaultScreen(dpy);
651 Colormap cmap = DefaultColormap(dpy, scr);
653 ok = gr_create_stipple(xc, black_data,
654 black_data_width, black_data_height,
655 &black_data_pixmap, &width, &height);
656 ok = gr_create_stipple(xc, gray_data_75,
657 gray_data_75_width, gray_data_75_height,
658 &gray_data_75_pixmap, &width, &height);
659 ok = gr_create_stipple(xc, gray_data_50,
660 gray_data_50_width, gray_data_50_height,
661 &gray_data_50_pixmap, &width, &height);
662 ok = gr_create_stipple(xc, gray_data_25,
663 gray_data_25_width, gray_data_25_height,
664 &gray_data_25_pixmap, &width, &height);
666 ok = XAllocNamedColor(dpy, cmap,
667 "dark slate grey", &xc->colorcell_del[DARKGREY], &rgb_db_ref);
668 ok = XAllocNamedColor(dpy, cmap,
669 "dim grey", &xc->colorcell_del[DIMGREY], &rgb_db_ref);
670 ok = XAllocNamedColor(dpy, cmap,
671 "grey", &xc->colorcell_del[GREY], &rgb_db_ref);
672 ok = XAllocNamedColor(dpy, cmap,
673 "light grey", &xc->colorcell_del[LIGHTGREY], &rgb_db_ref);
674 ok = XAllocNamedColor(dpy, cmap,
675 "red", &xc->colorcell_del[RED], &rgb_db_ref);