📄 gcs.c
字号:
static char rcsid[] = "$Id: Gcs.c,v 1.3 1998/12/15 04:55:05 falk Exp $" ;/* * Gcs.c - Utility functions to allocate GCs. * * Author: Edward A. Falk * falk@falconer.vip.best.com * * Date: Sept 29, 1998 * * * $Log: Gcs.c,v $ * Revision 1.3 1998/12/15 04:55:05 falk * now uses Xmu library for stippled bitmap * now includes font in foreground & grey GC * * Revision 1.2 1998/10/12 16:29:32 falk * Now exports the allocPixel and GetGrey50 functions * * Revision 1.1 1998/10/12 01:38:14 falk * Initial revision * * *//* Functions: * * GC AllocFgGC(w, fg, font) * Return a GC with foreground set as specified. * If font is None, then the returned GC is allocated with font specified * as a "don't care" value. * * GC * AllocBackgroundGC(w, font) * Return a GC with the foreground set to the widget's background color. * * GC * AllocGreyGC(w, fg, font, contrast, gp, be_nice_to_cmap) * Widget w ; * Pixel fg ; * Font font ; * int contrast ; * Pixmap *gp ; * int be_nice_to_cmap ; * * Return a GC suitable for rendering a widget in its "inactive" color. * Normally returns a GC with a color somewhere between the widget's * background color and the specified foreground. If font is None, then * the returned GC is allocated with font specified as "don't care". * If be_nice_to_cmap is True, the returned GC is created using a 50% * dither instead of a new color. * * The 'gp' argument is a pointer to a Pixmap value, used to cache the * 50% dither pattern. If *gp points to a Pixmap value, it will be used * as the source of the 50% dither pattern. If *gp is None, then a * dither pattern will be created and stored in gp. If gp is NULL, then * a dither pattern will be created but not returned. * * GC * AllocTopShadowGC(w, contrast, be_nice_to_cmap) * Return a GC suitable for rendering the "top shadow" decorations of * a widget. Returns a GC with foreground computed from widget's * background color and contrast. If be_nice_to_cmap is True, the * returned GC will use a foreground color of white. If widget depth * is 1, this function will use a foreground color of black. * * GC * AllocBotShadowGC(w, contrast, be_nice_to_cmap) * Return a GC suitable for rendering the "bottom shadow" decorations * of a widget. Returns a GC with foreground computed from widget's * background color and contrast. If be_nice_to_cmap is True, the * returned GC will use a foreground color of black. * * GC * AllocArmGC(w, contrast, gp, be_nice_to_cmap) * Return a GC suitable for rendering the "armed" decorations of a * widget. This GC would typically be used to fill in the widget's * background. Returns a GC with foreground computed from widget's * background color and contrast. If be_nice_to_cmap is True, the * returned GC will use a foreground color of black and a 50% dither. * * The 'gp' argument is as described above. * * void * Draw3dBox(w, x,y,wid,hgt,s, topgc, botgc) * Utility function. Draws a raised shadow box with outside dimensions * as specified by x,y,wid,hgt and shadow width specified by s. * A lowered shadow box may be generated by swapping topgc and botgc. * */#include <stdio.h>#include <X11/Xlib.h>#include <X11/IntrinsicP.h>#include <X11/StringDefs.h>#include <X11/Xmu/Drawing.h>#include <X11/Xmu/Misc.h>#include "Gcs.h" /* Color & GC allocation. * * Frame widgets use the following graphics contexts: * * Foreground tab label text drawn this way * Insensitive Fg foreground color greyed out. * Background frame background color * Top shadow upper-left highlight around widget * Bottom shadow lower-right highlight around widget * Arm shadow button pressed and ready to be released * * * GC's are defined as follows, depending on attributes and * window depth: * * Monochrome: * Foreground = foreground color attribute or BlackPixel() * Grey = Foreground color + 50% dither * Background = background color attribute or WhitePixel() * top shadow = foreground * bottom shadow = foreground * arm shadow = (what?) * * Color, beNiceToColormap=true: * Foreground = foreground color attribute or BlackPixel() * Grey = Foreground color + 50% dither * Background = background color attribute or WhitePixel() * top shadow = white * bottom shadow = black * arm shadow = (what?) * * Color, beNiceToColormap=false: * Foreground = foreground color attribute or BlackPixel() * Grey = (foreground color + background color)/2 * Background = background color attribute or WhitePixel() * top shadow = background * 1.2 * bottom shadow = background * .6 * arm shadow = background * .8 * * Special cases: * If background is white, ?? * if background is black, ?? * * * If the widget's background is solid white or solid black, * this code just picks some numbers. (The choice is designed * to be compatibile with ThreeD interface.) */#if XtSpecificationRelease < 5static GC XtAllocateGC(Widget, int, u_long, XGCValues *, u_long, u_long) ;#endif /* return a GC with the specified foreground and optional font */GCAllocFgGC(w, fg, font) Widget w; Pixel fg ; Font font ;{ XGCValues values ; u_long vmask, dcmask ; values.foreground = fg ; values.font = font ; if( font != None ) { vmask = GCForeground|GCFont ; dcmask = GCSubwindowMode|GCGraphicsExposures|GCDashOffset| GCDashList|GCArcMode|GCBackground ; } else { vmask = GCForeground ; dcmask = GCFont|GCSubwindowMode|GCGraphicsExposures|GCDashOffset| GCDashList|GCArcMode|GCBackground ; } return XtAllocateGC(w, w->core.depth, vmask, &values, 0L, dcmask) ;} /* return gc with widget background color as the foreground */GCAllocBackgroundGC(w, font) Widget w; Font font ;{ return AllocFgGC(w, w->core.background_pixel, font) ;} /* Allocate an "inactive" GC. Color is grey (possibly via * dither pattern). This function optionally returns the * grey pixmap so the caller may cache it. */GCAllocGreyGC(w, fg, font, contrast, be_nice_to_cmap) Widget w ; Pixel fg ; Font font ; int contrast ; int be_nice_to_cmap ;{ XGCValues values ; u_long vmask, dcmask ; values.foreground = fg ; values.background = w->core.background_pixel ; values.font = font ; if( font != None ) { vmask = GCForeground|GCFont ; dcmask = GCSubwindowMode|GCGraphicsExposures|GCDashOffset| GCDashList|GCArcMode ; } else { vmask = GCForeground ; dcmask = GCFont|GCSubwindowMode|GCGraphicsExposures|GCDashOffset| GCDashList|GCArcMode ; } if( be_nice_to_cmap || w->core.depth == 1) { values.fill_style = FillStippled ; values.stipple = XmuCreateStippledPixmap(XtScreen(w), 1L, 0L, 1) ; vmask |= GCBackground|GCStipple|GCFillStyle ; return XtAllocateGC(w, w->core.depth, vmask, &values, 0L, dcmask) ; } else { values.foreground = AllocGreyPixel(w, fg, values.background, contrast) ; dcmask |= GCBackground ; return XtAllocateGC(w, w->core.depth, vmask, &values, 0L, dcmask) ; }} /* return top-shadow gc. */GCAllocTopShadowGC(w, contrast, be_nice_to_cmap) Widget w; int contrast ; int be_nice_to_cmap ;{ Screen *scr = XtScreen (w); XGCValues values ; if( w->core.depth == 1 ) values.foreground = BlackPixelOfScreen(scr) ; else if( be_nice_to_cmap ) values.foreground = WhitePixelOfScreen(scr) ; else values.foreground = AllocShadowPixel(w, 100+contrast) ; return XtAllocateGC(w, w->core.depth, GCForeground, &values, 0L, GCBackground|GCFont|GCSubwindowMode|GCGraphicsExposures| GCDashOffset|GCDashList|GCArcMode) ;} /* return bottom-shadow gc. */GCAllocBotShadowGC(w, contrast, be_nice_to_cmap) Widget w ; int contrast ; int be_nice_to_cmap ;{ Screen *scr = XtScreen (w); XGCValues values ; if( w->core.depth == 1 || be_nice_to_cmap ) values.foreground = BlackPixelOfScreen(scr) ; else values.foreground = AllocShadowPixel(w, 100-contrast) ; return XtAllocateGC(w, w->core.depth, GCForeground, &values, 0L, GCBackground|GCFont|GCSubwindowMode|GCGraphicsExposures| GCDashOffset|GCDashList|GCArcMode) ;} /* return arm-shadow gc. */GCAllocArmGC(w, contrast, be_nice_to_cmap) Widget w; int contrast ; int be_nice_to_cmap ;{ Screen *scr = XtScreen (w); XGCValues values ; /* Not clear exactly what we should do here. Take a look at * Xaw3d to see what they do. */ if( w->core.depth == 1 || be_nice_to_cmap ) { values.background = w->core.background_pixel ; if( values.background == BlackPixelOfScreen(scr) ) values.foreground = WhitePixelOfScreen(scr) ; else values.foreground = BlackPixelOfScreen(scr) ; values.fill_style = FillStippled ; values.stipple = XmuCreateStippledPixmap(XtScreen(w), 1L, 0L, 1) ; return XtAllocateGC(w, w->core.depth, GCForeground|GCBackground|GCStipple|GCFillStyle, &values, 0L, GCFont|GCSubwindowMode|GCGraphicsExposures| GCDashOffset|GCDashList|GCArcMode) ; } else { values.foreground = AllocShadowPixel(w, 100-contrast) ; return XtAllocateGC(w, w->core.depth, GCForeground, &values, 0L, GCBackground|GCFont|GCSubwindowMode|GCGraphicsExposures| GCDashOffset|GCDashList|GCArcMode) ; }}PixelAllocShadowPixel(w, scale) Widget w; int scale ;{ XColor get_c, set_c ; Display *dpy = XtDisplay(w) ; Screen *scr = XtScreen(w) ; Colormap cmap ; Pixel maxColor ; cmap = w->core.colormap ; get_c.pixel = w->core.background_pixel ; if( get_c.pixel == WhitePixelOfScreen(scr) || get_c.pixel == BlackPixelOfScreen(scr) ) { /* what we *ought* to do is choose gray75 as the base color, * or perhaps gray83. Instead, we choose colors that are * the same as ThreeD would choose. */ if( scale > 100 ) scale = 200 - scale ; set_c.red = set_c.green = set_c.blue = 65535*scale/100 ; } else { XQueryColor(dpy, cmap, &get_c) ; /* adjust scale so that brightest component does not * exceed 65535; otherwise hue would change. */ if( scale > 100 ) { maxColor = Max(get_c.red, Max(get_c.green, get_c.blue)) ; if( scale*maxColor > 65535*100 ) scale = 65535*100/maxColor ; } set_c.red = scale * get_c.red / 100 ; set_c.green = scale * get_c.green / 100 ; set_c.blue = scale * get_c.blue / 100 ; } if( XAllocColor(dpy, cmap, &set_c) ) return set_c.pixel ; else if( scale > 100 ) return WhitePixelOfScreen(scr) ; else return BlackPixelOfScreen(scr) ;} /* Allocate a pixel halfway between foreground and background */PixelAllocGreyPixel(w, fg, bg, cnt) Widget w ; Pixel fg, bg ; int cnt ;{ XColor get_cf, get_cb, set_c ; Display *dpy = XtDisplay(w) ; Colormap cmap ; cmap = w->core.colormap ; get_cf.pixel = fg ; get_cb.pixel = bg ; XQueryColor(dpy, cmap, &get_cf) ; XQueryColor(dpy, cmap, &get_cb) ; set_c.red = (get_cf.red * cnt + get_cb.red * (100-cnt)) / 100 ; set_c.green = (get_cf.green * cnt + get_cb.green * (100-cnt)) / 100 ; set_c.blue = (get_cf.blue * cnt + get_cb.blue * (100-cnt)) / 100 ; (void)XAllocColor(dpy, cmap, &set_c) ; return set_c.pixel ;} /* draw a 3-d box */voidDraw3dBox(w, x,y,wid,hgt,s, topgc, botgc) Widget w ; int x,y ; /* position */ int wid,hgt,s ; /* outside dimensions, shadow wid */ GC topgc ; GC botgc ;{ Display *dpy = XtDisplay(w) ; Window win = XtWindow(w) ; if( s == 0 ) return ; if( s == 1 ) { XDrawLine(dpy,win,botgc, x,y+hgt-1, x+wid-1,y+hgt-1) ; XDrawLine(dpy,win,botgc, x+wid-1,y, x+wid-1,y+hgt-1) ; XDrawLine(dpy,win,topgc, x,y, x,y+hgt-1) ; XDrawLine(dpy,win,topgc, x,y, x+wid-1,y) ; } else { XPoint pts[6] ; /* bottom-right shadow */ pts[0].x = x ; pts[0].y = y + hgt ; pts[1].x = s ; pts[1].y = -s ; pts[2].x = wid-2*s ; pts[2].y = 0 ; pts[3].x = 0 ; pts[3].y = -(hgt-2*s) ; pts[4].x = s ; pts[4].y = -s ; pts[5].x = 0 ; pts[5].y = hgt ; XFillPolygon(dpy,win,botgc, pts,6, Nonconvex,CoordModePrevious) ; /* top-left shadow */ pts[0].x = x ; pts[0].y = y ; pts[1].x = wid ; pts[1].y = 0 ; pts[2].x = -s ; pts[2].y = s ; pts[3].x = -wid+2*s ; pts[3].y = 0 ; pts[4].x = 0 ; pts[4].y = hgt-2*s ; pts[5].x = -s ; pts[5].y = s ; XFillPolygon(dpy,win,topgc, pts,6, Nonconvex,CoordModePrevious) ; }}#if XtSpecificationRelease < 5static GCXtAllocateGC(w, depth, mask, values, dynamic, dontcare) Widget w ; int depth ; unsigned long mask, dynamic, dontcare ; XGCValues *values ;{ return XtGetGC(w, mask, values) ;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -