1 /*
2  * appear_dlg.c
3  *
4  * Code for the capture appearance parameters dialog
5  *
6  * (C) 1997 Randall Hopper
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are
10  * met: 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer. 2.
12  * Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  */
29 
30 /*      ******************** Include Files                ************** */
31 
32 #include <stdio.h>
33 #include <X11/Intrinsic.h>
34 #include <X11/StringDefs.h>
35 #include <X11/Shell.h>
36 #include <X11/Xaw/Box.h>
37 #include <X11/Xaw/Command.h>
38 #include <X11/Xaw/Label.h>
39 #include <X11/Xaw/AsciiText.h>
40 #include <X11/Xaw/Form.h>
41 #include <X11/Xaw/Scrollbar.h>
42 #include "tvdefines.h"
43 #include "glob.h"
44 #include "xutil.h"
45 #include "appear_dlg.h"
46 
47 
48 /*      ******************** Local defines                ************** */
49 
50 #define THUMB_LEN  0.1
51 
52 typedef struct {
53     TV_DRIVER_PARAM  param;
54     char            *title_name;
55     char            *value_name;
56     char            *scroll_name;
57     char            *min_name;
58     char            *max_name;
59     Widget           value_wgt;
60     Widget           scroll_wgt;
61     Widget           min_wgt;
62     Widget           max_wgt;
63 } TV_APPEAR_CTL_DEF;
64 
65 /*      ******************** Private variables            ************** */
66 
67 static Widget Dialog_wgt = NULL;
68 
69 static TV_APPEAR_CTL_DEF Appearctl_def[] = {
70 
71   { TV_PARAM_HUE     , "hueTitleLabel"   , "hueValueText"   ,
72     "hueScrollbar"   , "hueMinLabel"     , "hueMaxLabel"     },
73   { TV_PARAM_BRIGHT  , "brightTitleLabel", "brightValueText",
74     "brightScrollbar", "brightMinLabel"  , "brightMaxLabel"  },
75   { TV_PARAM_CONTRAST, "contrTitleLabel" , "contrValueText" ,
76     "contrScrollbar" , "contrMinLabel"   , "contrMaxLabel"   },
77   { TV_PARAM_SATU    , "satUTitleLabel"  , "satUValueText"  ,
78     "satUScrollbar"  , "satUMinLabel"    , "satUMaxLabel"    },
79   { TV_PARAM_SATV    , "satVTitleLabel"  , "satVValueText"  ,
80     "satVScrollbar"  , "satVMinLabel"    , "satVMaxLabel"    }
81 };
82 
83 /*      ******************** Forward declarations         ************** */
84 /*      ******************** Function Definitions         ************** */
85 
86 /*  OkCmdCB - Dismiss the dialog  */
OkCmdCB(Widget w,XtPointer cl,XtPointer cb)87 static void OkCmdCB( Widget w, XtPointer cl, XtPointer cb )
88 {
89     if ( Dialog_wgt == NULL )
90         return;
91     XtPopdown( Dialog_wgt );
92 }
93 
TextValUpdate(Widget text_wgt,double val)94 static void TextValUpdate( Widget text_wgt, double val )
95 {
96 #ifdef WHEN_WE_MAKE_IT_EDITABLE
97     XawTextBlock     tblk;
98     char             *old_str;
99     int              old_len;
100 #endif
101     char             str[ 80 ];
102 
103     assert( text_wgt != NULL );
104 
105     sprintf( str, "%.0f", val );
106 
107 #ifdef WHEN_WE_MAKE_IT_EDITABLE
108     memset( &tblk, '\0', sizeof( tblk ) );
109     tblk.firstPos = 0;
110     tblk.length   = strlen( str );
111     tblk.ptr      = str;
112     tblk.format   = XawFmt8Bit;
113 
114     XtVaGetValues( text_wgt, XtNstring, &old_str,
115                              NULL );
116     old_len = (old_str == NULL) ? 0 : strlen( old_str );
117     XawTextReplace( text_wgt, 0, old_len, &tblk );
118 #else
119     XtVaSetValues( text_wgt, XtNstring, str,
120                              NULL );
121 #endif
122 }
123 
124 
ScrollValUpdate(Widget scroll_wgt,double val,double lim[2])125 static void ScrollValUpdate( Widget scroll_wgt, double val, double lim[2] )
126 {
127     assert( scroll_wgt != NULL );
128     assert( !APPROX( lim[0], lim[1], DOUBLE_EPS ) );
129 
130     val = (val - lim[0]) / (lim[1] - lim[0]);
131     val *= (1.0 - THUMB_LEN);
132     XUTILXawScrollbarSetThumb ( scroll_wgt, val, THUMB_LEN );
133 }
134 
135 
ControlSliderJumpCB(Widget w,XtPointer cl_data,XtPointer cb_data)136 static void ControlSliderJumpCB( Widget w,
137                                  XtPointer cl_data,
138                                  XtPointer cb_data )
139 {
140     TV_CAPTURE        *c       = &G_glob.capture;
141     TV_APPEAR_CTL_DEF *r       = (TV_APPEAR_CTL_DEF *) cl_data;
142     float              percent = *(float *)cb_data;
143     double             lim[2],
144                        val;
145 
146     TVCAPTUREQueryParamLimits( c, r->param, lim );
147 
148     val = (percent / (1.0 - THUMB_LEN)) * (lim[1] - lim[0]) + lim[0];
149 
150     TVCAPTURESetAppearanceParam( c, r->param, val );
151     TextValUpdate( r->value_wgt, val );
152 }
153 
154 
ControlSliderScrollCB(Widget w,XtPointer cl_data,XtPointer cb_data)155 static void ControlSliderScrollCB( Widget w,
156                                    XtPointer cl_data,
157                                    XtPointer cb_data )
158 {
159     TV_CAPTURE        *c       = &G_glob.capture;
160     TV_APPEAR_CTL_DEF *r       = (TV_APPEAR_CTL_DEF *) cl_data;
161     float              percent;
162     int                pos     = (int)cb_data;
163     Dimension          length;
164     double             lim[2],
165                        val;
166 
167     TVCAPTUREQueryParamLimits( c, r->param, lim );
168     XtVaGetValues( w, XtNlength    , &length,
169                       XtNtopOfThumb, &percent,
170                       NULL );
171 
172     percent /= (1.0 - THUMB_LEN);
173 
174     percent += (double)pos / length;
175     percent = MAX( 0.0, MIN( 1.0, percent ) );
176     val = percent * (lim[1] - lim[0]) + lim[0];
177 
178     XUTILXawScrollbarSetThumb ( w, percent * (1.0 - THUMB_LEN), THUMB_LEN );
179     TVCAPTURESetAppearanceParam( c, r->param, val );
180     TextValUpdate( r->value_wgt, val );
181 }
182 
183 
TVAppearDialogBuild(Widget * dialog_wgt)184 static void TVAppearDialogBuild( Widget *dialog_wgt )
185 {
186     Position  x, y;
187     Dimension height;
188     Widget    w, box;
189     TV_INT32     i;
190 
191     /*  Create the dialog widgets  */
192     *dialog_wgt = XtVaCreatePopupShell( "inputAppearDialog",
193                       transientShellWidgetClass, TVTOPLEVEL,
194                       NULL );
195 
196     box = XtVaCreateManagedWidget( "mainBox", boxWidgetClass, *dialog_wgt,
197                                    XtNorientation, XtorientVertical,
198                                    NULL );
199 
200     for ( i = 0; i < XtNumber( Appearctl_def ); i++ ) {
201         TV_APPEAR_CTL_DEF *r = &Appearctl_def[i];
202         Widget             gbox, cbox;
203 
204         gbox = XtVaCreateManagedWidget( "groupBox", boxWidgetClass, box,
205                                        XtNorientation, XtorientVertical,
206                                        NULL );
207 
208         cbox = XtVaCreateManagedWidget( "headerBox", boxWidgetClass, gbox,
209                                        XtNorientation, XtorientHorizontal,
210                                        NULL );
211 
212         w = XtVaCreateManagedWidget( r->title_name, labelWidgetClass, cbox,
213                                      NULL );
214 
215         w = XtVaCreateManagedWidget( r->value_name, asciiTextWidgetClass,
216                                      cbox,
217                                  XtNtype            , XawAsciiString,
218                                  XtNuseStringInPlace, False,
219                                  XtNscrollHorizontal, XawtextScrollNever,
220                                  XtNscrollVertical  , XawtextScrollNever,
221                                  XtNdisplayCaret    , False,
222                                  XtNeditType        , XawtextRead,
223                                  XtNresize          , XawtextResizeNever,
224                                  NULL );
225         r->value_wgt = w;
226 
227         cbox = XtVaCreateManagedWidget( "scrollBox", boxWidgetClass, gbox,
228                                        XtNorientation, XtorientHorizontal,
229                                        NULL );
230 
231         w = XtVaCreateManagedWidget( r->min_name, labelWidgetClass, cbox,
232                                      XtNresize, False,
233                                      XtNencoding, XawTextEncoding8bit,
234                                      NULL );
235         r->min_wgt = w;
236 
237         w = XtVaCreateManagedWidget( r->scroll_name, scrollbarWidgetClass,
238                                      cbox,
239                                      XtNorientation, XtorientHorizontal,
240                                      NULL );
241         r->scroll_wgt = w;
242 
243         XtAddCallback( w, XtNjumpProc  , ControlSliderJumpCB  , r );
244         XtAddCallback( w, XtNscrollProc, ControlSliderScrollCB, r );
245 
246         w = XtVaCreateManagedWidget( r->max_name, labelWidgetClass, cbox,
247                                      XtNresize, False,
248                                      XtNencoding, XawTextEncoding8bit,
249                                      NULL );
250         r->max_wgt = w;
251     }
252 
253     w = XtVaCreateManagedWidget( "actionForm", formWidgetClass, box,
254                                  NULL );
255 
256     w = XtVaCreateManagedWidget( "okCmd", commandWidgetClass, w,
257                                  NULL );
258     XtAddCallback( w, XtNcallback, OkCmdCB, NULL );
259 
260     /*  By default, position dialog just below main TV window  */
261     XtVaGetValues( TVTOPLEVEL, XtNheight , &height,
262                                NULL);
263 
264     XtTranslateCoords( TVTOPLEVEL, 0, height, &x, &y );
265 
266     XtVaSetValues( *dialog_wgt, XtNx, x,
267                                 XtNy, y,
268                                 NULL );
269 }
270 
271 
TVAPPEARDIALOGPopUp()272 void TVAPPEARDIALOGPopUp()
273 {
274     if ( Dialog_wgt == NULL )
275         TVAppearDialogBuild( &Dialog_wgt );
276 
277     TVAPPEARDIALOGResync();
278 
279     XUTILXtPopup( Dialog_wgt, XtGrabNone, TVTOPLEVEL );
280 }
281 
282 
TVAPPEARDIALOGResync()283 void TVAPPEARDIALOGResync()
284 {
285     TV_CAPTURE      *c       = &G_glob.capture;
286     TV_DRIVER_STATE  s;
287     TV_INT32            i;
288     double           lim[2],
289                      val;
290     char             str[80];
291 
292     /*  FIXME:  Also install EnterNotify handler for this dialog to  */
293     /*    resync values on entry of it's shell.                      */
294 
295     if ( Dialog_wgt == NULL )
296         return;
297 
298     /*  Query capture driver's current values  */
299     if ( !TVCAPTUREQueryDriverState( c, &s ) ) {
300         fprintf( stderr, "TVCAPTUREQueryDriverState() failed\n" );
301         exit(1);
302     }
303 
304     /*  Update min/max labels, scrollbar position, and value text widget  */
305     for ( i = 0; i < XtNumber( Appearctl_def ); i++ ) {
306         TV_APPEAR_CTL_DEF *r = &Appearctl_def[i];
307 
308         TVCAPTUREQueryParamLimits( c, r->param, lim );
309 
310         assert( r->min_wgt != NULL );
311         sprintf( str, "%.0f", lim[0] );
312         XtVaSetValues( r->min_wgt, XtNlabel, str,
313                                    NULL );
314 
315         assert( r->max_wgt != NULL );
316         sprintf( str, "%.0f", lim[1] );
317         XtVaSetValues( r->max_wgt, XtNlabel, str,
318                                    NULL );
319 
320         switch ( r->param ) {
321             case TV_PARAM_HUE      :  val = s.hue       ;  break;
322             case TV_PARAM_BRIGHT   :  val = s.brightness;  break;
323             case TV_PARAM_CONTRAST :  val = s.contrast  ;  break;
324             case TV_PARAM_SATU     :  val = s.sat_u     ;  break;
325             case TV_PARAM_SATV     :  val = s.sat_v     ;  break;
326             default :
327                 fprintf( stderr,
328                    "TVAPPEARDIALOGResync: Unsupported param %d\n", r->param );
329                 exit(1);
330         }
331 
332         TextValUpdate  ( r->value_wgt , val );
333         ScrollValUpdate( r->scroll_wgt, val, lim );
334     }
335 }
336 
337