1 /*
2  *  This file is part of XForms.
3  *
4  *  XForms is free software; you can redistribute it and/or modify it
5  *  under the terms of the GNU Lesser General Public License as
6  *  published by the Free Software Foundation; either version 2.1, or
7  *  (at your option) any later version.
8  *
9  *  XForms is distributed in the hope that it will be useful, but
10  *  WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public
15  *  License along with XForms; see the file COPYING.  If not, write to
16  *  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
17  *  MA 02111-1307, USA.
18  */
19 
20 
21 /*
22  * Test browser/slider and color handling. Select a colorname,
23  * the program will show the color. Change the sliders, the
24  * program will pick a colorname that has the closest color.
25  *
26  *  This file is part of xforms package.
27  *  T.C. Zhao and M. Overmars  (1997)
28  */
29 
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33 
34 #include "include/forms.h"
35 #include <stdlib.h>
36 #include <limits.h>
37 
38 #define MAX_RGB 3000
39 
40 static FL_FORM *cl;
41 static FL_OBJECT *rescol,
42                  *dbobj,
43                  *colbr,
44                  *rs,
45                  *gs,
46                  *bs;
47 char dbname[ FL_PATH_MAX ] ;
48 static void create_form_cl( void );
49 static int load_browser( const char * );
50 
51 /* the RGB data file does not have a standard location on unix. */
52 
53 #ifdef __VMS
54     static char *rgbfile = "SYS$MANAGER:DECW$RGB.DAT";
55 #else
56 #ifdef __EMX__   /* OS2 */
57     static char *rgbfile = "/XFree86/lib/X11/rgb.txt";
58 #else
59 	#include <sys/stat.h>
60 
61     static char *rgbfile = "/usr/lib/X11/rgb.txt";
62     static char *rgbfile_2 = "/usr/share/X11/rgb.txt";
63 #endif
64 #endif
65 
66 typedef struct { int r,
67                      g,
68                      b;
69 } RGBdb;
70 
71 static RGBdb rgbdb[ MAX_RGB ];
72 
73 
74 /***************************************
75  ***************************************/
76 
77 int
main(int argc,char * argv[])78 main( int    argc,
79       char * argv[ ] )
80 {
81     fl_initialize( &argc, argv, "FormDemo", 0, 0 );
82 
83     create_form_cl( );
84     strcpy( dbname, rgbfile );
85 
86 #if ! defined __EMX__ && ! defined __VMS
87     {
88         struct stat buf;
89 
90         if ( stat( rgbfile, &buf ) == -1 )
91             strcpy( dbname, rgbfile_2 );
92     }
93 #endif
94 
95     if ( load_browser( dbname ) )
96         fl_set_object_label( dbobj, dbname );
97     else
98         fl_set_object_label( dbobj, "None" );
99 
100     fl_set_form_minsize( cl, cl->w , cl->h );
101     fl_set_form_maxsize( cl, 2 * cl->w , 2 * cl->h );
102     fl_show_form( cl, FL_PLACE_FREE, FL_TRANSIENT, "RGB Browser" );
103 
104     fl_do_forms( );
105 
106     return 0;
107 }
108 
109 
110 /***************************************
111  ***************************************/
112 
113 static void
set_entry(int i)114 set_entry( int i )
115 {
116     RGBdb *db = rgbdb + i;
117 
118     fl_freeze_form( cl );
119     fl_mapcolor( FL_FREE_COL4 + i, db->r, db->g, db->b );
120     fl_mapcolor( FL_FREE_COL4, db->r, db->g, db->b );
121     fl_set_slider_value( rs, db->r );
122     fl_set_slider_value( gs, db->g );
123     fl_set_slider_value( bs, db->b );
124     fl_unfreeze_form( cl );
125 }
126 
127 
128 /***************************************
129  ***************************************/
130 
131 static void
br_cb(FL_OBJECT * ob,long q FL_UNUSED_ARG)132 br_cb( FL_OBJECT * ob,
133        long        q   FL_UNUSED_ARG )
134 {
135     int r = fl_get_browser( ob );
136 
137     if ( r > 0 )
138         set_entry( r - 1 );
139 }
140 
141 
142 /***************************************
143  ***************************************/
144 
145 static int
read_entry(FILE * fp,int * r,int * g,int * b,char * name)146 read_entry( FILE * fp,
147             int  * r,
148             int  * g,
149             int  * b,
150             char * name )
151 {
152     int  n;
153     char buf[ 512 ],
154          *p;
155 
156     if ( ! fgets( buf, sizeof buf, fp ) )
157         return 0;
158 
159     if ( *buf == '!' )
160         if ( ! fgets( buf, sizeof buf, fp ) )
161              return 0;
162 
163     if ( sscanf( buf, " %d %d %d %n", r, g, b, &n ) != 3 )
164         return 0;
165 
166     p = buf + n;
167 
168     /* Remove all spaces */
169 
170     while ( *p )
171     {
172         if ( * p != ' ' && *p != '\n' )
173             *name++ = *p;
174         p++;
175     }
176     *name = '\0';
177 
178     return ! ( feof( fp ) || ferror( fp ) );
179 }
180 
181 
182 /***************************************
183  ***************************************/
184 
185 static int
load_browser(const char * fname)186 load_browser( const char * fname )
187 {
188     FILE *fp;
189     RGBdb *db = rgbdb,
190           *dbs = db + MAX_RGB;
191     int r,
192         g,
193         b,
194         lr = -1,
195         lg = -1,
196         lb = -1;
197     char name[ 256 ],
198          buf[ 256 ];
199 
200 #ifdef __EMX__
201     extern char *__XOS2RedirRoot( const char * );
202     if ( ! ( fp = fopen( __XOS2RedirRoot( fname ), "r" ) ) )
203 #else
204     if ( ! ( fp = fopen( fname, "r" ) ) )
205 #endif
206     {
207         fl_show_alert( "Load", fname, "Can't open database file", 0 );
208         return 0;
209     }
210 
211     /* read the items */
212 
213     fl_freeze_form( cl );
214 
215     while ( db < dbs && read_entry( fp, &r, &g, &b, name ) )
216     {
217         db->r = r;
218         db->g = g;
219         db->b = b;
220 
221         /* unique the entries on the fly */
222 
223         if ( lr != r || lg != g || lb != b )
224         {
225             db++;
226             lr = r;
227             lg = g;
228             lb = b;
229             sprintf( buf, "(%3d %3d %3d) %s", r, g, b, name );
230             fl_addto_browser( colbr, buf );
231         }
232     }
233 
234     fclose( fp );
235 
236     if ( db < dbs )
237         db->r = 1000;       /* sentinel */
238     else
239     {
240         db--;
241         db->r = 1000;
242     }
243 
244     fl_set_browser_topline( colbr, 1 );
245     fl_select_browser_line( colbr, 1 );
246     set_entry( 0 );
247     fl_unfreeze_form( cl );
248 
249     return 1;
250 }
251 
252 
253 /***************************************
254  ***************************************/
255 
256 static int
search_entry(int r,int g,int b)257 search_entry( int r,
258               int g,
259               int b )
260 {
261     RGBdb *db = rgbdb;
262     int i,
263         j;
264     unsigned int mindiff = UINT_MAX;
265 
266     for ( i = j = 0; db->r < 256; db++, i++ )
267     {
268         int diffr = r - db->r;
269         int diffg = g - db->g;
270         int diffb = b - db->b;
271 
272 #ifdef FL_LINEAR
273         unsigned int diff = ( int ) ( 3.0 * FL_abs( diffr ) +
274                                       5.9 * FL_abs( diffg ) +
275                                       1.1 * FL_abs( diffb ) );
276 #else
277         unsigned int diff = ( int ) ( 3.0 * ( diffr * diffr ) +
278                                       5.9 * ( diffg * diffg ) +
279                                       1.1 * ( diffb * diffb ) );
280 #endif
281 
282         if ( mindiff > diff )
283         {
284             mindiff = diff;
285             j = i;
286         }
287     }
288 
289     return j;
290 }
291 
292 
293 /***************************************
294  ***************************************/
295 
296 static void
search_rgb(FL_OBJECT * ob FL_UNUSED_ARG,long q FL_UNUSED_ARG)297 search_rgb( FL_OBJECT * ob  FL_UNUSED_ARG,
298             long        q   FL_UNUSED_ARG )
299 {
300     int r,
301         g,
302         b,
303         i;
304     int top  = fl_get_browser_topline( colbr );
305 
306     r = ( int ) fl_get_slider_value( rs );
307     g = ( int ) fl_get_slider_value( gs );
308     b = ( int ) fl_get_slider_value( bs );
309 
310     fl_freeze_form( cl );
311     fl_mapcolor( FL_FREE_COL4, r, g, b );
312     i = search_entry( r, g, b );
313 
314     /* Change topline only if necessary */
315 
316     if ( i < top || i > top + 15 )
317         fl_set_browser_topline( colbr, i - 8 );
318     fl_select_browser_line( colbr, i + 1 );
319     fl_unfreeze_form( cl );
320 }
321 
322 
323 /***************************************
324  * change database
325  ***************************************/
326 
327 static void
db_cb(FL_OBJECT * ob,long q FL_UNUSED_ARG)328 db_cb( FL_OBJECT * ob,
329        long        q   FL_UNUSED_ARG )
330 {
331     const char *p = fl_show_input( "Enter new database name", dbname );
332     char buf[ 512 ];
333 
334     if ( ! p || ! strcmp( p, dbname ) )
335         return;
336 
337     strcpy( buf, p );
338     if ( load_browser( buf ) )
339     {
340         strcpy( dbname, buf );
341         fl_set_object_label( ob, dbname );
342     }
343 }
344 
345 
346 /***************************************
347  ***************************************/
348 
349 static void
done_cb(FL_OBJECT * ob FL_UNUSED_ARG,long q FL_UNUSED_ARG)350 done_cb( FL_OBJECT * ob  FL_UNUSED_ARG,
351          long        q   FL_UNUSED_ARG )
352 {
353     fl_finish( );
354     exit( 0 );
355 }
356 
357 
358 /***************************************
359  ***************************************/
360 
361 static void
create_form_cl(void)362 create_form_cl( void )
363 {
364     FL_OBJECT *obj;
365 
366     cl = fl_bgn_form( FL_NO_BOX, 330, 385 );
367 
368     obj = fl_add_box( FL_UP_BOX, 0, 0, 330, 385, "" );
369     fl_set_object_color( obj, FL_COL1, FL_COL1 );
370 
371     obj = fl_add_box( FL_NO_BOX, 40, 10, 250, 30, "Color Browser" );
372     fl_set_object_lcolor( obj, FL_RED );
373     fl_set_object_lsize( obj, FL_HUGE_SIZE );
374     fl_set_object_lstyle( obj, FL_BOLD_STYLE + FL_SHADOW_STYLE );
375     fl_set_object_gravity( obj, FL_North, FL_North );
376     fl_set_object_resize( obj, FL_RESIZE_NONE );
377 
378     dbobj = obj = fl_add_button( FL_NORMAL_BUTTON, 40, 50, 250, 25, "" );
379     fl_set_object_boxtype( obj, FL_BORDER_BOX );
380     fl_set_object_color( obj,
381                          fl_get_visual_depth( )==1 ? FL_WHITE:  FL_COL1,
382                           FL_COL1 );
383     fl_set_object_callback( obj, db_cb, 0 );
384     fl_set_object_gravity( obj, FL_North, FL_North );
385     fl_set_object_resize( obj, FL_RESIZE_X );
386 
387     rescol = obj = fl_add_box( FL_FLAT_BOX, 225, 90, 90, 35, "" );
388     fl_set_object_color( obj, FL_FREE_COL4, FL_FREE_COL4 );
389     fl_set_object_boxtype( obj, FL_BORDER_BOX );
390     fl_set_object_resize( obj, FL_RESIZE_NONE );
391     fl_set_object_gravity( obj, FL_NorthEast, FL_East );
392 
393     rs = obj = fl_add_valslider( FL_VERT_FILL_SLIDER, 225, 130, 30, 200, "" );
394     fl_set_object_color( obj,  FL_COL1, FL_RED );
395     fl_set_slider_bounds( obj, 0, 255 );
396     fl_set_slider_precision( obj, 0 );
397     fl_set_object_callback( obj, search_rgb, 0 );
398     fl_set_slider_return( obj, 0 );
399     fl_set_object_resize( obj, FL_RESIZE_Y );
400     fl_set_object_gravity( obj, FL_NorthEast, FL_SouthEast );
401     fl_set_object_return( obj, FL_RETURN_CHANGED );
402 
403     gs = obj = fl_add_valslider( FL_VERT_FILL_SLIDER, 255, 130, 30, 200, "" );
404     fl_set_object_color( obj,  FL_COL1, FL_GREEN );
405     fl_set_slider_bounds( obj, 0, 255 );
406     fl_set_slider_precision( obj, 0 );
407     fl_set_object_callback( obj, search_rgb, 1 );
408     fl_set_slider_return( obj, 0 );
409     fl_set_object_resize( obj, FL_RESIZE_Y );
410     fl_set_object_gravity( obj, FL_NorthEast, FL_SouthEast );
411     fl_set_object_return( obj, FL_RETURN_CHANGED );
412 
413     bs = obj = fl_add_valslider( FL_VERT_FILL_SLIDER, 285, 130, 30, 200, "" );
414     fl_set_object_color( obj,  FL_COL1, FL_BLUE );
415     fl_set_slider_bounds( obj, 0, 255 );
416     fl_set_slider_precision( obj, 0 );
417     fl_set_object_callback( obj, search_rgb, 2 );
418     fl_set_slider_return( obj, 0 );
419     fl_set_object_resize( obj, FL_RESIZE_Y );
420     fl_set_object_gravity( obj, FL_NorthEast, FL_SouthEast );
421     fl_set_object_return( obj, FL_RETURN_CHANGED );
422 
423     colbr = obj = fl_add_browser( FL_HOLD_BROWSER, 10, 90, 205, 240, "" );
424     fl_set_browser_fontstyle( obj, FL_FIXED_STYLE );
425     fl_set_object_callback( obj, br_cb, 0 );
426     fl_set_object_gravity( obj, FL_NorthWest, FL_SouthEast );
427 
428     obj = fl_add_button( FL_NORMAL_BUTTON, 135, 345, 80, 30, "Done" );
429     fl_set_object_callback( obj, done_cb, 0 );
430     fl_set_object_gravity( obj, FL_South, FL_South );
431     fl_set_object_resize( obj, FL_RESIZE_NONE );
432 
433     fl_end_form( );
434 
435     fl_scale_form( cl, 1.1, 1.0 );
436 }
437 
438 
439 /*
440  * Local variables:
441  * tab-width: 4
442  * indent-tabs-mode: nil
443  * End:
444  */
445