Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /* 
  2     channel for Bt848 frame grabber driver
  3 
  4     Copyright (C) 1996,97 Marcus Metzler (mocm@thp.uni-koeln.de)
  5               (c) 1998-2003 Gerd Knorr <kraxel@bytesex.org>
  6 
  7     This program is free software; you can redistribute it and/or modify
  8     it under the terms of the GNU General Public License as published by
  9     the Free Software Foundation; either version 2 of the License, or
 10     (at your option) any later version.
 11 
 12     This program is distributed in the hope that it will be useful,
 13     but WITHOUT ANY WARRANTY; without even the implied warranty of
 14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15     GNU General Public License for more details.
 16 
 17     You should have received a copy of the GNU General Public License
 18     along with this program; if not, write to the Free Software
 19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20 */
 21 
 22 #include "config.h"
 23 
 24 #include <stdio.h>
 25 #include <stdlib.h>
 26 #include <unistd.h>
 27 #include <string.h>
 28 #include <ctype.h>
 29 #include <math.h>
 30 #include <pthread.h>
 31 
 32 #ifndef NO_X11
 33 # include <X11/Xlib.h>
 34 # include <X11/Intrinsic.h>
 35 # include <X11/StringDefs.h>
 36 # include <X11/Xaw/XawInit.h>
 37 # include <X11/Xaw/Command.h>
 38 # include <X11/Xaw/Paned.h>
 39 #endif
 40 
 41 #include "grab-ng.h"
 42 #include "channel.h"
 43 #include "commands.h"
 44 #include "frequencies.h"
 45 #include "sound.h"
 46 #include "parseconfig.h"
 47 #include "event.h"
 48 
 49 /* ----------------------------------------------------------------------- */
 50 /* misc common stuff, not only channel related                             */ 
 51 
 52 struct CHANNEL defaults = {
 53     name:     "defaults",
 54     group:    "main",
 55     capture:  CAPTURE_ON,
 56     channel:  -1,
 57     audio:    -1,
 58     color:    -1,
 59     bright:   -1,
 60     hue:      -1,
 61     contrast: -1,
 62 };
 63                                 
 64 struct CHANNEL  **channels  = NULL;
 65 int             count       = 0;
 66 int             alloc_count = 0;
 67 
 68 int last_sender = -1, cur_sender = -1, cur_channel = -1, cur_fine = 0;
 69 int cur_freq;
 70 struct ng_filter *cur_filter;
 71 
 72 int cur_capture = CAPTURE_OFF;
 73 int have_config;
 74 int keypad_ntsc = 0;
 75 int keypad_partial = 1;
 76 int use_wm_fullscreen = 1;
 77 int use_osd = 1;
 78 int osd_x = 30;
 79 int osd_y = 20;
 80 int fs_width,fs_height,fs_xoff,fs_yoff;
 81 int pix_width=128, pix_height=96, pix_cols=1;
 82 
 83 char *mov_driver = NULL;
 84 char *mov_video  = NULL;
 85 char *mov_fps    = NULL;
 86 char *mov_audio  = NULL;
 87 char *mov_rate   = NULL;
 88 
 89 #ifndef NO_X11
 90 extern Widget chan_box, chan_viewport, tv, opt_paned, launch_paned;
 91 #endif
 92 
 93 static char *mixer = NULL;
 94 char mixerdev[32],mixerctl[16];
 95 char *midi = NULL;
 96 
 97 struct LAUNCH *launch = NULL;
 98 int nlaunch           = 0;
 99 
100 /* ----------------------------------------------------------------------- */
101 
102 int lookup_channel(char *channel)
103 {
104 #if 0
105     /* Hmm, why the heck that used to be that complex?
106      * Any good reason I forgot ? */
107     int    i,nr1,nr2;
108     char   tag1[5],tag2[5];
109 
110     if (NULL == channel)
111         return -1;
112 
113     if (isdigit(channel[0])) {
114         tag1[0] = 0;
115         nr1  = atoi(channel);
116     } else {
117         sscanf(channel,"%4[A-Za-z]%d",tag1,&nr1);
118     }
119 
120     for (i = 0; i < chancount; i++) {
121         if (isdigit(chanlist[i].name[0])) {
122             tag2[0] = 0;
123             nr2  = atoi(chanlist[i].name);
124         } else {
125             sscanf(chanlist[i].name,"%4[A-Za-z]%d",tag2,&nr2);
126         }
127         if (tag1[0] && tag2[0])
128             if (nr1 == nr2 && 0 == strcmp(tag1,tag2))
129                 break;
130         if (!tag1[0] && !tag2[0])
131             if (nr1 == nr2)
132                 break;
133     }
134     if (i == chancount)
135         return -1;
136 
137     return i;
138 #else
139     int i;
140     
141     if (NULL == channel)
142         return -1;
143     for (i = 0; i < chancount; i++)
144         if (0 == strcasecmp(chanlist[i].name,channel))
145             break;
146     if (i == chancount)
147         return -1;
148     return i;
149 #endif
150 }
151 
152 int get_freq(int i)
153 {
154     if (i < 0 || i >= chancount)
155         return -1;
156     return chanlist[i].freq*16/1000;
157 }
158 
159 int  cf2freq(char *name, int fine)
160 {
161     int i;
162     
163     if (-1 == (i = lookup_channel(name)))
164         return -1;
165     return get_freq(i)+fine;
166 }
167 
168 /* ----------------------------------------------------------------------- */
169 
170 struct STRTAB captab[] = {
171     {  CAPTURE_ON,          "on"          },
172     {  CAPTURE_ON,          "yes"         },
173     {  CAPTURE_ON,          "true"        },
174     {  CAPTURE_OFF,         "off"         },
175     {  CAPTURE_OFF,         "no"          },
176     {  CAPTURE_OFF,         "false"       },
177     {  CAPTURE_OVERLAY,     "over"        },
178     {  CAPTURE_OVERLAY,     "overlay"     },
179     {  CAPTURE_GRABDISPLAY, "grab"        },
180     {  CAPTURE_GRABDISPLAY, "grabdisplay" },
181     {  -1, NULL,     },
182 };
183 
184 /* just malloc memory for a new channel ... */
185 struct CHANNEL*
186 add_channel(char *name)
187 {
188     struct CHANNEL *channel;
189 
190     if (alloc_count == count) {
191         alloc_count += 16;
192         if (alloc_count == 16)
193             channels = malloc(sizeof(struct CHANNEL*)*alloc_count);
194         else
195             channels = realloc(channels,sizeof(struct CHANNEL*)*alloc_count);
196     }
197     channel = channels[count++] = malloc(sizeof(struct CHANNEL));
198     memcpy(channel,&defaults,sizeof(struct CHANNEL));
199     channel->name = strdup(name);
200     return channel;
201 }
202 
203 #ifndef NO_X11
204 
205 #define PANED_FIX               \
206         XtNallowResize, False,  \
207         XtNshowGrip,    False,  \
208         XtNskipAdjust,  True
209 
210 void hotkey_channel(struct CHANNEL *channel)
211 {
212     char str[100],key[32],ctrl[16];
213 
214     if (NULL == channel->key)
215         return;
216     if (2 == sscanf(channel->key,"%15[A-Za-z0-9_]+%31[A-Za-z0-9_]",
217                     ctrl,key))
218         sprintf(str,"%s<Key>%s: Command(setstation,\"%s\")",
219                 ctrl,key,channel->name);
220     else
221         sprintf(str,"<Key>%s: Command(setstation,\"%s\")",
222                 channel->key,channel->name);
223     XtOverrideTranslations(tv,XtParseTranslationTable(str));
224     XtOverrideTranslations(opt_paned,XtParseTranslationTable(str));
225     XtOverrideTranslations(chan_viewport,XtParseTranslationTable(str));
226 }
227 
228 static void
229 launch_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
230 {
231     char *argv[2];
232 
233     argv[0] = (char*)clientdata;
234     argv[1] = NULL;
235     XtCallActionProc(widget,"Launch",NULL,argv,1);
236 }
237 
238 static void
239 hotkey_launch(struct LAUNCH *launch)
240 {
241     Widget c;
242     char str[100],key[32],ctrl[16],label[64];
243 
244     if (NULL == launch->key)
245         return;
246     if (2 == sscanf(launch->key,"%15[A-Za-z0-9_]+%31[A-Za-z0-9_]",
247                     ctrl,key))
248         sprintf(str,"%s<Key>%s: Launch(\"%s\")",ctrl,key,launch->name);
249     else
250         sprintf(str,"<Key>%s: Launch(\"%s\")",launch->key,launch->name);
251     XtOverrideTranslations(tv,XtParseTranslationTable(str));
252     XtOverrideTranslations(opt_paned,XtParseTranslationTable(str));
253     XtOverrideTranslations(chan_viewport,XtParseTranslationTable(str));
254 
255     sprintf(label,"%-20s %s",launch->name,launch->key);
256     c = XtVaCreateManagedWidget(launch->name, commandWidgetClass,
257                                 launch_paned,
258                                 PANED_FIX,
259                                 XtNlabel,label,
260                                 NULL);
261     XtAddCallback(c,XtNcallback,launch_cb,(XtPointer)(launch->name));
262 }
263 
264 static void
265 button_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
266 {
267     struct CHANNEL *channel = clientdata;
268     do_va_cmd(2,"setstation",channel->name);
269 }
270 
271 /* ... and initalize later */
272 void configure_channel(struct CHANNEL *channel)
273 {
274     channel->button =
275         XtVaCreateManagedWidget(channel->name,
276                                 commandWidgetClass, chan_box,
277                                 XtNwidth,pix_width,
278                                 XtNheight,pix_height,
279                                 NULL);
280     XtAddCallback(channel->button,XtNcallback,button_cb,(XtPointer*)channel);
281     hotkey_channel(channel);
282 }
283 #endif
284 
285 /* delete channel */
286 void
287 del_channel(int i)
288 {
289     free(channels[i]->name);
290     if (channels[i]->key)
291         free(channels[i]->key);
292     free(channels[i]);
293     count--;
294     if (i < count)
295         memmove(channels+i,channels+i+1,(count-i)*sizeof(struct CHANNEL*));
296 }
297 
298 void
299 calc_frequencies()
300 {
301     int i;
302 
303     for (i = 0; i < count; i++) {
304         if (NULL == channels[i]->cname)
305             continue;
306         channels[i]->channel = lookup_channel(channels[i]->cname);
307         if (-1 == channels[i]->channel)
308             channels[i]->freq = -1;
309         else
310             channels[i]->freq = get_freq(channels[i]->channel)
311                 + channels[i]->fine;
312     }
313 }
314 
315 /* ----------------------------------------------------------------------- */
316 
317 static void
318 init_channel(char *name, struct CHANNEL *c)
319 {
320     struct ng_attribute *attr;
321     char *val; int n,i;
322 
323     if (NULL != (val = cfg_get_str(name,"capture"))) {
324         if (-1 != (i = str_to_int(val,captab)))
325             c->capture = i;
326         else
327             fprintf(stderr,"config: invalid value for capture: %s\n",val);
328     }
329     if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_INPUT)) &&
330         (NULL != (val = cfg_get_str(name,"input")) ||
331          NULL != (val = cfg_get_str(name,"source")))) { /* obsolete */
332         if (-1 != (i = ng_attr_getint(attr,val)))
333             c->input = i;
334         else {
335             fprintf(stderr,"config: invalid value for input: %s\n",val);
336             ng_attr_listchoices(attr);
337         }
338     }
339     if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_NORM)) &&
340         NULL != (val = cfg_get_str(name,"norm"))) {
341         if (-1 != (i = ng_attr_getint(attr,val)))
342             c->norm = i;
343         else {
344             fprintf(stderr,"config: invalid value for norm: %s\n",val);
345             ng_attr_listchoices(attr);
346         }
347     }
348     if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_AUDIO_MODE)) &&
349         NULL != (val = cfg_get_str(name,"audio"))) {
350         if (-1 != (i = ng_attr_getint(attr,val)))
351             c->audio = i;
352         else {
353             fprintf(stderr,"config: invalid value for audio: %s\n",val);
354             ng_attr_listchoices(attr);
355         }
356     }
357     
358     if (NULL != (val = cfg_get_str(name,"channel")))
359         c->cname   = strdup(val);
360     if (NULL != (val = cfg_get_str(name,"freq")))
361         c->freq   = (int)(atof(val)*16);
362     if (0 != (n = cfg_get_signed_int(name,"fine")))
363         c->fine = n;
364 
365     if (NULL != (val = cfg_get_str(name,"key")))
366         c->key  = strdup(val);
367     if (NULL != (val = cfg_get_str(name,"group")))
368         c->group  = strdup(val);
369     if (NULL != (val = cfg_get_str(name,"midi")))
370         c->midi = atoi(val);
371 
372     attr = ng_attr_byid(attrs,ATTR_ID_COLOR);
373     if (attr && NULL != (val = cfg_get_str(name,"color")))
374         c->color = ng_attr_parse_int(attr,val);
375     attr = ng_attr_byid(attrs,ATTR_ID_BRIGHT);
376     if (attr && NULL != (val = cfg_get_str(name,"bright")))
377         c->bright = ng_attr_parse_int(attr,val);
378     attr = ng_attr_byid(attrs,ATTR_ID_HUE);
379     if (attr && NULL != (val = cfg_get_str(name,"hue")))
380         c->hue = ng_attr_parse_int(attr,val);
381     attr = ng_attr_byid(attrs,ATTR_ID_CONTRAST);
382     if (attr && NULL != (val = cfg_get_str(name,"contrast")))
383         c->contrast = ng_attr_parse_int(attr,val);
384 }
385 
386 void
387 read_config(char *conffile, int *argc, char **argv)
388 {
389     struct list_head *item;
390     char filename[100];
391     char *val;
392     int  i;
393 
394     if (conffile) {
395         if (0 == cfg_parse_file(conffile))
396             have_config = 1;
397     } else {
398         sprintf(filename,"%.*s/%s",(int)sizeof(filename)-8,
399                 getenv("HOME"),".xawtv");
400         if (0 == cfg_parse_file(CONFIGFILE))
401             have_config = 1;
402         if (0 == cfg_parse_file(filename))
403             have_config = 1;
404     }
405     if (argc)
406         cfg_parse_options(argc,argv);
407 
408     /* misc global settings */
409     if (NULL != (val = cfg_get_str("global","mixer"))) {
410         mixer = strdup(val);
411         if (2 != sscanf(mixer,"%31[^:]:%15s",mixerdev,mixerctl)) {
412             strcpy(mixerdev,ng_dev.mixer);
413             strncpy(mixerctl,val,15);
414             mixerctl[15] = 0;
415         }
416     }
417 
418     if (NULL != (val = cfg_get_str("global","midi")))
419         midi = strdup(val);
420 
421     if (NULL != (val = cfg_get_str("global","freqtab"))) {
422         for (i = 0; chanlists[i].name != NULL; i++)
423             if (0 == strcasecmp(val,chanlists[i].name))
424                 break;
425         if (chanlists[i].name != NULL) {
426             freq_newtab(i);
427         } else
428             fprintf(stderr,"invalid value for freqtab: %s\n",val);
429     }
430 
431     if (NULL != (val = cfg_get_str("global","fullscreen"))) {
432         if (2 != sscanf(val,"%d x %d",&fs_width,&fs_height)) {
433             fprintf(stderr,"invalid value for fullscreen: %s\n",val);
434             fs_width = fs_height = 0;
435         }
436     }
437 
438     if (NULL != (val = cfg_get_str("global","pixsize"))) {
439         if (2 != sscanf(val,"%d x %d",&pix_width,&pix_height)) {
440             fprintf(stderr,"invalid value for pixsize: %s\n",val);
441             pix_width = 128;
442             pix_height = 96;
443         }
444     }
445     if (-1 != (i = cfg_get_int("global","pixcols")))
446         pix_cols = i;
447 
448     if (NULL != (val = cfg_get_str("global","wm-off-by"))) {
449         if (2 != sscanf(val,"%d %d",&fs_xoff,&fs_yoff)) {
450             fprintf(stderr,"invalid value for wm-off-by: %s\n",val);
451             fs_xoff = fs_yoff = 0;
452         }
453     }
454     if (NULL != (val = cfg_get_str("global","ratio"))) {
455         if (2 != sscanf(val,"%d:%d",&ng_ratio_x,&ng_ratio_y)) {
456             fprintf(stderr,"invalid value for ratio: %s\n",val);
457             ng_ratio_x = ng_ratio_y = 0;
458         }
459     }
460     
461     if (-1 != (i = cfg_get_int("global","jpeg-quality")))
462         ng_jpeg_quality = i;
463 
464     if (NULL != (val = cfg_get_str("global","keypad-ntsc")))
465         if (-1 != (i = str_to_int(val,booltab)))
466             keypad_ntsc = i;
467     if (NULL != (val = cfg_get_str("global","keypad-partial")))
468         if (-1 != (i = str_to_int(val,booltab)))
469             keypad_partial = i;
470     if (NULL != (val = cfg_get_str("global","osd")))
471         if (-1 != (i = str_to_int(val,booltab)))
472             use_osd = i;
473     if (NULL != (val = cfg_get_str("global","osd-position")))
474         if (2 != sscanf(val,"%d , %d",&osd_x,&osd_y))
475             fprintf(stderr,"invalid values for osd-position: %s\n",val);
476     if (NULL != (val = cfg_get_str("global","use-wm-fullscreen")))
477         if (-1 != (i = str_to_int(val,booltab)))
478             use_wm_fullscreen = i;
479 
480     if (NULL != (val = cfg_get_str("global","mov-driver")))
481         mov_driver = val;
482     if (NULL != (val = cfg_get_str("global","mov-video")))
483         mov_video = val;
484     if (NULL != (val = cfg_get_str("global","mov-fps")))
485         mov_fps = val;
486     if (NULL != (val = cfg_get_str("global","mov-audio")))
487         mov_audio = val;
488     if (NULL != (val = cfg_get_str("global","mov-rate")))
489         mov_rate = val;
490 
491     if (NULL != (val = cfg_get_str("global","filter"))) {
492         list_for_each(item,&ng_filters) {
493             struct ng_filter *f = list_entry(item, struct ng_filter, list);
494             if (0 == strcasecmp(f->name, val))
495                 cur_filter = f;
496         }
497     }
498 }
499 
500 void
501 parse_config(void)
502 {
503     char key[16], cmdline[128];
504     char **list,*val;
505 #ifndef NO_X11
506     int i;
507 #endif
508 
509     /* launch */
510     list = cfg_list_entries("launch");
511     if (NULL != list) {
512         for (; *list != NULL; list++) {
513             if (NULL != (val = cfg_get_str("launch",*list)) &&
514                 2 == sscanf(val,"%15[^,], %127[^\n]",
515                             key,cmdline)) {
516                 launch = realloc(launch,sizeof(struct LAUNCH)*(nlaunch+1));
517                 launch[nlaunch].name    = strdup(*list);
518                 launch[nlaunch].key     = strdup(key);
519                 launch[nlaunch].cmdline = strdup(cmdline);
520 #ifndef NO_X11
521                 hotkey_launch(launch+nlaunch);
522 #endif
523                 nlaunch++;
524             } else {
525                 fprintf(stderr,"invalid value in section [launch]: %s\n",val);
526             }
527         }
528     }
529 
530     /* events */
531     event_readconfig();
532 
533     /* channels */
534     init_channel("defaults",&defaults);
535     for (list = cfg_list_sections(); *list != NULL; list++) {
536         if (0 == strcmp(*list,"defaults")) continue;
537         if (0 == strcmp(*list,"global"))   continue;
538         if (0 == strcmp(*list,"launch"))   continue;
539         if (0 == strcmp(*list,"eventmap")) continue;
540         init_channel(*list,add_channel(*list));
541     }
542 
543     /* calculate channel frequencies */
544     defaults.channel = lookup_channel(defaults.cname);
545     defaults.freq    = get_freq(defaults.channel) + defaults.fine;
546     calc_frequencies();
547 #ifndef NO_X11
548     for (i = 0; i < count; i++)
549         configure_channel(channels[i]);
550 #endif
551 }
552 
553 /* ----------------------------------------------------------------------- */
554 
555 void
556 save_config()
557 {
558     struct ng_attribute *attr;
559     char filename1[100], filename2[100];
560     FILE *fp;
561     int i;
562 
563     sprintf(filename1,"%s/%s",getenv("HOME"),".xawtv");
564     sprintf(filename2,"%s/%s",getenv("HOME"),".xawtv~");
565 
566     /* delete old backup */
567     unlink(filename2);
568 
569     /* current becomes backup */
570     if (0 == link(filename1,filename2))
571         unlink(filename1);
572 
573     /* write new one... */
574     fp = fopen(filename1,"w");
575     if (NULL == fp) {
576         fprintf(stderr,"can't open config file %s\n",filename1);
577         return;
578     }
579 
580     fprintf(fp,"[global]\n");
581     if (fs_width && fs_height)
582         fprintf(fp,"fullscreen = %d x %d\n",fs_width,fs_height);
583     if (fs_xoff || fs_yoff)
584         fprintf(fp,"wm-off-by = %+d%+d\n",fs_xoff,fs_yoff);
585     if (ng_ratio_x || ng_ratio_y)
586         fprintf(fp,"ratio = %d:%d\n",ng_ratio_x,ng_ratio_y);
587     fprintf(fp,"freqtab = %s\n",chanlists[chantab].name);
588     fprintf(fp,"pixsize = %d x %d\n",pix_width,pix_height);
589     fprintf(fp,"pixcols = %d\n",pix_cols);
590     fprintf(fp,"jpeg-quality = %d\n",ng_jpeg_quality);
591     fprintf(fp,"keypad-ntsc = %s\n",int_to_str(keypad_ntsc,booltab));
592     fprintf(fp,"keypad-partial = %s\n",int_to_str(keypad_partial,booltab));
593     fprintf(fp,"osd = %s\n",int_to_str(use_osd,booltab));
594     fprintf(fp,"osd-position = %d , %d\n",osd_x,osd_y);
595     fprintf(fp,"use-wm-fullscreen = %s\n",
596             int_to_str(use_wm_fullscreen,booltab));
597     if (mixer)
598         fprintf(fp,"mixer = %s\n",mixer);
599     if (midi)
600         fprintf(fp,"midi = %s\n",midi);
601 
602     if (mov_driver)
603         fprintf(fp,"mov-driver = %s\n",mov_driver);
604     if (mov_video)
605         fprintf(fp,"mov-video = %s\n",mov_video);
606     if (mov_fps)
607         fprintf(fp,"mov-fps = %s\n",mov_fps);
608     if (mov_audio)
609         fprintf(fp,"mov-audio = %s\n",mov_audio);
610     if (mov_rate)
611         fprintf(fp,"mov-rate = %s\n",mov_rate);
612     
613     fprintf(fp,"\n");
614     
615     if (nlaunch > 0) {
616         fprintf(fp,"[launch]\n");
617         for (i = 0; i < nlaunch; i++) {
618             fprintf(fp,"%s = %s, %s\n",
619                     launch[i].name,launch[i].key,launch[i].cmdline);
620         }
621         fprintf(fp,"\n");
622     }
623 
624     /* events */
625     event_writeconfig(fp);
626 
627     /* write help */
628     fprintf(fp,"# [Station name]\n");
629     fprintf(fp,"# capture = overlay | grabdisplay | on | off\n");
630     fprintf(fp,"# input = Television | Composite1 | S-Video | ...\n");
631     fprintf(fp,"# norm = PAL | NTSC | SECAM | ... \n");
632     fprintf(fp,"# channel = #\n");
633     fprintf(fp,"# fine = # (-128..+127)\n");
634     fprintf(fp,"# key = keysym | modifier+keysym\n");
635     fprintf(fp,"# color = #\n");
636     fprintf(fp,"# bright = #\n");
637     fprintf(fp,"# hue = #\n");
638     fprintf(fp,"# contrast = #\n");
639     fprintf(fp,"\n");
640 
641     /* write defaults */
642     fprintf(fp,"[defaults]\n");
643     fprintf(fp,"group = %s\n",defaults.group);
644 
645     fprintf(fp,"norm = %s\n",
646             ng_attr_getstr(ng_attr_byid(attrs,ATTR_ID_NORM),
647                            cur_attrs[ATTR_ID_NORM]));
648     fprintf(fp,"input = %s\n",
649             ng_attr_getstr(ng_attr_byid(attrs,ATTR_ID_INPUT),
650                            cur_attrs[ATTR_ID_INPUT]));
651     fprintf(fp,"capture = %s\n",int_to_str(cur_capture,captab));
652 
653     attr = ng_attr_byid(attrs,ATTR_ID_COLOR);
654     if (attr && attr->defval != cur_attrs[ATTR_ID_COLOR])
655         fprintf(fp,"color = %d%%\n",
656                 ng_attr_int2percent(attr,cur_attrs[ATTR_ID_COLOR]));
657     attr = ng_attr_byid(attrs,ATTR_ID_BRIGHT);
658     if (attr && attr->defval != cur_attrs[ATTR_ID_BRIGHT])
659         fprintf(fp,"bright = %d%%\n",
660                 ng_attr_int2percent(attr,cur_attrs[ATTR_ID_BRIGHT]));
661     attr = ng_attr_byid(attrs,ATTR_ID_HUE);
662     if (attr && attr->defval != cur_attrs[ATTR_ID_HUE])
663         fprintf(fp,"hue = %d%%\n",
664                 ng_attr_int2percent(attr,cur_attrs[ATTR_ID_HUE]));
665     attr = ng_attr_byid(attrs,ATTR_ID_CONTRAST);
666     if (attr && attr->defval != cur_attrs[ATTR_ID_CONTRAST])
667         fprintf(fp,"contrast = %d%%\n",
668                 ng_attr_int2percent(attr,cur_attrs[ATTR_ID_CONTRAST]));
669     fprintf(fp,"\n");
670 
671     /* write channels */
672     for (i = 0; i < count; i++) {
673         fprintf(fp,"[%s]\n",channels[i]->name);
674         if (NULL != channels[i]->cname) {
675             fprintf(fp,"channel = %s\n",chanlist[channels[i]->channel].name);
676             if (0 != channels[i]->fine)
677                 fprintf(fp,"fine = %+d\n", channels[i]->fine);
678         } else {
679             fprintf(fp,"freq = %.2f\n",(float)(channels[i]->freq)/16);
680         }
681         
682         if ( channels[i]->norm != cur_attrs[ATTR_ID_NORM])
683             fprintf(fp,"norm = %s\n",
684                     ng_attr_getstr(ng_attr_byid(attrs,ATTR_ID_NORM),
685                                    channels[i]->norm));
686         if (channels[i]->input != cur_attrs[ATTR_ID_INPUT])
687             fprintf(fp,"input = %s\n",
688                     ng_attr_getstr(ng_attr_byid(attrs,ATTR_ID_INPUT),
689                                    channels[i]->input));
690 
691         if (channels[i]->key != NULL)
692             fprintf(fp,"key = %s\n",channels[i]->key);
693         if (0 != strcmp(channels[i]->group,defaults.group))
694             fprintf(fp,"group = %s\n",channels[i]->group);
695         if (channels[i]->midi != 0)
696             fprintf(fp,"midi = %d\n",channels[i]->midi);
697         if (channels[i]->capture != cur_capture)
698             fprintf(fp,"capture = %s\n",
699                     int_to_str(channels[i]->capture,captab));
700         
701         attr = ng_attr_byid(attrs,ATTR_ID_COLOR);
702         if (attr && cur_attrs[ATTR_ID_COLOR] != channels[i]->color)
703             fprintf(fp,"color = %d%%\n",
704                     ng_attr_int2percent(attr,channels[i]->color));
705         attr = ng_attr_byid(attrs,ATTR_ID_BRIGHT);
706         if (attr && cur_attrs[ATTR_ID_BRIGHT] != channels[i]->bright)
707             fprintf(fp,"bright = %d%%\n",
708                     ng_attr_int2percent(attr,channels[i]->bright));
709         attr = ng_attr_byid(attrs,ATTR_ID_HUE);
710         if (attr && cur_attrs[ATTR_ID_HUE] != channels[i]->hue)
711             fprintf(fp,"hue = %d%%\n",
712                     ng_attr_int2percent(attr,channels[i]->hue));
713         attr = ng_attr_byid(attrs,ATTR_ID_CONTRAST);
714         if (attr && cur_attrs[ATTR_ID_CONTRAST] != channels[i]->contrast)
715             fprintf(fp,"contrast = %d%%\n",
716                     ng_attr_int2percent(attr,channels[i]->contrast));
717 
718         fprintf(fp,"\n");
719     }
720     fclose(fp);
721 }
722 
723 /* ----------------------------------------------------------------------- */
724 
725 struct STRTAB booltab[] = {
726     {  0, "no" },
727     {  0, "false" },
728     {  0, "off" },
729     {  1, "yes" },
730     {  1, "true" },
731     {  1, "on" },
732     { -1, NULL }
733 };
734 
735 int
736 str_to_int(char *str, struct STRTAB *tab)
737 {
738     int i;
739     
740     if (str[0] >= '' && str[0] <= '9')
741         return atoi(str);
742     for (i = 0; tab[i].str != NULL; i++)
743         if (0 == strcasecmp(str,tab[i].str))
744             return(tab[i].nr);
745     return -1;
746 }
747 
748 const char*
749 int_to_str(int n, struct STRTAB *tab)
750 {
751     int i;
752     
753     for (i = 0; tab[i].str != NULL; i++)
754         if (tab[i].nr == n)
755             return tab[i].str;
756     return NULL;
757 }
758 
  This page was automatically generated by the LXR engine.