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