1 /*
2 * Motif
3 *
4 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5 *
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)
10 * any later version.
11 *
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
16 * details.
17 *
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
22 *
23 */
24 /*
25 * HISTORY
26 */
27 #ifdef REV_INFO
28 #ifndef lint
29 static char rcsid[] = "$XConsortium: earth.c /main/5 1995/07/14 09:41:16 drk $"
30 #endif
31 #endif
32 /***************************************************************************
33 * earth.
34 * This demo illustrates the use of the R4 shape extension and Motif.
35 * Author: Daniel Dardailler.
36 *
37 * Effects by: Andrew deBlois
38 ***************************************************************************/
39 #define APP_CLASS "XmdEarth"
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <math.h>
44 #include <Xm/XmAll.h>
45 #include <X11/extensions/shape.h> /* R4 header required */
46 #include "terre.xbm" /* can cause compilation problem with
47 some gcc version, due of the size of
48 the bitmap array */
49 /*** Application default stuff */
50 typedef struct {
51 int speed;
52 XtIntervalId timeoutID;
53 Pixel foreground ;
54 Pixel background ;
55 Boolean persue;
56 } ApplicationData, *ApplicationDataPtr;
57 ApplicationData AppData;
58
59 #define PERSUE_ON_VALUE 94
60 #define PERSUE_OFF_VALUE -94
61 #define XmNspeed "speed"
62 #define XmCSpeed "Speed"
63 #define XmNpersue "persue"
64 #define XmCPersue "Persue"
65 static XtResource resources[] = {
66 {
67 XmNspeed, XmCSpeed, XmRInt, sizeof(int),
68 XtOffsetOf (ApplicationData, speed),
69 XmRImmediate, (caddr_t) 50 },
70
71 /* overwrite the default colors (doing that will lead to weird
72 behavior if you specify -fg or -bg on the command line, but
73 I really don't care, it's easier to use the standard names) */
74 {
75 XmNforeground, XmCForeground, XmRPixel, sizeof (Pixel),
76 XtOffsetOf (ApplicationData, foreground),
77 XmRString, "brown"},
78 {
79 XmNbackground, XmCBackground, XmRPixel, sizeof (Pixel),
80 XtOffsetOf (ApplicationData, background),
81 XmRString, "turquoise"},
82 {
83 XmNpersue, XmCPersue, XmRBoolean, sizeof (Boolean),
84 XtOffsetOf (ApplicationData, persue),
85 XmRImmediate, (caddr_t) 0}
86 };
87
88 static XrmOptionDescRec options[] = {
89 {"-speed", "*speed", XrmoptionSepArg, NULL},
90 } ;
91 /*** end of Application default stuff */
92
93 static XtAppContext app_con;
94 static Widget toplevel, draw ;
95 static Pixmap pterre ;
96 static GC gc ;
97 static int n ;
98
99 static void Syntax() ;
100 static void input_callback();
101 static void expose_callback();
102 static void speed_callback() ;
103 static void NextBitmap ();
104
delayInterval(speed)105 int delayInterval (speed)
106 /**************************/
107 int speed;
108 {
109 double maxDelay = 1000.0;
110 double val = (double)(abs(speed));
111
112
113 return (int)( maxDelay / val );
114 }
115
116 char *fallback[] = {
117 /* too bad there is no real converter for that stuff! */
118 "*mwmDecorations: 0",
119 "*XmDialogShell*mwmDecorations: 1",
120 NULL
121 };
122
123
main(argc,argv)124 int main(argc, argv) int argc; char **argv ;
125 /**************************************/
126 {
127 Arg args[10] ;
128 Cardinal n;
129
130 XGCValues values;
131 XtGCMask valueMask;
132 Pixmap shape_mask ;
133 XGCValues xgcv;
134 GC shapeGC ;
135 int shape_event_base,
136 shape_error_base; /* just used as dummy parameters */
137
138 /* Initialize, using my options */
139 toplevel = XtAppInitialize(&app_con, APP_CLASS,
140 options, XtNumber(options),
141 &argc, argv, fallback, NULL, 0);
142
143 /* if a bad option was reached, XtAppInitialize should let it */
144 if (argc > 1) Syntax(argv[0]) ;
145
146 /* read the programmer app default */
147 XtGetApplicationResources(toplevel,
148 (XtPointer)&AppData,
149 resources,
150 XtNumber(resources),
151 NULL,
152 0);
153
154 /* create a fixed size drawing area + callback for dialog popup */
155 n = 0 ;
156 XtSetArg(args[n], XmNwidth, 64); n++ ;
157 XtSetArg(args[n], XmNheight, 64); n++ ;
158 draw = XmCreateDrawingArea (toplevel, "draw", args, n);
159 XtManageChild(draw);
160 XtAddCallback(draw,XmNinputCallback,(XtCallbackProc)input_callback,NULL);
161 XtAddCallback(draw,XmNexposeCallback,(XtCallbackProc)expose_callback,NULL);
162
163 XtRealizeWidget(toplevel);
164
165 /* create the big bitmap on the server */
166 pterre = XCreateBitmapFromData (XtDisplay(toplevel),XtWindow(toplevel),
167 (char *)terre_bits,terre_width,terre_height) ;
168
169 /* create a GC for the earth colors */
170 valueMask = GCForeground | GCBackground ;
171 values.foreground = AppData.foreground ;
172 values.background = AppData.background ;
173 gc = XtGetGC ((Widget) toplevel, valueMask , &values);
174
175 /* if there is a shape extension, use it */
176 if (XShapeQueryExtension (XtDisplay (draw),
177 &shape_event_base,
178 &shape_error_base)) {
179 shape_mask = XCreatePixmap (XtDisplay (draw), XtWindow (draw),
180 64, 64, 1);
181 shapeGC = XCreateGC (XtDisplay (draw), shape_mask, 0, &xgcv);
182
183 /* erase the pixmap as a mask */
184 XSetForeground (XtDisplay (draw), shapeGC, 0);
185 XFillRectangle (XtDisplay (draw), shape_mask, shapeGC, 0,0, 64,64);
186 XSetForeground (XtDisplay (draw), shapeGC, 1);
187 /* draw the bounding/clipping shape : a circle */
188 XFillArc(XtDisplay (draw), shape_mask, shapeGC, 0,0, 64,64, 0,23040);
189 /* shape the parent for event managing and the widget for drawing */
190 XShapeCombineMask (XtDisplay (toplevel), XtWindow (toplevel),
191 ShapeBounding, 0,0, shape_mask, ShapeSet);
192 XShapeCombineMask (XtDisplay (draw), XtWindow (draw),
193 ShapeClip, 0,0, shape_mask, ShapeSet);
194 XFreePixmap (XtDisplay (draw), shape_mask);
195 /* don't ask me why I use alternatively draw and toplevel as
196 a parameter of XtDisplay, it doesn't matter at all */
197 } else {
198 fprintf(stderr,
199 "Bad news: there is no shape extension on your server...\n");
200 }
201
202 /* animation done in background */
203 AppData.timeoutID = XtAppAddTimeOut(app_con,
204 delayInterval(AppData.speed),
205 NextBitmap, NULL);
206
207 XtAppMainLoop(app_con);
208
209 return 0; /* make compiler happy */
210 }
211
NextBitmap(client_data,id)212 static void NextBitmap (client_data, id)
213 /****************************************************/
214 XtPointer client_data;
215 XtIntervalId *id;
216 {
217
218
219 AppData.timeoutID = 0;
220
221 if (AppData.speed != 0)
222 {
223 if (XtIsRealized(draw))
224 {
225 Position x, y;
226
227 if (AppData.speed > 0) n = (n>28)?0:n+1;
228 else n = (n>0)?n-1:29;
229
230 XCopyPlane (XtDisplay(draw), pterre, XtWindow(draw), gc,
231 0, 64*n, 64, 64, 0, 0, 1);
232
233 if (AppData.persue)
234 {
235 Position x, y;
236 int mx, my, ji;
237 Window jw;
238 unsigned int jk;
239
240 XtVaGetValues(toplevel, XmNx, &x, XmNy, &y, NULL);
241 XQueryPointer(XtDisplay(toplevel), XtWindow(toplevel),
242 &jw, &jw, &mx, &my, &ji, &ji, &jk);
243 XtVaSetValues(toplevel,XmNx, x+((mx-x)/10),XmNy,
244 y+((my-y)/10),NULL);
245 }
246 }
247
248 AppData.timeoutID = XtAppAddTimeOut(app_con,
249 delayInterval(AppData.speed),
250 NextBitmap, NULL);
251 }
252 }
253
254
expose_callback(widget,tag,callback_data)255 static void expose_callback(widget, tag, callback_data)
256 /****************************************************/
257 Widget widget ;
258 XtPointer tag ;
259 XtPointer callback_data ;
260 {
261 XCopyPlane (XtDisplay(draw), pterre, XtWindow(draw), gc,
262 0, 64*n, 64, 64, 0, 0, 1);
263 }
264
input_callback(widget,tag,callback_data)265 static void input_callback(widget, tag, callback_data)
266 /****************************************************/
267 Widget widget ;
268 XtPointer tag ;
269 XtPointer callback_data ;
270 {
271 XmDrawingAreaCallbackStruct * dacb = (XmDrawingAreaCallbackStruct *) callback_data ;
272 static Widget speed_dialog = NULL ;
273 Widget speed_scale ;
274 Arg args[15] ;
275 Cardinal n;
276 XmString title_string;
277
278
279 if ((dacb->event->type == ButtonPress) &&
280 (dacb->event->xbutton.button == Button3))
281 {
282 if (speed_dialog == NULL) {
283 speed_dialog = XmCreateFormDialog(toplevel,
284 "Speed control",
285 NULL, 0) ;
286 n = 0 ;
287 title_string = XmStringGenerate("rotation speed", NULL,
288 XmCHARSET_TEXT, NULL);
289 XtSetArg(args[n], XmNtitleString, title_string); n++ ;
290 XtSetArg(args[n], XmNshowValue, True); n++ ;
291 XtSetArg(args[n], XmNvalue, AppData.speed); n++ ;
292 XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++ ;
293 XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
294 XtSetArg(args[n], XmNleftPosition, 10); n++;
295 XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
296 XtSetArg(args[n], XmNrightPosition, 90); n++;
297 XtSetArg(args[n], XmNminimum, -100); n++;
298 XtSetArg(args[n], XmNmaximum, 100); n++;
299 speed_scale = XmCreateScale(speed_dialog,
300 "speed_scale",
301 args, n) ;
302 XtAddCallback(speed_scale,XmNdragCallback,
303 (XtCallbackProc)speed_callback,NULL);
304 XtAddCallback(speed_scale,XmNvalueChangedCallback,
305 (XtCallbackProc)speed_callback,NULL);
306 XtManageChild(speed_scale);
307 }
308
309 XtManageChild(speed_dialog);
310 if (AppData.speed == PERSUE_ON_VALUE) AppData.persue = TRUE;
311 else
312 if (AppData.speed == PERSUE_OFF_VALUE) AppData.persue = FALSE;
313 }
314 }
315
316
speed_callback(widget,tag,callback_data)317 static void speed_callback(widget, tag, callback_data)
318 /******************************************************/
319 Widget widget ;
320 XtPointer tag ;
321 XtPointer callback_data ;
322 {
323 XmScaleCallbackStruct * scb =
324 (XmScaleCallbackStruct *) callback_data ;
325
326
327 if ((AppData.speed == 0) && (scb->value != 0))
328 {
329 AppData.speed = scb->value;
330 if (AppData.timeoutID != 0) XtRemoveTimeOut(AppData.timeoutID);
331 XtAppAddTimeOut(app_con, delayInterval(AppData.speed), NextBitmap, NULL);
332 }
333 else
334 AppData.speed = scb->value ;
335 }
336
337
Syntax(com)338 static void Syntax(com) char * com ;
339 /**********************************/
340 {
341 fprintf(stderr, "%s understands all standard Xt options, plus:\n",com);
342 fprintf(stderr, " -speed: -100,100 (earth rotation speed)\n");
343 }
344
345
346