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 #include "config.h"
  2 #ifndef HAVE_LIBXV
  3 #include "stdio.h"
  4 #include "stdlib.h"
  5 int main(void)
  6 {puts("Compiled without Xvideo extention support, sorry.");exit(0);}
  7 #else
  8 /*
  9  * put a TV image to the root window - requires Xvideo
 10  */
 11 
 12 #include <stdio.h>
 13 #include <stdlib.h>
 14 #include <unistd.h>
 15 #include <signal.h>
 16 #include <string.h>
 17 #include <sys/types.h>
 18 #include <sys/wait.h>
 19 
 20 #include <X11/Xlib.h>
 21 #include <X11/Xutil.h>
 22 #include <X11/StringDefs.h>
 23 #include <X11/Xatom.h>
 24 #include <X11/extensions/Xv.h>
 25 #include <X11/extensions/Xvlib.h>
 26 
 27 #include "vroot.h"
 28 #include "atoms.h"
 29 #include "parseconfig.h"
 30 
 31 #define SDIMOF(array)  ((signed int)(sizeof(array)/sizeof(array[0])))
 32 
 33 int     port=-1,bye=0,termsig=0,verbose=0;
 34 GC      gc;
 35 
 36 XvAdaptorInfo        *ai;
 37 XvEncodingInfo       *ei;
 38 XvAttribute          *at;
 39 XvImageFormatValues  *fo;
 40 
 41 static char *reasons[] = {
 42     "XvStarted",
 43     "XvStopped",
 44     "XvBusy",
 45     "XvPreempted",
 46     "XvHardError",
 47 };
 48 
 49 static char *events[] = {
 50     "", "1",
 51     "KeyPress",
 52     "KeyRelease",
 53     "ButtonPress",
 54     "ButtonRelease",
 55     "MotionNotify",
 56     "EnterNotify",
 57     "LeaveNotify",
 58     "FocusIn",
 59     "FocusOut",
 60     "KeymapNotify",
 61     "Expose",
 62     "GraphicsExpose",
 63     "NoExpose",
 64     "VisibilityNotify",
 65     "CreateNotify",
 66     "DestroyNotify",
 67     "UnmapNotify",
 68     "MapNotify",
 69     "MapRequest",
 70     "ReparentNotify",
 71     "ConfigureNotify",
 72     "ConfigureRequest",
 73     "GravityNotify",
 74     "ResizeRequest",
 75     "CirculateNotify",
 76     "CirculateRequest",
 77     "PropertyNotify",
 78     "SelectionClear",
 79     "SelectionRequest",
 80     "SelectionNotify",
 81     "ColormapNotify",
 82     "ClientMessage",
 83     "MappingNotify"
 84 };
 85 
 86 static void station_list(FILE *fp)
 87 {
 88     char filename[100];
 89     char **list;
 90     
 91     sprintf(filename,"%.*s/%s",(int)sizeof(filename)-8,
 92             getenv("HOME"),".xawtv");
 93     cfg_parse_file(CONFIGFILE);
 94     cfg_parse_file(filename);
 95 
 96     for (list = cfg_list_sections(); *list != NULL; list++) {
 97         if (0 == strcmp(*list,"defaults")) continue;
 98         if (0 == strcmp(*list,"global"))   continue;
 99         if (0 == strcmp(*list,"launch"))   continue;
100         if (0 == strcmp(*list,"eventmap")) continue;
101         fprintf(fp,"\t\"%s\" EXEC v4lctl setstation \"%s\"\n",
102                 *list,*list);
103     }
104 }
105 
106 static void wm_menu(FILE *fp)
107 {
108     fprintf(fp,"\"TV stations\" MENU\n");
109     station_list(fp);
110     fprintf(fp,"\"TV stations\" END\n");    
111 }
112 
113 static void video_blit(Display *dpy, Window win)
114 {
115     XWindowAttributes wts;
116 
117     XGetWindowAttributes(dpy, win, &wts);
118 #if 0
119     XClearArea(dpy,win,0,0,0,0,False);
120     XvStopVideo(dpy,port,win);
121 #endif
122     XvPutVideo(dpy,port,win,gc,
123                0,0,wts.width,wts.height,
124                0,0,wts.width,wts.height);
125     if (verbose)
126         fprintf(stderr,"XvPutVideo(win=0x%lx,w=%d,h=%d)\n",
127                 win,wts.width,wts.height);
128 }
129 
130 static void
131 catch_sig(int signal)
132 {
133     termsig = signal;
134     if (verbose)
135         fprintf(stderr,"received signal %d [%s]\n",
136                 termsig,sys_siglist[termsig]);
137 }
138 
139 static void usage(FILE *fp)
140 {
141     fprintf(fp,
142             "rootv is a simple TV application.  Uses and requires Xvideo.\n"
143             "Most settings must be tweaked done using some other tool,\n"
144             "v4lctl for example.\n"
145             "\n"
146             "options:\n"
147             "  -help          print this text\n"
148             "  -verbose       be verbose\n"
149             "  -root          put video onto the root window instead of\n"
150             "                 creating a new window.\n"
151             "  -id <win>      put video into the window <win> instead of\n"
152             "                 creating a new window.\n"
153             "  -station <st>  tune station <st> (just calls v4lctl)\n"
154             "  -no-mute       don't toggle mute on start/exit.\n"
155             "  -port <n>      use Xvideo port <n>.\n"
156             "  -bg            fork into background.\n"
157             "  -wm            print WindowMaker menu, to set all stations\n"
158             "                 listed in ~/.xawtv using v4lctl.\n"
159             "\n");
160 }
161 
162 int
163 main(int argc, char *argv[])
164 {
165     struct sigaction act,old;
166     Display *dpy;
167     Screen  *scr;
168     Window win = -1;
169     XWindowAttributes wts;
170     KeySym keysym;
171     char c;
172 
173     int ver, rel, req, ev, err, dummy;
174     int adaptors,attributes;
175     int i,stop,bg,newwin,do_mute,have_mute,grab;
176 
177     dpy = XOpenDisplay(NULL);
178     scr = DefaultScreenOfDisplay(dpy);
179     init_atoms(dpy);
180 
181     stop = 0;
182     bg = 0;
183     do_mute = 1;
184     have_mute = 0;
185     newwin = 1;
186 
187     while (argc > 1) {
188         if (0 == strcmp(argv[1],"-wm")) {
189             /* windowmaker menu */
190             wm_menu(stdout);
191             exit(0);
192         }
193         if (0 == strcmp(argv[1],"-h") ||
194             0 == strcmp(argv[1],"-help") ||
195             0 == strcmp(argv[1],"--help")) {
196             usage(stdout);
197             exit(0);
198         }
199         if (argc > 2  &&  (0 == strcmp(argv[1],"-id") ||
200                            0 == strcmp(argv[1],"-window-id"))) {
201             sscanf(argv[2],"%li",&win);
202             newwin = 0;
203             if (verbose)
204                 fprintf(stderr,"using window id 0x%lx\n",win);
205             argc-=2;
206             argv+=2;
207         } else if (argc > 2 && 0 == strcmp(argv[1],"-port")) {
208             sscanf(argv[2],"%i",&port);
209             argc-=2;
210             argv+=2;
211         } else if (argc > 2 && 0 == strcmp(argv[1],"-station")) {
212             if (0 == fork()) {
213                 execlp("v4lctl","v4lctl","setstation",argv[2],NULL);
214                 exit(1);
215             } else {
216                 wait(&dummy);
217             }
218             argc-=2;
219             argv+=2;
220         } else if (0 == strcmp(argv[1],"-root")) {
221             win = RootWindowOfScreen(scr);
222             newwin = 0;
223             if (verbose)
224                 fprintf(stderr,"using root window [0x%lx]\n",win);
225             argc--;
226             argv++;
227         } else if (0 == strcmp(argv[1],"-bg")) {
228             bg = 1;
229             argc--;
230             argv++;
231         } else if (0 == strcmp(argv[1],"-verbose")) {
232             verbose = 1;
233             argc--;
234             argv++;
235         } else if (0 == strcmp(argv[1],"-no-mute")) {
236             do_mute = 0;
237             argc--;
238             argv++;
239         } else {
240             fprintf(stderr,"unknown arg: \"%s\"\n",argv[1]);
241             exit(1);
242         }
243     }
244 
245     /* init X11 */
246     if (newwin) {
247         win = XCreateSimpleWindow(dpy,RootWindowOfScreen(scr),
248                                   0,0,640,480,1,
249                                   BlackPixelOfScreen(scr),
250                                   BlackPixelOfScreen(scr));
251         XChangeProperty(dpy, win, WM_PROTOCOLS, XA_ATOM, 32,
252                         PropModeReplace,
253                         (unsigned char *) &WM_DELETE_WINDOW, 1);
254     }
255     XGetWindowAttributes (dpy, win, &wts);
256     XSelectInput(dpy, win, wts.your_event_mask |
257                  KeyPressMask | StructureNotifyMask | ExposureMask);
258     
259     /* query+print Xvideo properties */
260     if (Success != XvQueryExtension(dpy,&ver,&rel,&req,&ev,&err)) {
261         puts("Server does'nt support Xvideo");
262         exit(1);
263     }
264     if (Success != XvQueryAdaptors(dpy,DefaultRootWindow(dpy),&adaptors,&ai)) {
265         puts("Oops: XvQueryAdaptors failed");
266         exit(1);
267     }
268     if (verbose)
269         fprintf(stderr,"%d adaptors available.\n",adaptors);
270     for (i = 0; i < adaptors; i++) {
271         if (verbose)
272             fprintf(stderr,"  port=%ld name=\"%s\"\n",ai[i].base_id,ai[i].name);
273         
274         /* video adaptor ? */
275         if ((ai[i].type & XvInputMask) &&
276             (ai[i].type & XvVideoMask) &&
277             (port == -1)) {
278             port = ai[i].base_id;
279         }
280     }
281     if (adaptors > 0)
282         XvFreeAdaptorInfo(ai);
283     if (-1 == port) {
284         fprintf(stderr,"no Xvideo port found\n");
285         exit(1);
286     }
287 
288     /* grab Xvideo port */
289     grab = 0;
290     for (i = 0; !grab && i < 3; i++) {
291         switch (XvGrabPort(dpy,port,CurrentTime)) {
292         case Success:
293             if (verbose)
294                 fprintf(stderr,"grabbed Xv port\n");
295             grab=1;
296             break;
297         case XvAlreadyGrabbed:
298             if (verbose)
299                 fprintf(stderr,"Xv port already grabbed\n");
300             sleep(1);
301             break;
302         default:
303             fprintf(stderr,"Xv port grab: Huh?\n");
304             exit(1);
305         }
306     }
307     if (!grab) {
308         fprintf(stderr,"can't grab Xv port\n");
309         exit(1);
310     }
311 
312     at = XvQueryPortAttributes(dpy,port,&attributes);
313     for (i = 0; i < attributes; i++) {
314         if (0 == strcmp("XV_MUTE",at[i].name))
315             have_mute = 1;
316     }
317     gc = XCreateGC(dpy,win,0,NULL);
318 
319     /* fork into background, but keep tty */
320     if (bg)
321         if (fork())
322             exit(0);
323 
324     /* catch signals */
325     memset(&act,0,sizeof(act));
326     sigemptyset(&act.sa_mask);
327     act.sa_handler = catch_sig;
328     sigaction(SIGINT,&act,&old);
329     sigaction(SIGHUP,&act,&old);
330     sigaction(SIGTERM,&act,&old);
331     
332     /* put video to the window */
333     if (newwin)
334         XMapWindow(dpy,win);
335     if (verbose)
336         fprintf(stderr,"starting video\n");
337     video_blit(dpy,win);
338     if (do_mute && have_mute)
339         XvSetPortAttribute(dpy,port,XV_MUTE,0);
340 
341     /* receive events */
342     XvSelectPortNotify(dpy, port, 1);
343     XvSelectVideoNotify(dpy, win, 1);
344     
345     /* main loop */
346     for (;!bye && !termsig;) {
347         int rc;
348         fd_set set;
349         XEvent event;
350 
351         if (False == XCheckMaskEvent(dpy, ~0, &event)) {
352             /* wait for x11 events, make sure that signals are catched */
353             XFlush(dpy);
354             FD_ZERO(&set);
355             FD_SET(ConnectionNumber(dpy),&set);
356             rc = select(ConnectionNumber(dpy)+1,&set,NULL,NULL,NULL);
357             if (-1 == rc)
358                 if (verbose)
359                     perror("... select");
360             continue;
361         }
362         
363         if (event.type > ev) {
364             /* Xvideo extention event */
365             switch (event.type-ev) {
366             case XvVideoNotify:
367             {
368                 XvVideoNotifyEvent *xve = (XvVideoNotifyEvent*)&event;
369                 if (verbose)
370                     fprintf(stderr,"XvVideoNotify, reason=%s, exiting\n",
371                             reasons[xve->reason]);
372 #if 0
373                 bye=1;
374 #endif
375                 break;
376             }
377             case XvPortNotify:
378             {
379                 XvPortNotifyEvent *xpe = (XvPortNotifyEvent*)&event;
380                 if (verbose)
381                     fprintf(stderr,"XvPortNotify: %s=%ld\n",
382                             XGetAtomName(dpy,xpe->attribute),xpe->value);
383                 break;
384             }
385             }
386         } else {
387             /* other event */
388             switch (event.type) {
389             case KeyPress:
390                 c = 0;
391                 XLookupString (&event.xkey, &c, 1, &keysym, 0);
392                 if (verbose)
393                     fprintf(stderr,"key: %c\n",c);
394                 switch (c) {
395                 case 'q':
396                 case 'Q':
397                 case 3:   /* ^C  */
398                 case 27:  /* ESC */
399                     bye = 1;
400                 }
401                 break;
402             case ClientMessage:
403                 if (event.xclient.message_type    == WM_PROTOCOLS &&
404                     (Atom)event.xclient.data.l[0] == WM_DELETE_WINDOW)
405                     bye = 1;
406                 break;
407             case Expose:
408                 if (event.xexpose.count)
409                     break;
410                 /* fall througth */
411             case ConfigureNotify:
412                 video_blit(dpy,win);
413                 break;
414             default:
415                 if (verbose) {
416                     if (event.type < SDIMOF(events))
417                         fprintf(stderr,"ev: %s\n",events[event.type]);
418                     else
419                         fprintf(stderr,"ev: #%d\n",event.type);
420                 }
421             }
422         }
423     }
424     if (verbose && termsig)
425         fprintf(stderr,"exiting on signal %d [%s]\n",
426                 termsig,sys_siglist[termsig]);
427     if (do_mute && have_mute)
428         XvSetPortAttribute(dpy,port,XV_MUTE,1);
429     XvStopVideo(dpy,port,win);
430     XvUngrabPort(dpy,port,CurrentTime);
431     XClearArea(dpy,win,0,0,0,0,True);
432     XCloseDisplay(dpy);
433     if (verbose)
434         fprintf(stderr,"bye\n");
435 
436     /* keep compiler happy */
437     exit(0);
438 }
439 
440 #endif
441 
  This page was automatically generated by the LXR engine.