1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10 #include "../base/defines.h"
11
12 #include <Xm/DialogS.h>
13 #include <Xm/DrawP.h>
14
15 #ifdef OS2
16 #include <stdlib.h>
17 #include <types.h>
18 #endif
19
20 #include "VCRControl.h"
21 #include "VCRControlP.h"
22 #include "backward.bm"
23 #include "forward.bm"
24 /* #include "frame.bm" */
25 #include "loop.bm"
26 #include "palim.bm"
27 #include "pause.bm"
28 #include "step.bm"
29 #include "stepb.bm"
30 #include "stepf.bm"
31 #include "stop.bm"
32
33 #ifndef MIN
34 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
35 #endif
36 #ifndef MAX
37 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
38 #endif
39
40
41
42 extern void _XmForegroundColorDefault();
43 extern void _XmBackgroundColorDefault();
44
45 static XtResource resources[] =
46 {
47 {
48 XmNactionCallback,XmCActionCallback, XmRCallback, sizeof(XtPointer),
49 XtOffset(XmVCRControlWidget, vcr_control.action_callback),
50 XmRCallback, NULL
51 },
52 {
53 XmNframeCallback, XmCFrameCallback, XmRCallback, sizeof(XtPointer),
54 XtOffset(XmVCRControlWidget, vcr_control.frame_callback),
55 XmRCallback, NULL
56 },
57 {
58 XmNstart, XmCStart, XmRShort, sizeof(short),
59 XtOffset(XmVCRControlWidget, vcr_control.start_value),
60 XmRImmediate, (XtPointer) 0
61 },
62 {
63 XmNnext, XmCNext, XmRShort, sizeof(short),
64 XtOffset(XmVCRControlWidget, vcr_control.next_value),
65 XmRImmediate, (XtPointer) 0
66 },
67 {
68 XmNcurrent, XmCCurrent, XmRShort, sizeof(short),
69 XtOffset(XmVCRControlWidget, vcr_control.current_value),
70 XmRImmediate, (XtPointer) 0
71 },
72 {
73 XmNcurrentVisible,XmCCurrentVisible,XmRBoolean, sizeof(Boolean),
74 XtOffset(XmVCRControlWidget, vcr_control.current_visible),
75 XmRImmediate, (XtPointer) True
76 },
77 {
78 XmNstop, XmCStop, XmRShort, sizeof(short),
79 XtOffset(XmVCRControlWidget, vcr_control.stop_value),
80 XmRImmediate, (XtPointer) 0
81 },
82 {
83 XmNminimum, XmCMinimum, XmRShort, sizeof(short),
84 XtOffset(XmVCRControlWidget, vcr_control.min_value),
85 XmRImmediate, (XtPointer) 1
86 },
87 {
88 XmNmaximum, XmCMaximum, XmRShort, sizeof(short),
89 XtOffset(XmVCRControlWidget, vcr_control.max_value),
90 XmRImmediate, (XtPointer) 10
91 },
92 {
93 XmNincrement, XmCIncrement, XmRShort, sizeof(short),
94 XtOffset(XmVCRControlWidget, vcr_control.frame_increment),
95 XmRImmediate, (XtPointer) 1
96 },
97 {
98 XmNforwardButtonState, XmCForwardButtonState, XmRBoolean, sizeof(Boolean),
99 XtOffset(XmVCRControlWidget, vcr_control.button_is_in[VCR_FORWARD]),
100 XmRImmediate, (XtPointer) 0
101 },
102 {
103 XmNbackwardButtonState,XmCBackwardButtonState,XmRBoolean, sizeof(Boolean),
104 XtOffset(XmVCRControlWidget, vcr_control.button_is_in[VCR_BACKWARD]),
105 XmRImmediate, (XtPointer) 0
106 },
107 {
108 XmNloopButtonState, XmCLoopButtonState, XmRBoolean, sizeof(Boolean),
109 XtOffset(XmVCRControlWidget, vcr_control.button_is_in[VCR_LOOP]),
110 XmRImmediate, (XtPointer) 0
111 },
112 {
113 XmNpalindromeButtonState, XmCPalindromeButtonState, XmRBoolean, sizeof(Boolean),
114 XtOffset(XmVCRControlWidget, vcr_control.button_is_in[VCR_PALINDROME]),
115 XmRImmediate, (XtPointer) 0
116 },
117 {
118 XmNstepButtonState, XmCStepButtonState, XmRBoolean, sizeof(Boolean),
119 XtOffset(XmVCRControlWidget, vcr_control.button_is_in[VCR_STEP]),
120 XmRImmediate, (XtPointer) 0
121 },
122 {
123 XmNcountButtonState, XmCCountButtonState, XmRBoolean, sizeof(Boolean),
124 XtOffset(XmVCRControlWidget, vcr_control.button_is_in[VCR_COUNT]),
125 XmRImmediate, (XtPointer) 0
126 },
127 {
128 XmNlimitColor, XmCLimitColor, XmRPixel, sizeof(Pixel),
129 XtOffset(XmVCRControlWidget, vcr_control.limit_color),
130 XmRCallProc, (XtPointer) _XmForegroundColorDefault
131 },
132 {
133 XmNnextColor, XmCNextColor, XmRPixel, sizeof(Pixel),
134 XtOffset(XmVCRControlWidget, vcr_control.next_color),
135 XmRCallProc, (XtPointer) _XmForegroundColorDefault
136 },
137 {
138 XmNcurrentColor, XmCCurrentColor, XmRPixel, sizeof(Pixel),
139 XtOffset(XmVCRControlWidget, vcr_control.current_color),
140 XmRCallProc, (XtPointer) _XmForegroundColorDefault
141 },
142 {
143 XmNframeSensitive, XmCFrameSensitive, XmRBoolean, sizeof(Boolean),
144 XtOffset(XmVCRControlWidget, vcr_control.frame_sensitive),
145 XmRImmediate, (XtPointer) TRUE
146 },
147 {
148 XmNminSensitive, XmCMinSensitive, XmRBoolean, sizeof(Boolean),
149 XtOffset(XmVCRControlWidget, vcr_control.min_sensitive),
150 XmRImmediate, (XtPointer) TRUE
151 },
152 {
153 XmNmaxSensitive, XmCMaxSensitive, XmRBoolean, sizeof(Boolean),
154 XtOffset(XmVCRControlWidget, vcr_control.max_sensitive),
155 XmRImmediate, (XtPointer) TRUE
156 },
157 {
158 XmNincSensitive, XmCIncSensitive, XmRBoolean, sizeof(Boolean),
159 XtOffset(XmVCRControlWidget, vcr_control.inc_sensitive),
160 XmRImmediate, (XtPointer) TRUE
161 },
162 };
163
164
165 /* Maintain actions support for basic manager functioning */
166 static char defaultTranslations[] =
167 "<EnterWindow>: Enter() \n\
168 <FocusIn>: FocusIn()";
169
170 extern void _XmManagerEnter();
171 extern void _XmManagerFocusIn();
172
173 static XtActionsRec actionsList[] =
174 {
175 { "Enter", (XtActionProc) _XmManagerEnter },
176 { "FocusIn", (XtActionProc) _XmManagerFocusIn },
177 };
178
179
180 /****************************************************************
181 *
182 * Full class record constant
183 *
184 ****************************************************************/
185
186 static void Initialize(XmVCRControlWidget request, XmVCRControlWidget new);
187 static Boolean SetValues(XmVCRControlWidget current,
188 XmVCRControlWidget request,
189 XmVCRControlWidget new);
190 static void Destroy(XmVCRControlWidget w);
191 static void MyRealize(XmVCRControlWidget w, XtValueMask *valueMask,
192 XSetWindowAttributes *attributes);
193 static void SimulateButtonPress(XmVCRControlWidget vcr, int button_num);
194
195 XmVCRControlClassRec xmVCRControlClassRec =
196 {
197 { /* core_class fields */
198 (WidgetClass) &xmFormClassRec, /* superclass */
199 "XmVCRControl", /* class_name */
200 sizeof(XmVCRControlRec), /* widget_size */
201 NULL, /* class_initialize */
202 NULL, /* class_part_init */
203 FALSE, /* class_inited */
204 (XtInitProc) Initialize, /* initialize */
205 NULL, /* initialize_hook */
206 (XtRealizeProc)MyRealize, /* realize */
207 actionsList, /* actions */
208 XtNumber(actionsList), /* num_actions */
209 resources, /* resources */
210 XtNumber(resources), /* num_resources */
211 NULLQUARK, /* xrm_class */
212 TRUE, /* compress_motion */
213 TRUE, /* compress_exposure */
214 TRUE, /* compress_enterlv */
215 FALSE, /* visible_interest */
216 (XtWidgetProc) Destroy, /* destroy */
217 (XtWidgetProc) XtInheritResize, /* resize */
218 (XtExposeProc)_XtInherit,/*(XtExposeProc) Redisplay,*//* expose */
219 (XtSetValuesFunc) SetValues, /* set_values */
220 NULL, /* set_values_hook */
221 (XtAlmostProc)_XtInherit, /* set_values_almost */
222 NULL, /* get_values_hook */
223 NULL, /* accept_focus */
224 XtVersion, /* version */
225 NULL, /* callback_private */
226 defaultTranslations, /* tm_table */
227 XtInheritQueryGeometry, /* query_geometry */
228 NULL, /* display_accelerator */
229 NULL, /* extension */
230 },
231
232 { /* composite_class fields */
233 XtInheritGeometryManager, /* geometry _manager */
234 XtInheritChangeManaged, /* change_managed */
235 (XtWidgetProc)_XtInherit, /* insert_child */
236 XtInheritDeleteChild, /* delete_child */
237 NULL, /* extension */
238 },
239
240 { /* constraint_class fields */
241 NULL, /* resource list */
242 0, /* num resources */
243 sizeof(XmFormConstraintRec), /* constraint size */
244 NULL, /* init proc */
245 NULL, /* destroy proc */
246 NULL, /* set values proc */
247 NULL, /* extension */
248 },
249
250 { /* manager_class fields */
251 #if (XmVersion >= 1001)
252 XtInheritTranslations, /* translations */
253 #else
254 (XtTranslations)_XtInherit, /* translations */
255 #endif
256 NULL, /* get resources */
257 0, /* num get_resources */
258 NULL, /* get_cont_resources */
259 0, /* num_get_cont_resources */
260 (XmParentProcessProc)NULL, /* parent_process */
261 NULL, /* extension */
262 },
263
264 { /* bulletin board widget class */
265 False, /* install_accelarators */
266 NULL, /* install_accelarators */
267 NULL, /* install_accelarators */
268 NULL, /* extension */
269 },
270
271 { /* form widget class */
272 NULL, /* extension */
273 },
274
275 { /* vcr_control class - none */
276 NULL, /* mumble */
277 }
278 };
279
280 WidgetClass xmVCRControlWidgetClass = (WidgetClass) &xmVCRControlClassRec;
281
282 /* Define interval of showing momentary button as depressed */
283
284 #define SHORT_WAIT 150
285 #define LONG_WAIT 500
286 #define MAX_VAL(a,b) ((a)>(b)?(a):(b))
287 #define MIN_VAL(a,b) ((a)<(b)?(a):(b))
288 #define superclass (&widgetClassRec)
289
290 static void SetLabel();
291 static void CreateVCRCounter();
292 static void VCRButtonResize();
293 static void _VCRButtonEvent();
294 static void VCRButtonEvent();
295 static void VCRButtonExpose();
296 static void VCRCounterExpose();
297 static void ReleaseVCRButton();
298 static void PushVCRButton();
299 static void ReleaseModeButtons();
300 static void ReplaceFrame();
301 void ChangeVCRStopValue( XmVCRControlWidget vcr, int value, Boolean to_vcr,
302 Boolean to_frame_control, Boolean to_outside );
303 void ChangeVCRStartValue( XmVCRControlWidget vcr, int value, Boolean to_vcr,
304 Boolean to_frame_control, Boolean to_outside );
305 void ChangeVCRNextValue( XmVCRControlWidget vcr, int value, Boolean to_vcr,
306 Boolean to_frame_control, Boolean to_outside );
307 void ChangeVCRCurrentValue( XmVCRControlWidget vcr, int value, Boolean to_vcr,
308 Boolean to_frame_control, Boolean to_outside );
309 void ChangeVCRIncrementValue( XmVCRControlWidget vcr, int increment,
310 Boolean to_vcr, Boolean to_frame_control,
311 Boolean to_outside );
312 static void PopdownCallback();
313 static void map_dialog();
314 static void FrameControlCallback();
315
316 /* Subroutine: Initialize
317 * Effect: Create and initialize the component widgets
318 */
319
Initialize(XmVCRControlWidget request,XmVCRControlWidget new)320 static void Initialize( XmVCRControlWidget request, XmVCRControlWidget new )
321 {
322 Arg wargs[20];
323
324 if (request->core.width == 0)
325 new->core.width = 240;
326 if (request->core.height == 0)
327 new->core.height = 60;
328
329 new->vcr_control.last_frame_control_press = -1; /* Net pressed yet */
330
331 new->vcr_control.parent = XtParent(new);
332
333 new->vcr_control.button_timeout = (XtIntervalId)NULL;
334
335 /*
336 * Check min and max relative to each other
337 */
338 if( request->vcr_control.max_value < request->vcr_control.min_value )
339 new->vcr_control.max_value = new->vcr_control.min_value;
340
341 /*
342 * Check current and next relative to min.
343 */
344 if( request->vcr_control.next_value < request->vcr_control.min_value )
345 new->vcr_control.next_value = new->vcr_control.min_value;
346 if( request->vcr_control.current_value < request->vcr_control.min_value )
347 new->vcr_control.current_value = new->vcr_control.min_value;
348
349 /*
350 * Check current and next relative to max.
351 */
352 if( request->vcr_control.next_value > request->vcr_control.max_value )
353 new->vcr_control.next_value = new->vcr_control.max_value;
354 if( request->vcr_control.current_value > request->vcr_control.max_value )
355 new->vcr_control.current_value = new->vcr_control.max_value;
356
357 new->vcr_control.step_being_held = FALSE;
358 new->vcr_control.frame_control_is_up = FALSE;
359
360 /* Init all non-resource buttons to the up state */
361 new->vcr_control.button_is_in[VCR_STOP] = FALSE;
362 new->vcr_control.button_is_in[VCR_PAUSE] = FALSE;
363 new->vcr_control.button_is_in[VCR_FORWARD_STEP] = FALSE;
364 new->vcr_control.button_is_in[VCR_BACKWARD_STEP] = FALSE;
365
366
367 /* Loop */
368 XtSetArg(wargs[0], XmNleftAttachment, XmATTACH_POSITION);
369 XtSetArg(wargs[1], XmNrightAttachment, XmATTACH_POSITION);
370 XtSetArg(wargs[2], XmNtopAttachment, XmATTACH_FORM);
371 XtSetArg(wargs[3], XmNbottomAttachment, XmATTACH_POSITION);
372 XtSetArg(wargs[4], XmNleftPosition, 0);
373 XtSetArg(wargs[5], XmNrightPosition, 25);
374 XtSetArg(wargs[6], XmNtopPosition, 0);
375 XtSetArg(wargs[7], XmNbottomPosition, 50);
376 XtSetArg(wargs[8], XmNshadowType, XmSHADOW_OUT);
377 new->vcr_control.frame[VCR_LOOP] =
378 (XmFrameWidget)XmCreateFrame((Widget)new, "loop", wargs, 9);
379 SetLabel(new, VCR_LOOP, loop_bits, loop_width, loop_height);
380
381 /* Palindrome */
382 XtSetArg(wargs[4], XmNleftPosition, 25);
383 XtSetArg(wargs[5], XmNrightPosition, 50);
384 new->vcr_control.frame[VCR_PALINDROME] =
385 (XmFrameWidget)XmCreateFrame((Widget)new, "palindrome", wargs, 9);
386 SetLabel(new, VCR_PALINDROME, palim_bits, palim_width, palim_height);
387
388 /* Step */
389 XtSetArg(wargs[4], XmNleftPosition, 50);
390 XtSetArg(wargs[5], XmNrightPosition, 75);
391 new->vcr_control.frame[VCR_STEP] =
392 (XmFrameWidget)XmCreateFrame((Widget)new, "step", wargs, 9);
393 SetLabel(new, VCR_STEP, step_bits, step_width, step_height);
394
395 /* Counter */
396 XtSetArg(wargs[4], XmNleftPosition, 75);
397 XtSetArg(wargs[5], XmNrightPosition, 100);
398 new->vcr_control.frame[VCR_COUNT] =
399 (XmFrameWidget)XmCreateFrame((Widget)new, "frame", wargs, 9);
400 CreateVCRCounter(new);
401
402 /* Backward */
403 XtSetArg(wargs[2], XmNtopAttachment, XmATTACH_POSITION);
404 XtSetArg(wargs[4], XmNleftPosition, 0);
405 XtSetArg(wargs[5], XmNrightPosition, 25);
406 XtSetArg(wargs[6], XmNtopPosition, 50);
407 XtSetArg(wargs[7], XmNbottomPosition, 100);
408 new->vcr_control.frame[VCR_BACKWARD] =
409 (XmFrameWidget)XmCreateFrame((Widget)new, "backward", wargs, 9);
410 SetLabel(new, VCR_BACKWARD, backward_bits, backward_width, backward_height);
411
412 /* Forward */
413 XtSetArg(wargs[4], XmNleftPosition, 25);
414 XtSetArg(wargs[5], XmNrightPosition, 50);
415 new->vcr_control.frame[VCR_FORWARD] =
416 (XmFrameWidget)XmCreateFrame((Widget)new, "forward", wargs, 9);
417 SetLabel(new, VCR_FORWARD, forward_bits, forward_width, forward_height);
418
419 /* Stop */
420 XtSetArg(wargs[4], XmNleftPosition, 50);
421 XtSetArg(wargs[5], XmNrightPosition, 62);
422 new->vcr_control.frame[VCR_STOP] =
423 (XmFrameWidget)XmCreateFrame((Widget)new, "stop", wargs, 9);
424 SetLabel(new, VCR_STOP, stop_bits, stop_width, stop_height);
425
426 /* Pause */
427 XtSetArg(wargs[4], XmNleftPosition, 62);
428 XtSetArg(wargs[5], XmNrightPosition, 100);
429 new->vcr_control.frame[VCR_PAUSE] =
430 (XmFrameWidget) XmCreateFrame((Widget)new, "pause", wargs, 9);
431 SetLabel(new, VCR_PAUSE, pause_bits, pause_width, pause_height);
432 XtManageChildren((Widget*)new->vcr_control.frame, 8);
433
434 /* Forward Step */
435 new->vcr_control.frame[VCR_FORWARD_STEP] =
436 (XmFrameWidget)XmCreateFrame((Widget)new, "stepf", wargs, 9);
437 SetLabel(new, VCR_FORWARD_STEP, stepf_bits, stepf_width, stepf_height);
438
439 /* Backward Step */
440 new->vcr_control.frame[VCR_BACKWARD_STEP] =
441 (XmFrameWidget)XmCreateFrame((Widget)new, "stepb", wargs, 9);
442 SetLabel(new, VCR_BACKWARD_STEP, stepb_bits, stepb_width, stepb_height);
443
444 XtSetArg(wargs[0], XmNwidth, 400);
445 XtSetArg(wargs[1], XmNheight, 180);
446 XtSetArg(wargs[2], XmNdeleteResponse, XmUNMAP);
447 XtSetArg(wargs[3], XmNallowShellResize, True);
448 XtSetArg(wargs[4], XmNminWidth, 380);
449 XtSetArg(wargs[5], XmNminHeight, 160);
450
451 new->vcr_control.shell = XmCreateDialogShell((Widget)new, "Frame Control",
452 wargs, 6);
453
454 XtSetArg(wargs[2], XmNstart, new->vcr_control.start_value);
455 XtSetArg(wargs[3], XmNnext, new->vcr_control.next_value);
456 XtSetArg(wargs[4], XmNcurrent, new->vcr_control.current_value);
457 XtSetArg(wargs[5], XmNstop, new->vcr_control.stop_value);
458 XtSetArg(wargs[6], XmNminimum, new->vcr_control.min_value);
459 XtSetArg(wargs[7], XmNincrement, new->vcr_control.frame_increment);
460 XtSetArg(wargs[8], XmNmaximum, new->vcr_control.max_value);
461 XtSetArg(wargs[9], XmNnextColor, new->vcr_control.next_color);
462 XtSetArg(wargs[10], XmNcurrentColor, new->vcr_control.current_color);
463 XtSetArg(wargs[11], XmNlimitColor, new->vcr_control.limit_color);
464 XtSetArg(wargs[12], XmNcurrentVisible, new->vcr_control.current_visible);
465 XtSetArg(wargs[13], XmNdefaultPosition, False);
466 new->vcr_control.frame_control = (XmFrameControlWidget)XmCreateFrameControl(
467 (Widget)new->vcr_control.shell, "frame_control", wargs, 14);
468
469
470 XtAddCallback((Widget)new->vcr_control.frame_control, XmNvalueCallback,
471 (XtCallbackProc)FrameControlCallback, new);
472 XtAddCallback((Widget)new->vcr_control.shell, XmNpopdownCallback,
473 (XtCallbackProc)PopdownCallback, new);
474 XtAddCallback((Widget)new->vcr_control.frame_control, XmNmapCallback,
475 (XtCallbackProc)map_dialog, new);
476 }
477
478 #undef MIN_VAL
479 #undef MAX_VAL
MyRealize(XmVCRControlWidget w,XtValueMask * valueMask,XSetWindowAttributes * attributes)480 static void MyRealize(XmVCRControlWidget w, XtValueMask *valueMask,
481 XSetWindowAttributes *attributes)
482 {
483
484 /* Call the superclass Realize */
485 (*superclass->core_class.realize)((Widget)w, valueMask, attributes);
486 if (w->vcr_control.button_is_in[VCR_COUNT]) {
487 w->vcr_control.button_is_in[VCR_COUNT] = FALSE;
488 SimulateButtonPress(w, VCR_COUNT);
489 }
490 XtRealizeWidget((Widget)w->vcr_control.frame[VCR_BACKWARD]);
491 XtRealizeWidget((Widget)w->vcr_control.button[VCR_BACKWARD]);
492 if (w->vcr_control.button_is_in[VCR_BACKWARD]) {
493 w->vcr_control.button_is_in[VCR_BACKWARD] = FALSE;
494 SimulateButtonPress(w, VCR_BACKWARD);
495 }
496 XtRealizeWidget((Widget)w->vcr_control.frame[VCR_FORWARD]);
497 XtRealizeWidget((Widget)w->vcr_control.button[VCR_FORWARD]);
498 if (w->vcr_control.button_is_in[VCR_FORWARD]) {
499 w->vcr_control.button_is_in[VCR_FORWARD] = FALSE;
500 SimulateButtonPress(w, VCR_FORWARD);
501 }
502 XtRealizeWidget((Widget)w->vcr_control.frame[VCR_LOOP]);
503 XtRealizeWidget((Widget)w->vcr_control.button[VCR_LOOP]);
504 if (w->vcr_control.button_is_in[VCR_LOOP]) {
505 w->vcr_control.button_is_in[VCR_LOOP] = FALSE;
506 SimulateButtonPress(w, VCR_LOOP);
507 }
508 XtRealizeWidget((Widget)w->vcr_control.frame[VCR_STEP]);
509 XtRealizeWidget((Widget)w->vcr_control.button[VCR_STEP]);
510 if (w->vcr_control.button_is_in[VCR_STEP]) {
511 w->vcr_control.button_is_in[VCR_STEP] = FALSE;
512 SimulateButtonPress(w, VCR_STEP);
513 }
514 XtRealizeWidget((Widget)w->vcr_control.frame[VCR_PALINDROME]);
515 XtRealizeWidget((Widget)w->vcr_control.button[VCR_PALINDROME]);
516 if (w->vcr_control.button_is_in[VCR_PALINDROME]) {
517 w->vcr_control.button_is_in[VCR_PALINDROME] = FALSE;
518 SimulateButtonPress(w, VCR_PALINDROME);
519 }
520 }
SimulateButtonPress(XmVCRControlWidget vcr,int button_num)521 static void SimulateButtonPress(XmVCRControlWidget vcr, int button_num)
522 {
523 Widget widget;
524 XmDrawingAreaCallbackStruct call_data;
525
526 call_data.event = (XEvent *)XtMalloc(sizeof(XEvent));
527
528 call_data.event->type = ButtonPress;
529 call_data.event->xbutton.button = Button1;
530
531 /*
532 * Kludge to tell VCRButtonEvent not to callback application.
533 */
534 call_data.event->xbutton.x = -1;
535 widget = (Widget)vcr->vcr_control.button[button_num];
536 VCRButtonEvent(widget, vcr, &call_data);
537 XtFree((char*)call_data.event);
538
539 }
540
541 /* Subroutine: SetValues
542 * Effect: Handles requests to change things from the application
543 */
544
SetValues(XmVCRControlWidget current,XmVCRControlWidget request,XmVCRControlWidget new)545 static Boolean SetValues(XmVCRControlWidget current,
546 XmVCRControlWidget request,
547 XmVCRControlWidget new)
548 {
549 int i;
550 Arg wargs[12];
551
552 if (new->vcr_control.min_value > new->vcr_control.max_value) {
553 new->vcr_control.min_value = new->vcr_control.max_value;
554 };
555
556 if (new->vcr_control.max_value < new->vcr_control.min_value) {
557 new->vcr_control.max_value = new->vcr_control.min_value;
558 };
559
560 if (new->vcr_control.start_value > new->vcr_control.stop_value) {
561 new->vcr_control.start_value = new->vcr_control.stop_value;
562 };
563
564 if (new->vcr_control.stop_value < new->vcr_control.start_value) {
565 new->vcr_control.stop_value = new->vcr_control.start_value;
566 };
567
568 if (new->vcr_control.next_value < new->vcr_control.start_value) {
569 new->vcr_control.next_value = new->vcr_control.start_value;
570 };
571 #ifdef OBSOLETE
572
573 if (new->vcr_control.current_value < new->vcr_control.start_value) {
574 new->vcr_control.current_value = new->vcr_control.start_value;
575 };
576 #endif
577
578 if (new->vcr_control.next_value > (new->vcr_control.stop_value)) {
579 new->vcr_control.next_value = new->vcr_control.stop_value;
580 };
581 #ifdef OBSOLETE
582
583 if (new->vcr_control.current_value > (new->vcr_control.stop_value)) {
584 new->vcr_control.current_value = new->vcr_control.stop_value;
585 };
586 #endif
587
588 if (new->vcr_control.frame_increment > (new->vcr_control.stop_value -
589 new->vcr_control.start_value)) {
590 new->vcr_control.frame_increment = new->vcr_control.stop_value -
591 new->vcr_control.start_value;
592 };
593
594 for(i = 0; i < VCR_STOP; i++) /* To first non-resource button */
595 {
596 if (current->vcr_control.button_is_in[i] !=
597 request->vcr_control.button_is_in[i])
598 {
599 new->vcr_control.button_is_in[i] =
600 current->vcr_control.button_is_in[i];
601 SimulateButtonPress(new, i);
602 XFlush(XtDisplay(new));
603 }
604 }
605 if (current->vcr_control.min_value !=
606 new->vcr_control.min_value) {
607 XtSetArg(wargs[0], XmNminimum, new->vcr_control.min_value);
608 XtSetValues((Widget)new->vcr_control.frame_control, wargs, 1);
609 if (new->vcr_control.min_value > new->vcr_control.next_value)
610 ChangeVCRNextValue(new, new->vcr_control.min_value,
611 TRUE, FALSE, TRUE);
612 }
613 if (current->vcr_control.max_value !=
614 new->vcr_control.max_value) {
615 XtSetArg(wargs[0], XmNmaximum, new->vcr_control.max_value);
616 XtSetValues((Widget)new->vcr_control.frame_control, wargs, 1);
617 if (new->vcr_control.max_value < new->vcr_control.next_value)
618 ChangeVCRNextValue(new, new->vcr_control.max_value,
619 TRUE, FALSE, TRUE);
620 }
621 if (current->vcr_control.start_value !=
622 request->vcr_control.start_value) {
623 ChangeVCRStartValue(new, request->vcr_control.start_value,
624 TRUE, TRUE, FALSE);
625 }
626 if (current->vcr_control.stop_value !=
627 request->vcr_control.stop_value) {
628 ChangeVCRStopValue(new, request->vcr_control.stop_value,
629 TRUE, TRUE, FALSE);
630 }
631 if (current->vcr_control.next_value !=
632 request->vcr_control.next_value) {
633 ChangeVCRNextValue(new, new->vcr_control.next_value,
634 TRUE, TRUE, FALSE);
635 }
636 if (current->vcr_control.current_value !=
637 request->vcr_control.current_value) {
638 ChangeVCRCurrentValue(new, new->vcr_control.current_value,
639 TRUE, TRUE, FALSE);
640 }
641 if (current->vcr_control.frame_increment !=
642 request->vcr_control.frame_increment) {
643 ChangeVCRIncrementValue(new, new->vcr_control.frame_increment,
644 TRUE, TRUE, FALSE);
645 }
646 if (current->vcr_control.next_color !=
647 new->vcr_control.next_color) {
648 XtSetArg(wargs[0],XmNnextColor, new->vcr_control.next_color);
649 XtSetValues((Widget)new->vcr_control.frame_control, wargs, 1);
650 }
651 if (current->vcr_control.current_color !=
652 new->vcr_control.current_color) {
653 XtSetArg(wargs[0],XmNcurrentColor, new->vcr_control.current_color);
654 XtSetValues((Widget)new->vcr_control.frame_control, wargs, 1);
655 }
656 if (current->vcr_control.limit_color !=
657 new->vcr_control.limit_color) {
658 XtSetArg(wargs[0], XmNlimitColor, new->vcr_control.limit_color);
659 XtSetValues((Widget)new->vcr_control.frame_control, wargs, 1);
660 }
661 if (current->vcr_control.frame_sensitive !=
662 new->vcr_control.frame_sensitive) {
663 XtSetSensitive((Widget)new->vcr_control.frame_control,
664 new->vcr_control.frame_sensitive);
665 }
666 if (current->vcr_control.min_sensitive !=
667 new->vcr_control.min_sensitive) {
668 XtVaSetValues((Widget)new->vcr_control.frame_control,
669 XmNminSensitive, new->vcr_control.min_sensitive, NULL);
670 }
671 if (current->vcr_control.max_sensitive !=
672 new->vcr_control.max_sensitive) {
673 XtVaSetValues((Widget)new->vcr_control.frame_control,
674 XmNmaxSensitive, new->vcr_control.max_sensitive, NULL);
675 }
676 if (current->vcr_control.inc_sensitive !=
677 new->vcr_control.inc_sensitive) {
678 XtVaSetValues((Widget)new->vcr_control.frame_control,
679 XmNincSensitive, new->vcr_control.inc_sensitive, NULL);
680 }
681 if (current->vcr_control.current_visible !=
682 new->vcr_control.current_visible) {
683 ChangeVCRCurrentValue(new, new->vcr_control.current_value,
684 TRUE, TRUE, FALSE);
685 }
686
687 return FALSE;
688 }
689
690 /* Subroutine: Destroy
691 * Effect: Frees resources before widget is destroyed
692 */
693
Destroy(XmVCRControlWidget w)694 static void Destroy(XmVCRControlWidget w)
695 {
696 /* Free all the callbacks */
697 }
698
699 /* Subroutine: SetLabel
700 * Purpose: Prepare the interactive part of a button and its iconic image
701 * Note: The interaction is through a DrawingArea while the 3d frame
702 * is currently a Frame parent (only because the DrawingArea
703 * doesn't want to draw its own shadow). Since we are already
704 * handling some of the Frame's shadow drawing, we may be able
705 * to do the same for a DrawingArea without frame).
706 */
707
SetLabel(XmVCRControlWidget vcr,int i,char * bits,int width,int height)708 static void SetLabel( XmVCRControlWidget vcr,
709 int i, char* bits, int width, int height )
710 {
711 Arg wargs[2];
712 unsigned long fg, bg;
713 Display *display;
714
715 vcr->vcr_control.button[i] =
716 (XmDrawingAreaWidget) XmCreateDrawingArea((Widget)vcr->vcr_control.frame[i],
717 "label", wargs, 0);
718 display = XtDisplay(vcr->vcr_control.button[i]);
719 fg = vcr->vcr_control.button[i]->manager.foreground;
720 bg = vcr->vcr_control.button[i]->core.background_pixel;
721 vcr->vcr_control.button_image[i].width = width;
722 vcr->vcr_control.button_image[i].height = height;
723 vcr->vcr_control.button_image[i].gc = NULL;
724 vcr->vcr_control.button_image[i].pixid =
725 XCreatePixmapFromBitmapData(display,
726 XRootWindowOfScreen(XtScreen(vcr)), bits, width, height,
727 fg,bg,DefaultDepth(display,XScreenNumberOfScreen(XtScreen(vcr))));
728 vcr->vcr_control.button[i]->manager.user_data =
729 (void *)(&vcr->vcr_control.button_image[i]);
730
731 XtAddCallback((Widget)vcr->vcr_control.button[i], XmNexposeCallback,
732 VCRButtonExpose, vcr);
733 XtAddCallback((Widget)vcr->vcr_control.button[i], XmNresizeCallback,
734 VCRButtonResize, vcr);
735 XtAddCallback((Widget)vcr->vcr_control.button[i], XmNinputCallback,
736 VCRButtonEvent, vcr);
737 XtManageChild((Widget)vcr->vcr_control.button[i]);
738 }
739
740 /* Subroutine: CreateVCRCounter
741 * Purpose: Prepare the frame number display and the button which brings
742 * up the frame_control. This button is different from the others.
743 */
CreateVCRCounter(XmVCRControlWidget vcr)744 static void CreateVCRCounter( XmVCRControlWidget vcr )
745 {
746 Arg wargs[16];
747 XmString text;
748 char string[100];
749 Dimension width;
750
751 vcr->vcr_control.button[VCR_COUNT] = (XmDrawingAreaWidget)
752 XmCreateDrawingArea((Widget)vcr->vcr_control.frame[VCR_COUNT],
753 "label", wargs, 0);
754 XtManageChild((Widget)vcr->vcr_control.button[VCR_COUNT]);
755 XtAddCallback((Widget)vcr->vcr_control.button[VCR_COUNT], XmNexposeCallback,
756 VCRCounterExpose, vcr);
757 XtAddCallback((Widget)vcr->vcr_control.button[VCR_COUNT], XmNinputCallback,
758 VCRButtonEvent, vcr);
759
760 /* Create the label */
761 XtSetArg(wargs[0], XmNx, 10);
762 XtSetArg(wargs[1], XmNy, 15);
763 /* Leave room for 5 digits */
764 sprintf(string, "55555");
765 text = XmStringCreate(string, XmSTRING_DEFAULT_CHARSET);
766 XtSetArg(wargs[2], XmNlabelString, text);
767 XtSetArg(wargs[3], XmNrecomputeSize, False);
768 vcr->vcr_control.label = (XmLabelWidget)XmCreateLabel(
769 (Widget)vcr->vcr_control.button[VCR_COUNT],
770 "label", wargs, 4);
771 XtManageChild((Widget)vcr->vcr_control.label);
772 XmStringFree(text);
773
774 /*
775 * Now give the label the real string to display
776 */
777 if (vcr->vcr_control.current_visible) {
778 sprintf(string, "%5d", vcr->vcr_control.current_value);
779 } else {
780 sprintf(string, " ");
781 }
782 text = XmStringCreate(string, XmSTRING_DEFAULT_CHARSET);
783 XtSetArg(wargs[0], XmNlabelString, text);
784 XtSetValues((Widget)vcr->vcr_control.label, wargs, 1);
785 XmStringFree(text);
786
787 XtSetArg(wargs[0], XmNwidth, &width);
788 XtGetValues((Widget)vcr->vcr_control.label, wargs, 1);
789
790 text = XmStringCreate("...", XmSTRING_DEFAULT_CHARSET);
791 XtSetArg(wargs[0], XmNx, 20 + width);
792 XtSetArg(wargs[1], XmNy, 15);
793 XtSetArg(wargs[2], XmNlabelString, text);
794 vcr->vcr_control.dot_dot_dot =
795 (XmLabelWidget)XmCreateLabel((Widget)vcr->vcr_control.button[VCR_COUNT],
796 "label", wargs,3);
797 XmStringFree(text);
798 XtManageChild((Widget)vcr->vcr_control.dot_dot_dot);
799
800 XtAddEventHandler((Widget)vcr->vcr_control.label, ButtonPressMask,
801 False, _VCRButtonEvent, vcr);
802 XtAddEventHandler((Widget)vcr->vcr_control.dot_dot_dot, ButtonPressMask,
803 False, _VCRButtonEvent, vcr);
804 }
805
806
807 /* Subroutine: VCRButtonResize
808 * Purpose: Clear the old image and treat the resize as a new exposure
809 */
VCRButtonResize(XmDrawingAreaWidget w,XmVCRControlWidget vcr,XmDrawingAreaCallbackStruct * cb)810 static void VCRButtonResize( XmDrawingAreaWidget w, XmVCRControlWidget vcr,
811 XmDrawingAreaCallbackStruct* cb )
812 {
813 if( XtIsRealized((Widget)w) ) {
814 XClearWindow(XtDisplay(w), XtWindow(w));
815 VCRButtonExpose(w, vcr, cb);
816 }
817 }
818
819 /* Subroutine: VCRButtonExpose
820 * Purpose: Draw the iconic image in the button (it is usually attached
821 * as user_data, but there may be exceptions).
822 */
VCRButtonExpose(XmDrawingAreaWidget w,XmVCRControlWidget vcr,XmDrawingAreaCallbackStruct * cb)823 static void VCRButtonExpose( XmDrawingAreaWidget w, XmVCRControlWidget vcr,
824 XmDrawingAreaCallbackStruct* cb )
825 {
826 int x, y;
827 ButtonImage *image_data = (ButtonImage *)(w->manager.user_data);
828 Display *display;
829 Window window;
830
831 if( (image_data->background != w->core.background_pixel)
832 && image_data->gc ) {
833 XtReleaseGC((Widget)w, image_data->gc);
834 image_data->gc = NULL;
835 }
836 if( image_data->gc == NULL ) {
837 XGCValues values;
838 XtGCMask valueMask;
839 valueMask = GCForeground | GCBackground | GCFunction;
840 values.foreground = w->manager.foreground;
841 values.background = w->core.background_pixel;
842 values.function = GXcopy;
843 image_data->gc = XtGetGC((Widget)w, valueMask, &values);
844 image_data->background = w->core.background_pixel;
845 }
846 x = (w->core.width - image_data->width) / 2;
847 y = (w->core.height - image_data->height) / 2;
848 display = XtDisplay(w);
849 if (XtIsRealized((Widget)w)) {
850 window = XtWindow(w);
851 XCopyArea(display, image_data->pixid, window, image_data->gc, 0, 0,
852 image_data->width, image_data->height, x, y);
853 }
854 }
855
856
857 /* Subroutine: VCRCounterExpose
858 * Purpose: Center the contents of the counter button
859 */
VCRCounterExpose(XmDrawingAreaWidget w,XmVCRControlWidget vcr,XmDrawingAreaCallbackStruct * cb)860 static void VCRCounterExpose( XmDrawingAreaWidget w, XmVCRControlWidget vcr,
861 XmDrawingAreaCallbackStruct* cb )
862 {
863 int x1, x2, y;
864 x1 = vcr->vcr_control.button[VCR_COUNT]->core.width
865 - (vcr->vcr_control.label->core.width * 2);
866 if( x1 > 16 )
867 x1 /= 4;
868 else if( x1 > 4 )
869 x1 = 4;
870 else
871 x1 = 0;
872 y = (vcr->vcr_control.button[VCR_COUNT]->core.height
873 - vcr->vcr_control.label->core.height) / 2;
874 if( (x1 != vcr->vcr_control.label->core.x) ||
875 (y != vcr->vcr_control.label->core.y) ) {
876 RectObj g = (RectObj) vcr->vcr_control.label;
877 XmDropSiteStartUpdate((Widget)vcr->vcr_control.label);
878 XtMoveWidget((Widget)g, x1, y);
879 }
880 x1 += vcr->vcr_control.label->core.width;
881 x2 = x1 + ((vcr->vcr_control.button[VCR_COUNT]->core.width -
882 (x1 + vcr->vcr_control.dot_dot_dot->core.width)) / 2);
883 y = (vcr->vcr_control.button[VCR_COUNT]->core.height
884 - vcr->vcr_control.dot_dot_dot->core.height) / 2;
885 if( (x2 != vcr->vcr_control.dot_dot_dot->core.x)
886 || (y != vcr->vcr_control.dot_dot_dot->core.y) ) {
887 /* Move the Gadget (XtMoveWidget doesn't move Gadgets in R3) */
888 RectObj g = (RectObj) vcr->vcr_control.dot_dot_dot;
889 XmDropSiteStartUpdate((Widget)vcr->vcr_control.dot_dot_dot);
890 XtMoveWidget((Widget)g, x2, y);
891 }
892 }
893
894 /* Subroutine: _VCRButtonEvent
895 * Purpose: In XtR4/Motif1.1, the button events did not get to the drawing
896 * area widget, so we will dispatch them on our own...
897 */
_VCRButtonEvent(Widget w,XmVCRControlWidget vcr,XEvent * event,Boolean * continue_to_dispatch)898 static void _VCRButtonEvent( Widget w, XmVCRControlWidget vcr,
899 XEvent *event, Boolean *continue_to_dispatch )
900 {
901 XmDrawingAreaCallbackStruct call_data;
902
903 call_data.event = event;
904 VCRButtonEvent(vcr->vcr_control.button[VCR_COUNT], vcr, &call_data);
905 }
906 /* Subroutine: VCRButtonEvent
907 * Purpose: Field button events from the Drawing Areas to make them behave
908 * like buttons (including all interactions among the buttons).
909 */
VCRButtonEvent(XmDrawingAreaWidget w,XmVCRControlWidget vcr,XmDrawingAreaCallbackStruct * call_data)910 static void VCRButtonEvent( XmDrawingAreaWidget w, XmVCRControlWidget vcr,
911 XmDrawingAreaCallbackStruct* call_data )
912 {
913 VCRCallbackStruct data;
914
915 if( call_data->event->type == ButtonPress &&
916 call_data->event->xbutton.button == Button1 )
917 {
918 if ( w != vcr->vcr_control.button[VCR_COUNT] )
919 vcr->vcr_control.last_frame_control_press = -1;
920
921 if( w == vcr->vcr_control.button[VCR_FORWARD] ) {
922 if( !vcr->vcr_control.button_is_in[VCR_FORWARD] ) {
923 ReleaseModeButtons(vcr);
924 PushVCRButton(vcr, VCR_FORWARD);
925
926 if (call_data->event->xbutton.x != -1) {
927 data.action = VCR_FORWARD;
928 data.on = TRUE;
929 XtCallCallbacks((Widget)vcr, XmNactionCallback, &data);
930 }
931 if( (vcr->vcr_control.button_is_in[VCR_LOOP] == FALSE)
932 && (vcr->vcr_control.button_is_in[VCR_PALINDROME] == FALSE)
933 && ( (vcr->vcr_control.next_value +
934 vcr->vcr_control.frame_increment)
935 > vcr->vcr_control.stop_value) ) {
936 /* Do not queue up additional step is step mode */
937 if( vcr->vcr_control.button_is_in[VCR_STEP] )
938 return;
939 }
940 }
941 /* If in, pressing releases (releases pause as well) exc. step */
942 else if( vcr->vcr_control.button_is_in[VCR_STEP] == FALSE ) {
943 ReleaseVCRButton(vcr, VCR_FORWARD);
944
945
946 if (call_data->event->xbutton.x != -1) {
947 data.action = VCR_PAUSE;
948 data.on = TRUE;
949 XtCallCallbacks((Widget)vcr, XmNactionCallback, &data);
950 }
951 }
952 } else if( w == vcr->vcr_control.button[VCR_BACKWARD] ) {
953 /* If out, unset forward, stop, pause */
954 if( !vcr->vcr_control.button_is_in[VCR_BACKWARD] ) {
955 ReleaseModeButtons(vcr);
956 PushVCRButton(vcr, VCR_BACKWARD);
957 if (call_data->event->xbutton.x != -1) {
958 data.action = VCR_BACKWARD;
959 data.on = TRUE;
960 XtCallCallbacks((Widget)vcr, XmNactionCallback, &data);
961 }
962 if( (vcr->vcr_control.button_is_in[VCR_LOOP] == FALSE)
963 && (vcr->vcr_control.button_is_in[VCR_PALINDROME] == FALSE)
964 && ( (vcr->vcr_control.next_value -
965 vcr->vcr_control.frame_increment)
966 < vcr->vcr_control.start_value) ) {
967 /* Do not queue up additional step is step mode */
968 if( vcr->vcr_control.button_is_in[VCR_STEP] )
969 return;
970 }
971 }
972 /* If in, pressing releases (releases pause as well) exc. step */
973 else if( vcr->vcr_control.button_is_in[VCR_STEP] == FALSE ) {
974 ReleaseVCRButton(vcr, VCR_BACKWARD);
975
976 if (call_data->event->xbutton.x != -1) {
977 data.action = VCR_PAUSE;
978 data.on = TRUE;
979 XtCallCallbacks((Widget)vcr, XmNactionCallback, &data);
980 }
981 }
982 } else if( w == vcr->vcr_control.button[VCR_PALINDROME] ) {
983 if( vcr->vcr_control.button_is_in[VCR_PALINDROME] ) {
984 ReleaseVCRButton(vcr, VCR_PALINDROME);
985 } else {
986 PushVCRButton(vcr, VCR_PALINDROME);
987 }
988 if (call_data->event->xbutton.x != -1) {
989 data.action = VCR_PALINDROME;
990 data.on = vcr->vcr_control.button_is_in[VCR_PALINDROME];
991 XtCallCallbacks((Widget)vcr, XmNactionCallback, &data);
992 }
993 } else if( w == vcr->vcr_control.button[VCR_STEP] ) {
994 if( vcr->vcr_control.button_is_in[VCR_STEP] ) {
995 /* Call application first, then change the button state */
996 data.action = VCR_STEP;
997 if (call_data->event->xbutton.x != -1) {
998 data.on = FALSE;
999 XtCallCallbacks((Widget)vcr, XmNactionCallback, &data);
1000 }
1001 ReleaseVCRButton(vcr, VCR_STEP);
1002 /* Switch the button icons */
1003 vcr->vcr_control.button[VCR_FORWARD]->manager.user_data =
1004 (void *)(&vcr->vcr_control.button_image[VCR_FORWARD]);
1005 vcr->vcr_control.button[VCR_BACKWARD]->manager.user_data =
1006 (void *)(&vcr->vcr_control.button_image[VCR_BACKWARD]);
1007 /* Clear old icons before drawing new ones */
1008 XClearWindow(XtDisplay(vcr),
1009 XtWindow(vcr->vcr_control.button[VCR_FORWARD]));
1010 XClearWindow(XtDisplay(vcr),
1011 XtWindow(vcr->vcr_control.button[VCR_BACKWARD]));
1012 } else {
1013 /* Call application first, then change the button state */
1014 if (call_data->event->xbutton.x != -1) {
1015 data.action = VCR_STEP;
1016 data.on = TRUE;
1017 XtCallCallbacks((Widget)vcr, XmNactionCallback, &data);
1018 }
1019 PushVCRButton(vcr, VCR_STEP);
1020 if( vcr->vcr_control.button_is_in[VCR_FORWARD]
1021 || vcr->vcr_control.button_is_in[VCR_BACKWARD] ) {
1022 /* Invoking step during playing pauses action */
1023 if( vcr->vcr_control.button_is_in[VCR_FORWARD] )
1024 ReleaseVCRButton(vcr, VCR_FORWARD);
1025 else
1026 ReleaseVCRButton(vcr, VCR_BACKWARD);
1027 }
1028 /* Switch the button icons */
1029 vcr->vcr_control.button[VCR_FORWARD]->manager.user_data =
1030 (void *)(&vcr->vcr_control.button_image[VCR_FORWARD_STEP]);
1031 vcr->vcr_control.button[VCR_BACKWARD]->manager.user_data =
1032 (void *)(&vcr->vcr_control.button_image[VCR_BACKWARD_STEP]);
1033 /* No need to clear since the step icon is bigger */
1034 }
1035 /* Redraw the Button icon */
1036 VCRButtonExpose(vcr->vcr_control.button[VCR_FORWARD], vcr, NULL);
1037 VCRButtonExpose(vcr->vcr_control.button[VCR_BACKWARD], vcr, NULL);
1038 } else if( w == vcr->vcr_control.button[VCR_LOOP] ) {
1039 if( vcr->vcr_control.button_is_in[VCR_LOOP] )
1040 ReleaseVCRButton(vcr, VCR_LOOP);
1041 else
1042 PushVCRButton(vcr, VCR_LOOP);
1043 if (call_data->event->xbutton.x != -1) {
1044 data.action = VCR_LOOP;
1045 data.on = vcr->vcr_control.button_is_in[VCR_LOOP];
1046 XtCallCallbacks((Widget)vcr, XmNactionCallback, &data);
1047 }
1048 } else if( w == vcr->vcr_control.button[VCR_STOP] ) {
1049 if( !vcr->vcr_control.button_is_in[VCR_STOP] ) {
1050 ReleaseModeButtons(vcr);
1051 if( vcr->vcr_control.button_is_in[VCR_PAUSE] )
1052 ReleaseVCRButton(vcr, VCR_PAUSE);
1053 PushVCRButton(vcr, VCR_STOP);
1054 if (call_data->event->xbutton.x != -1) {
1055 data.action = VCR_STOP;
1056 data.on = TRUE;
1057 XtCallCallbacks((Widget)vcr, XmNactionCallback, &data);
1058 }
1059 }
1060 } else if( w == vcr->vcr_control.button[VCR_PAUSE] ) {
1061 /* This only happens if pause is a toggle */
1062 if( vcr->vcr_control.button_is_in[VCR_PAUSE] )
1063 ReleaseVCRButton(vcr, VCR_PAUSE);
1064 else {
1065 ReleaseModeButtons(vcr);
1066 PushVCRButton(vcr, VCR_PAUSE);
1067 }
1068 if (call_data->event->xbutton.x != -1) {
1069 data.action = VCR_PAUSE;
1070 data.on = TRUE;
1071 XtCallCallbacks((Widget)vcr, XmNactionCallback, &data);
1072 }
1073 } else if( w == vcr->vcr_control.button[VCR_COUNT] ) {
1074 /*
1075 * Ignore the second click of a double click on this button.
1076 */
1077 if((vcr->vcr_control.last_frame_control_press != -1) &&
1078 (abs(vcr->vcr_control.last_frame_control_press -
1079 call_data->event->xbutton.time) < 500)) {
1080 return;
1081 }
1082
1083 vcr->vcr_control.last_frame_control_press =
1084 call_data->event->xbutton.time;
1085 if( vcr->vcr_control.button_is_in[VCR_COUNT] ) {
1086 ReleaseVCRButton(vcr, VCR_COUNT);
1087 if( vcr->vcr_control.frame_control_is_up ) {
1088 XtUnmanageChild((Widget)vcr->vcr_control.frame_control);
1089 }
1090 vcr->vcr_control.frame_control_is_up = False;
1091 } else {
1092
1093 XtManageChild((Widget)vcr->vcr_control.frame_control);
1094
1095 PushVCRButton(vcr, VCR_COUNT);
1096 vcr->vcr_control.frame_control_is_up = True;
1097 ChangeVCRCurrentValue(vcr, vcr->vcr_control.current_value,
1098 TRUE, TRUE, FALSE);
1099 ChangeVCRNextValue(vcr, vcr->vcr_control.next_value,
1100 TRUE, TRUE, FALSE);
1101 }
1102 }
1103 } else if( call_data->event->type == ButtonRelease ) {
1104 /* Release buttons which are press-only (momentary) */
1105 if( vcr->vcr_control.button_is_in[VCR_PAUSE] )
1106 ReleaseVCRButton(vcr, VCR_PAUSE);
1107 else if( vcr->vcr_control.button_is_in[VCR_STOP] )
1108 ReleaseVCRButton(vcr, VCR_STOP);
1109 else if( vcr->vcr_control.button_is_in[VCR_STEP]
1110 && (vcr->vcr_control.button_timeout == 0) ) {
1111 /* If in step mode and time has expired, release play button */
1112 if( vcr->vcr_control.button_is_in[VCR_FORWARD] )
1113 ReleaseVCRButton(vcr, VCR_FORWARD);
1114 else if( vcr->vcr_control.button_is_in[VCR_BACKWARD] )
1115 ReleaseVCRButton(vcr, VCR_BACKWARD);
1116 }
1117 vcr->vcr_control.step_being_held = FALSE;
1118 }
1119 }
1120
1121 /* Subroutine: ReleaseVCRButton
1122 * Purpose: Simulate effect of releasing button which had been pushed in
1123 */
ReleaseVCRButton(XmVCRControlWidget vcr,int button)1124 static void ReleaseVCRButton( XmVCRControlWidget vcr, int button )
1125 {
1126 Arg wargs[2];
1127
1128 XtSetArg(wargs[0], XmNshadowType, XmSHADOW_OUT);
1129 XtSetValues((Widget)vcr->vcr_control.frame[button], wargs, 1);
1130 vcr->vcr_control.button_is_in[button] = FALSE;
1131 /* Since the Frame's SetValues doesn't ask to redraw, we must do it! */
1132 ReplaceFrame(vcr->vcr_control.frame[button]);
1133 }
1134
1135 /* Subroutine: PushVCRButton
1136 * Purpose: Simulate effect of pushing in a button
1137 */
PushVCRButton(XmVCRControlWidget vcr,int button)1138 static void PushVCRButton( XmVCRControlWidget vcr, int button )
1139 {
1140 Arg wargs[2];
1141
1142 XtSetArg(wargs[0], XmNshadowType, XmSHADOW_IN);
1143 XtSetValues((Widget)vcr->vcr_control.frame[button], wargs, 1);
1144 vcr->vcr_control.button_is_in[button] = TRUE;
1145 /* Since the Frame's SetValues doesn't ask to redraw, we must do it! */
1146 if (XtIsRealized((Widget)vcr->vcr_control.frame[button])) {
1147 ReplaceFrame(vcr->vcr_control.frame[button]);
1148 /* Send it right-away to maximize flicker, before it gets released */
1149
1150 }
1151 }
1152
1153
1154 /* Subroutine: ReleaseModeButtons
1155 * Purpose: Release any pushed button of the ganged radiobutton set
1156 */
ReleaseModeButtons(XmVCRControlWidget vcr)1157 static void ReleaseModeButtons( XmVCRControlWidget vcr )
1158 {
1159 if( vcr->vcr_control.button_is_in[VCR_FORWARD] )
1160 ReleaseVCRButton(vcr, VCR_FORWARD);
1161 else if( vcr->vcr_control.button_is_in[VCR_BACKWARD] )
1162 ReleaseVCRButton(vcr, VCR_BACKWARD);
1163 else if( vcr->vcr_control.button_is_in[VCR_STOP] )
1164 ReleaseVCRButton(vcr, VCR_STOP);
1165 else if( vcr->vcr_control.button_is_in[VCR_PAUSE] )
1166 ReleaseVCRButton(vcr, VCR_PAUSE);
1167 }
1168
1169 /* Subroutine: ReplaceFrame
1170 * Purpose: Redraw widget shadow. Calls internal Xm call when stupid
1171 * widget doesn't but should (i.e. when shadow of Frame is
1172 * changed by SetValues).
1173 * Note: %% This uses Xm internals in violation of object oriented
1174 * practice. It may need adjustment with rev changes in Xm.
1175 */
ReplaceFrame(XmFrameWidget frame)1176 static void ReplaceFrame( XmFrameWidget frame )
1177 {
1178 #if (OLD_LESSTIF != 1)
1179
1180 short highlight_thickness = 0;
1181
1182 if( XtIsRealized((Widget)frame) )
1183 #if (XmVersion < 2000)
1184
1185 _XmDrawShadowType((Widget)frame, frame->frame.shadow_type,
1186 frame->core.width, frame->core.height,
1187 frame->manager.shadow_thickness,
1188 highlight_thickness, frame->manager.top_shadow_GC,
1189 frame->manager.bottom_shadow_GC);
1190 #else /* XmVersion >= 2000 */
1191
1192 XmeDrawShadows(XtDisplay((Widget)frame), XtWindow((Widget)frame),
1193 frame->manager.top_shadow_GC,
1194 frame->manager.bottom_shadow_GC,
1195 highlight_thickness, highlight_thickness,
1196 frame->core.width, frame->core.height,
1197 frame->manager.shadow_thickness,
1198 frame->frame.shadow_type);
1199 #endif /* XmVersion */
1200 #endif /* OLD_LESSTIF */
1201 }
1202
1203
1204
1205 /* Subroutine: ChangeVCRNextValue
1206 * Purpose: Change the next frame value everywhere in the VCR control
1207 */
ChangeVCRNextValue(XmVCRControlWidget vcr,int value,Boolean to_vcr,Boolean to_frame_control,Boolean to_outside)1208 void ChangeVCRNextValue( XmVCRControlWidget vcr, int value, Boolean to_vcr,
1209 Boolean to_frame_control, Boolean to_outside )
1210 {
1211 VCRCallbackStruct data;
1212 Arg wargs[2];
1213
1214 vcr->vcr_control.next_value = value;
1215 /* An idea to try, but may not be so great */
1216 /* Use the change of number to trigger the button release */
1217 if( vcr->vcr_control.button_is_in[VCR_STEP] &&
1218 (vcr->vcr_control.step_being_held == FALSE) ) {
1219 if( vcr->vcr_control.button_timeout ) {
1220 XtRemoveTimeOut(vcr->vcr_control.button_timeout);
1221 vcr->vcr_control.button_timeout = 0;
1222 }
1223 if( vcr->vcr_control.button_is_in[VCR_FORWARD] )
1224 ReleaseVCRButton(vcr, VCR_FORWARD);
1225 if( vcr->vcr_control.button_is_in[VCR_BACKWARD] )
1226 ReleaseVCRButton(vcr, VCR_BACKWARD);
1227 }
1228
1229 if( to_frame_control && vcr->vcr_control.frame_control_is_up) {
1230 XtSetArg(wargs[0], XmNnext, value);
1231 XtSetValues((Widget)vcr->vcr_control.frame_control, wargs, 1);
1232 }
1233
1234 if( to_outside ) {
1235
1236 data.detent = value;
1237 data.which = XmCR_NEXT;
1238 XtCallCallbacks((Widget)vcr, XmNframeCallback, &data);
1239 }
1240 }
1241
1242
1243 /* Subroutine: ChangeVCRCurrentValue
1244 * Purpose: Change the current frame value everywhere in the VCR control
1245 */
ChangeVCRCurrentValue(XmVCRControlWidget vcr,int value,Boolean to_vcr,Boolean to_frame_control,Boolean to_outside)1246 void ChangeVCRCurrentValue( XmVCRControlWidget vcr, int value, Boolean to_vcr,
1247 Boolean to_frame_control, Boolean to_outside )
1248 {
1249 VCRCallbackStruct data;
1250 Arg wargs[2];
1251 char string[100];
1252 XmString text;
1253
1254 vcr->vcr_control.current_value = value;
1255
1256 /*Update the display */
1257 if (vcr->vcr_control.current_visible) {
1258 sprintf(string, "%4d", vcr->vcr_control.current_value);
1259 } else {
1260 sprintf(string, " ");
1261 }
1262
1263 text = XmStringCreate(string, XmSTRING_DEFAULT_CHARSET);
1264 XtSetArg(wargs[0], XmNlabelString, text);
1265 XtSetValues( (Widget)vcr->vcr_control.label, wargs, 1);
1266 XmStringFree(text);
1267
1268 if( to_frame_control && vcr->vcr_control.frame_control_is_up) {
1269 XtSetArg(wargs[0], XmNcurrent, value);
1270 XtSetArg(wargs[1], XmNcurrentVisible, vcr->vcr_control.current_visible);
1271 XtSetValues((Widget)vcr->vcr_control.frame_control, wargs, 2);
1272 }
1273
1274 if( to_outside ) {
1275
1276 data.detent = value;
1277 data.which = XmCR_CURRENT;
1278 XtCallCallbacks((Widget)vcr, XmNframeCallback, &data);
1279 }
1280 }
1281
1282 /* Function: FrameControlCallback
1283 * Purpose: Handle changes due to the frame_control
1284 */
FrameControlCallback(Widget w,XmVCRControlWidget vcr,FrameControlCallbackStruct * call_data)1285 static void FrameControlCallback( Widget w, XmVCRControlWidget vcr,
1286 FrameControlCallbackStruct *call_data )
1287 {
1288 VCRCallbackStruct data;
1289
1290 if (call_data->reason == XmCR_START) {
1291 ChangeVCRStartValue(vcr, call_data->value, TRUE, FALSE, TRUE);
1292 }
1293 if (call_data->reason == XmCR_STOP) {
1294 ChangeVCRStopValue(vcr, call_data->value, TRUE, FALSE, TRUE);
1295 }
1296 if (call_data->reason == XmCR_NEXT) {
1297 ChangeVCRNextValue(vcr, call_data->value, TRUE, FALSE, TRUE);
1298 }
1299 if (call_data->reason == XmCR_INCREMENT) {
1300 ChangeVCRIncrementValue(vcr, call_data->value, TRUE, FALSE, TRUE);
1301 }
1302 if (call_data->reason == XmCR_MIN) {
1303 data.value = call_data->value;
1304 data.which = XmCR_MIN;
1305 XtCallCallbacks((Widget)vcr, XmNframeCallback, &data);
1306 }
1307 if (call_data->reason == XmCR_MAX) {
1308 data.value = call_data->value;
1309 data.which = XmCR_MAX;
1310 XtCallCallbacks((Widget)vcr, XmNframeCallback,
1311 &data);
1312 }
1313 }
1314
1315 /* Function: PopdownCallback
1316 * Purpose: Assure appropriate state of interface if something else pops
1317 * down the frame guide
1318 */
PopdownCallback(Widget w,XmVCRControlWidget vcr,XmAnyCallbackStruct * call_data)1319 static void PopdownCallback( Widget w, XmVCRControlWidget vcr,
1320 XmAnyCallbackStruct* call_data )
1321 {
1322 if( vcr->vcr_control.button_is_in[VCR_COUNT] )
1323 ReleaseVCRButton(vcr, VCR_COUNT);
1324 }
1325
1326 /* Function: map_dialog
1327 * Purpose: Make sure the frame control doesn't map over the sequencer.
1328 */
map_dialog(Widget dialog,XmVCRControlWidget vcr,XmAnyCallbackStruct * call_data)1329 static void map_dialog (Widget dialog, XmVCRControlWidget vcr,
1330 XmAnyCallbackStruct* call_data)
1331 {
1332 Arg wargs[12];
1333 Display *display;
1334 Dimension width, height;
1335 int dest_x, dest_y;
1336 int dispHeight = 0, dispWidth = 0, wmHeight = 0, borderWidth = 0;
1337 int screen = 0;
1338 Window child, rootW, parentW, *childrenW, vcrW;
1339 unsigned int numChildren;
1340 XWindowAttributes xwa;
1341
1342 /*
1343 Get the location of the VCR control and then
1344 determine if the frame control should go above or
1345 below. Once determined, put it there.
1346 */
1347
1348 display = XtDisplay(vcr);
1349 XtSetArg(wargs[0], XmNheight, &height);
1350 XtSetArg(wargs[1], XmNwidth, &width);
1351 XtGetValues((Widget)vcr, wargs, 2);
1352 screen = XScreenNumberOfScreen(XtScreen(vcr));
1353 dispHeight = DisplayHeight(display, screen);
1354 dispWidth = DisplayWidth(display, screen);
1355
1356 vcrW = XtWindow(vcr);
1357
1358 XTranslateCoordinates( display, vcrW,
1359 XRootWindowOfScreen(XtScreen(vcr)),
1360 0, 0, &dest_x, &dest_y, &child);
1361
1362 /*
1363 Not very elegant, but it does the job. In order
1364 to get the window manager decorations sizes, it
1365 is required to get the window attributes of the
1366 parent's, parent's, parent of the shell.
1367 */
1368
1369 XQueryTree(display, vcrW, &rootW, &parentW,
1370 &childrenW, &numChildren);
1371 if(childrenW)
1372 XFree((char *)childrenW);
1373
1374 XQueryTree(display, parentW, &rootW, &parentW,
1375 &childrenW, &numChildren);
1376 if(childrenW)
1377 XFree((char *)childrenW);
1378
1379 XQueryTree(display, parentW, &rootW, &parentW,
1380 &childrenW, &numChildren);
1381 if(childrenW)
1382 XFree((char *)childrenW);
1383
1384 XGetWindowAttributes(display, parentW, &xwa);
1385 wmHeight = dest_y - xwa.y;
1386 borderWidth = dest_x - xwa.x;
1387
1388 if(dest_y + height + 180 + wmHeight + 2 + borderWidth * 2 > dispHeight) {
1389 XtGetValues((Widget)vcr->vcr_control.frame_control, wargs, 1);
1390 dest_y = dest_y - 2 * wmHeight - borderWidth - height - 2;
1391 } else
1392 dest_y = dest_y + height + borderWidth + 2;
1393
1394 if(dest_x + 400 + borderWidth * 2 > dispWidth) {
1395 dest_x = dispWidth - 2*borderWidth - 400 - 2;
1396 } else
1397 dest_x -= borderWidth;
1398
1399 XtVaSetValues(dialog,
1400 XmNx, dest_x,
1401 XmNy, dest_y,
1402 NULL);
1403
1404 }
1405
1406 /* Subroutine: ChangeVCRStartValue
1407 * Purpose: Change the start frame value everywhere in the VCR control
1408 * Note: Values are in external format (min based or +min from internal)
1409 */
1410
ChangeVCRStartValue(XmVCRControlWidget vcr,int value,Boolean to_vcr,Boolean to_frame_control,Boolean to_outside)1411 void ChangeVCRStartValue( XmVCRControlWidget vcr, int value, Boolean to_vcr,
1412 Boolean to_frame_control, Boolean to_outside )
1413 {
1414 VCRCallbackStruct data;
1415 Arg wargs[2];
1416
1417 vcr->vcr_control.start_value = value;
1418 if( to_frame_control) {
1419 XtSetArg(wargs[0], XmNstart, value);
1420 XtSetValues((Widget)vcr->vcr_control.frame_control, wargs, 1);
1421 }
1422 if( to_outside ) {
1423 data.detent = value;
1424 data.which = XmCR_START;
1425 XtCallCallbacks((Widget)vcr, XmNframeCallback, &data);
1426 }
1427 }
1428
1429
1430 /* Subroutine: ChangeVCRStopValue
1431 * Purpose: Change the stop frame value everywhere in the VCR control
1432 * Note: Values are in external format (min based or +min from internal)
1433 */
ChangeVCRStopValue(XmVCRControlWidget vcr,int value,Boolean to_vcr,Boolean to_frame_control,Boolean to_outside)1434 void ChangeVCRStopValue( XmVCRControlWidget vcr, int value, Boolean to_vcr,
1435 Boolean to_frame_control, Boolean to_outside )
1436 {
1437 VCRCallbackStruct data;
1438 Arg wargs[2];
1439
1440 vcr->vcr_control.stop_value = value;
1441 if( to_frame_control) {
1442 XtSetArg(wargs[0], XmNstop, value);
1443 XtSetValues((Widget)vcr->vcr_control.frame_control, wargs, 1);
1444 }
1445 if( to_outside ) {
1446 data.detent = value;
1447 data.which = XmCR_STOP;
1448 XtCallCallbacks((Widget)vcr, XmNframeCallback, &data);
1449 }
1450 }
1451
1452
1453 /* Subroutine: ChangeVCRIncrementValue
1454 * Purpose: Change the frame increment value for the sequence controller
1455 */
ChangeVCRIncrementValue(XmVCRControlWidget vcr,int increment,Boolean to_vcr,Boolean to_frame_control,Boolean to_outside)1456 void ChangeVCRIncrementValue( XmVCRControlWidget vcr, int increment,
1457 Boolean to_vcr, Boolean to_frame_control,
1458 Boolean to_outside )
1459 {
1460 VCRCallbackStruct data;
1461 Arg wargs[2];
1462
1463 vcr->vcr_control.frame_increment = increment;
1464 if( to_frame_control) {
1465 XtSetArg(wargs[0], XmNincrement, increment);
1466 XtSetValues((Widget)vcr->vcr_control.frame_control, wargs, 1);
1467 }
1468 if( to_outside ) {/*&& vcr->vcr_control.value_callback )*/
1469 data.detent = increment;
1470 data.which = XmCR_INCREMENT;
1471 XtCallCallbacks((Widget)vcr, XmNframeCallback, &data);
1472 }
1473 }
1474
1475 /* Subroutine: XmCreateVCRControl
1476 * Purpose: This function creates and returns a VCRControl widget.
1477 */
1478
XmCreateVCRControl(Widget parent,char * name,ArgList args,Cardinal num_args)1479 Widget XmCreateVCRControl( Widget parent, char *name, ArgList args,
1480 Cardinal num_args)
1481 {
1482 return (XtCreateWidget(name, xmVCRControlWidgetClass, parent, args,
1483 num_args));
1484
1485 }
1486