SmeLine.c revision 5ec34c4c
1/*
2Copyright 1989, 1998  The Open Group
3
4Permission to use, copy, modify, distribute, and sell this software and its
5documentation for any purpose is hereby granted without fee, provided that
6the above copyright notice appear in all copies and that both that
7copyright notice and this permission notice appear in supporting
8documentation.
9
10The above copyright notice and this permission notice shall be included in
11all copies or substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
16OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
17AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
20Except as contained in this notice, the name of The Open Group shall not be
21used in advertising or otherwise to promote the sale, use or other dealings
22in 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@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 */
51static void XawSmeLineDestroy(Widget);
52static void XawSmeLineInitialize(Widget, Widget, ArgList, Cardinal*);
53static void XawSmeLineRedisplay(Widget, XEvent*, Region);
54static Boolean XawSmeLineSetValues(Widget, Widget, Widget,
55				   ArgList, Cardinal*);
56
57/*
58 * Prototypes
59 */
60static void CreateGC(Widget);
61static void DestroyGC(Widget);
62
63/*
64 * Initialization
65 */
66#define offset(field)	XtOffsetOf(SmeLineRec, sme_line.field)
67static 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)
99SmeLineClassRec 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
148WidgetClass smeLineObjectClass = (WidgetClass)&smeLineClassRec;
149
150/*
151 * Implementation
152 */
153/*ARGSUSED*/
154static void
155XawSmeLineInitialize(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 */
180static void
181CreateGC(Widget w)
182{
183    SmeLineObject entry = (SmeLineObject)w;
184    XGCValues values;
185    XtGCMask mask = GCForeground | GCGraphicsExposures | GCLineWidth;
186
187    values.foreground = entry->sme_line.foreground;
188    values.graphics_exposures = False;
189    values.line_width = entry->sme_line.line_width;
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
204static void
205XawSmeLineDestroy(Widget w)
206{
207    DestroyGC(w);
208}
209
210static void
211DestroyGC(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*/
222static void
223XawSmeLineRedisplay(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*/
249static Boolean
250XawSmeLineSetValues(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