1 /* 2 Copyright 1989, 1998 The Open Group 3 4 Permission to use, copy, modify, distribute, and sell this software and its 5 documentation for any purpose is hereby granted without fee, provided that 6 the above copyright notice appear in all copies and that both that 7 copyright notice and this permission notice appear in supporting 8 documentation. 9 10 The above copyright notice and this permission notice shall be included in 11 all copies or substantial portions of the Software. 12 13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 17 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 20 Except as contained in this notice, the name of The Open Group shall not be 21 used in advertising or otherwise to promote the sale, use or other dealings 22 in this Software without prior written authorization from The Open Group. 23 * 24 * Author: Chris D. Peterson, MIT X Consortium 25 */ 26 27 /* 28 * Sme.c - Source code for the generic menu entry 29 * 30 * Date: September 26, 1989 31 * 32 * By: Chris D. Peterson 33 * MIT X Consortium 34 * kit (at) expo.lcs.mit.edu 35 */ 36 37 #ifdef HAVE_CONFIG_H 38 #include <config.h> 39 #endif 40 #include <stdio.h> 41 #include <X11/IntrinsicP.h> 42 #include <X11/StringDefs.h> 43 #include <X11/Xaw/Cardinals.h> 44 #include <X11/Xaw/SmeLineP.h> 45 #include <X11/Xaw/XawInit.h> 46 #include "Private.h" 47 48 /* 49 * Class Methods 50 */ 51 static void XawSmeLineDestroy(Widget); 52 static void XawSmeLineInitialize(Widget, Widget, ArgList, Cardinal*); 53 static void XawSmeLineRedisplay(Widget, XEvent*, Region); 54 static Boolean XawSmeLineSetValues(Widget, Widget, Widget, 55 ArgList, Cardinal*); 56 57 /* 58 * Prototypes 59 */ 60 static void CreateGC(Widget); 61 static void DestroyGC(Widget); 62 63 /* 64 * Initialization 65 */ 66 #define offset(field) XtOffsetOf(SmeLineRec, sme_line.field) 67 static XtResource resources[] = { 68 { 69 XtNlineWidth, 70 XtCLineWidth, 71 XtRDimension, 72 sizeof(Dimension), 73 offset(line_width), 74 XtRImmediate, 75 (XtPointer)1 76 }, 77 { 78 XtNstipple, 79 XtCStipple, 80 XtRBitmap, 81 sizeof(Pixmap), 82 offset(stipple), 83 XtRImmediate, 84 (XtPointer)XtUnspecifiedPixmap 85 }, 86 { 87 XtNforeground, 88 XtCForeground, 89 XtRPixel, 90 sizeof(Pixel), 91 offset(foreground), 92 XtRString, 93 (XtPointer)XtDefaultForeground 94 }, 95 }; 96 #undef offset 97 98 #define Superclass (&smeClassRec) 99 SmeLineClassRec smeLineClassRec = { 100 /* rectangle */ 101 { 102 (WidgetClass)Superclass, /* superclass */ 103 "SmeLine", /* class_name */ 104 sizeof(SmeLineRec), /* widget_size */ 105 XawInitializeWidgetSet, /* class_initialize */ 106 NULL, /* class_part_initialize */ 107 False, /* class inited */ 108 XawSmeLineInitialize, /* initialize */ 109 NULL, /* initialize_hook */ 110 NULL, /* realize */ 111 NULL, /* actions */ 112 0, /* num_actions */ 113 resources, /* resources */ 114 XtNumber(resources), /* num_resources */ 115 NULLQUARK, /* xrm_class */ 116 False, /* compress_motion */ 117 False, /* compress_exposure */ 118 False, /* compress_enterleave */ 119 False, /* visible_interest */ 120 XawSmeLineDestroy, /* destroy */ 121 NULL, /* resize */ 122 XawSmeLineRedisplay, /* expose */ 123 XawSmeLineSetValues, /* set_values */ 124 NULL, /* set_values_hook */ 125 XtInheritSetValuesAlmost, /* set_values_almost */ 126 NULL, /* get_values_hook */ 127 NULL, /* accept_focus */ 128 XtVersion, /* intrinsics version */ 129 NULL, /* callback offsets */ 130 NULL, /* tm_table */ 131 XtInheritQueryGeometry, /* query_geometry */ 132 NULL, /* display_accelerator */ 133 NULL, /* extension */ 134 }, 135 /* sme */ 136 { 137 XtInheritHighlight, /* highlight */ 138 XtInheritUnhighlight, /* unhighlight */ 139 XtInheritNotify, /* notify */ 140 NULL, /* extension */ 141 }, 142 /* sme_line */ 143 { 144 NULL, /* extension */ 145 } 146 }; 147 148 WidgetClass smeLineObjectClass = (WidgetClass)&smeLineClassRec; 149 150 /* 151 * Implementation 152 */ 153 /*ARGSUSED*/ 154 static void 155 XawSmeLineInitialize(Widget request _X_UNUSED, Widget cnew, 156 ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED) 157 { 158 SmeLineObject entry = (SmeLineObject)cnew; 159 160 if (XtHeight(entry) == 0) 161 XtHeight(entry) = entry->sme_line.line_width; 162 163 CreateGC(cnew); 164 } 165 166 /* 167 * Function: 168 * CreateGC 169 * 170 * Parameters: 171 * w - Line entry widget 172 * 173 * Description: 174 * Creates the GC for the line entry widget. 175 * 176 * Note: 177 * We can only share the GC if there is no stipple, because 178 * we need to change the stipple origin when drawing 179 */ 180 static void 181 CreateGC(Widget w) 182 { 183 SmeLineObject entry = (SmeLineObject)w; 184 XtGCMask mask = GCForeground | GCGraphicsExposures | GCLineWidth; 185 XGCValues values = { 186 .foreground = entry->sme_line.foreground, 187 .graphics_exposures = False, 188 .line_width = entry->sme_line.line_width 189 }; 190 191 if (entry->sme_line.stipple != XtUnspecifiedPixmap) { 192 values.stipple = entry->sme_line.stipple; 193 values.fill_style = FillStippled; 194 mask |= GCStipple | GCFillStyle; 195 196 entry->sme_line.gc = XCreateGC(XtDisplayOfObject(w), 197 RootWindowOfScreen(XtScreenOfObject(w)), 198 mask, &values); 199 } 200 else 201 entry->sme_line.gc = XtGetGC(w, mask, &values); 202 } 203 204 static void 205 XawSmeLineDestroy(Widget w) 206 { 207 DestroyGC(w); 208 } 209 210 static void 211 DestroyGC(Widget w) 212 { 213 SmeLineObject entry = (SmeLineObject)w; 214 215 if (entry->sme_line.stipple != XtUnspecifiedPixmap) 216 XFreeGC(XtDisplayOfObject(w), entry->sme_line.gc); 217 else 218 XtReleaseGC(w, entry->sme_line.gc); 219 } 220 221 /*ARGSUSED*/ 222 static void 223 XawSmeLineRedisplay(Widget w, XEvent *event _X_UNUSED, Region region _X_UNUSED) 224 { 225 SmeLineObject entry = (SmeLineObject)w; 226 int y = XtY(w) + (((int)XtHeight(w) - entry->sme_line.line_width) >> 1); 227 228 if (entry->sme_line.stipple != XtUnspecifiedPixmap) 229 XSetTSOrigin(XtDisplayOfObject(w), entry->sme_line.gc, 0, y); 230 231 XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w), 232 entry->sme_line.gc, XtX(w), y, 233 XtWidth(w), entry->sme_line.line_width); 234 } 235 236 /* 237 * Function: 238 * XawSmeLineSetValues 239 * 240 * Parameters: 241 * current - current state of the widget 242 * request - what was requested 243 * cnew - what the widget will become 244 * 245 * Description: 246 * Relayout the menu when one of the resources is changed. 247 */ 248 /*ARGSUSED*/ 249 static Boolean 250 XawSmeLineSetValues(Widget current, Widget request _X_UNUSED, Widget cnew, 251 ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED) 252 { 253 SmeLineObject entry = (SmeLineObject)cnew; 254 SmeLineObject old_entry = (SmeLineObject)current; 255 256 if (entry->sme_line.line_width != old_entry->sme_line.line_width && 257 entry->sme_line.stipple != old_entry->sme_line.stipple) { 258 DestroyGC(current); 259 CreateGC(cnew); 260 return (True); 261 } 262 263 return (False); 264 } 265