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  * common X11 stuff (mostly libXt level) moved here from main.c
  3  *
  4  *   (c) 1997-2003 Gerd Knorr <kraxel@bytesex.org>
  5  *
  6  */
  7 
  8 #define _GNU_SOURCE
  9 
 10 #include <stdio.h>
 11 #include <stdlib.h>
 12 #include <unistd.h>
 13 #include <string.h>
 14 #include <fcntl.h>
 15 #include <errno.h>
 16 #include <signal.h>
 17 #include <sys/socket.h>
 18 #include <sys/wait.h>
 19 #include <sys/types.h>
 20 #include <sys/stat.h>
 21 #include <sys/utsname.h>
 22 #include <netinet/in.h>
 23 #include <netdb.h>
 24 #include <pthread.h>
 25 
 26 #if defined(__linux__)
 27 # include <sys/ioctl.h>
 28 # include "videodev.h"
 29 #endif
 30 
 31 #include "config.h"
 32 
 33 #include <X11/Xlib.h>
 34 #include <X11/Xproto.h>
 35 #include <X11/Xatom.h>
 36 #include <X11/Intrinsic.h>
 37 #include <X11/Shell.h>
 38 #include <X11/StringDefs.h>
 39 #include <X11/cursorfont.h>
 40 #include <X11/extensions/XShm.h>
 41 
 42 #include "grab-ng.h"
 43 #include "commands.h"
 44 #include "sound.h"
 45 #include "toolbox.h"
 46 #include "xv.h"
 47 #include "atoms.h"
 48 #include "xt.h"
 49 #include "x11.h"
 50 #include "wmhooks.h"
 51 #include "channel.h"
 52 #include "capture.h"
 53 #include "midictrl.h"
 54 #include "lirc.h"
 55 #include "joystick.h"
 56 #include "vbi-data.h"
 57 #include "blit.h"
 58 #include "parseconfig.h"
 59 #include "event.h"
 60 
 61 /* jwz */
 62 #include "remote.h"
 63 
 64 /*----------------------------------------------------------------------*/
 65 
 66 XtAppContext      app_context;
 67 Widget            app_shell, tv;
 68 Widget            on_shell;
 69 Display           *dpy;
 70 int               stay_on_top = 0;
 71 
 72 XVisualInfo       vinfo;
 73 Colormap          colormap;
 74 
 75 int               have_dga   = 0;
 76 int               have_vm    = 0;
 77 int               have_randr = 0;
 78 int               fs = 0;
 79 
 80 void              *movie_state;
 81 int               movie_blit;
 82 
 83 XtIntervalId      zap_timer,scan_timer;
 84 
 85 #ifdef HAVE_LIBXXF86VM
 86 int               vm_count;
 87 XF86VidModeModeInfo **vm_modelines;
 88 XF86VidModeModeLine vm_line;
 89 int                 vm_dot;
 90 #endif
 91 #ifdef HAVE_LIBXINERAMA
 92 XineramaScreenInfo *xinerama;
 93 int                nxinerama;
 94 #endif
 95 #ifdef HAVE_LIBXRANDR
 96 XRRScreenSize      *randr;
 97 int                nrandr;
 98 int                randr_evbase;
 99 #endif
100 
101 static Widget on_label;
102 static XtIntervalId title_timer, on_timer;
103 static char default_title[256] = "???";
104 
105 static int zap_start,zap_fast;
106 
107 /*--- args ----------------------------------------------------------------*/
108 
109 struct ARGS args;
110 
111 XtResource args_desc[] = {
112     /* name, class, type, size, offset, default_type, default_addr */
113     {
114         /* Strings */
115         "device",
116         XtCString, XtRString, sizeof(char*),
117         XtOffset(struct ARGS*,device),
118         XtRString, NULL
119     },{
120         "driver",
121         XtCString, XtRString, sizeof(char*),
122         XtOffset(struct ARGS*,driver),
123         XtRString, NULL
124     },{
125         "dspdev",
126         XtCString, XtRString, sizeof(char*),
127         XtOffset(struct ARGS*,dspdev),
128         XtRString, NULL
129     },{
130         "vbidev",
131         XtCString, XtRString, sizeof(char*),
132         XtOffset(struct ARGS*,vbidev),
133         XtRString, NULL
134     },{
135         "joydev",
136         XtCString, XtRString, sizeof(char*),
137         XtOffset(struct ARGS*,joydev),
138         XtRString, NULL
139     },{
140         "basename",
141         XtCString, XtRString, sizeof(char*),
142         XtOffset(struct ARGS*,basename),
143         XtRString, "snap"
144     },{
145         "conffile",
146         XtCString, XtRString, sizeof(char*),
147         XtOffset(struct ARGS*,conffile),
148         XtRString, NULL
149     },{
150         /* Integer */
151         "debug",
152         XtCValue, XtRInt, sizeof(int),
153         XtOffset(struct ARGS*,debug),
154         XtRString, ""
155     },{
156         "bpp",
157         XtCValue, XtRInt, sizeof(int),
158         XtOffset(struct ARGS*,bpp),
159         XtRString, ""
160     },{
161         "shift",
162         XtCValue, XtRInt, sizeof(int),
163         XtOffset(struct ARGS*,shift),
164         XtRString, ""
165     },{
166         "xvport",
167         XtCValue, XtRInt, sizeof(int),
168         XtOffset(struct ARGS*,xv_port),
169         XtRString, ""
170     },{
171         "parallel",
172         XtCValue, XtRInt, sizeof(int),
173         XtOffset(struct ARGS*,parallel),
174         XtRString, "1"
175     },{
176         "bufcount",
177         XtCValue, XtRInt, sizeof(int),
178         XtOffset(struct ARGS*,bufcount),
179         XtRString, "16"
180     },{
181         /* Boolean */
182         "remote",
183         XtCBoolean, XtRBoolean, sizeof(int),
184         XtOffset(struct ARGS*,remote),
185         XtRString, ""
186     },{
187         "readconfig",
188         XtCBoolean, XtRBoolean, sizeof(int),
189         XtOffset(struct ARGS*,readconfig),
190         XtRString, "1"
191     },{
192         "fullscreen",
193         XtCBoolean, XtRBoolean, sizeof(int),
194         XtOffset(struct ARGS*,fullscreen),
195         XtRString, ""
196     },{
197         "fbdev",
198         XtCBoolean, XtRBoolean, sizeof(int),
199         XtOffset(struct ARGS*,fbdev),
200         XtRString, ""
201     },{
202         "xv",
203         XtCBoolean, XtRBoolean, sizeof(int),
204         XtOffset(struct ARGS*,xv),
205         XtRString, "1"
206     },{
207         "xvVideo",
208         XtCBoolean, XtRBoolean, sizeof(int),
209         XtOffset(struct ARGS*,xv_video),
210         XtRString, "1"
211     },{
212         "xvImage",
213         XtCBoolean, XtRBoolean, sizeof(int),
214         XtOffset(struct ARGS*,xv_image),
215         XtRString, "1"
216     },{
217         "gl",
218         XtCBoolean, XtRBoolean, sizeof(int),
219         XtOffset(struct ARGS*,gl),
220         XtRString, "1"
221     },{
222         "vidmode",
223         XtCBoolean, XtRBoolean, sizeof(int),
224         XtOffset(struct ARGS*,vidmode),
225         XtRString, "1"
226     },{
227         "dga",
228         XtCBoolean, XtRBoolean, sizeof(int),
229         XtOffset(struct ARGS*,dga),
230         XtRString, "1"
231     },{
232         "randr",
233         XtCBoolean, XtRBoolean, sizeof(int),
234         XtOffset(struct ARGS*,randr),
235         XtRString, "1"
236     },{
237         "help",
238         XtCBoolean, XtRBoolean, sizeof(int),
239         XtOffset(struct ARGS*,help),
240         XtRString, ""
241     },{
242         "hwscan",
243         XtCBoolean, XtRBoolean, sizeof(int),
244         XtOffset(struct ARGS*,hwscan),
245         XtRString, ""
246     }
247 };
248 
249 const int args_count = XtNumber(args_desc);
250 
251 XrmOptionDescRec opt_desc[] = {
252     { "-c",          "device",      XrmoptionSepArg, NULL },
253     { "-device",     "device",      XrmoptionSepArg, NULL },
254     { "-driver",     "driver",      XrmoptionSepArg, NULL },
255     { "-C",          "dspdev",      XrmoptionSepArg, NULL },
256     { "-dspdev",     "dspdev",      XrmoptionSepArg, NULL },
257     { "-vbidev",     "vbidev",      XrmoptionSepArg, NULL },
258     { "-joydev",     "joydev",      XrmoptionSepArg, NULL },
259     { "-o",          "basename",    XrmoptionSepArg, NULL },
260     { "-outfile",    "basename",    XrmoptionSepArg, NULL },
261     { "-conffile",   "conffile",    XrmoptionSepArg, NULL },
262     
263     { "-v",          "debug",       XrmoptionSepArg, NULL },
264     { "-debug",      "debug",       XrmoptionSepArg, NULL },
265     { "-b",          "bpp",         XrmoptionSepArg, NULL },
266     { "-bpp",        "bpp",         XrmoptionSepArg, NULL },
267     { "-shift",      "shift",       XrmoptionSepArg, NULL },
268     { "-xvport",     "xvport",      XrmoptionSepArg, NULL },
269     { "-parallel",   "parallel",    XrmoptionSepArg, NULL },
270     { "-bufcount",   "bufcount",    XrmoptionSepArg, NULL },
271     
272     { "-remote",     "remote",      XrmoptionNoArg,  "1" },
273     { "-n",          "readconfig",  XrmoptionNoArg,  "" },
274     { "-noconf",     "readconfig",  XrmoptionNoArg,  "" },
275     { "-f",          "fullscreen",  XrmoptionNoArg,  "1" },
276     { "-fullscreen", "fullscreen",  XrmoptionNoArg,  "1" },
277     { "-hwscan",     "hwscan",      XrmoptionNoArg,  "1" },
278     { "-fb",         "fbdev",       XrmoptionNoArg,  "1" },
279     
280     { "-xv",         "xv",          XrmoptionNoArg,  "1" },
281     { "-noxv",       "xv",          XrmoptionNoArg,  "" },
282     { "-xv-video",   "xvVideo",     XrmoptionNoArg,  "1" },
283     { "-noxv-video", "xvVideo",     XrmoptionNoArg,  "" },
284     { "-xv-image",   "xvImage",     XrmoptionNoArg,  "1" },
285     { "-noxv-image", "xvImage",     XrmoptionNoArg,  "" },
286     { "-gl",         "gl",          XrmoptionNoArg,  "1" },
287     { "-nogl",       "gl",          XrmoptionNoArg,  "" },
288 
289     { "-vm",         "vidmode",     XrmoptionNoArg,  "1" },
290     { "-novm",       "vidmode",     XrmoptionNoArg,  "" },
291     { "-dga",        "dga",         XrmoptionNoArg,  "1" },
292     { "-nodga",      "dga",         XrmoptionNoArg,  "" },
293     { "-randr",      "randr",       XrmoptionNoArg,  "1" },
294     { "-norandr",    "randr",       XrmoptionNoArg,  "" },
295     
296     { "-h",          "help",        XrmoptionNoArg,  "1" },
297     { "-help",       "help",        XrmoptionNoArg,  "1" },
298     { "--help",      "help",        XrmoptionNoArg,  "1" },
299 };
300 
301 const int opt_count = (sizeof(opt_desc)/sizeof(XrmOptionDescRec));
302 /*----------------------------------------------------------------------*/
303 
304 Boolean
305 ExitWP(XtPointer client_data)
306 {
307     /* exit if the application is idle,
308      * i.e. all the DestroyCallback's are called.
309      */
310     exit(0);
311 }
312 
313 void
314 ExitCB(Widget widget, XtPointer client_data, XtPointer calldata)
315 {
316     audio_off();
317     video_overlay(0);
318     video_close();
319     do_va_cmd(2,"capture", "off");
320     if (fs)
321         do_va_cmd(1,"fullscreen");
322     XSync(dpy,False);
323     drv->close(h_drv);
324     XtAppAddWorkProc(app_context,ExitWP, NULL);
325     XtDestroyWidget(app_shell);
326 }
327 
328 void
329 do_exit(void)
330 {
331     ExitCB(NULL,NULL,NULL);
332 }
333 
334 void
335 CloseMainAction(Widget widget, XEvent *event,
336                 String *params, Cardinal *num_params)
337 {
338     if (NULL != event && event->type == ClientMessage) {
339         if (debug)
340             fprintf(stderr,"CloseMainAction: received %s message\n",
341                     XGetAtomName(dpy,event->xclient.data.l[0]));
342         if ((Atom)event->xclient.data.l[0] == WM_DELETE_WINDOW) {
343             /* fall throuth -- popdown window */
344         } else {
345             /* whats this ?? */
346             return;
347         }
348     }
349     ExitCB(widget,NULL,NULL);
350 }
351 
352 void
353 RemoteAction(Widget widget, XEvent * event,
354              String * params, Cardinal * num_params)
355 {
356     Atom            type;
357     int             format, argc;
358     unsigned int    i;
359     char            *argv[32];
360     unsigned long   nitems, bytesafter;
361     unsigned char   *args = NULL;
362 
363     if (event->type == PropertyNotify) {
364         if (debug > 1)
365             fprintf(stderr,"PropertyNotify %s\n",
366                     XGetAtomName(dpy,event->xproperty.atom));
367         if (event->xproperty.atom == _XAWTV_REMOTE &&
368             Success == XGetWindowProperty(dpy,
369                                           event->xproperty.window,
370                                           event->xproperty.atom,
371                                           0, (65536 / sizeof(long)),
372                                           True, XA_STRING,
373                                           &type, &format, &nitems, &bytesafter,
374                                           &args) &&
375             nitems != 0) {
376             for (i = 0, argc = 0; i <= nitems; i += strlen(args + i) + 1) {
377                 if (i == nitems || args[i] == '\0') {
378                     argv[argc] = NULL;
379                     do_command(argc,argv);
380                     argc = 0;
381                 } else {
382                     argv[argc++] = args+i;
383                 }
384             }
385             XFree(args);
386         }
387     }
388 }
389 
390 static void
391 zap_timeout(XtPointer client_data, XtIntervalId *id)
392 {
393     static int muted = 0;
394 
395     if (zap_fast && !cur_attrs[ATTR_ID_MUTE]) {
396         /* mute for fast channel scan */
397         muted = 1;
398         do_va_cmd(2,"volume","mute","on");
399     }
400     /* pixit(); */
401     do_va_cmd(2,"setstation","next");
402     if (cur_sender != zap_start) {
403         zap_timer = XtAppAddTimeOut
404             (app_context, zap_fast ? CAP_TIME : ZAP_TIME, zap_timeout,NULL);
405     } else {
406         if(muted) {
407             /* unmute */
408             muted = 0;
409             do_va_cmd(2,"volume","mute","off");
410         }
411     }
412 }
413 
414 void
415 ZapAction(Widget widget, XEvent *event,
416           String *params, Cardinal *num_params)
417 {
418     if (zap_timer) {
419         XtRemoveTimeOut(zap_timer);
420         zap_timer = 0;
421 #if 0
422         strcpy(title,"channel hopping off");
423         set_timer_title();
424 #endif
425     } else {
426         zap_start = (cur_sender == -1) ? 0 : cur_sender;
427         zap_fast = 0;
428         if (*num_params > 0) {
429             if (0 == strcasecmp(params[0],"fast"))
430                 zap_fast = 1;
431         }
432         if (count)
433             zap_timer = XtAppAddTimeOut
434                 (app_context, CAP_TIME, zap_timeout,NULL);
435     }
436 }
437 
438 static void
439 scan_timeout(XtPointer client_data, XtIntervalId *id)
440 {
441     scan_timer = 0;
442     
443     /* check */
444     if (!(f_drv & CAN_TUNE))
445         return;
446     if (drv->is_tuned(h_drv))
447         return;
448 
449     do_va_cmd(2,"setchannel","next");
450     scan_timer = XtAppAddTimeOut
451         (app_context, SCAN_TIME, scan_timeout, NULL);
452 }
453 
454 void
455 ScanAction(Widget widget, XEvent *event,
456            String *params, Cardinal *num_params)
457 {
458     if (channel_switch_hook)
459         channel_switch_hook();
460     do_va_cmd(2,"setchannel","next");
461     scan_timer = XtAppAddTimeOut
462         (app_context, SCAN_TIME, scan_timeout,NULL);
463 }
464 
465 void
466 RatioAction(Widget widget, XEvent *event,
467             String *params, Cardinal *num_params)
468 {
469     int w,h;
470     
471     if (2 != *num_params)
472         return;
473     w = atoi(params[0]);
474     h = atoi(params[1]);
475     ng_ratio_x = w;
476     ng_ratio_y = h;
477     do_va_cmd(2,"capture","off");
478     do_va_cmd(2,"capture","on");
479 }
480 
481 /*--- onscreen display (fullscreen) --------------------------------------*/
482 
483 void
484 create_onscreen(WidgetClass class)
485 {
486     on_shell = XtVaCreateWidget("onscreen",transientShellWidgetClass,
487                                 app_shell,
488                                 XtNoverrideRedirect,True,
489                                 XtNvisual,vinfo.visual,
490                                 XtNcolormap,colormap,
491                                 XtNdepth,vinfo.depth,
492                                 NULL);
493     on_label = XtVaCreateManagedWidget("label", class, on_shell,
494                                        NULL);
495 }
496 
497 static void
498 popdown_onscreen(XtPointer client_data, XtIntervalId *id)
499 {
500     if (debug)
501         fprintf(stderr,"osd: hide\n");
502     XtPopdown(on_shell);
503     on_timer = 0;
504 }
505 
506 static void
507 display_onscreen(char *title)
508 {
509     static int first = 1;
510     Dimension x,y;
511 
512     if (!fs)
513         return;
514     if (!use_osd)
515         return;
516 
517     if (debug)
518         fprintf(stderr,"osd: show (%s)\n",title);
519     XtVaGetValues(app_shell,XtNx,&x,XtNy,&y,NULL);
520     XtVaSetValues(on_shell,XtNx,x+osd_x,XtNy,y+osd_y,NULL);
521     toolkit_set_label(on_label,title);
522     XtPopup(on_shell, XtGrabNone);
523     if (wm_stay_on_top && stay_on_top > 0)
524         wm_stay_on_top(dpy,XtWindow(on_shell),1);
525     if (on_timer)
526         XtRemoveTimeOut(on_timer);
527     on_timer = XtAppAddTimeOut
528         (app_context, ONSCREEN_TIME, popdown_onscreen,NULL);
529 
530     if (first) {
531         first = 0;
532         XDefineCursor(dpy, XtWindow(on_shell), no_ptr);
533         XDefineCursor(dpy, XtWindow(on_label), no_ptr);
534     }
535 }
536 
537 /*----------------------------------------------------------------------*/
538 
539 Boolean
540 rec_work(XtPointer client_data)
541 {
542     struct ng_video_buf *buf;
543 
544     if (movie_blit) {
545         buf = NULL;
546         movie_grab_put_video(movie_state, &buf);
547         if (buf)
548             video_gd_blitframe(&vh,buf);
549     } else {
550         movie_grab_put_video(movie_state, NULL);
551     }
552     return False;
553 }
554 
555 void
556 exec_done(int signal)
557 {
558     int pid,stat;
559 
560     if (debug)
561         fprintf(stderr,"got sigchild\n");
562     pid = waitpid(-1,&stat,WUNTRACED|WNOHANG);
563     if (debug) {
564         if (-1 == pid) {
565             perror("waitpid");
566         } else if (0 == pid) {
567             fprintf(stderr,"oops: got sigchild and waitpid returns 0 ???\n");
568         } else if (WIFEXITED(stat)){
569             fprintf(stderr,"[%d]: normal exit (%d)\n",pid,WEXITSTATUS(stat));
570         } else if (WIFSIGNALED(stat)){
571             fprintf(stderr,"[%d]: %s\n",pid,strsignal(WTERMSIG(stat)));
572         } else if (WIFSTOPPED(stat)){
573             fprintf(stderr,"[%d]: %s\n",pid,strsignal(WSTOPSIG(stat)));
574         }
575     }
576 }
577 
578 static void
579 exec_output(XtPointer data, int *fd, XtInputId * iproc)
580 {
581     char buffer[81];
582     int len;
583 
584     switch (len = read(*fd,buffer,80)) {
585     case -1: /* error */
586         perror("read pipe");
587         /* fall */
588     case 0:  /* EOF */
589         close(*fd);
590         XtRemoveInput(*iproc);
591         break;
592     default: /* got some bytes */
593         buffer[len] = 0;
594         fprintf(stderr,"%s",buffer);
595         break;
596     }
597 }
598 
599 int
600 exec_x11(char **argv)
601 {
602     int p[2],pid,i;
603 
604     if (debug) {
605         fprintf(stderr,"exec: \"%s\"",argv[0]);
606         for (i = 1; argv[i] != NULL; i++)
607             fprintf(stderr,", \"%s\"",argv[i]);
608         fprintf(stderr,"\n");
609     }
610     pipe(p);
611     switch (pid = fork()) {
612     case -1:
613         perror("fork");
614         return -1;
615     case 0:
616         /* child */
617         dup2(p[1],1);
618         dup2(p[1],2);
619         close(p[0]);
620         close(p[1]);
621         close(ConnectionNumber(dpy));
622         execvp(argv[0],argv);
623         fprintf(stderr,"exec %s: %s\n",argv[0],strerror(errno));
624         exit(1);
625     default:
626         /* parent */
627         close(p[1]);
628         XtAppAddInput(app_context, p[0], (XtPointer) XtInputReadMask,
629                       exec_output, NULL);
630         break;
631     }
632     return pid;
633 }
634 
635 void
636 exec_player(char *moviefile)
637 {
638     //static char *command = "xanim +f +Sr +Ze -Zr";
639     static char *command = "pia";
640     char *cmd;
641     char **argv;
642     int  argc;
643     
644     /* go! */
645     cmd = malloc(strlen(command)+strlen(moviefile)+5);
646     sprintf(cmd,"%s %s",command,moviefile);
647     argv = split_cmdline(cmd,&argc);
648     exec_x11(argv);
649 }
650 
651 void
652 LaunchAction(Widget widget, XEvent *event,
653             String *params, Cardinal *num_params)
654 {
655     char **argv;
656     int  i,argc;
657     
658     if (*num_params != 1)
659         return;
660     for (i = 0; i < nlaunch; i++) {
661         if (0 == strcasecmp(params[0],launch[i].name))
662             break;
663     }
664     if (i == nlaunch)
665         return;
666 
667     argv = split_cmdline(launch[i].cmdline,&argc);
668 
669     switch (fork()) {
670     case -1:
671         perror("fork");
672         break;
673     case 0:
674         if (debug) {
675             fprintf(stderr,"[%d]: exec ",getpid());
676             for (i = 0; i < argc; i++) {
677                 fprintf(stderr,"\"%s\" ",argv[i]);
678             }
679             fprintf(stderr,"\n");
680         }
681         execvp(argv[0],argv);
682         fprintf(stderr,"execvp %s: %s",argv[0],strerror(errno));
683         exit(1);
684         break;
685     default:
686         break;
687     }
688 }
689 
690 /*------------------------------------------------------------------------*/
691 
692 XtSignalId sig_id;
693 
694 static void termsig_handler(XtPointer data, XtSignalId *id)
695 {
696     ExitCB(NULL,NULL,NULL);
697 }
698 
699 static void
700 termsig(int signal)
701 {
702     if (debug)
703         fprintf(stderr,"received signal %d [%s]\n",signal,strsignal(signal));
704     XtNoticeSignal(sig_id);
705 }
706 
707 static void
708 segfault(int signal)
709 {
710     fprintf(stderr,"[pid=%d] segfault catched, aborting\n",getpid());
711     abort();
712 }
713 
714 void
715 xt_siginit(void)
716 {
717     struct sigaction act,old;
718 
719     memset(&act,0,sizeof(act));
720     sigemptyset(&act.sa_mask);
721     act.sa_handler  = exec_done;
722     sigaction(SIGCHLD,&act,&old);
723 
724     sig_id = XtAppAddSignal(app_context,termsig_handler,NULL);
725     act.sa_handler  = termsig;
726     sigaction(SIGINT,&act,&old);
727     sigaction(SIGTERM,&act,&old);
728 
729     act.sa_handler  = SIG_IGN;
730     sigaction(SIGPIPE,&act,&old);
731     
732     if (debug) {
733         act.sa_handler  = segfault;
734         sigaction(SIGSEGV,&act,&old);
735         fprintf(stderr,"main thread [pid=%d]\n",getpid());
736     }
737 }
738 
739 /*----------------------------------------------------------------------*/
740 
741 static XtIntervalId xscreensaver_timer;
742 
743 static void
744 xscreensaver_timefunc(XtPointer clientData, XtIntervalId *id)
745 {
746     static int first = 1;
747     int status;
748     char *err;
749 
750     if (debug)
751         fprintf(stderr,"xscreensaver_timefunc\n");
752     xscreensaver_timer = 0;
753     if (first) {
754         xscreensaver_init(dpy);
755         first = 0;
756     }
757     status = xscreensaver_command(dpy,XA_DEACTIVATE,0,debug,&err);
758     if (0 != status) {
759         if (debug)
760             fprintf(stderr,"xscreensaver_command: %s\n",err);
761         return;
762     }
763     xscreensaver_timer = XtAppAddTimeOut(app_context,60000,
764                                          xscreensaver_timefunc,NULL);
765 }
766 
767 /*----------------------------------------------------------------------*/
768 
769 #ifdef HAVE_LIBXXF86VM
770 static void
771 vidmode_timer(XtPointer clientData, XtIntervalId *id)
772 {
773     do_va_cmd(2,"capture", "on");
774 }
775 
776 static void
777 set_vidmode(XF86VidModeModeInfo *mode)
778 {
779     if (CAPTURE_OVERLAY == cur_capture) {
780         do_va_cmd(2,"capture", "off");
781         XtAppAddTimeOut(app_context,VIDMODE_DELAY,vidmode_timer,NULL);
782     }
783     /* usleep(VIDMODE_DELAY*1000); */
784     if (debug)
785         fprintf(stderr,"switching mode: %d  %d %d %d %d  %d %d %d %d  %d\n",
786                 mode->dotclock,
787                 mode->hdisplay,
788                 mode->hsyncstart,
789                 mode->hsyncend,
790                 mode->htotal,
791                 mode->vdisplay,
792                 mode->vsyncstart,
793                 mode->vsyncend,
794                 mode->vtotal,
795                 mode->flags);
796     XF86VidModeSwitchToMode(dpy,XDefaultScreen(dpy),mode);
797     XSync(dpy,False);
798 }
799 
800 static void
801 do_vidmode_modeswitch(int fs_state, int *vp_width, int *vp_height)
802 {
803     static int                  vm_switched;
804     static XF86VidModeModeInfo  *vm_current    = NULL;
805     static XF86VidModeModeInfo  *vm_fullscreen = NULL;
806     int i;
807     
808     if (fs_state) {
809         /* enter fullscreen mode */
810         XF86VidModeGetModeLine(dpy,XDefaultScreen(dpy),&vm_dot,&vm_line);
811         XF86VidModeGetAllModeLines(dpy,XDefaultScreen(dpy),
812                                    &vm_count,&vm_modelines);
813         vm_fullscreen = NULL;
814         for (i = 0; i < vm_count; i++) {
815             if (fs_width  == vm_modelines[i]->hdisplay &&
816                 fs_height == vm_modelines[i]->vdisplay &&
817                 vm_fullscreen == NULL)
818                 vm_fullscreen = vm_modelines[i];
819             if (vm_line.hdisplay == vm_modelines[i]->hdisplay &&
820                 vm_line.vdisplay == vm_modelines[i]->vdisplay &&
821                 vm_current == NULL)
822                 vm_current = vm_modelines[i];
823         }
824         if (debug) {
825             fprintf(stderr,"vm: current=%dx%d",
826                     vm_current->hdisplay,vm_current->vdisplay);
827             if (vm_fullscreen)
828                 fprintf(stderr,"fullscreen=%dx%d",
829                         vm_fullscreen->hdisplay,vm_fullscreen->vdisplay);
830             fprintf(stderr,"\n");
831         }
832         if (vm_current && vm_fullscreen &&
833             vm_fullscreen->hdisplay != vm_current->hdisplay &&
834             vm_fullscreen->vdisplay != vm_current->vdisplay) {
835             set_vidmode(vm_fullscreen);
836             vm_switched = 1;
837             *vp_width   = vm_fullscreen->hdisplay;
838             *vp_height  = vm_fullscreen->vdisplay;
839         } else {
840             vm_switched = 0;
841             *vp_width   = vm_current->hdisplay;
842             *vp_height  = vm_current->vdisplay;
843         }
844     } else {
845         /* leave fullscreen mode */
846         if (vm_switched) {
847             set_vidmode(vm_current);
848             vm_switched = 0;
849         }
850     }
851 }
852 #endif
853 
854 #ifdef HAVE_LIBXRANDR
855 static void
856 do_randr_modeswitch(int fs_state, int *vp_width, int *vp_height)
857 {
858     static SizeID normal;
859     Window root = RootWindow(dpy, DefaultScreen(dpy));
860     XRRScreenConfiguration *sc;
861     Rotation rotation;
862     SizeID current, new, i;
863     
864     sc = XRRGetScreenInfo(dpy, root);
865     current = XRRConfigCurrentConfiguration(sc, &rotation);
866     new = current;
867     if (fs_state) {
868         /* enter fullscreen mode */
869         normal = current;
870         new = current;
871         for (i = 0; i < nrandr; i++) {
872             if (randr[i].width  == fs_width &&
873                 randr[i].height == fs_height) {
874                 new = i;
875                 break;
876             }
877         }
878     } else {
879         /* leave fullscreen mode */
880         new = normal;
881     }
882 
883     if (new != current) {
884         /* switch mode */
885         if (debug)
886             fprintf(stderr, "randr: switch to %dx%d\n",
887                     randr[new].width, randr[new].height);
888         XRRSetScreenConfig(dpy, sc, root, new, rotation, CurrentTime);
889     }
890     XRRFreeScreenConfigInfo(sc);
891 
892     /* FIXME: change swidth / sheight instead */
893     *vp_width  = randr[new].width;
894     *vp_height = randr[new].height;
895 }
896 #endif
897 
898 static void
899 do_modeswitch(int fs_state, int *vp_width, int *vp_height)
900 {
901     *vp_width  = swidth;
902     *vp_height = sheight;
903 
904 #ifdef HAVE_LIBXXF86VM
905     if (have_vm)
906         do_vidmode_modeswitch(fs_state,vp_width,vp_height);
907 #endif
908 #ifdef HAVE_LIBXRANDR
909     if (!have_vm && have_randr)
910         do_randr_modeswitch(fs_state,vp_width,vp_height);
911 #endif
912 }
913 
914 /*----------------------------------------------------------------------*/
915 
916 Boolean
917 MyResize(XtPointer client_data)
918 {
919     /* needed for program-triggered resizes (fullscreen mode) */
920     video_new_size();
921     return TRUE;
922 }
923 
924 static void
925 do_screensaver(int fs_state)
926 {
927     static int timeout,interval,prefer_blanking,allow_exposures;
928 #ifdef HAVE_LIBXDPMS
929     static BOOL dpms_on;
930     CARD16 dpms_state;
931     int dpms_dummy;
932 #endif
933 
934     if (fs_state) {
935         /* fullscreen on -- disable screensaver */
936         XGetScreenSaver(dpy,&timeout,&interval,
937                         &prefer_blanking,&allow_exposures);
938         XSetScreenSaver(dpy,0,0,DefaultBlanking,DefaultExposures);
939 #ifdef HAVE_LIBXDPMS
940         if ((DPMSQueryExtension(dpy, &dpms_dummy, &dpms_dummy)) && 
941             (DPMSCapable(dpy))) {
942             DPMSInfo(dpy, &dpms_state, &dpms_on);
943             DPMSDisable(dpy); 
944         }
945 #endif
946         xscreensaver_timer = XtAppAddTimeOut(app_context,60000,
947                                              xscreensaver_timefunc,NULL);
948     } else {
949         /* fullscreen off -- enable screensaver */
950         XSetScreenSaver(dpy,timeout,interval,prefer_blanking,allow_exposures);
951 #ifdef HAVE_LIBXDPMS
952         if ((DPMSQueryExtension(dpy, &dpms_dummy, &dpms_dummy)) && 
953             (DPMSCapable(dpy)) && (dpms_on)) {
954                 DPMSEnable(dpy);
955         }
956 #endif
957         if (xscreensaver_timer)
958             XtRemoveTimeOut(xscreensaver_timer);
959     }
960 }
961 
962 void
963 do_fullscreen(void)
964 {
965     static Dimension x,y,w,h;
966     static int rpx,rpy;
967     static int warp_pointer;
968 
969     Window root,child;
970     int    wpx,wpy,mask;
971     unsigned int vp_width, vp_height;
972 
973     if (use_wm_fullscreen && wm_fullscreen) {
974         /* full service for us, next to nothing to do */
975         fs = !fs;
976         if (debug)
977             fprintf(stderr,"fullscreen %s via netwm\n", fs ? "on" : "off");
978 
979         do_modeswitch(fs,&vp_width,&vp_height);
980         XSync(dpy,False);
981         wm_fullscreen(dpy,XtWindow(app_shell),fs);
982 
983         if (0 == fs  &&  on_timer) {
984             XtPopdown(on_shell);
985             XtRemoveTimeOut(on_timer);
986             on_timer = 0;
987         }
988         do_screensaver(fs);
989         return;
990     }
991 
992     if (fs) {
993         if (debug)
994             fprintf(stderr,"turning fs off (%dx%d+%d+%d)\n",w,h,x,y);
995         do_modeswitch(0,&vp_width,&vp_height);
996         
997         if (on_timer) {
998             XtPopdown(on_shell);
999             XtRemoveTimeOut(on_timer);
1000             on_timer = 0;
1001         }
1002         
1003         XtVaSetValues(app_shell,
1004                       XtNwidthInc, WIDTH_INC,
1005                       XtNheightInc,HEIGHT_INC,
1006                       XtNx,        x + fs_xoff,
1007                       XtNy,        y + fs_yoff,
1008                       XtNwidth,    w,
1009                       XtNheight,   h,
1010                       NULL);
1011 
1012         do_screensaver(0);
1013         if (warp_pointer)
1014             XWarpPointer(dpy, None, RootWindowOfScreen(XtScreen(tv)),
1015                          0, 0, 0, 0, rpx, rpy);
1016         fs = 0;
1017     } else {
1018         int vp_x, vp_y;
1019 
1020         if (debug)
1021             fprintf(stderr,"turning fs on\n");
1022         XQueryPointer(dpy, RootWindowOfScreen(XtScreen(tv)),
1023                       &root, &child, &rpx, &rpy, &wpx, &wpy, &mask);
1024 
1025         vp_x = 0;
1026         vp_y = 0;
1027         do_modeswitch(1,&vp_width,&vp_height);
1028         if (vp_width < sheight || vp_width < swidth) {
1029             /* move viewpoint, make sure the pointer is in there */
1030             warp_pointer = 1;
1031             XWarpPointer(dpy, None, RootWindowOfScreen(XtScreen(tv)),
1032                          0, 0, 0, 0, vp_width/2, vp_height/2);
1033 #ifdef HAVE_LIBXXF86VM
1034             XF86VidModeSetViewPort(dpy,XDefaultScreen(dpy),0,0);
1035 #endif
1036         }
1037         XtVaGetValues(app_shell,
1038                       XtNx,          &x,
1039                       XtNy,          &y,
1040                       XtNwidth,      &w,
1041                       XtNheight,     &h,
1042                       NULL);
1043 
1044 #ifdef HAVE_LIBXINERAMA
1045         if (nxinerama) {
1046             /* check which physical screen we are visible on */
1047             int i;
1048             for (i = 0; i < nxinerama; i++) {
1049                 if (x >= xinerama[i].x_org &&
1050                     y >= xinerama[i].y_org && 
1051                     x <  xinerama[i].x_org + xinerama[i].width &&
1052                     y <  xinerama[i].y_org + xinerama[i].height) {
1053                     vp_x      = xinerama[i].x_org;
1054                     vp_y      = xinerama[i].y_org;
1055                     vp_width  = xinerama[i].width;
1056                     vp_height = xinerama[i].height;
1057                     break;
1058                 }
1059             }
1060         }
1061 #endif
1062         if (debug)
1063             fprintf(stderr,"viewport: %dx%d+%d+%d\n",
1064                     vp_width,vp_height,vp_x,vp_y);
1065 
1066         XtVaSetValues(app_shell,
1067                       XtNwidthInc,   1,
1068                       XtNheightInc,  1,
1069                       NULL);
1070         XtVaSetValues(app_shell,
1071                       XtNx,          (vp_x & 0xfffc) + fs_xoff,
1072                       XtNy,          vp_y            + fs_yoff,
1073                       XtNwidth,      vp_width,
1074                       XtNheight,     vp_height,
1075                       NULL);
1076 
1077         XRaiseWindow(dpy, XtWindow(app_shell));
1078         do_screensaver(1);
1079         if (warp_pointer)
1080             XWarpPointer(dpy, None, XtWindow(tv), 0, 0, 0, 0, 30, 15);
1081         fs = 1;
1082     }
1083     XtAppAddWorkProc (app_context, MyResize, NULL);
1084 }
1085 
1086 /*----------------------------------------------------------------------*/
1087 
1088 static void
1089 title_timeout(XtPointer client_data, XtIntervalId *id)
1090 {
1091     keypad_timeout();
1092     XtVaSetValues(app_shell,XtNtitle,default_title,NULL);
1093     title_timer = 0;
1094 }
1095 
1096 void
1097 new_title(char *txt)
1098 {
1099     strcpy(default_title,txt);
1100     XtVaSetValues(app_shell,
1101                   XtNtitle,default_title,
1102                   XtNiconName,default_title,
1103                   NULL);
1104     display_onscreen(default_title);
1105 
1106     if (title_timer) {
1107         XtRemoveTimeOut(title_timer);
1108         title_timer = 0;
1109     }
1110 }
1111 
1112 void
1113 new_message(char *txt)
1114 {
1115     XtVaSetValues(app_shell,XtNtitle,txt,NULL);
1116     display_onscreen(txt);
1117     if (title_timer)
1118         XtRemoveTimeOut(title_timer);
1119     title_timer = XtAppAddTimeOut
1120         (app_context, TITLE_TIME, title_timeout,NULL);
1121 }
1122 
1123 /*
1124  * mode = -1: check mode (just update the title)
1125  * mode =  0: set autodetect (and read back result)
1126  * mode >  0: set some mode
1127  */
1128 void
1129 change_audio(int mode)
1130 {
1131     struct ng_attribute *attr;
1132     const char *mname;
1133     char label[64];
1134 
1135     attr = ng_attr_byid(attrs,ATTR_ID_AUDIO_MODE);
1136     if (NULL == attr)
1137         return;
1138 
1139     if (-1 != mode)
1140         attr->write(attr,mode);
1141     if (-1 == mode || 0 == mode)
1142         mode = attr->read(attr);
1143 
1144     mname = ng_attr_getstr(attr,mode);
1145     if (NULL == mname)
1146         mname = "???";
1147 
1148     if (attr_notify)
1149         attr_notify(attr,mode);
1150 
1151     sprintf(label,"%s (%s)",default_title,mname);
1152     XtVaSetValues(app_shell,XtNtitle,label,NULL);
1153 }
1154 
1155 /*----------------------------------------------------------------------*/
1156 
1157 void
1158 CommandAction(Widget widget, XEvent *event,
1159               String *params, Cardinal *num_params)
1160 {
1161     do_command(*num_params,params);
1162 }
1163 
1164 void
1165 set_property(int freq, char *channel, char *name)
1166 {
1167     int  len;
1168     char line[80];
1169 
1170     len  = sprintf(line,"%.3f",(float)freq/16)+1;
1171     len += sprintf(line+len,"%s",channel ? channel : "?") +1;
1172     len += sprintf(line+len,"%s",name    ? name    : "?") +1;
1173     XChangeProperty(dpy, XtWindow(app_shell),
1174                     _XAWTV_STATION, XA_STRING,
1175                     8, PropModeReplace,
1176                     line, len);
1177 }
1178 
1179 void command_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
1180 {
1181     struct DO_CMD *cmd = clientdata;
1182     do_command(cmd->argc,cmd->argv);
1183 }
1184 
1185 void tv_expose_event(Widget widget, XtPointer client_data,
1186                      XEvent *event, Boolean *d)
1187 {
1188     static GC  gc;
1189     XGCValues  values;
1190 
1191     switch(event->type) {
1192     case Expose:
1193         if (debug)
1194             fprintf(stderr,"expose count=%d\n",
1195                     event->xexpose.count);
1196         if (0 == event->xexpose.count && CAPTURE_OVERLAY == cur_capture) {
1197             if (f_drv & NEEDS_CHROMAKEY) {
1198                 Dimension win_width, win_height;
1199                 if (debug)
1200                     fprintf(stderr,"expose: chromakey [%dx%d]\n",
1201                             cur_tv_width, cur_tv_height);
1202                 if (0 == gc) {
1203                     XColor color;
1204                     color.red   = (ng_chromakey & 0x00ff0000) >> 8;
1205                     color.green = (ng_chromakey & 0x0000ff00);
1206                     color.blue  = (ng_chromakey & 0x000000ff) << 8;
1207                     XAllocColor(dpy,colormap,&color);
1208                     values.foreground = color.pixel;
1209                     gc = XCreateGC(dpy, XtWindow(widget), GCForeground,
1210                                    &values);
1211                 }
1212                 /* draw background for chroma keying */
1213                 XtVaGetValues(widget, XtNwidth, &win_width,
1214                               XtNheight, &win_height, NULL);
1215                 XFillRectangle(dpy,XtWindow(widget),gc,
1216                                (win_width  - cur_tv_width)  >> 1,
1217                                (win_height - cur_tv_height) >> 1,
1218                                cur_tv_width, cur_tv_height);
1219             }
1220             if (have_xv) {
1221                 if (debug)
1222                     fprintf(stderr,"expose: xv reblit\n");
1223                 video_new_size();
1224             }
1225         }
1226         break;
1227     }
1228 }
1229 
1230 void
1231 FilterAction(Widget widget, XEvent *event,
1232               String *params, Cardinal *num_params)
1233 {
1234     struct list_head *item;
1235     struct ng_filter *filter;
1236 
1237     cur_filter = NULL;
1238     if (0 == *num_params)
1239         return;
1240     list_for_each(item,&ng_filters) {
1241         filter = list_entry(item, struct ng_filter, list);
1242         if (0 == strcasecmp(filter->name,params[0])) {
1243             cur_filter = filter;
1244             break;
1245         }
1246     }
1247 }
1248 
1249 /*----------------------------------------------------------------------*/
1250 
1251 void
1252 xfree_dga_init(Display *dpy)
1253 {
1254 #ifdef HAVE_LIBXXF86DGA
1255     int  flags,foo,bar,ma,mi;
1256 
1257     if (!do_overlay)
1258         return;
1259     
1260     if (args.dga) {
1261         if (XF86DGAQueryExtension(dpy,&foo,&bar)) {
1262             XF86DGAQueryDirectVideo(dpy,XDefaultScreen(dpy),&flags);
1263             if (flags & XF86DGADirectPresent) {
1264                 XF86DGAQueryVersion(dpy,&ma,&mi);
1265                 if (debug)
1266                     fprintf(stderr,"DGA version %d.%d\n",ma,mi);
1267                 have_dga = 1;
1268             }
1269         }
1270     }
1271 #endif
1272 }
1273 
1274 void
1275 xfree_vm_init(Display *dpy)
1276 {
1277 #ifdef HAVE_LIBXXF86VM
1278     int  foo,bar,i,ma,mi;
1279 
1280     if (!do_overlay)
1281         return;
1282 
1283     if (args.vidmode) {
1284         if (XF86VidModeQueryExtension(dpy,&foo,&bar)) {
1285             XF86VidModeQueryVersion(dpy,&ma,&mi);
1286             if (debug)
1287                 fprintf(stderr,"VidMode  version %d.%d\n",ma,mi);
1288             have_vm = 1;
1289             XF86VidModeGetAllModeLines(dpy,XDefaultScreen(dpy),
1290                                        &vm_count,&vm_modelines);
1291             if (debug) {
1292                 fprintf(stderr,"  available video mode(s):");
1293                 for (i = 0; i < vm_count; i++) {
1294                     fprintf(stderr," %dx%d",
1295                             vm_modelines[i]->hdisplay,
1296                             vm_modelines[i]->vdisplay);
1297                 }           
1298                 fprintf(stderr,"\n");
1299             }
1300         }
1301     }
1302 #endif
1303 }
1304 
1305 void
1306 xfree_randr_init(Display *dpy)
1307 {
1308 #ifdef HAVE_LIBXRANDR
1309     int bar,i;
1310     
1311     if (args.randr) {
1312         if (XRRQueryExtension(dpy,&randr_evbase,&bar)) {
1313             randr = XRRSizes(dpy,DefaultScreen(dpy),&nrandr);
1314             if (nrandr > 0) {
1315                 have_randr = 1;
1316                 if (debug) {
1317                     fprintf(stderr,"xrandr:");
1318                     for (i = 0; i < nrandr; i++) {
1319                         fprintf(stderr, " %dx%d",
1320                                 randr[i].width, randr[i].height);
1321                     }
1322                     fprintf(stderr,"\n");
1323                 }
1324             }
1325         }
1326     }
1327 #endif
1328 }
1329 
1330 void
1331 xfree_xinerama_init(Display *dpy)
1332 {
1333 #ifdef HAVE_LIBXINERAMA
1334     int foo,bar,i;
1335     
1336     if (XineramaQueryExtension(dpy,&foo,&bar) &&
1337         XineramaIsActive(dpy)) {
1338         xinerama = XineramaQueryScreens(dpy,&nxinerama);
1339         for (i = 0; i < nxinerama; i++) {
1340             fprintf(stderr,"xinerama %d: %dx%d+%d+%d\n",
1341                     xinerama[i].screen_number,
1342                     xinerama[i].width,
1343                     xinerama[i].height,
1344                     xinerama[i].x_org,
1345                     xinerama[i].y_org);
1346         }
1347     }
1348 #endif
1349 }
1350 
1351 void
1352 grabber_init()
1353 {
1354     struct ng_video_fmt screen;
1355     void *base = NULL;
1356 
1357     memset(&screen,0,sizeof(screen));
1358 #ifdef HAVE_LIBXXF86DGA
1359     if (have_dga) {
1360         int bar,fred;
1361         XF86DGAGetVideoLL(dpy,XDefaultScreen(dpy),(void*)&base,
1362                           &screen.bytesperline,&bar,&fred);
1363     }
1364 #endif
1365     if (!do_overlay) {
1366         if (debug)
1367             fprintf(stderr,"x11: remote display (overlay disabled)\n");
1368         drv = ng_vid_open(args.device, args.driver, NULL, base, &h_drv);
1369     } else {
1370         screen.width  = XtScreen(app_shell)->width;
1371         screen.height = XtScreen(app_shell)->height;
1372         screen.fmtid  = x11_dpy_fmtid;
1373         screen.bytesperline *= ng_vfmt_to_depth[x11_dpy_fmtid]/8;
1374         if (debug)
1375             fprintf(stderr,"x11: %dx%d, %d bit/pixel, %d byte/scanline%s%s\n",
1376                     screen.width,screen.height,
1377                     ng_vfmt_to_depth[screen.fmtid],
1378                     screen.bytesperline,
1379                     have_dga ? ", DGA"     : "",
1380                     have_vm  ? ", VidMode" : "");
1381         drv = ng_vid_open(args.device, args.driver, &screen, base, &h_drv);
1382     }
1383     if (NULL == drv) {
1384         fprintf(stderr,"no video grabber device available\n");
1385         exit(1);
1386     }
1387     f_drv = drv->capabilities(h_drv);
1388     add_attrs(drv->list_attrs(h_drv));
1389 }
1390 
1391 void
1392 grabber_scan(void)
1393 {
1394     const struct ng_vid_driver  *driver;
1395     void *handle;
1396     struct stat st;
1397     int n,i,fh,flags;
1398 
1399     for (i = 0; ng_dev.video_scan[i] != NULL; i++) {
1400         if (-1 == lstat(ng_dev.video_scan[i],&st)) {
1401             if (ENOENT == errno)
1402                 continue;
1403             fprintf(stderr,"%s: %s\n",ng_dev.video_scan[i],strerror(errno));
1404             continue;
1405         }
1406         fh = open(ng_dev.video_scan[i],O_RDWR);
1407         if (-1 == fh) {
1408             if (ENODEV == errno)
1409                 continue;
1410             fprintf(stderr,"%s: %s\n",ng_dev.video_scan[i],strerror(errno));
1411             continue;
1412         }
1413         close(fh);
1414 
1415         driver = ng_vid_open(ng_dev.video_scan[i], args.driver,
1416                              NULL, NULL, &handle);
1417         if (NULL == driver) {
1418             fprintf(stderr,"%s: initialization failed\n",ng_dev.video_scan[i]);
1419             continue;
1420         }
1421         flags = driver->capabilities(handle);
1422         n = fprintf(stderr,"%s: OK",ng_dev.video_scan[i]);
1423         fprintf(stderr,"%*s[ -device %s ]\n",40-n,"",ng_dev.video_scan[i]);
1424         fprintf(stderr,"    type : %s\n",driver->name);
1425         if (driver->get_devname)
1426             fprintf(stderr,"    name : %s\n",driver->get_devname(handle));
1427         fprintf(stderr,"    flags: %s %s %s %s\n",
1428                 (flags & CAN_OVERLAY)     ? "overlay"   : "",
1429                 (flags & CAN_CAPTURE)     ? "capture"   : "",
1430                 (flags & CAN_TUNE)        ? "tuner"     : "",
1431                 (flags & NEEDS_CHROMAKEY) ? "chromakey" : "");
1432         driver->close(handle);
1433         fprintf(stderr,"\n");
1434     }
1435     exit(0);
1436 }
1437 
1438 void
1439 x11_check_remote()
1440 {
1441 #if defined(HAVE_GETNAMEINFO) && defined(HAVE_SOCKADDR_STORAGE)
1442     int fd = ConnectionNumber(dpy);
1443     struct sockaddr_storage ss;
1444     char me[INET6_ADDRSTRLEN+1];
1445     char peer[INET6_ADDRSTRLEN+1];
1446     char port[17];
1447     int length;
1448 
1449     if (debug)
1450         fprintf(stderr, "check if the X-Server is local ... ");
1451     
1452     /* me */
1453     length = sizeof(ss);
1454     if (-1 == getsockname(fd,(struct sockaddr*)&ss,&length)) {
1455         perror("getsockname");
1456         return;
1457     }
1458     if (debug)
1459         fprintf(stderr,"*");
1460 
1461     /* catch unix sockets on FreeBSD */
1462     if (0 == length || ss.ss_family == AF_UNIX) {
1463         if (debug)
1464             fprintf(stderr, " ok (unix socket)\n");
1465         return;
1466     }
1467     
1468     getnameinfo((struct sockaddr*)&ss,length,
1469                 me,INET6_ADDRSTRLEN,port,16,
1470                 NI_NUMERICHOST | NI_NUMERICSERV);
1471     if (debug)
1472         fprintf(stderr,"*");
1473 
1474     /* peer */
1475     length = sizeof(ss);
1476     if (-1 == getpeername(fd,(struct sockaddr*)&ss,&length)) {
1477         perror("getsockname");
1478         return;
1479     }
1480     if (debug)
1481         fprintf(stderr,"*");
1482 
1483     getnameinfo((struct sockaddr*)&ss,length,
1484                 peer,INET6_ADDRSTRLEN,port,16,
1485                 NI_NUMERICHOST | NI_NUMERICSERV);
1486     if (debug)
1487         fprintf(stderr,"*");
1488 
1489     if (debug)
1490         fprintf(stderr," ok\nx11 socket: me=%s, server=%s\n",me,peer);
1491     if (0 != strcmp(me,peer))
1492         /* different hosts => assume remote display */
1493         do_overlay = 0;
1494 #endif
1495     return;
1496 }
1497 
1498 void x11_misc_init(Display *dpy)
1499 {
1500     fcntl(ConnectionNumber(dpy),F_SETFD,FD_CLOEXEC);
1501 }
1502 
1503 /*----------------------------------------------------------------------*/
1504 
1505 void
1506 visual_init(char *n1, char *n2)
1507 {
1508     Visual         *visual;
1509     XVisualInfo    *vinfo_list;
1510     int            n;
1511 
1512     /* look for a useful visual */
1513     visual = x11_find_visual(XtDisplay(app_shell));
1514     vinfo.visualid = XVisualIDFromVisual(visual);
1515     vinfo_list = XGetVisualInfo(dpy, VisualIDMask, &vinfo, &n);
1516     vinfo = vinfo_list[0];
1517     XFree(vinfo_list);
1518     if (visual != DefaultVisualOfScreen(XtScreen(app_shell))) {
1519         fprintf(stderr,"switching visual (0x%lx)\n",vinfo.visualid);
1520         colormap = XCreateColormap(dpy,RootWindowOfScreen(XtScreen(app_shell)),
1521                                    vinfo.visual,AllocNone);
1522         XtDestroyWidget(app_shell);
1523         app_shell = XtVaAppCreateShell(n1,n2,
1524                                        applicationShellWidgetClass, dpy,
1525                                        XtNvisual,vinfo.visual,
1526                                        XtNcolormap,colormap,
1527                                        XtNdepth, vinfo.depth,
1528                                        NULL);
1529     } else {
1530         colormap = DefaultColormapOfScreen(XtScreen(app_shell));
1531     }
1532     x11_init_visual(XtDisplay(app_shell),&vinfo);
1533 }
1534 
1535 void
1536 v4lconf_init()
1537 {
1538     if (!do_overlay)
1539         return;
1540 
1541     strcpy(ng_v4l_conf,"v4l-conf");
1542     if (!args.debug)
1543         strcat(ng_v4l_conf," -q");
1544     if (args.fbdev)
1545         strcat(ng_v4l_conf," -f");
1546     if (args.shift)
1547         sprintf(ng_v4l_conf+strlen(ng_v4l_conf)," -s %d",args.shift);
1548     if (args.bpp)
1549         sprintf(ng_v4l_conf+strlen(ng_v4l_conf)," -b %d",args.bpp);
1550     if (args.device)
1551         sprintf(ng_v4l_conf+strlen(ng_v4l_conf)," -c %s",args.device);
1552 }
1553 
1554 static void
1555 usage(void)
1556 {
1557     fprintf(stderr,
1558             "\n"
1559             "usage: xawtv [ options ] [ station ]\n"
1560             "options:\n"
1561             "  -h  -help           print this text\n"
1562             "  -v  -debug n        debug level n, n = [0..2]\n"
1563             "      -remote         assume remote display\n"
1564             "  -n  -noconf         don't read the config file\n"
1565             "  -m  -nomouse        startup with mouse pointer disabled\n"
1566             "  -f  -fullscreen     startup in fullscreen mode\n"
1567 #ifdef HAVE_LIBXXF86DGA
1568             "      -(no)dga        enable/disable DGA extention\n"
1569 #endif
1570 #ifdef HAVE_LIBXXF86VM
1571             "      -(no)vm         enable/disable VidMode extention\n"
1572 #endif
1573 #ifdef HAVE_LIBXRANDR
1574             "      -(no)randr      enable/disable Xrandr extention\n"
1575 #endif
1576 #ifdef HAVE_LIBXV
1577             "      -(no)xv         enable/disable Xvideo extention altogether\n"
1578             "      -(no)xv-video   enable/disable Xvideo extention (for video only,\n"
1579             "                      i.e. XvPutVideo() calls)\n"
1580             "      -(no)xv-image   enable/disable Xvideo extention (for image scaling\n"
1581             "                      only, i.e. XvPutImage() calls)\n"
1582 #endif
1583 #ifdef HAVE_GL
1584             "      -(no)gl         enable/disable OpenGL\n"
1585 #endif
1586             "  -b  -bpp n          color depth of the display is n (n=24,32)\n"
1587             "  -o  -outfile file   filename base for snapshots\n"
1588             "  -c  -device file    use <file> as video4linux device\n"
1589             "  -C  -dspdev file    use <file> as audio (oss) device\n"
1590             "      -vbidev file    use <file> as vbi device\n"
1591             "      -joydev file    use <file> as joystick device\n"
1592             "      -shift x        shift display by x bytes\n"
1593             "      -fb             let fb (not X) set up v4l device\n"
1594             "      -parallel n     use n compression threads\n"
1595             "      -bufcount n     use n video buffers\n"
1596             "      -hwscan         print a list of available devices.\n"
1597             "station:\n"
1598             "  this is one of the stations listed in $HOME/.xawtv\n"
1599             "\n"
1600             "Check the manual page for a more detailed description.\n"
1601             "\n"
1602             "--\n"
1603             "Gerd Knorr <kraxel@bytesex.org>\n");
1604 }
1605 
1606 void
1607 hello_world(char *name)
1608 {
1609     struct utsname uts;
1610 
1611     if (0 == geteuid() && 0 != getuid()) {
1612         fprintf(stderr,"%s *must not* be installed suid root\n",name);
1613         exit(1);
1614     }
1615     
1616     uname(&uts);
1617     fprintf(stderr,"This is %s-%s, running on %s/%s (%s)\n",
1618             name,VERSION,uts.sysname,uts.machine,uts.release);
1619 }
1620 
1621 void
1622 handle_cmdline_args(void)
1623 {
1624     XtGetApplicationResources(app_shell,&args,
1625                               args_desc,args_count,
1626                               NULL,0);
1627     if (args.help) {
1628         usage();
1629         exit(0);
1630     }
1631     snapbase = args.basename;
1632     debug    = args.debug;
1633     ng_debug = args.debug;
1634 
1635     if (0 == args.xv) {
1636         args.xv_video = 0;
1637         args.xv_image = 0;
1638     }
1639     if (NULL == args.dspdev)
1640         args.dspdev = ng_dev.dsp;
1641     if (NULL == args.vbidev)
1642         args.vbidev = ng_dev.vbi;
1643     if (NULL == args.device) {
1644         args.device = ng_dev.video;
1645     } else {
1646         args.xv_video = 0;
1647     }
1648     if (0 != args.xv_port)
1649         args.xv_video = 1;
1650 }
1651 
1652 int
1653 x11_ctrl_alt_backspace(Display *dpy)
1654 {
1655     fprintf(stderr,"game over\n");
1656     if (debug)
1657         abort();
1658     audio_off();
1659     video_overlay(0);
1660     video_close();
1661     drv->close(h_drv);
1662     exit(0);
1663 }
1664 
1665 /*----------------------------------------------------------------------*/
1666 
1667 static int mouse_visible;
1668 static XtIntervalId mouse_timer;
1669 
1670 static void
1671 mouse_timeout(XtPointer clientData, XtIntervalId *id)
1672 {
1673     Widget widget = clientData;
1674     if (debug > 1)
1675         fprintf(stderr,"xt: pointer hide\n");
1676     if (XtWindow(widget))
1677         XDefineCursor(dpy, XtWindow(widget), no_ptr);
1678     mouse_visible = 0;
1679     mouse_timer = 0;
1680 }
1681 
1682 void
1683 mouse_event(Widget widget, XtPointer client_data, XEvent *event, Boolean *d)
1684 {
1685     if (!mouse_visible) {
1686         if (debug > 1)
1687             fprintf(stderr,"xt: pointer show\n");
1688         if (XtWindow(widget))
1689             XDefineCursor(dpy, XtWindow(widget), left_ptr);
1690         mouse_visible = 1;
1691     }
1692     if (mouse_timer)
1693         XtRemoveTimeOut(mouse_timer);
1694     mouse_timer = XtAppAddTimeOut(app_context, 1000, mouse_timeout,widget);
1695 }
1696 
1697 /*----------------------------------------------------------------------*/
1698 
1699 #if TT
1700 static char *vtx_colors[8] = { "black", "red", "green", "yellow",
1701                                "blue", "magenta", "cyan", "white" };
1702 #endif
1703 
1704 #ifdef HAVE_ZVBI
1705 static XtInputId x11_vbi_input;
1706 static struct vbi_state *x11_vbi;
1707 static int x11_vbi_page;
1708 char x11_vbi_station[64];
1709 
1710 #if 0
1711 static struct TEXTELEM*
1712 vtx_to_tt(struct vt_page *vtp)
1713 {
1714     static struct TEXTELEM tt[VTX_COUNT];
1715     int t,x,y,color,lcolor;
1716     struct fmt_page pg[1];
1717     struct fmt_char l[W+2];
1718 #define L (l+1)
1719     
1720     t = 0;
1721     fmt_page(fmt,pg,vtp);
1722     memset(tt,0,sizeof(tt));
1723     for (y = 0; y < H; y++) {
1724         for (x = 0; x < W; x++) {
1725             struct fmt_char c = pg->data[y][x];
1726             switch (c.ch) {
1727             case 0x00:
1728             case 0xa0:
1729                 c.ch = ' ';
1730                 break;
1731             case 0x7f:
1732                 c.ch = '*';
1733                 break;
1734             case BAD_CHAR:
1735                 c.ch = '?';
1736                 break;
1737             default:
1738                 if (c.attr & EA_GRAPHIC)
1739                     c.ch = '#';
1740                 break;
1741             }
1742             L[x] = c;
1743         }
1744         
1745         /* delay fg and attr changes as far as possible */
1746         for (x = 0; x < W; ++x)
1747             if (L[x].ch == ' ') {
1748                 L[x].fg = L[x-1].fg;
1749                 L[x].attr = L[x-1].attr;
1750             }
1751         
1752         /* move fg and attr changes to prev bg change point */
1753         for (x = W-1; x >= 0; x--)
1754             if (L[x].ch == ' ' && L[x].bg == L[x+1].bg) {
1755                 L[x].fg = L[x+1].fg;
1756                 L[x].attr = L[x+1].attr;
1757             }
1758         
1759         /* now render the line */
1760         lcolor = -1;
1761         tt[t].line = y;
1762         tt[t].len  = 0;
1763         for (x = 0; x < W; x++) {
1764             color = (L[x].fg&0x0f) * 10 + (L[x].bg&0x0f);
1765             if (color != lcolor) {
1766                 if (-1 != lcolor)
1767                     if (tt[t].len) {
1768                         t++;
1769                         tt[t].line = y;
1770                     }
1771                 lcolor = color;
1772             }
1773             tt[t].str[tt[t].len++] = L[x].ch;
1774             tt[t].fg = vtx_colors[L[x].fg&0x0f];
1775             tt[t].bg = vtx_colors[L[x].bg&0x0f];
1776         }
1777         if (tt[t].len)
1778             t++;
1779     }
1780     return tt;
1781 }
1782 
1783 #define EMPTY_VBI_LINE "                                        "
1784 static struct TEXTELEM*
1785 tt_pick_subtitle(struct TEXTELEM *tt)
1786 {
1787     int i;
1788 
1789     /* skip header line */
1790     while (tt->len && 0 == tt->line)
1791         tt++;
1792     /* rm empty lines (from top) */
1793     while (tt->len &&
1794            0 == strcmp(tt->str,EMPTY_VBI_LINE))
1795         tt++;
1796 
1797     if (tt->len) {
1798         /* seek to end */
1799         for (i = 0; tt[i].len != 0; i++)
1800             ;
1801         /* rm empty lines (from bottom) */
1802         while (0 == strcmp(tt[i-1].str,EMPTY_VBI_LINE))
1803             i--;
1804         tt[i].len = 0;
1805     }
1806     
1807     return tt;
1808 }
1809 
1810 static void
1811 dump_tt(struct TEXTELEM *tt)
1812 {
1813     int i,lastline = 0;
1814 
1815     lastline = tt[0].line;
1816     for (i = 0; tt[i].len > 0; i++) {
1817         if (tt[i].line != lastline) {
1818             lastline = tt[i].line;
1819             fprintf(stderr,"\n");
1820         }
1821         fprintf(stderr,"[%s,%s,%d]%s",
1822                 tt[i].fg ? tt[i].fg : "def",
1823                 tt[i].bg ? tt[i].bg : "def",
1824                 tt[i].line,tt[i].str);
1825     }
1826     fprintf(stderr,"\n");
1827 }
1828 #endif
1829 
1830 static void
1831 x11_vbi_event(struct vbi_event *ev, void *user)
1832 {
1833     struct vbi_page pg;
1834     struct vbi_rect rect;
1835     
1836     switch (ev->type) {
1837     case VBI_EVENT_NETWORK:
1838         strcpy(x11_vbi_station,ev->ev.network.name);
1839         break;
1840     case VBI_EVENT_TTX_PAGE:
1841         if (ev->ev.ttx_page.pgno == x11_vbi_page) {
1842             if (debug)
1843                 fprintf(stderr,"got vtx page %03x\n",ev->ev.ttx_page.pgno);
1844             if (vtx_subtitle) {
1845                 vbi_fetch_vt_page(x11_vbi->dec,&pg,
1846                                   ev->ev.ttx_page.pgno,
1847                                   ev->ev.ttx_page.subno,
1848                                   VBI_WST_LEVEL_1p5,25,1);
1849                 vbi_find_subtitle(&pg,&rect);
1850                 if (25 == rect.y1)
1851                     vtx_subtitle(NULL,NULL);
1852                 else
1853                     vtx_subtitle(&pg,&rect);
1854             }
1855         }
1856         break;
1857     }
1858 }
1859 
1860 static void x11_vbi_data(XtPointer data, int *fd, XtInputId *iproc)
1861 {
1862     struct vbi_state *vbi = data;
1863     vbi_hasdata(vbi);
1864 }
1865 
1866 int
1867 x11_vbi_start(char *device)
1868 {
1869     if (NULL != x11_vbi)
1870         return 0;
1871 
1872     if (NULL == device)
1873         device = ng_dev.vbi;
1874 
1875     x11_vbi = vbi_open(device, debug, 0);
1876     if (NULL == x11_vbi) {
1877         fprintf(stderr,"open %s: %s\n",device,strerror(errno));
1878         return -1;
1879     }
1880     vbi_event_handler_add(x11_vbi->dec,~0,x11_vbi_event,x11_vbi);
1881     x11_vbi_input = XtAppAddInput(app_context,x11_vbi->fd,
1882                                   (XtPointer) XtInputReadMask,
1883                                   x11_vbi_data,x11_vbi);
1884     if (debug)
1885         fprintf(stderr,"x11_vbi_start\n");
1886     return 0;
1887 }
1888 
1889 /* try to use the vbi device to see whenever we have a station or not.
1890  * failing that, fallback to the libng grabber driver. */
1891 int
1892 x11_vbi_tuned(void)
1893 {
1894 #if defined(__linux__)
1895     struct video_tuner tuner;
1896 
1897     if (NULL == x11_vbi)
1898         return drv->is_tuned(h_drv);
1899     memset(&tuner,0,sizeof(tuner));
1900     if (-1 != ioctl(x11_vbi->fd,VIDIOCGTUNER,&tuner))
1901         return tuner.signal ? 1 : 0;
1902 #endif
1903     return drv->is_tuned(h_drv);
1904 }
1905 
1906 void
1907 x11_vbi_stop(void)
1908 {
1909     if (NULL == x11_vbi)
1910         return;
1911     XtRemoveInput(x11_vbi_input);
1912     vbi_event_handler_remove(x11_vbi->dec,x11_vbi_event);
1913     vbi_close(x11_vbi);
1914     x11_vbi = NULL;
1915     if (debug)
1916         fprintf(stderr,"x11_vbi_stop\n");
1917 }
1918 
1919 void
1920 VtxAction(Widget widget, XEvent *event,
1921           String *params, Cardinal *num_params)
1922 {
1923     if (0 == *num_params)
1924         return;
1925     if (0 == strcasecmp(params[0],"start")) {
1926         if (2 >= *num_params)
1927             sscanf(params[1],"%x",&x11_vbi_page);
1928         if (debug)
1929             fprintf(stderr,"subtitles page: %x\n",x11_vbi_page);
1930         x11_vbi_start(args.vbidev);
1931     }
1932     if (0 == strcasecmp(params[0],"stop")) {
1933         x11_vbi_page = 0;
1934         x11_vbi_stop();
1935 #if TT
1936         if (vtx_message)
1937             vtx_message(NULL);
1938 #endif
1939 #ifdef HAVE_ZVBI
1940         if (vtx_subtitle)
1941             vtx_subtitle(NULL,NULL);
1942 #endif
1943     }
1944 }
1945 #endif
1946 
1947 /* ---------------------------------------------------------------------- */
1948 /* control via lirc / midi / joystick                                     */
1949 
1950 static int xt_lirc;
1951 
1952 static void
1953 xt_lirc_data(XtPointer data, int *fd, XtInputId *iproc)
1954 {
1955     if (debug)
1956         fprintf(stderr,"lirc_input triggered\n");
1957     if (-1 == lirc_tv_havedata()) {
1958         fprintf(stderr,"lirc: connection lost\n");
1959         XtRemoveInput(*iproc);
1960         close(*fd);
1961     }
1962 }
1963 
1964 int xt_lirc_init(void)
1965 {
1966     if (-1 != (xt_lirc = lirc_tv_init()))
1967         XtAppAddInput(app_context,xt_lirc,(XtPointer)XtInputReadMask,
1968                       xt_lirc_data,NULL);
1969     return 0;
1970 }
1971 
1972 #ifdef HAVE_ALSA
1973 static struct midi_handle xt_midi;
1974 
1975 static void
1976 xt_midi_data(XtPointer data, int *fd, XtInputId *iproc)
1977 {
1978     midi_read(&xt_midi);
1979     midi_translate(&xt_midi);
1980 }
1981 #endif
1982 
1983 int xt_midi_init(char *dev)
1984 {
1985     if (NULL == dev)
1986         return -1;
1987 
1988 #ifdef HAVE_ALSA
1989     memset(&xt_midi,0,sizeof(xt_midi));
1990     if (-1 == midi_open(&xt_midi, "xawtv"))
1991         return -1;
1992     midi_connect(&xt_midi,dev);
1993     XtAppAddInput(app_context,xt_midi.fd,(XtPointer) XtInputReadMask,
1994                   xt_midi_data,NULL);
1995     return 0;
1996 #else
1997     fprintf(stderr,"midi: not compiled in, sorry\n");
1998     return -1;
1999 #endif
2000 }
2001 
2002 static int xt_joystick;
2003 
2004 static void
2005 xt_joystick_data(XtPointer data, int *fd, XtInputId *iproc)
2006 {
2007     joystick_tv_havedata(xt_joystick);
2008 }
2009 
2010 int xt_joystick_init(void)
2011 {
2012     if (-1 != (xt_joystick = joystick_tv_init(args.joydev)))
2013         XtAppAddInput(app_context,xt_joystick,(XtPointer)XtInputReadMask,
2014                       xt_joystick_data,NULL);
2015     return 0;
2016 }
2017 
2018 /* ---------------------------------------------------------------------- */
2019 
2020 void xt_kbd_init(Widget tv)
2021 {
2022     char **list,key[32],str[128];
2023 
2024     list = cfg_list_entries("eventmap");
2025     if (NULL == list)
2026         return;
2027     
2028     for (; *list != NULL; list++) {
2029         if (1 != sscanf(*list,"kbd-key-%31s",key))
2030             continue;
2031         sprintf(str,"<Key>%s: Event(%s)",key,*list);
2032         XtOverrideTranslations(tv,XtParseTranslationTable(str));
2033     }
2034 }
2035 
2036 void
2037 EventAction(Widget widget, XEvent *event,
2038             String *params, Cardinal *num_params)
2039 {
2040     if (0 != *num_params)
2041         event_dispatch(params[0]);
2042 }
2043 
2044 /* ---------------------------------------------------------------------- */
2045 
2046 Cursor left_ptr;
2047 Cursor menu_ptr;
2048 Cursor qu_ptr;
2049 Cursor no_ptr;
2050 
2051 Pixmap bm_yes;
2052 Pixmap bm_no;
2053 
2054 static unsigned char bm_yes_data[] = {
2055     /* -------- -------- */  0x00,
2056     /* -------- -------- */  0x00,
2057     /* ------xx xx------ */  0x18,                         
2058     /* ----xxxx xxxx---- */  0x3c,
2059     /* ----xxxx xxxx---- */  0x3c,
2060     /* ------xx xx------ */  0x18,
2061     /* -------- -------- */  0x00,
2062     /* -------- -------- */  0x00
2063 };
2064 
2065 static unsigned char bm_no_data[] = { 0,0,0,0, 0,0,0,0 };
2066 
2067 void
2068 create_pointers(Widget app_shell)
2069 {
2070     XColor white,red,dummy;
2071     Screen *scr;
2072     
2073     left_ptr = XCreateFontCursor(dpy,XC_left_ptr);
2074     menu_ptr = XCreateFontCursor(dpy,XC_right_ptr);
2075     qu_ptr   = XCreateFontCursor(dpy,XC_question_arrow);
2076     scr = DefaultScreenOfDisplay(dpy);
2077     if (vinfo.depth > 1) {
2078         if (XAllocNamedColor(dpy,colormap,"white",&white,&dummy) &&
2079             XAllocNamedColor(dpy,colormap,"red",&red,&dummy)) {
2080             XRecolorCursor(dpy,left_ptr,&red,&white);
2081             XRecolorCursor(dpy,menu_ptr,&red,&white);
2082             XRecolorCursor(dpy,qu_ptr,&red,&white);
2083         } 
2084     }
2085 }
2086 
2087 void
2088 create_bitmaps(Widget app_shell)
2089 {
2090     XColor black, dummy;
2091 
2092     bm_yes = XCreateBitmapFromData(dpy, XtWindow(app_shell),
2093                                    bm_yes_data, 8,8);
2094     bm_no = XCreateBitmapFromData(dpy, XtWindow(app_shell),
2095                                   bm_no_data, 8,8);
2096 
2097     XAllocNamedColor(dpy,colormap,"black",&black,&dummy);
2098     no_ptr = XCreatePixmapCursor(dpy, bm_no, bm_no,
2099                                  &black, &black,
2100                                  0, 0);
2101 }
2102 
2103 /* ---------------------------------------------------------------------- */
2104 
2105 int xt_handle_pending(Display *dpy)
2106 {
2107     XEvent event;
2108 
2109     if (debug)
2110         fprintf(stderr,"xt: handle_pending:  start ...\n");
2111     XFlush(dpy);
2112     while (True == XCheckMaskEvent(dpy, ~0, &event))
2113         XtDispatchEvent(&event);
2114     if (debug)
2115         fprintf(stderr,"xt: handle_pending:  ... done\n");
2116     return 0;
2117 }
2118 
2119 /* ---------------------------------------------------------------------- */
2120 
2121 int xt_vm_randr_input_init(Display *dpy)
2122 {
2123     /* vidmode / randr */
2124     if (debug)
2125         fprintf(stderr,"xt: checking for randr extention ...\n");
2126     xfree_randr_init(dpy);
2127 #if 0
2128     if (fs_width && fs_height && !args.vidmode) {
2129         if (debug)
2130             fprintf(stderr,"fullscreen mode configured (%dx%d), "
2131                     "VidMode extention enabled\n",fs_width,fs_height);
2132         args.vidmode = 1;
2133     }
2134 #endif
2135     if (debug)
2136         fprintf(stderr,"xt: checking for vidmode extention ...\n");
2137     xfree_vm_init(dpy);
2138     
2139     /* input */
2140     if (debug)
2141         fprintf(stderr,"xt: checking for lirc ...\n");
2142     xt_lirc_init();
2143     if (debug)
2144         fprintf(stderr,"xt: checking for joystick ...\n");
2145     xt_joystick_init();
2146     if (debug)
2147         fprintf(stderr,"xt: checking for midi ...\n");
2148     xt_midi_init(midi);
2149     if (debug)
2150         fprintf(stderr,"xt: adding kbd hooks ...\n");
2151     xt_kbd_init(tv);
2152 
2153     return 0;
2154 }
2155 
2156 int xt_main_loop()
2157 {
2158     XEvent event;
2159     
2160     if (debug)
2161         fprintf(stderr,"xt: enter main event loop... \n");
2162     signal(SIGHUP,SIG_IGN); /* don't really need a tty ... */
2163 
2164     for (;;) {
2165         if (XtAppGetExitFlag(app_context))
2166             break;
2167         XtAppNextEvent(app_context, &event);
2168         if (True == XtDispatchEvent(&event))
2169             continue;
2170     }
2171     return 0;
2172 }
2173 
  This page was automatically generated by the LXR engine.