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  * misc x11 functions:  pixmap handling (incl. MIT SHMEM), event
  3  *                      tracking for the TV widget.
  4  *
  5  *  (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
  6  *
  7  */
  8 
  9 #include "config.h"
 10 
 11 #include <stdio.h>
 12 #include <stdlib.h>
 13 #include <strings.h>
 14 #include <errno.h>
 15 #include <pthread.h>
 16 #include <sys/types.h>
 17 #include <sys/time.h>
 18 #include <sys/socket.h>
 19 #include <sys/ipc.h>
 20 #include <sys/shm.h>
 21 
 22 #include <X11/Xlib.h>
 23 #include <X11/Xutil.h>
 24 #include <X11/Intrinsic.h>
 25 #include <X11/StringDefs.h>
 26 #include <X11/Shell.h>
 27 #include <X11/extensions/XShm.h>
 28 #ifdef HAVE_LIBXV
 29 # include <X11/extensions/Xv.h>
 30 # include <X11/extensions/Xvlib.h>
 31 #endif
 32 
 33 #include "grab-ng.h"
 34 #include "capture.h"
 35 #include "channel.h"
 36 #include "x11.h"
 37 #include "xv.h"
 38 #include "commands.h"
 39 #include "blit.h"
 40 
 41 #define DEL_TIMER(proc)     XtRemoveTimeOut(proc)
 42 #define ADD_TIMER(proc)     XtAppAddTimeOut(app_context,200,proc,NULL)
 43 
 44 extern XtAppContext    app_context;
 45 extern XVisualInfo     vinfo;
 46 
 47 /* ------------------------------------------------------------------------ */
 48 
 49 Pixmap
 50 x11_capture_pixmap(Display *dpy, XVisualInfo *vinfo, Colormap colormap,
 51                    unsigned int width, unsigned int height)
 52 {
 53     struct ng_video_buf *buf;
 54     struct ng_video_fmt fmt;
 55     Pixmap pix = 0;
 56 
 57     if (!(f_drv & CAN_CAPTURE))
 58         return 0;
 59 
 60     memset(&fmt,0,sizeof(fmt));
 61     fmt.fmtid  = x11_dpy_fmtid;
 62     fmt.width  = width  ? width  : cur_tv_width;
 63     fmt.height = height ? height : cur_tv_height;
 64     if (NULL == (buf = ng_grabber_get_image(&fmt)))
 65         return 0;
 66     buf = ng_filter_single(cur_filter,buf);
 67     pix = x11_create_pixmap(dpy,vinfo,buf);
 68     ng_release_video_buf(buf);
 69     return pix;
 70 }
 71 
 72 void
 73 x11_label_pixmap(Display *dpy, Colormap colormap, Pixmap pixmap,
 74                  int height, char *label)
 75 {
 76     static XFontStruct    *font;
 77     static XColor          color,dummy;
 78     XGCValues              values;
 79     GC                     gc;
 80     
 81     if (!font) {
 82         font = XLoadQueryFont(dpy,"fixed");
 83         XAllocNamedColor(dpy,colormap,"yellow",&color,&dummy);
 84     }
 85     values.font       = font->fid;
 86     values.foreground = color.pixel;
 87     gc = XCreateGC(dpy, pixmap, GCFont | GCForeground, &values);
 88     XDrawString(dpy,pixmap,gc,5,height-5,label,strlen(label));
 89     XFreeGC(dpy, gc);
 90 }
 91 
 92 static int
 93 x11_error_dev_null(Display * dpy, XErrorEvent * event)
 94 {
 95     return 0;
 96 }
 97 
 98 /* ------------------------------------------------------------------------ */
 99 /* video grabdisplay stuff                                                  */
100 
101 struct video_handle {
102     Widget                win;
103     Dimension             width,height;
104     XtWorkProcId          work_id;
105     int                   suspend;         /* temporarely disabled */
106     int                   nw,nh;           /* new size (suspend)   */
107     struct ng_video_fmt   best;
108     struct blit_state     *blit;
109 
110     /* image filtering */
111     struct ng_filter      *filter;
112     void                  *fhandle;
113     struct ng_video_fmt   ffmt;
114 };
115 struct video_handle vh;
116 
117 void video_gd_init(Widget widget, int use_gl)
118 {
119     struct video_handle *h = &vh;
120 
121     if (debug)
122         fprintf(stderr,"gd: init\n");
123     h->win  = widget;
124     h->blit = blit_init(h->win,&vinfo, use_gl);
125 }
126 
127 static struct ng_video_buf*
128 video_gd_filter(struct video_handle *h, struct ng_video_buf *buf)
129 {
130     if (NULL != h->filter &&
131         (cur_filter      != h->filter ||
132          buf->fmt.fmtid  != h->ffmt.fmtid ||
133          buf->fmt.width  != h->ffmt.width ||
134          buf->fmt.height != h->ffmt.height)) {
135         h->filter->fini(h->fhandle);
136         h->filter  = NULL;
137         h->fhandle = NULL;
138         memset(&h->ffmt,0,sizeof(h->ffmt));
139     }
140     if ((1 << buf->fmt.fmtid) & cur_filter->fmts) {
141         if (NULL == h->filter) {
142             h->filter  = cur_filter;
143             h->fhandle = h->filter->init(&buf->fmt);
144             h->ffmt    = buf->fmt;
145         }
146         buf = cur_filter->frame(h->fhandle,buf);
147     }
148     return buf;
149 }
150 
151 int
152 video_gd_blitframe(struct video_handle *h, struct ng_video_buf *buf)
153 {
154     if (buf->fmt.width  > cur_tv_width ||
155         buf->fmt.height > cur_tv_height)
156         return -1;
157 
158     if (cur_filter)
159         buf = video_gd_filter(h,buf);
160     blit_putframe(h->blit,buf);
161     return 0;
162 }
163 
164 static Boolean
165 video_gd_idle(XtPointer data)
166 {
167     struct video_handle *h = data;
168     struct ng_video_buf *buf;
169     
170     if (!(f_drv & CAN_CAPTURE))
171         goto oops;
172 
173     buf = ng_grabber_grab_image(0);
174     if (NULL != buf) {
175         video_gd_blitframe(h,buf);
176     } else {
177         goto oops;
178     }
179     
180     if (debug) {
181         static long count,lastsec;
182         struct timeval  t;
183         struct timezone tz;
184         gettimeofday(&t,&tz);
185         if (t.tv_sec != lastsec) {
186             if (lastsec == t.tv_sec-1)
187                 fprintf(stderr,"%5ld fps \r", count);
188             lastsec = t.tv_sec;
189             count = 0;
190         }
191         count++;
192     }
193     return FALSE;
194 
195  oops:
196     h->work_id = 0;
197     if (f_drv & CAN_CAPTURE)
198         drv->stopvideo(h_drv);
199     return TRUE;
200 }
201 
202 void
203 video_gd_start(void)
204 {
205     struct video_handle *h = &vh;
206 
207     if (debug)
208         fprintf(stderr,"gd: start [%d]\n",h->best.fmtid);
209     if (0 == h->best.fmtid)
210         return;
211     if (0 != ng_grabber_setformat(&h->best,0))
212         return;
213     drv->startvideo(h_drv,-1,2);
214 //    drv->startvideo(h_drv,-1,4);
215     h->work_id = XtAppAddWorkProc(app_context, video_gd_idle, h);
216 }
217 
218 void
219 video_gd_stop(void)
220 {
221     struct video_handle *h = &vh;
222 
223     if (debug)
224         fprintf(stderr,"gd: stop\n");
225     if (h->work_id) {
226         drv->stopvideo(h_drv);
227         XtRemoveWorkProc(h->work_id);
228         h->work_id = 0;
229         blit_fini_frame(h->blit);
230     }
231 }
232 
233 void
234 video_gd_suspend(void)
235 {
236     struct video_handle *h = &vh;
237     
238     h->suspend = 1;
239     if (cur_capture != CAPTURE_GRABDISPLAY)
240         return;
241     do_va_cmd(2, "capture", "off");
242 }
243 
244 void
245 video_gd_restart(void)
246 {
247     struct video_handle *h = &vh;
248 
249     if (!h->suspend)
250         return;
251     h->suspend = 0;
252     if (h->nw && h->nh) {
253         video_gd_configure(h->nw,h->nh);
254         h->nw = 0;
255         h->nh = 0;
256     }
257     if (cur_capture != CAPTURE_OFF)
258         return;
259     do_va_cmd(2, "capture", "grab");
260 }
261 
262 void
263 video_gd_configure(int width, int height)
264 {
265     struct video_handle *h = &vh;
266     unsigned int i,fmtids[2*VIDEO_FMT_COUNT];
267 
268     if (!(f_drv & CAN_CAPTURE))
269         return;
270 
271     blit_resize(h->blit,width,height);
272 
273     if (h->suspend) {
274         if (debug)
275             fprintf(stderr,"gd: delay configure\n");
276         h->nw = width;
277         h->nh = height;
278         return;
279     }
280 
281     if (debug)
282         fprintf(stderr,"gd: config %dx%d win=%lx\n",
283                 width,height,XtWindow(h->win));
284         
285     if (!XtWindow(h->win))
286         return;
287 
288     cur_tv_width  = width;
289     cur_tv_height = height;
290     h->best.width   = width;
291     h->best.height  = height;
292     h->best.bytesperline = 0;
293     ng_ratio_fixup(&cur_tv_width,  &cur_tv_height,  NULL, NULL);
294     ng_ratio_fixup(&h->best.width, &h->best.height, NULL, NULL);
295 
296     if (0 == h->best.fmtid) {
297         blit_get_formats(h->blit,fmtids,sizeof(fmtids)/sizeof(int));
298         for (i = 0; i < sizeof(fmtids)/sizeof(int); i++) {
299             h->best.fmtid = fmtids[i];
300             if (0 == ng_grabber_setformat(&h->best,0))
301                 goto done;
302         }
303         /* failed */
304         h->best.fmtid = 0;
305     }
306 
307  done:
308     if (debug)
309         fprintf(stderr,"grabdisplay: using \"%s\"\n",
310                 ng_vfmt_to_desc[h->best.fmtid]);
311     if (cur_capture == CAPTURE_GRABDISPLAY) {
312         do_va_cmd(2, "capture", "off");
313         do_va_cmd(2, "capture", "grab");
314     }
315 }
316 
317 /* ------------------------------------------------------------------------ */
318 /* video overlay stuff                                                      */
319 
320 unsigned int     swidth,sheight;           /* screen  */
321 static int       x11_overlay_fmtid;
322 
323 /* window  */
324 static Widget    video,video_parent;
325 static int       wx, wy, wmap;
326 static struct ng_video_fmt wfmt;
327 
328 static XtIntervalId          overlay_refresh;
329 static int                   did_refresh, oc_count;
330 static int                   visibility = VisibilityFullyObscured;
331 static int                   conf = 1, move = 1;
332 static int                   overlay_on = 0, overlay_enabled = 0;
333 static struct OVERLAY_CLIP   oc[256];
334 static XtWorkProcId          conf_id;
335 
336 /* ------------------------------------------------------------------------ */
337 
338 char *event_names[] = {
339     "", "1",
340     "KeyPress",
341     "KeyRelease",
342     "ButtonPress",
343     "ButtonRelease",
344     "MotionNotify",
345     "EnterNotify",
346     "LeaveNotify",
347     "FocusIn",
348     "FocusOut",
349     "KeymapNotify",
350     "Expose",
351     "GraphicsExpose",
352     "NoExpose",
353     "VisibilityNotify",
354     "CreateNotify",
355     "DestroyNotify",
356     "UnmapNotify",
357     "MapNotify",
358     "MapRequest",
359     "ReparentNotify",
360     "ConfigureNotify",
361     "ConfigureRequest",
362     "GravityNotify",
363     "ResizeRequest",
364     "CirculateNotify",
365     "CirculateRequest",
366     "PropertyNotify",
367     "SelectionClear",
368     "SelectionRequest",
369     "SelectionNotify",
370     "ColormapNotify",
371     "ClientMessage",
372     "MappingNotify"
373 };
374 const int nevent_names = sizeof(event_names)/sizeof(event_names[0]);
375 
376 /* ------------------------------------------------------------------------ */
377 
378 static void
379 add_clip(int x1, int y1, int x2, int y2)
380 {
381     if (oc[oc_count].x1 != x1 || oc[oc_count].y1 != y1 ||
382         oc[oc_count].x2 != x2 || oc[oc_count].y2 != y2) {
383         conf = 1;
384     }
385     oc[oc_count].x1 = x1;
386     oc[oc_count].y1 = y1;
387     oc[oc_count].x2 = x2;
388     oc[oc_count].y2 = y2;
389     oc_count++;
390 } 
391 
392 static void
393 get_clips(void)
394 {
395     int x1,y1,x2,y2,lastcount;
396     Display *dpy;
397     XWindowAttributes wts;
398     Window root, me, rroot, parent, *children;
399     uint nchildren, i;
400     void *old_handler = XSetErrorHandler(x11_error_dev_null);
401 
402     if (debug > 1)
403         fprintf(stderr," getclips");
404     lastcount = oc_count;
405     oc_count = 0;
406     dpy = XtDisplay(video);
407 
408     if (wx<0)
409         add_clip(0, 0, (uint)(-wx), wfmt.height);
410     if (wy<0)
411         add_clip(0, 0, wfmt.width, (uint)(-wy));
412     if ((wx+wfmt.width) > swidth)
413         add_clip(swidth-wx, 0, wfmt.width, wfmt.height);
414     if ((wy+wfmt.height) > sheight)
415         add_clip(0, sheight-wy, wfmt.width, wfmt.height);
416     
417     root=DefaultRootWindow(dpy);
418     me = XtWindow(video);
419     for (;;) {
420         XQueryTree(dpy, me, &rroot, &parent, &children, &nchildren);
421         XFree((char *) children);
422         /* fprintf(stderr,"me=0x%x, parent=0x%x\n",me,parent); */
423         if (root == parent)
424             break;
425         me = parent;
426     }
427     XQueryTree(dpy, root, &rroot, &parent, &children, &nchildren);
428 
429     for (i = 0; i < nchildren; i++)
430         if (children[i]==me)
431             break;
432     
433     for (i++; i<nchildren; i++) {
434         XGetWindowAttributes(dpy, children[i], &wts);
435         if (!(wts.map_state & IsViewable))
436             continue;
437 
438         x1=wts.x-wx;
439         y1=wts.y-wy;
440         x2=x1+wts.width+2*wts.border_width;
441         y2=y1+wts.height+2*wts.border_width;
442         if ((x2 < 0) || (x1 > (int)wfmt.width) ||
443             (y2 < 0) || (y1 > (int)wfmt.height))
444             continue;
445         
446         if (x1<0)                x1=0;
447         if (y1<0)                y1=0;
448         if (x2>(int)wfmt.width)  x2=wfmt.width;
449         if (y2>(int)wfmt.height) y2=wfmt.height;
450         add_clip(x1, y1, x2, y2);
451     }
452     XFree((char *) children);
453 
454     if (lastcount != oc_count)
455         conf = 1;
456     XSetErrorHandler(old_handler);
457 }
458 
459 static void
460 refresh_timer(XtPointer clientData, XtIntervalId *id)
461 {
462     Window   win = RootWindowOfScreen(XtScreen(video));
463     Display *dpy = XtDisplay(video);
464     XSetWindowAttributes xswa;
465     unsigned long mask;
466     Window   tmp;
467 
468     if (!move && wmap && visibility == VisibilityUnobscured) {
469         if (debug > 1)
470             fprintf(stderr,"video: refresh skipped\n");
471         return;
472     }
473 
474     if (debug > 1)
475         fprintf(stderr,"video: refresh\n");
476     overlay_refresh = 0;
477     if (wmap && visibility != VisibilityFullyObscured)
478         did_refresh = 1;
479 
480     xswa.override_redirect = True;
481     xswa.backing_store = NotUseful;
482     xswa.save_under = False;
483     mask = (CWSaveUnder | CWBackingStore| CWOverrideRedirect );
484     tmp = XCreateWindow(dpy,win, 0,0, swidth,sheight, 0,
485                         CopyFromParent, InputOutput, CopyFromParent,
486                         mask, &xswa);
487     XMapWindow(dpy, tmp);
488     XUnmapWindow(dpy, tmp);
489     XDestroyWindow(dpy, tmp);
490     move = 0;
491 }
492 
493 static Boolean
494 configure_delayed(XtPointer data)
495 {
496     if (debug > 1)
497         fprintf(stderr,"video: configure delayed");
498     if (wmap && visibility != VisibilityFullyObscured) {
499         if (visibility == VisibilityPartiallyObscured)
500             get_clips();
501         else
502             oc_count = 0;
503 
504         if (debug > 1)
505             fprintf(stderr," %s\n",conf ? "yes" : "no");
506         if (conf) {
507             overlay_on = 1;
508             if (f_drv & CAN_OVERLAY)
509                 drv->overlay(h_drv,&wfmt,wx,wy,oc,oc_count,1);
510             if (overlay_refresh)
511                 DEL_TIMER(overlay_refresh);
512             overlay_refresh = ADD_TIMER(refresh_timer);
513             conf = 0;
514         }
515     } else {
516         if (debug > 1)
517             fprintf(stderr," off\n");
518         if (conf && overlay_on) {
519             overlay_on = 0;
520             if (f_drv & CAN_OVERLAY)
521                 drv->overlay(h_drv,NULL,0,0,NULL,0,0);
522             if (overlay_refresh)
523                 DEL_TIMER(overlay_refresh);
524             overlay_refresh = ADD_TIMER(refresh_timer);
525             conf = 0;
526         }
527     }
528     conf_id = 0;
529     return TRUE;
530 }
531 
532 static void
533 configure_overlay(void)
534 {
535     if (!overlay_enabled)
536         return;
537 
538 #ifdef HAVE_LIBXV
539     if (have_xv) {
540         if (wfmt.width && wfmt.height)
541             xv_video(XtWindow(video),wfmt.width,wfmt.height,1);
542         return;
543     }
544 #endif
545 
546     if (0 == conf_id)
547         conf_id = XtAppAddWorkProc(app_context,configure_delayed,NULL);
548 }
549 
550 void
551 video_new_size()
552 {
553     Dimension x,y,w,h;
554 
555     XtVaGetValues(video_parent, XtNx, &x, XtNy, &y,
556                   XtNwidth, &w, XtNheight, &h, NULL);
557     wx          = x; if (wx > 32768)          wx          -= 65536;
558     wy          = y; if (wy > 32768)          wy          -= 65536;
559     wfmt.width  = w; if (wfmt.width > 32768)  wfmt.width  -= 65536;
560     wfmt.height = h; if (wfmt.height > 32768) wfmt.height -= 65536;
561     wfmt.fmtid  = x11_overlay_fmtid;
562     if (debug > 1)
563         fprintf(stderr,"video: shell: size %dx%d+%d+%d\n",
564                 wfmt.width,wfmt.height,wx,wy);
565 
566     conf = 1;
567     move = 1;
568     configure_overlay();
569 }
570 
571 /* ------------------------------------------------------------------------ */
572 
573 static void
574 video_event(Widget widget, XtPointer client_data, XEvent *event, Boolean *d)
575 {
576     if (widget == video_parent) {
577         /* shell widget */
578         switch(event->type) {
579         case ConfigureNotify:
580 #if 0
581             wx      = event->xconfigure.x;
582             wy      = event->xconfigure.y;
583             wwidth  = event->xconfigure.width;
584             wheight = event->xconfigure.height;
585             if (debug > 1)
586                 fprintf(stderr,"video: shell: cfg %dx%d+%d+%d\n",
587                         wwidth,wheight,wx,wy);
588 #endif
589             video_new_size();
590             break;
591         case MapNotify:
592             if (debug > 1)
593                 fprintf(stderr,"video: shell: map\n");
594             wmap = 1;
595             conf = 1;
596             configure_overlay();
597             break;
598         case UnmapNotify:
599             if (debug > 1)
600                 fprintf(stderr,"video: shell: unmap\n");
601             wmap = 0;
602             conf = 1;
603             configure_overlay();
604             break;
605         default:
606             if (debug > 1)
607                 fprintf(stderr,"video: shell: %s\n",
608                         event_names[event->type]);
609         }
610         return;
611 
612     } else {
613         /* TV widget (+root window) */
614         switch(event->type) {
615         case Expose:
616             if (event->xvisibility.window == XtWindow(video)) {
617                 /* tv */
618                 if (!event->xexpose.count) {
619                     if (did_refresh) {
620                         did_refresh = 0;
621                         if (debug > 1)
622                             fprintf(stderr,"video: tv: last refresh expose\n");
623                     } else {
624                         if (debug > 1)
625                             fprintf(stderr,"video: tv: expose\n");
626                         conf = 1;
627                         configure_overlay();
628                     }
629                 }
630             }
631             break;
632         case VisibilityNotify:
633             if (event->xvisibility.window == XtWindow(video)) {
634                 /* tv */
635                 visibility = event->xvisibility.state;
636                 if (debug > 1)
637                     fprintf(stderr,"video: tv: visibility %d%s\n",
638                             event->xvisibility.state,
639                             did_refresh?" (ignored)":"");
640                 if (did_refresh) {
641                     if (event->xvisibility.state != VisibilityFullyObscured)
642                         did_refresh = 0;
643                 } else {
644                     conf = 1;
645                     configure_overlay();
646                 }
647             } else {
648                 /* root */
649                 if (debug > 1)
650                     fprintf(stderr,"video: root: visibility\n");
651             }
652             break;
653         case MapNotify:
654         case UnmapNotify:
655         case ConfigureNotify:
656             if (event->xvisibility.window != XtWindow(video)) {
657                 if (debug > 1)
658                     fprintf(stderr,"video: root: %s%s\n",
659                             event_names[event->type],did_refresh?" (ignored)":"");
660                 if (!did_refresh)
661                     configure_overlay();
662             }
663             break;
664         default:
665             if (debug > 1)
666                 fprintf(stderr,"video: tv(+root): %s\n",
667                         event_names[event->type]);
668             break;
669         }       
670     }
671 }
672 
673 void
674 video_overlay(int state)
675 {
676     if (state) {
677         conf = 1;
678         overlay_enabled = 1;
679         configure_overlay();
680     } else {
681         if (1 == overlay_enabled) {
682 #ifdef HAVE_LIBXV
683             if (have_xv) {
684                 xv_video(XtWindow(video),0,0,0);
685             } else
686 #endif
687             {
688                 overlay_on = 0;
689                 if (f_drv & CAN_OVERLAY)
690                     drv->overlay(h_drv,NULL,0,0,NULL,0,0);
691                 overlay_refresh = ADD_TIMER(refresh_timer);
692             }
693         }
694         overlay_enabled = 0;
695     }
696 }
697 
698 Widget
699 video_init(Widget parent, XVisualInfo *vinfo, WidgetClass class,
700            int args_bpp, int args_gl)
701 {
702     Window root = DefaultRootWindow(XtDisplay(parent));
703 
704     swidth  = XtScreen(parent)->width;
705     sheight = XtScreen(parent)->height;
706 
707     x11_overlay_fmtid = x11_dpy_fmtid;
708     if (ImageByteOrder(XtDisplay(parent)) == MSBFirst) {
709         /* X-Server is BE */
710         switch(args_bpp) {
711         case  8: x11_overlay_fmtid = VIDEO_RGB08;    break;
712         case 15: x11_overlay_fmtid = VIDEO_RGB15_BE; break;
713         case 16: x11_overlay_fmtid = VIDEO_RGB16_BE; break;
714         case 24: x11_overlay_fmtid = VIDEO_BGR24;    break;
715         case 32: x11_overlay_fmtid = VIDEO_BGR32;    break;
716         }
717     } else {
718         /* X-Server is LE */
719         switch(args_bpp) {
720         case  8: x11_overlay_fmtid = VIDEO_RGB08;    break;
721         case 15: x11_overlay_fmtid = VIDEO_RGB15_LE; break;
722         case 16: x11_overlay_fmtid = VIDEO_RGB16_LE; break;
723         case 24: x11_overlay_fmtid = VIDEO_BGR24;    break;
724         case 32: x11_overlay_fmtid = VIDEO_BGR32;    break;
725         }
726     }
727 
728     video_parent = parent;
729     video = XtVaCreateManagedWidget("tv",class,parent,NULL);
730 
731     /* Shell widget -- need map, unmap, configure */
732     XtAddEventHandler(parent,
733                       StructureNotifyMask,
734                       True, video_event, NULL);
735 
736     if (!have_xv) {
737         /* TV Widget -- need visibility, expose */
738         XtAddEventHandler(video,
739                           VisibilityChangeMask |
740                           StructureNotifyMask,
741                           False, video_event, NULL);
742         
743         /* root window -- need */
744         XSelectInput(XtDisplay(video),root,
745                      VisibilityChangeMask |
746                      SubstructureNotifyMask |
747                      StructureNotifyMask);
748         
749         XtRegisterDrawable(XtDisplay(video),root,video);
750     }
751 
752     return video;
753 }
754 
755 void
756 video_close(void)
757 {
758     Window root = DefaultRootWindow(XtDisplay(video));
759 
760     if (overlay_refresh)
761         DEL_TIMER(overlay_refresh);
762     XSelectInput(XtDisplay(video),root,0);
763     XtUnregisterDrawable(XtDisplay(video),root);
764 }
765 
  This page was automatically generated by the LXR engine.