Mercurial > ~darius > hgwebdir.cgi > simpletv
comparison simpletv.c @ 7:210d197c77f9
Tolerate LIRC going away.
author | darius |
---|---|
date | Sun, 21 Aug 2005 12:35:01 +0000 |
parents | f0cbbe964629 |
children | fc60aa65d85f |
comparison
equal
deleted
inserted
replaced
6:f0cbbe964629 | 7:210d197c77f9 |
---|---|
82 unsigned char *bktr_buffer; | 82 unsigned char *bktr_buffer; |
83 #if 1 | 83 #if 1 |
84 int width = 320; | 84 int width = 320; |
85 int height = 240; | 85 int height = 240; |
86 #else | 86 #else |
87 int width = 640; | 87 int width = 720; |
88 int height = 480; | 88 int height = 576; |
89 #endif | 89 #endif |
90 | 90 |
91 #ifndef USE_XVIMAGES | 91 #ifndef USE_XVIMAGES |
92 static XImage *rgb_image; | 92 static XImage *rgb_image; |
93 static Pixmap pmap; | 93 static Pixmap pmap; |
110 | 110 |
111 static int channel; | 111 static int channel; |
112 | 112 |
113 #define DO_IOCTL_GERR(str) fprintf(stderr, "ioctl(%s) failed: %s\n", \ | 113 #define DO_IOCTL_GERR(str) fprintf(stderr, "ioctl(%s) failed: %s\n", \ |
114 str, strerror(errno) ) | 114 str, strerror(errno) ) |
115 #define DO_IOCTL_SERR(str,arg) fprintf(stderr, "ioctl(%s, %ld) failed: %s\n",\ | 115 #define DO_IOCTL_SERR(str,arg) fprintf(stderr, "ioctl(%s, %ld) failed: %s\n", \ |
116 str, (long)arg, strerror(errno) ) | 116 str, (long)arg, strerror(errno) ) |
117 /*--------------------------------------------------------------------------*/ | 117 /*--------------------------------------------------------------------------*/ |
118 | 118 |
119 void | 119 void |
120 Close() { | 120 Close() { |
146 geo.columns = width; | 146 geo.columns = width; |
147 geo.frames = 1; | 147 geo.frames = 1; |
148 #ifdef USE_XVIMAGES | 148 #ifdef USE_XVIMAGES |
149 /* Should be YUV_12, but 422 actually gives a synced picture. Though */ | 149 /* Should be YUV_12, but 422 actually gives a synced picture. Though */ |
150 geo.oformat = METEOR_GEO_YUV_422 | METEOR_GEO_YUV_12; | 150 geo.oformat = METEOR_GEO_YUV_422 | METEOR_GEO_YUV_12; |
151 | |
151 #else | 152 #else |
152 geo.oformat = METEOR_GEO_RGB24; | 153 geo.oformat = METEOR_GEO_RGB24; |
153 #endif | 154 #endif |
154 | 155 |
155 /* switch from interlaced capture to single field capture if */ | 156 /* switch from interlaced capture to single field capture if */ |
223 exit(1); | 224 exit(1); |
224 } | 225 } |
225 /* Use mmap to Map the drivers grab buffer */ | 226 /* Use mmap to Map the drivers grab buffer */ |
226 buffer_size = width * height * 4; /* R,G,B,spare */ | 227 buffer_size = width * height * 4; /* R,G,B,spare */ |
227 bktr_buffer = (unsigned char *)mmap((caddr_t) 0, buffer_size, PROT_READ, | 228 bktr_buffer = (unsigned char *)mmap((caddr_t) 0, buffer_size, PROT_READ, |
228 MAP_SHARED, bktr_fd, (off_t) 0); | 229 MAP_SHARED, bktr_fd, (off_t) 0); |
229 | 230 |
230 if (bktr_buffer == (unsigned char *)MAP_FAILED) | 231 if (bktr_buffer == (unsigned char *)MAP_FAILED) |
231 exit(1); | 232 exit(1); |
232 | 233 |
233 | 234 |
321 void | 322 void |
322 vo_x11_ewmh_fullscreen(int action) { | 323 vo_x11_ewmh_fullscreen(int action) { |
323 XEvent xev; | 324 XEvent xev; |
324 | 325 |
325 assert(action == _NET_WM_STATE_REMOVE || | 326 assert(action == _NET_WM_STATE_REMOVE || |
326 action == _NET_WM_STATE_ADD || action == _NET_WM_STATE_TOGGLE); | 327 action == _NET_WM_STATE_ADD || action == _NET_WM_STATE_TOGGLE); |
327 | 328 |
328 | 329 |
329 /* init X event structure for _NET_WM_FULLSCREEN client msg */ | 330 /* init X event structure for _NET_WM_FULLSCREEN client msg */ |
330 xev.xclient.type = ClientMessage; | 331 xev.xclient.type = ClientMessage; |
331 xev.xclient.serial = 0; | 332 xev.xclient.serial = 0; |
339 xev.xclient.data.l[3] = 0; | 340 xev.xclient.data.l[3] = 0; |
340 xev.xclient.data.l[4] = 0; | 341 xev.xclient.data.l[4] = 0; |
341 | 342 |
342 /* finally send that damn thing */ | 343 /* finally send that damn thing */ |
343 if (!XSendEvent(disp, DefaultRootWindow(disp), False, | 344 if (!XSendEvent(disp, DefaultRootWindow(disp), False, |
344 SubstructureRedirectMask | SubstructureNotifyMask, | 345 SubstructureRedirectMask | SubstructureNotifyMask, |
345 &xev)) { | 346 &xev)) { |
346 fprintf(stderr, "Failed to send fullscreen command\n"); | 347 fprintf(stderr, "Failed to send fullscreen command\n"); |
347 } | 348 } |
348 } | 349 } |
349 | 350 |
350 | 351 |
371 depth = DefaultDepth(disp, scr); | 372 depth = DefaultDepth(disp, scr); |
372 | 373 |
373 vinfo_pref.screen = scr; | 374 vinfo_pref.screen = scr; |
374 vinfo_pref.visualid = XVisualIDFromVisual(vis); | 375 vinfo_pref.visualid = XVisualIDFromVisual(vis); |
375 vi = XGetVisualInfo(disp, VisualScreenMask | VisualIDMask, | 376 vi = XGetVisualInfo(disp, VisualScreenMask | VisualIDMask, |
376 &vinfo_pref, &num_vis); | 377 &vinfo_pref, &num_vis); |
377 assert(num_vis == 1); | 378 assert(num_vis == 1); |
378 | 379 |
379 win = XCreateSimpleWindow(disp, root, 0, 0, w, h, 0, 0, 0); | 380 win = XCreateSimpleWindow(disp, root, 0, 0, w, h, 0, 0, 0); |
380 gc = XCreateGC(disp, win, (unsigned long)0, &gcvals); | 381 gc = XCreateGC(disp, win, (unsigned long)0, &gcvals); |
381 XSetForeground(disp, gc, 0); | 382 XSetForeground(disp, gc, 0); |
425 assert(xv_adaptor >= 0); | 426 assert(xv_adaptor >= 0); |
426 | 427 |
427 /* Create an image to captured frames */ | 428 /* Create an image to captured frames */ |
428 #ifdef USE_XVIMAGES | 429 #ifdef USE_XVIMAGES |
429 yuv_image = XvShmCreateImage(disp, xv_adaptors[xv_adaptor].base_id, | 430 yuv_image = XvShmCreateImage(disp, xv_adaptors[xv_adaptor].base_id, |
430 xv_format_id, 0, w, h, &shminfo); | 431 xv_format_id, 0, w, h, &shminfo); |
431 if (!yuv_image) | 432 if (!yuv_image) |
432 fprintf(stderr, "X-Error: unable to create XvShm XImage\n"); | 433 fprintf(stderr, "X-Error: unable to create XvShm XImage\n"); |
433 | 434 |
434 shminfo.shmid = shmget(IPC_PRIVATE, yuv_image->data_size, IPC_CREAT | 0777); | 435 shminfo.shmid = shmget(IPC_PRIVATE, yuv_image->data_size, IPC_CREAT | 0777); |
435 if (shminfo.shmid == -1) | 436 if (shminfo.shmid == -1) |
441 rgb_image = XShmCreateImage(disp, vis, depth, ZPixmap, NULL, &shminfo, w, h); | 442 rgb_image = XShmCreateImage(disp, vis, depth, ZPixmap, NULL, &shminfo, w, h); |
442 if (!rgb_image) | 443 if (!rgb_image) |
443 fprintf(stderr, "X-Error: unable to create XShm XImage\n"); | 444 fprintf(stderr, "X-Error: unable to create XShm XImage\n"); |
444 | 445 |
445 shminfo.shmid = shmget(IPC_PRIVATE, | 446 shminfo.shmid = shmget(IPC_PRIVATE, |
446 rgb_image->bytes_per_line * rgb_image->height, | 447 rgb_image->bytes_per_line * rgb_image->height, |
447 IPC_CREAT | 0777); | 448 IPC_CREAT | 0777); |
448 if (shminfo.shmid == -1) | 449 if (shminfo.shmid == -1) |
449 fprintf(stderr, "SharedMemory Error: unable to get identifier\n"); | 450 fprintf(stderr, "SharedMemory Error: unable to get identifier\n"); |
450 | 451 |
451 shminfo.shmaddr = rgb_image->data = shmat(shminfo.shmid, 0, 0); | 452 shminfo.shmaddr = rgb_image->data = shmat(shminfo.shmid, 0, 0); |
452 #endif | 453 #endif |
501 Window _dw; | 502 Window _dw; |
502 | 503 |
503 #ifdef USE_XVIMAGES | 504 #ifdef USE_XVIMAGES |
504 XGetGeometry(disp, win, &_dw, &_d, &_d, &_w, &_h, &_d, &_d); | 505 XGetGeometry(disp, win, &_dw, &_d, &_d, &_w, &_h, &_d, &_d); |
505 XvShmPutImage(disp, xv_adaptors[xv_adaptor].base_id, win, | 506 XvShmPutImage(disp, xv_adaptors[xv_adaptor].base_id, win, |
506 gc, yuv_image, 0, 0, yuv_image->width, yuv_image->height, | 507 gc, yuv_image, 0, 0, yuv_image->width, yuv_image->height, |
507 0, 0, _w, _h, True); | 508 0, 0, _w, _h, True); |
508 #else | 509 #else |
509 XShmPutImage(disp, win, gc, rgb_image, 0, 0, 0, 0, | 510 XShmPutImage(disp, win, gc, rgb_image, 0, 0, 0, 0, |
510 rgb_image->width, rgb_image->height, False); | 511 rgb_image->width, rgb_image->height, False); |
511 #endif | 512 #endif |
512 XSync(disp, False); | 513 XSync(disp, False); |
513 } | 514 } |
514 | 515 |
515 #define CMD_NONE 0 | 516 #define CMD_NONE 0 |
530 #ifndef USE_XVIMAGES | 531 #ifndef USE_XVIMAGES |
531 HermesHandle conv; | 532 HermesHandle conv; |
532 HermesFormat fmt_source, fmt_dest; | 533 HermesFormat fmt_source, fmt_dest; |
533 #endif | 534 #endif |
534 XEvent e; | 535 XEvent e; |
535 char *scratch_buf, *code, *c, *mixerdev; | 536 char *scratch_buf, *code, *c, *mixerdev; |
536 int frames , channelidx, oldchan, mute, cursor, fd, ret, cmd; | 537 int frames, channelidx, oldchan, mute, cursor, fd, ret, cmd; |
537 int exitnow , mfd, uselirc, curvol; | 538 int exitnow, mfd, uselirc, curvol; |
538 struct timeval then, now, diff, lastmove; | 539 struct timeval then, now, diff, lastmove; |
539 float rate; | 540 float rate; |
540 KeySym key; | 541 KeySym key; |
541 char text [255]; | 542 char text [255]; |
542 int channellist[] = {2, 7, 9, 10, 28}; | 543 int channellist[] = {2, 7, 9, 10, 28}; |
543 struct lirc_config *config; | 544 struct lirc_config *config; |
544 struct pollfd fds[1]; | 545 struct pollfd fds[1]; |
545 | 546 |
546 #define NUMCHANS (sizeof(channellist) / sizeof(channellist[0])) | 547 #define NUMCHANS (sizeof(channellist) / sizeof(channellist[0])) |
547 | 548 |
548 channelidx = mute = cursor = 0; | 549 channelidx = mute = cursor = 0; |
549 | 550 |
550 oldchan = channel = channellist[channelidx]; | 551 oldchan = channel = channellist[channelidx]; |
693 case 'f': | 694 case 'f': |
694 cmd = CMD_FSTOGGLE; | 695 cmd = CMD_FSTOGGLE; |
695 break; | 696 break; |
696 } | 697 } |
697 } | 698 } |
699 | |
698 /* Poll for IR events */ | 700 /* Poll for IR events */ |
699 if (uselirc) { | 701 if (uselirc) { |
700 fds[0].revents = 0; | 702 fds[0].revents = 0; |
701 | 703 |
702 while (1) { | 704 while (1) { |
705 | |
703 if (poll(fds, 1, 0) == -1) { | 706 if (poll(fds, 1, 0) == -1) { |
704 fprintf(stderr, "Poll failed - %s\n", strerror(errno)); | 707 fprintf(stderr, "Poll failed - %s\n", strerror(errno)); |
705 exit(EXIT_FAILURE); | 708 exit(EXIT_FAILURE); |
706 } | 709 } |
707 if ((fds[0].revents & POLLRDNORM) != 0) { | 710 if ((fds[0].revents & POLLRDNORM) != 0) { |
708 fprintf(stderr, "Processing IR..\n"); | 711 fprintf(stderr, "Processing IR.. \n", lircfails); |
709 | 712 |
713 /* Try and get an event */ | |
710 if (lirc_nextcode(&code) == 0) { | 714 if (lirc_nextcode(&code) == 0) { |
711 if (code == NULL) | 715 if (code == NULL) { |
712 continue; | 716 continue; |
713 | 717 } |
718 | |
719 /* Translate it (via the config file) */ | |
714 while ((ret = lirc_code2char(config, code, &c)) == 0 && | 720 while ((ret = lirc_code2char(config, code, &c)) == 0 && |
715 c != NULL) { | 721 c != NULL) { |
716 fprintf(stderr, "Got command \"%s\"\n", c); | 722 fprintf(stderr, "Got command \"%s\"\n", c); |
717 | 723 |
718 if (!strcmp(c, "Mute")) | 724 if (!strcmp(c, "Mute")) |
719 cmd = CMD_MUTE; | 725 cmd = CMD_MUTE; |
720 else if (!strcmp(c, "CH_UP")) | 726 else if (!strcmp(c, "CH_UP")) |
727 cmd = CMD_VOLUP; | 733 cmd = CMD_VOLUP; |
728 else if (!strcmp(c, "VOL_DOWN")) | 734 else if (!strcmp(c, "VOL_DOWN")) |
729 cmd = CMD_VOLDN; | 735 cmd = CMD_VOLDN; |
730 else if (!strcmp(c, "AV/TV")) | 736 else if (!strcmp(c, "AV/TV")) |
731 cmd = CMD_FSTOGGLE; | 737 cmd = CMD_FSTOGGLE; |
732 | 738 |
733 free(code); | 739 free(code); |
734 } | 740 } |
741 } else { | |
742 /* lircd probably died */ | |
743 uselirc = 0; | |
744 fprintf(stderr, "Failed to communicate with LIRC - daemon exited?"); | |
735 } | 745 } |
736 } else | 746 } else |
737 break; | 747 break; |
738 } | 748 } |
739 } | 749 } |
851 #else | 861 #else |
852 /* SaveImage(); */ | 862 /* SaveImage(); */ |
853 | 863 |
854 Hermes_ConverterRequest(conv, &fmt_source, &fmt_dest); | 864 Hermes_ConverterRequest(conv, &fmt_source, &fmt_dest); |
855 Hermes_ConverterCopy(conv, bktr_buffer, 0, 0, width, height, width * 4, | 865 Hermes_ConverterCopy(conv, bktr_buffer, 0, 0, width, height, width * 4, |
856 rgb_image->data, 0, 0, width, height, | 866 rgb_image->data, 0, 0, width, height, |
857 rgb_image->bytes_per_line); | 867 rgb_image->bytes_per_line); |
858 #endif | 868 #endif |
859 | 869 |
860 X_Display(); | 870 X_Display(); |
861 if (exitnow) { | 871 if (exitnow) { |
862 printf("quitting\n"); | 872 printf("quitting\n"); |