Mercurial > ~darius > hgwebdir.cgi > simpletv
comparison simpletv.c @ 3:8d7d1680db7d
style(9) mostly with
indent -nbad -nfbs -br -ci4 -nfc1 -l80 -nlp
author | darius |
---|---|
date | Tue, 04 Jan 2005 05:20:58 +0000 |
parents | 769b155a34f9 |
children | 8b6b46a1261d |
comparison
equal
deleted
inserted
replaced
2:a3e8aae64d40 | 3:8d7d1680db7d |
---|---|
75 | 75 |
76 /* PAL is 768 x 576. NTSC is 640 x 480 */ | 76 /* PAL is 768 x 576. NTSC is 640 x 480 */ |
77 #define PAL_HEIGHT 576 | 77 #define PAL_HEIGHT 576 |
78 #define NTSC_HEIGHT 480 | 78 #define NTSC_HEIGHT 480 |
79 | 79 |
80 int bktr_fd; | 80 int bktr_fd; |
81 int tuner_fd; | 81 int tuner_fd; |
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 = 640; |
88 int height = 480; | 88 int height = 480; |
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; |
94 #endif | 94 #endif |
95 static XShmSegmentInfo shminfo; | 95 static XShmSegmentInfo shminfo; |
96 static Display *disp; | 96 static Display *disp; |
97 static Window win; | 97 static Window win; |
98 static Visual *vis; | 98 static Visual *vis; |
99 static int scr; | 99 static int scr; |
100 static GC gc; | 100 static GC gc; |
101 static int depth; | 101 static int depth; |
102 static Colormap cmap; | 102 static Colormap cmap; |
103 static XVisualInfo *vi; | 103 static XVisualInfo *vi; |
104 static int bits_per_pixel; | 104 static int bits_per_pixel; |
105 static XvImage *yuv_image; | 105 static XvImage *yuv_image; |
106 static XvAdaptorInfo *xv_adaptors; | 106 static XvAdaptorInfo *xv_adaptors; |
107 static int xv_num_adaptors; | 107 static int xv_num_adaptors; |
108 static int xv_adaptor; | 108 static int xv_adaptor; |
109 static int xv_format_id; | 109 static int xv_format_id; |
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 Close() | 119 void |
120 { | 120 Close() { |
121 close(tuner_fd); | 121 close(tuner_fd); |
122 close(bktr_fd); | 122 close(bktr_fd); |
123 } | 123 } |
124 | 124 |
125 void Open() | 125 void |
126 { | 126 Open() { |
127 struct meteor_geomet geo; | 127 struct meteor_geomet geo; |
128 int buffer_size, format, source, c; | 128 int buffer_size, format, source, c; |
129 char *device_name; | 129 char *device_name; |
130 | 130 |
131 format = PAL; /* default value */ | 131 format = PAL; /* default value */ |
132 source = 1; /* default value */ | 132 source = 1; /* default value */ |
133 device_name = "/dev/bktr0"; /* default value */ | 133 device_name = "/dev/bktr0"; /* default value */ |
134 | 134 |
135 /* Open the Meteor or Bt848/Bt878 grabber */ | 135 /* Open the Meteor or Bt848/Bt878 grabber */ |
136 if ((bktr_fd = open(device_name, O_RDONLY)) < 0) { | 136 if ((bktr_fd = open(device_name, O_RDONLY)) < 0) { |
137 printf("open failed: %d\n", errno); | 137 printf("open failed: %d\n", errno); |
138 exit(1); | 138 exit(1); |
139 } | 139 } |
140 | 140 if ((tuner_fd = open("/dev/tuner0", O_RDONLY)) < 0) { |
141 if ((tuner_fd = open("/dev/tuner0", O_RDONLY)) < 0) { | 141 printf("open failed: %d\n", errno); |
142 printf("open failed: %d\n", errno); | 142 exit(1); |
143 exit(1); | 143 } |
144 } | 144 /* set up the capture type and size */ |
145 | 145 geo.rows = height; |
146 /* set up the capture type and size */ | 146 geo.columns = width; |
147 geo.rows = height; | 147 geo.frames = 1; |
148 geo.columns = width; | |
149 geo.frames = 1; | |
150 #ifdef USE_XVIMAGES | 148 #ifdef USE_XVIMAGES |
151 /* 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 */ |
152 | 150 |
153 /*geo.oformat = METEOR_GEO_YUV_12;*/ | 151 /* geo.oformat = METEOR_GEO_YUV_12; */ |
154 geo.oformat = METEOR_GEO_YUV_422 | METEOR_GEO_YUV_12; | 152 geo.oformat = METEOR_GEO_YUV_422 | METEOR_GEO_YUV_12; |
155 /* geo.oformat = METEOR_GEO_YUV_12; */ | 153 /* geo.oformat = METEOR_GEO_YUV_12; */ |
156 #else | 154 #else |
157 geo.oformat = METEOR_GEO_RGB24; | 155 geo.oformat = METEOR_GEO_RGB24; |
158 #endif | 156 #endif |
159 | 157 |
160 /* switch from interlaced capture to single field capture if */ | 158 /* switch from interlaced capture to single field capture if */ |
161 /* the grab height is less than half the normal TV height */ | 159 /* the grab height is less than half the normal TV height */ |
162 /* this gives better quality captures when the object in the TV */ | 160 /* this gives better quality captures when the object in the TV */ |
163 /* picture is moving */ | 161 /* picture is moving */ |
164 if ((format == PAL) && (height <= (PAL_HEIGHT/2))) | 162 if ((format == PAL) && (height <= (PAL_HEIGHT / 2))) |
165 geo.oformat |= METEOR_GEO_ODD_ONLY; | 163 geo.oformat |= METEOR_GEO_ODD_ONLY; |
166 if ((format == NTSC) && (height <= (NTSC_HEIGHT/2))) | 164 if ((format == NTSC) && (height <= (NTSC_HEIGHT / 2))) |
167 geo.oformat |= METEOR_GEO_ODD_ONLY; | 165 geo.oformat |= METEOR_GEO_ODD_ONLY; |
168 | 166 |
169 if (ioctl(bktr_fd, METEORSETGEO, &geo) < 0) { | 167 if (ioctl(bktr_fd, METEORSETGEO, &geo) < 0) { |
170 printf("METEORSETGEO ioctl failed: %d\n", errno); | 168 printf("METEORSETGEO ioctl failed: %d\n", errno); |
171 exit(1); | 169 exit(1); |
172 } | 170 } |
173 | 171 /* Select PAL or NTSC */ |
174 /* Select PAL or NTSC */ | 172 switch (format) { |
175 switch (format) { | 173 case PAL: |
176 case PAL: c = METEOR_FMT_PAL; break; | 174 c = METEOR_FMT_PAL; |
177 case NTSC: c = METEOR_FMT_NTSC; break; | 175 break; |
178 default: c = METEOR_FMT_NTSC; break; | 176 case NTSC: |
179 } | 177 c = METEOR_FMT_NTSC; |
180 | 178 break; |
181 c = BT848_IFORM_F_PALBDGHI; | 179 default: |
182 if ( ioctl( bktr_fd, BT848SFMT, &c ) < 0 ) { | 180 c = METEOR_FMT_NTSC; |
183 DO_IOCTL_SERR( "BT848SFMT", c ); | 181 break; |
184 return; | 182 } |
185 } | 183 |
186 c = AUDIO_TUNER; | 184 c = BT848_IFORM_F_PALBDGHI; |
187 if ( ioctl( tuner_fd, BT848_SAUDIO, &c ) < 0 ) { | 185 if (ioctl(bktr_fd, BT848SFMT, &c) < 0) { |
188 DO_IOCTL_SERR( "BT848SFMT", c ); | 186 DO_IOCTL_SERR("BT848SFMT", c); |
189 return; | 187 return; |
190 } | 188 } |
191 c = CHNLSET_AUSTRALIA; | 189 c = AUDIO_TUNER; |
192 if ( ioctl( tuner_fd, TVTUNER_SETTYPE, &c ) < 0 ) { | 190 if (ioctl(tuner_fd, BT848_SAUDIO, &c) < 0) { |
193 DO_IOCTL_SERR( "TVTUNER_SETTYPE", c ); | 191 DO_IOCTL_SERR("BT848SFMT", c); |
194 return; | 192 return; |
195 } | 193 } |
196 | 194 c = CHNLSET_AUSTRALIA; |
197 if ( ioctl( tuner_fd, TVTUNER_SETCHNL, &channel ) < 0 ) { | 195 if (ioctl(tuner_fd, TVTUNER_SETTYPE, &c) < 0) { |
198 DO_IOCTL_SERR( "TVTUNER_SETCHNL", channel ); | 196 DO_IOCTL_SERR("TVTUNER_SETTYPE", c); |
199 return; | 197 return; |
200 } | 198 } |
201 | 199 if (ioctl(tuner_fd, TVTUNER_SETCHNL, &channel) < 0) { |
202 | 200 DO_IOCTL_SERR("TVTUNER_SETCHNL", channel); |
203 /* Select the Video Source */ | 201 return; |
204 /* Video In, Tuner, S-Video */ | 202 } |
205 switch (source) { | 203 /* Select the Video Source */ |
206 case 0: c = METEOR_INPUT_DEV0; break; | 204 /* Video In, Tuner, S-Video */ |
207 case 1: c = METEOR_INPUT_DEV1; break; | 205 switch (source) { |
208 case 2: c = METEOR_INPUT_DEV2; break; | 206 case 0: |
209 case 3: c = METEOR_INPUT_DEV3; break; | 207 c = METEOR_INPUT_DEV0; |
210 default: c = METEOR_INPUT_DEV0; break; | 208 break; |
211 } | 209 case 1: |
212 | 210 c = METEOR_INPUT_DEV1; |
213 printf("Input - %x\n", c); | 211 break; |
214 if (ioctl(bktr_fd, METEORSINPUT, &c) < 0) { | 212 case 2: |
215 printf("ioctl failed: %d\n", errno); | 213 c = METEOR_INPUT_DEV2; |
216 exit(1); | 214 break; |
217 } | 215 case 3: |
218 | 216 c = METEOR_INPUT_DEV3; |
219 /* Use mmap to Map the drivers grab buffer */ | 217 break; |
220 buffer_size = width*height*4; /* R,G,B,spare */ | 218 default: |
221 bktr_buffer = (unsigned char *)mmap((caddr_t)0,buffer_size,PROT_READ, | 219 c = METEOR_INPUT_DEV0; |
222 MAP_SHARED, bktr_fd, (off_t)0); | 220 break; |
223 | 221 } |
224 if (bktr_buffer == (unsigned char *) MAP_FAILED) | 222 |
225 exit(1); | 223 printf("Input - %x\n", c); |
226 | 224 if (ioctl(bktr_fd, METEORSINPUT, &c) < 0) { |
227 | 225 printf("ioctl failed: %d\n", errno); |
228 /* We may need to wait for a short time to allow the grabber */ | 226 exit(1); |
229 /* brightness to settle down */ | 227 } |
230 sleep(GRABBER_SETTLE_TIME); | 228 /* Use mmap to Map the drivers grab buffer */ |
229 buffer_size = width * height * 4; /* R,G,B,spare */ | |
230 bktr_buffer = (unsigned char *)mmap((caddr_t) 0, buffer_size, PROT_READ, | |
231 MAP_SHARED, bktr_fd, (off_t) 0); | |
232 | |
233 if (bktr_buffer == (unsigned char *)MAP_FAILED) | |
234 exit(1); | |
235 | |
236 | |
237 /* We may need to wait for a short time to allow the grabber */ | |
238 /* brightness to settle down */ | |
239 sleep(GRABBER_SETTLE_TIME); | |
231 } | 240 } |
232 | 241 |
233 /*--------------------------------------------------------------------------*/ | 242 /*--------------------------------------------------------------------------*/ |
234 | 243 |
235 void Capture() | 244 void |
236 { | 245 Capture() { |
237 int c; | 246 int c; |
238 | 247 |
239 /* Perform a single frame capture */ | 248 /* Perform a single frame capture */ |
240 c = METEOR_CAP_SINGLE ; | 249 c = METEOR_CAP_SINGLE; |
241 ioctl(bktr_fd, METEORCAPTUR, &c); | 250 ioctl(bktr_fd, METEORCAPTUR, &c); |
242 } | 251 } |
243 | 252 |
244 /*--------------------------------------------------------------------------*/ | 253 /*--------------------------------------------------------------------------*/ |
245 | 254 |
246 void SaveImage() | 255 void |
247 { | 256 SaveImage() { |
248 unsigned char *line_buffer; | 257 unsigned char *line_buffer; |
249 int o,w,h; | 258 int o , w, h; |
250 unsigned char *p; | 259 unsigned char *p; |
251 unsigned char header[30]; | 260 unsigned char header[30]; |
252 char *filename = "t.ppm" /* argv[3] */; | 261 char *filename = "t.ppm" /* argv[3] */ ; |
253 | 262 |
254 /* Create the output file */ | 263 /* Create the output file */ |
255 if ((o = open(filename, O_WRONLY | O_CREAT, 0644)) < 0) { | 264 if ((o = open(filename, O_WRONLY | O_CREAT, 0644)) < 0) { |
256 printf("ppm open failed: %d\n", errno); | 265 printf("ppm open failed: %d\n", errno); |
257 exit(1); | 266 exit(1); |
258 } | 267 } |
259 | 268 /* make PPM header and save to file */ |
260 /* make PPM header and save to file */ | 269 sprintf(header, "P6\n%d\n%d\n255\n", width, height); |
261 sprintf(header, "P6\n%d\n%d\n255\n",width,height); | 270 write(o, header, strlen(header)); |
262 write (o, header, strlen(header)); | 271 |
263 | 272 /* save the RGB data to PPM file */ |
264 /* save the RGB data to PPM file */ | 273 /* save this one line at a time */ |
265 /* save this one line at a time */ | 274 line_buffer = (unsigned char *)malloc(width * 3 * sizeof(unsigned char)); |
266 line_buffer =(unsigned char *)malloc( width *3 * sizeof(unsigned char)); | 275 p = bktr_buffer; |
267 p = bktr_buffer; | 276 for (h = 0; h < height; h++) { |
268 for (h = 0; h < height; h++) { | 277 for (w = 0; w < width; w++) { |
269 for (w = 0; w < width; w++) { | 278 line_buffer[(w * 3) + 2] = *p++; /* blue */ |
270 line_buffer[(w*3) + 2] = *p++; /* blue */ | 279 line_buffer[(w * 3) + 1] = *p++; /* green */ |
271 line_buffer[(w*3) + 1] = *p++; /* green */ | 280 line_buffer[(w * 3) + 0] = *p++; /* red */ |
272 line_buffer[(w*3) + 0] = *p++; /* red */ | 281 p++; /* NULL byte */ |
273 p++; /* NULL byte */ | 282 } |
274 } | 283 write(o, line_buffer, width * 3); |
275 write(o,line_buffer, width*3); | 284 } |
276 } | 285 close(o); |
277 close(o); | 286 free(line_buffer); |
278 free(line_buffer); | 287 } |
279 } | 288 |
280 | 289 void |
281 void X_ShowCursor(void) { | 290 X_ShowCursor(void) { |
282 XDefineCursor(disp, win, 0); | 291 XDefineCursor(disp, win, 0); |
283 } | 292 } |
284 | 293 |
285 void X_HideCursor(void) { | 294 void |
286 Cursor no_ptr; | 295 X_HideCursor(void) { |
287 Pixmap bm_no; | 296 Cursor no_ptr; |
288 XColor black,dummy; | 297 Pixmap bm_no; |
289 Colormap colormap; | 298 XColor black , dummy; |
290 static unsigned char bm_no_data[] = {0,0,0,0, 0,0,0,0}; | 299 Colormap colormap; |
291 | 300 static unsigned char bm_no_data[] = {0, 0, 0, 0, 0, 0, 0, 0}; |
292 colormap = DefaultColormap(disp, DefaultScreen(disp)); | 301 |
293 XAllocNamedColor(disp, colormap, "black", &black, &dummy); | 302 colormap = DefaultColormap(disp, DefaultScreen(disp)); |
294 bm_no = XCreateBitmapFromData(disp, win, bm_no_data, 8, 8); | 303 XAllocNamedColor(disp, colormap, "black", &black, &dummy); |
295 no_ptr = XCreatePixmapCursor(disp, bm_no, bm_no, &black, &black, 0, 0); | 304 bm_no = XCreateBitmapFromData(disp, win, bm_no_data, 8, 8); |
296 | 305 no_ptr = XCreatePixmapCursor(disp, bm_no, bm_no, &black, &black, 0, 0); |
297 XDefineCursor(disp, win, no_ptr); | 306 |
298 XFreeCursor(disp, no_ptr); | 307 XDefineCursor(disp, win, no_ptr); |
299 if (bm_no != None) | 308 XFreeCursor(disp, no_ptr); |
300 XFreePixmap(disp, bm_no); | 309 if (bm_no != None) |
301 | 310 XFreePixmap(disp, bm_no); |
311 | |
302 } | 312 } |
303 | 313 |
304 /* | 314 /* |
305 * Sends the EWMH fullscreen state event. | 315 * Sends the EWMH fullscreen state event. |
306 * | 316 * |
307 * action: could be on of _NET_WM_STATE_REMOVE -- remove state | 317 * action: could be on of _NET_WM_STATE_REMOVE -- remove state |
308 * _NET_WM_STATE_ADD -- add state | 318 * _NET_WM_STATE_ADD -- add state |
309 * _NET_WM_STATE_TOGGLE -- toggle | 319 * _NET_WM_STATE_TOGGLE -- toggle |
310 */ | 320 */ |
311 #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ | 321 #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ |
312 #define _NET_WM_STATE_ADD 1 /* add/set property */ | 322 #define _NET_WM_STATE_ADD 1 /* add/set property */ |
313 #define _NET_WM_STATE_TOGGLE 2 /* toggle property */ | 323 #define _NET_WM_STATE_TOGGLE 2 /* toggle property */ |
314 void | 324 void |
315 vo_x11_ewmh_fullscreen(int action) { | 325 vo_x11_ewmh_fullscreen(int action) { |
316 XEvent xev; | 326 XEvent xev; |
317 | 327 |
318 assert(action == _NET_WM_STATE_REMOVE || | 328 assert(action == _NET_WM_STATE_REMOVE || |
319 action == _NET_WM_STATE_ADD || action == _NET_WM_STATE_TOGGLE); | 329 action == _NET_WM_STATE_ADD || action == _NET_WM_STATE_TOGGLE); |
320 | 330 |
321 | 331 |
322 /* init X event structure for _NET_WM_FULLSCREEN client msg */ | 332 /* init X event structure for _NET_WM_FULLSCREEN client msg */ |
323 xev.xclient.type = ClientMessage; | 333 xev.xclient.type = ClientMessage; |
324 xev.xclient.serial = 0; | 334 xev.xclient.serial = 0; |
325 xev.xclient.send_event = True; | 335 xev.xclient.send_event = True; |
326 xev.xclient.message_type = XInternAtom(disp, "_NET_WM_STATE", False); | 336 xev.xclient.message_type = XInternAtom(disp, "_NET_WM_STATE", False); |
327 xev.xclient.window = win; | 337 xev.xclient.window = win; |
328 xev.xclient.format = 32; | 338 xev.xclient.format = 32; |
329 xev.xclient.data.l[0] = action; | 339 xev.xclient.data.l[0] = action; |
330 xev.xclient.data.l[1] = XInternAtom(disp, "_NET_WM_STATE_FULLSCREEN", False); | 340 xev.xclient.data.l[1] = XInternAtom(disp, "_NET_WM_STATE_FULLSCREEN", False); |
331 xev.xclient.data.l[2] = 0; | 341 xev.xclient.data.l[2] = 0; |
332 xev.xclient.data.l[3] = 0; | 342 xev.xclient.data.l[3] = 0; |
333 xev.xclient.data.l[4] = 0; | 343 xev.xclient.data.l[4] = 0; |
334 | 344 |
335 /* finally send that damn thing */ | 345 /* finally send that damn thing */ |
336 if (!XSendEvent(disp, DefaultRootWindow(disp), False, | 346 if (!XSendEvent(disp, DefaultRootWindow(disp), False, |
337 SubstructureRedirectMask | SubstructureNotifyMask, | 347 SubstructureRedirectMask | SubstructureNotifyMask, |
338 &xev)) { | 348 &xev)) { |
339 fprintf(stderr, "Failed to send fullscreen command\n"); | 349 fprintf(stderr, "Failed to send fullscreen command\n"); |
340 } | 350 } |
341 } | 351 } |
342 | 352 |
343 | 353 |
344 void X_Setup(int w,int h) | 354 void |
345 { | 355 X_Setup(int w, int h) { |
346 XGCValues gcvals; | 356 XGCValues gcvals; |
347 Window root; | 357 Window root; |
348 XVisualInfo vinfo_pref; | 358 XVisualInfo vinfo_pref; |
349 int num_vis; | 359 int num_vis; |
350 XPixmapFormatValues *pf; | 360 XPixmapFormatValues *pf; |
351 int num_pf, pfi, i,j; | 361 int num_pf , pfi, i, j; |
352 | 362 |
353 disp = XOpenDisplay(NULL); | 363 disp = XOpenDisplay(NULL); |
354 if (!disp) { | 364 if (!disp) { |
355 fprintf(stderr,"X-Error: unable to connect to display\n"); | 365 fprintf(stderr, "X-Error: unable to connect to display\n"); |
356 exit(1); | 366 exit(1); |
357 } | 367 } |
358 | 368 XSynchronize(disp, True); |
359 XSynchronize( disp, True ); | 369 |
360 | 370 scr = DefaultScreen(disp); |
361 scr=DefaultScreen(disp); | 371 vis = DefaultVisual(disp, scr); |
362 vis=DefaultVisual(disp,scr); | 372 root = DefaultRootWindow(disp); |
363 root=DefaultRootWindow(disp); | 373 depth = DefaultDepth(disp, scr); |
364 depth=DefaultDepth(disp,scr); | 374 |
365 | 375 vinfo_pref.screen = scr; |
366 vinfo_pref.screen = scr; | 376 vinfo_pref.visualid = XVisualIDFromVisual(vis); |
367 vinfo_pref.visualid = XVisualIDFromVisual( vis ); | 377 vi = XGetVisualInfo(disp, VisualScreenMask | VisualIDMask, |
368 vi = XGetVisualInfo( disp, VisualScreenMask | VisualIDMask, | 378 &vinfo_pref, &num_vis); |
369 &vinfo_pref, &num_vis ); | 379 assert(num_vis == 1); |
370 assert ( num_vis == 1 ); | 380 |
371 | 381 win = XCreateSimpleWindow(disp, root, 0, 0, w, h, 0, 0, 0); |
372 win = XCreateSimpleWindow(disp, root, 0, 0, w, h, 0, 0, 0); | 382 gc = XCreateGC(disp, win, (unsigned long)0, &gcvals); |
373 gc = XCreateGC(disp, win, (unsigned long)0, &gcvals); | 383 XSetForeground(disp, gc, 0); |
374 XSetForeground(disp, gc, 0); | 384 XSetBackground(disp, gc, 1); |
375 XSetBackground(disp, gc, 1); | 385 |
376 | 386 XMapWindow(disp, win); |
377 XMapWindow(disp,win); | 387 cmap = DefaultColormap(disp, scr); |
378 cmap = DefaultColormap(disp, scr); | 388 XSync(disp, False); |
379 XSync(disp,False); | 389 |
380 | 390 /* Setup with Xv extension */ |
381 /* Setup with Xv extension */ | 391 xv_adaptor = -1; |
382 xv_adaptor = -1; | 392 xv_format_id = -1; |
383 xv_format_id = -1; | 393 XvQueryAdaptors(disp, root, &xv_num_adaptors, &xv_adaptors); |
384 XvQueryAdaptors( disp, root, &xv_num_adaptors, &xv_adaptors ); | 394 for (i = 0; i < xv_num_adaptors; i++) { |
385 for ( i = 0; i < xv_num_adaptors; i++ ) { | 395 XvAdaptorInfo *adaptor = &xv_adaptors[i]; |
386 XvAdaptorInfo *adaptor = &xv_adaptors[i]; | 396 int takes_images; |
387 int takes_images; | 397 |
388 | 398 takes_images = adaptor->type & (XvInputMask | XvImageMask); |
389 takes_images = adaptor->type & ( XvInputMask | XvImageMask ); | 399 if (takes_images) { |
390 if ( takes_images ) { | 400 XvImageFormatValues *formats; |
391 XvImageFormatValues *formats; | 401 int num_formats; |
392 int num_formats; | 402 |
393 | 403 formats = XvListImageFormats(disp, adaptor->base_id, &num_formats); |
394 formats = XvListImageFormats( disp, adaptor->base_id, &num_formats ); | 404 for (j = 0; j < num_formats; j++) |
395 for ( j = 0; j < num_formats; j++ ) | 405 if (formats[j].type == XvYUV && formats[j].format == XvPlanar && |
396 if ( formats[j].type == XvYUV && formats[j].format == XvPlanar && | 406 strcmp(formats[j].guid, "YV12") == 0) |
397 strcmp( formats[j].guid, "YV12" ) == 0 ) | 407 break; |
398 break; | 408 if (j < num_formats) { |
399 if ( j < num_formats ) { | 409 xv_adaptor = i; |
400 xv_adaptor = i; | 410 xv_format_id = formats[j].id; |
401 xv_format_id = formats[j].id; | 411 break; |
402 break; | 412 } |
403 } | 413 } |
404 } | 414 } |
405 } | 415 assert(xv_adaptor >= 0); |
406 assert( xv_adaptor >= 0 ); | 416 |
407 | 417 /* Create an image to captured frames */ |
408 /* Create an image to captured frames */ | |
409 #ifdef USE_XVIMAGES | 418 #ifdef USE_XVIMAGES |
410 yuv_im age = XvShmCreateImage( disp, xv_adaptors[xv_adaptor].base_id, | 419 yuv_im age = XvShmCreateImage(disp, xv_adaptors[xv_adaptor].base_id, |
411 xv_format_id, 0, w, h, &shminfo ); | 420 xv_format_id, 0, w, h, &shminfo); |
412 if (!yuv_image) | 421 if (!yuv_image) |
413 fprintf(stderr,"X-Error: unable to create XvShm XImage\n"); | 422 fprintf(stderr, "X-Error: unable to create XvShm XImage\n"); |
414 | 423 |
415 shminfo.shmid = shmget( IPC_PRIVATE, yuv_image->data_size, IPC_CREAT|0777); | 424 shminfo.shmid = shmget(IPC_PRIVATE, yuv_image->data_size, IPC_CREAT | 0777); |
416 if (shminfo.shmid == -1) | 425 if (shminfo.shmid == -1) |
417 fprintf(stderr,"SharedMemory Error: unable to get identifier\n"); | 426 fprintf(stderr, "SharedMemory Error: unable to get identifier\n"); |
418 | 427 |
419 shminfo.shmaddr = yuv_image->data = shmat(shminfo.shmid, 0, 0); | 428 shminfo.shmaddr = yuv_image->data = shmat(shminfo.shmid, 0, 0); |
420 #else | 429 #else |
421 rgb_image = XShmCreateImage( disp, vis, depth, ZPixmap, NULL, &shminfo, w, h); | 430 rgb_image = XShmCreateImage(disp, vis, depth, ZPixmap, NULL, &shminfo, w, h); |
422 if (!rgb_image) | 431 if (!rgb_image) |
423 fprintf(stderr,"X-Error: unable to create XShm XImage\n"); | 432 fprintf(stderr, "X-Error: unable to create XShm XImage\n"); |
424 | 433 |
425 shminfo.shmid = shmget( IPC_PRIVATE, | 434 shminfo.shmid = shmget(IPC_PRIVATE, |
426 rgb_image->bytes_per_line * rgb_image->height, | 435 rgb_image->bytes_per_line * rgb_image->height, |
427 IPC_CREAT|0777); | 436 IPC_CREAT | 0777); |
428 if (shminfo.shmid == -1) | 437 if (shminfo.shmid == -1) |
429 fprintf(stderr, "SharedMemory Error: unable to get identifier\n"); | 438 fprintf(stderr, "SharedMemory Error: unable to get identifier\n"); |
430 | 439 |
431 shminfo.shmaddr = rgb_image->data = shmat(shminfo.shmid, 0, 0); | 440 shminfo.shmaddr = rgb_image->data = shmat(shminfo.shmid, 0, 0); |
432 #endif | 441 #endif |
433 | 442 |
434 if(!XShmAttach( disp,&shminfo )) | 443 if (!XShmAttach(disp, &shminfo)) |
435 fprintf(stderr,"X-Error: unable to attach XShm Shared Memory Segment\n"); | 444 fprintf(stderr, "X-Error: unable to attach XShm Shared Memory Segment\n"); |
436 | 445 |
437 /* Create a pixmap for the window background */ | 446 /* Create a pixmap for the window background */ |
438 #ifdef OLD | 447 #ifdef OLD |
439 pmap = XShmCreatePixmap(disp, win, shminfo.shmaddr, &shminfo, w, h, depth); | 448 pmap = XShmCreatePixmap(disp, win, shminfo.shmaddr, &shminfo, w, h, depth); |
440 if (!pmap) | 449 if (!pmap) |
441 fprintf(stderr,"Unable to create pixmap\n"); | 450 fprintf(stderr, "Unable to create pixmap\n"); |
442 #endif | 451 #endif |
443 | 452 |
444 /* Determine bits-per-pixel for pixmaps */ | 453 /* Determine bits-per-pixel for pixmaps */ |
445 pf = XListPixmapFormats( disp, &num_pf); | 454 pf = XListPixmapFormats(disp, &num_pf); |
446 assert(pf); | 455 assert(pf); |
447 for (pfi = 0; pfi < num_pf; pfi++) | 456 for (pfi = 0; pfi < num_pf; pfi++) |
448 if (pf[pfi].depth == vi->depth) | 457 if (pf[pfi].depth == vi->depth) |
449 break; | 458 break; |
450 assert(pfi < num_pf); | 459 assert(pfi < num_pf); |
451 bits_per_pixel = pf[pfi].bits_per_pixel; | 460 bits_per_pixel = pf[pfi].bits_per_pixel; |
452 XFree (pf); | 461 XFree(pf); |
453 | 462 |
454 #ifdef OLD | 463 #ifdef OLD |
455 XSetWindowBackgroundPixmap(disp,win,pmap); | 464 XSetWindowBackgroundPixmap(disp, win, pmap); |
456 #endif | 465 #endif |
457 } | 466 } |
458 | 467 |
459 /*--------------------------------------------------------------------------*/ | 468 /*--------------------------------------------------------------------------*/ |
460 | 469 |
461 void X_Shutdown() | 470 void |
462 { | 471 X_Shutdown() { |
463 XShmDetach( disp, &shminfo ); | 472 XShmDetach(disp, &shminfo); |
464 #ifdef USE_XVIMAGES | 473 #ifdef USE_XVIMAGES |
465 # warning How do we destroy an XvImage? | 474 #warning How do we destroy an XvImage? |
466 #else | 475 #else |
467 XDestroyImage( rgb_image ); | 476 XDestroyImage(rgb_image); |
468 #endif | 477 #endif |
469 shmdt( shminfo.shmaddr ); | 478 shmdt(shminfo.shmaddr); |
470 shmctl( shminfo.shmid, IPC_RMID, 0 ); | 479 shmctl(shminfo.shmid, IPC_RMID, 0); |
471 } | 480 } |
472 | 481 |
473 | 482 |
474 /*--------------------------------------------------------------------------*/ | 483 /*--------------------------------------------------------------------------*/ |
475 | 484 |
476 void X_Display(void) | 485 void |
477 { | 486 X_Display(void) { |
478 int _w,_h,_d; | 487 int _w , _h, _d; |
479 Window _dw; | 488 Window _dw; |
480 | 489 |
481 #ifdef USE_XVIMAGES | 490 #ifdef USE_XVIMAGES |
482 XGetGeometry( disp, win, &_dw, &_d, &_d, &_w, &_h, &_d, &_d); | 491 XGetGeometry(disp, win, &_dw, &_d, &_d, &_w, &_h, &_d, &_d); |
483 XvShmPutImage( disp, xv_adaptors[ xv_adaptor ].base_id, win, | 492 XvShmPutImage(disp, xv_adaptors[xv_adaptor].base_id, win, |
484 gc, yuv_image, 0, 0, yuv_image->width, yuv_image->height, | 493 gc, yuv_image, 0, 0, yuv_image->width, yuv_image->height, |
485 0, 0, _w, _h, True ); | 494 0, 0, _w, _h, True); |
486 #else | 495 #else |
487 XShmPutImage( disp, win, gc, rgb_image, 0,0,0,0, | 496 XShmPutImage(disp, win, gc, rgb_image, 0, 0, 0, 0, |
488 rgb_image->width, rgb_image->height, False ); | 497 rgb_image->width, rgb_image->height, False); |
489 #endif | 498 #endif |
490 XSync(disp, False); | 499 XSync(disp, False); |
491 } | 500 } |
492 | 501 |
493 #define CMD_NONE 0 | 502 #define CMD_NONE 0 |
494 #define CMD_CHNUP 1 | 503 #define CMD_CHNUP 1 |
495 #define CMD_CHNDN 2 | 504 #define CMD_CHNDN 2 |
501 #define CMD_VOLUP 8 | 510 #define CMD_VOLUP 8 |
502 #define CMD_FSTOGGLE 9 | 511 #define CMD_FSTOGGLE 9 |
503 | 512 |
504 /*--------------------------------------------------------------------------*/ | 513 /*--------------------------------------------------------------------------*/ |
505 | 514 |
506 int main(int argc, char *argv[]) { | 515 int |
516 main(int argc, char *argv[]) { | |
507 #ifndef USE_XVIMAGES | 517 #ifndef USE_XVIMAGES |
508 HermesHandle conv; | 518 HermesHandle conv; |
509 HermesFormat fmt_source,fmt_dest; | 519 HermesFormat fmt_source, fmt_dest; |
510 #endif | 520 #endif |
511 XEvent e; | 521 XEvent e; |
512 char *scratch_buf, *code, *c, *mixerdev; | 522 char *scratch_buf, *code, *c, *mixerdev; |
513 int frames, channelidx, oldchan, mute, cursor, fd, ret, cmd; | 523 int frames , channelidx, oldchan, mute, cursor, fd, ret, cmd; |
514 int exitnow, mfd, uselirc, curvol; | 524 int exitnow , mfd, uselirc, curvol; |
515 struct timeval then, now, diff, lastmove; | 525 struct timeval then, now, diff, lastmove; |
516 float rate; | 526 float rate; |
517 KeySym key; | 527 KeySym key; |
518 char text[255]; | 528 char text [255]; |
519 int channellist[] = { 2, 7, 9, 10, 28 }; | 529 int channellist[] = {2, 7, 9, 10, 28}; |
520 struct lirc_config *config; | 530 struct lirc_config *config; |
521 struct pollfd fds[1]; | 531 struct pollfd fds[1]; |
522 | 532 |
523 #define NUMCHANS (sizeof(channellist) / sizeof(channellist[0])) | 533 #define NUMCHANS (sizeof(channellist) / sizeof(channellist[0])) |
524 | 534 |
525 channelidx = mute = cursor = 0; | 535 channelidx = mute = cursor = 0; |
526 | 536 |
527 oldchan = channel = channellist[channelidx]; | 537 oldchan = channel = channellist[channelidx]; |
528 | 538 |
529 #ifndef USE_XVIMAGES | 539 #ifndef USE_XVIMAGES |
530 if (!Hermes_Init()) { | 540 if (!Hermes_Init()) { |
531 printf("Couldn't initialise Hermes!\n"); | 541 printf("Couldn't initialise Hermes!\n"); |
532 exit(1); | 542 exit(1); |
533 } | 543 } |
534 | 544 conv = Hermes_ConverterInstance(HERMES_CONVERT_NORMAL); |
535 conv=Hermes_ConverterInstance(HERMES_CONVERT_NORMAL); | 545 if (!conv) { |
536 if (!conv) { | 546 printf("Could not obtain converter instance from Hermes!\n"); |
537 printf("Could not obtain converter instance from Hermes!\n"); | 547 exit(1); |
538 exit(1); | 548 } |
539 } | 549 #endif |
540 #endif | 550 |
541 | 551 X_Setup(width, height); |
542 X_Setup(width, height); | 552 XSelectInput(disp, win, KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask); |
543 XSelectInput(disp, win, KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask); | 553 |
544 | 554 X_HideCursor(); |
545 X_HideCursor(); | 555 |
546 | 556 /* Open Capture device */ |
547 /* Open Capture device */ | 557 Open(); |
548 Open(); | 558 |
549 | 559 /* Open audio mixer */ |
550 /* Open audio mixer */ | 560 mixerdev = "/dev/mixer"; |
551 mixerdev = "/dev/mixer"; | 561 if ((mfd = open(mixerdev, O_RDWR)) == -1) |
552 if ((mfd = open(mixerdev, O_RDWR)) == -1) | 562 fprintf(stderr, "Unable to open %s - %s\n", mixerdev, strerror(errno)); |
553 fprintf(stderr, "Unable to open %s - %s\n", mixerdev, strerror(errno)); | 563 |
554 | 564 /* Talk to LIRC */ |
555 /* Talk to LIRC */ | 565 if ((fd = lirc_init(basename(argv[0]), 1)) == -1) { |
556 if ((fd = lirc_init(basename(argv[0]), 1)) == -1) { | 566 fprintf(stderr, "Unable to init lirc client library\n"); |
557 fprintf(stderr, "Unable to init lirc client library\n"); | 567 uselirc = 0; |
558 uselirc = 0; | 568 } else { |
559 } else { | 569 if (lirc_readconfig(NULL, &config, NULL) != 0) { |
560 if (lirc_readconfig(NULL, &config, NULL) != 0) { | 570 fprintf(stderr, "Unable to parse config file\n"); |
561 fprintf(stderr, "Unable to parse config file\n"); | 571 uselirc = 0; |
562 uselirc = 0; | 572 } else |
563 } else | 573 uselirc = 1; |
564 uselirc = 1; | 574 fds[0].fd = fd; |
565 fds[0].fd = fd; | 575 fds[0].events = POLLRDNORM; |
566 fds[0].events = POLLRDNORM; | 576 } |
567 } | |
568 | 577 |
569 #ifndef USE_XVIMAGES | 578 #ifndef USE_XVIMAGES |
570 /* Conversion from and to formats */ | 579 /* Conversion from and to formats */ |
571 fmt_source.indexed=0; | 580 fmt_source.indexed = 0; |
572 fmt_source.bits=32; | 581 fmt_source.bits = 32; |
573 fmt_source.r=0xff0000; | 582 fmt_source.r = 0xff0000; |
574 fmt_source.g=0x00ff00; | 583 fmt_source.g = 0x00ff00; |
575 fmt_source.b=0x0000ff; | 584 fmt_source.b = 0x0000ff; |
576 fmt_source.a=0; | 585 fmt_source.a = 0; |
577 | 586 |
578 fmt_dest.indexed=0; | 587 fmt_dest.indexed = 0; |
579 fmt_dest.bits=bits_per_pixel; | 588 fmt_dest.bits = bits_per_pixel; |
580 fmt_dest.r=vi->red_mask; | 589 fmt_dest.r = vi->red_mask; |
581 fmt_dest.g=vi->green_mask; | 590 fmt_dest.g = vi->green_mask; |
582 fmt_dest.b=vi->blue_mask; | 591 fmt_dest.b = vi->blue_mask; |
583 fmt_dest.a=0; | 592 fmt_dest.a = 0; |
584 #else | 593 #else |
585 scratch_buf = malloc(width * height); | 594 scratch_buf = malloc(width * height); |
586 #endif | 595 #endif |
587 | 596 |
588 frames = 0; | 597 frames = 0; |
589 gettimeofday(&then, NULL); | 598 gettimeofday(&then, NULL); |
590 gettimeofday(&lastmove, NULL); | 599 gettimeofday(&lastmove, NULL); |
591 | 600 |
592 exitnow = 0; | 601 exitnow = 0; |
593 | 602 |
594 /* Capture loop */ | 603 /* Capture loop */ |
595 while (1) { | 604 while (1) { |
596 if (frames == 50) { | 605 if (frames == 50) { |
597 gettimeofday(&now, NULL); | 606 gettimeofday(&now, NULL); |
598 timersub(&now, &then, &diff); | 607 timersub(&now, &then, &diff); |
599 | 608 |
600 rate = (float)frames / (float)(diff.tv_usec / 1000000.0 + diff.tv_sec); | 609 rate = (float)frames / (float)(diff.tv_usec / 1000000.0 + diff.tv_sec); |
601 | 610 |
602 printf("%d frames in %.2f seconds, rate %.2f\n", frames, (float)(diff.tv_usec / 1000000.0) + diff.tv_sec, rate); | 611 printf("%d frames in %.2f seconds, rate %.2f\n", frames, (float)(diff.tv_usec / 1000000.0) + diff.tv_sec, rate); |
603 gettimeofday(&then, NULL); | 612 gettimeofday(&then, NULL); |
604 frames = 0; | 613 frames = 0; |
605 XResetScreenSaver(disp); | 614 XResetScreenSaver(disp); |
606 } | 615 } |
607 frames++; | 616 frames++; |
608 | 617 |
609 timersub(&now, &lastmove, &diff); | 618 timersub(&now, &lastmove, &diff); |
610 if (((float)diff.tv_usec / 1000000.0 + (float)diff.tv_sec) > 2.0) { | 619 if (((float)diff.tv_usec / 1000000.0 + (float)diff.tv_sec) > 2.0) { |
611 if (cursor) { | 620 if (cursor) { |
612 X_HideCursor(); | 621 X_HideCursor(); |
613 cursor = 0; | 622 cursor = 0; |
614 } | 623 } |
615 } else { | 624 } else { |
616 if (!cursor) { | 625 if (!cursor) { |
617 X_ShowCursor(); | 626 X_ShowCursor(); |
618 cursor = 1; | 627 cursor = 1; |
619 } | 628 } |
620 } | 629 } |
621 | 630 |
622 if (XCheckMaskEvent(disp, PointerMotionMask, &e) && e.type == MotionNotify) { | 631 if (XCheckMaskEvent(disp, PointerMotionMask, &e) && e.type == MotionNotify) { |
623 gettimeofday(&lastmove, NULL); | 632 gettimeofday(&lastmove, NULL); |
624 } | 633 } |
625 | 634 cmd = CMD_NONE; |
626 cmd = CMD_NONE; | 635 |
627 | 636 if (XCheckMaskEvent(disp, ButtonReleaseMask, &e)) { |
628 if (XCheckMaskEvent(disp, ButtonReleaseMask, &e)) { | 637 printf("e.type = %d\n", e.type); |
629 printf("e.type = %d\n", e.type); | 638 cmd = CMD_MUTE; |
630 cmd = CMD_MUTE; | 639 } |
631 } | 640 if (XCheckMaskEvent(disp, KeyReleaseMask, &e) && e.type == KeyRelease) { |
632 | 641 gettimeofday(&lastmove, NULL); |
633 if (XCheckMaskEvent(disp, KeyReleaseMask, &e) && e.type == KeyRelease) { | 642 |
634 gettimeofday(&lastmove, NULL); | 643 XLookupString(&e.xkey, text, 255, &key, 0); |
635 | 644 printf("Press - %c\n", text[0]); |
636 XLookupString(&e.xkey, text, 255, &key, 0); | 645 |
637 printf("Press - %c\n", text[0]); | 646 switch (text[0]) { |
638 | 647 case 'q': |
639 switch (text[0]) { | 648 cmd = CMD_QUIT; |
640 case 'q': | 649 break; |
641 cmd = CMD_QUIT; | 650 |
642 break; | 651 case '=': |
643 | 652 case '+': |
644 case '=': | 653 cmd = CMD_CHNUP; |
645 case '+': | 654 break; |
646 cmd = CMD_CHNUP; | 655 |
647 break; | 656 case '-': |
648 | 657 cmd = CMD_CHNDN; |
649 case '-': | 658 break; |
650 cmd = CMD_CHNDN; | 659 |
651 break; | 660 case 'h': |
652 | 661 cmd = CMD_CURSOR; |
653 case 'h': | 662 break; |
654 cmd = CMD_CURSOR; | 663 |
655 break; | 664 case 'm': |
656 | |
657 case 'm': | |
658 cmd = CMD_MUTE; | |
659 break; | |
660 | |
661 case 'r': | |
662 cmd = CMD_RELOAD; | |
663 break; | |
664 | |
665 case ',': | |
666 cmd = CMD_VOLDN; | |
667 break; | |
668 | |
669 case '.': | |
670 cmd = CMD_VOLUP; | |
671 break; | |
672 | |
673 case 'f': | |
674 cmd = CMD_FSTOGGLE; | |
675 break; | |
676 } | |
677 } | |
678 | |
679 /* Poll for IR events */ | |
680 if (uselirc) { | |
681 fds[0].revents = 0; | |
682 | |
683 while (1) { | |
684 if (poll(fds, 1, 0) == -1) { | |
685 fprintf(stderr, "Poll failed - %s\n", strerror(errno)); | |
686 exit(EXIT_FAILURE); | |
687 } | |
688 if ((fds[0].revents & POLLRDNORM) != 0) { | |
689 fprintf(stderr, "Processing IR..\n"); | |
690 | |
691 if (lirc_nextcode(&code) == 0) { | |
692 if(code == NULL) | |
693 continue; | |
694 | |
695 while ((ret = lirc_code2char(config, code, &c)) == 0 && | |
696 c != NULL) { | |
697 fprintf(stderr, "Got command \"%s\"\n", c); | |
698 | |
699 if (!strcmp(c, "Mute")) | |
700 cmd = CMD_MUTE; | 665 cmd = CMD_MUTE; |
701 else if (!strcmp(c, "CH_UP")) | 666 break; |
702 cmd = CMD_CHNUP; | 667 |
703 else if (!strcmp(c, "CH_DOWN")) | 668 case 'r': |
704 cmd = CMD_CHNDN; | 669 cmd = CMD_RELOAD; |
705 else if (!strcmp(c, "Power")) | 670 break; |
706 cmd = CMD_QUIT; | 671 |
707 else if (!strcmp(c, "VOL_UP")) | 672 case ',': |
673 cmd = CMD_VOLDN; | |
674 break; | |
675 | |
676 case '.': | |
708 cmd = CMD_VOLUP; | 677 cmd = CMD_VOLUP; |
709 else if (!strcmp(c, "VOL_DOWN")) | 678 break; |
710 cmd = CMD_VOLDN; | 679 |
711 else if (!strcmp(c, "AV/TV")) | 680 case 'f': |
712 cmd = CMD_FSTOGGLE; | 681 cmd = CMD_FSTOGGLE; |
713 | 682 break; |
714 free(code); | 683 } |
715 } | 684 } |
716 } | 685 /* Poll for IR events */ |
717 } else | 686 if (uselirc) { |
718 break; | 687 fds[0].revents = 0; |
719 } | 688 |
720 } | 689 while (1) { |
721 | 690 if (poll(fds, 1, 0) == -1) { |
722 switch (cmd) { | 691 fprintf(stderr, "Poll failed - %s\n", strerror(errno)); |
723 case CMD_QUIT: | 692 exit(EXIT_FAILURE); |
724 exitnow = 1; | 693 } |
725 break; | 694 if ((fds[0].revents & POLLRDNORM) != 0) { |
726 | 695 fprintf(stderr, "Processing IR..\n"); |
727 case CMD_CHNUP: | 696 |
728 case CMD_CHNDN: | 697 if (lirc_nextcode(&code) == 0) { |
729 if (cmd == CMD_CHNUP) | 698 if (code == NULL) |
730 channelidx++; | 699 continue; |
731 else | 700 |
732 channelidx--; | 701 while ((ret = lirc_code2char(config, code, &c)) == 0 && |
733 | 702 c != NULL) { |
734 if (channelidx < 0) | 703 fprintf(stderr, "Got command \"%s\"\n", c); |
735 channelidx = NUMCHANS - 1; | 704 |
736 if (channelidx > NUMCHANS - 1) | 705 if (!strcmp(c, "Mute")) |
737 channelidx = 0; | 706 cmd = CMD_MUTE; |
738 | 707 else if (!strcmp(c, "CH_UP")) |
739 channel = channellist[channelidx]; | 708 cmd = CMD_CHNUP; |
740 | 709 else if (!strcmp(c, "CH_DOWN")) |
741 printf("Channel - %d\n", channel); | 710 cmd = CMD_CHNDN; |
742 if (oldchan != channel) { | 711 else if (!strcmp(c, "Power")) |
743 oldchan = channel; | 712 cmd = CMD_QUIT; |
744 | 713 else if (!strcmp(c, "VOL_UP")) |
745 if ( ioctl( tuner_fd, TVTUNER_SETCHNL, &channel ) < 0 ) { | 714 cmd = CMD_VOLUP; |
746 DO_IOCTL_SERR( "TVTUNER_SETCHNL", channel ); | 715 else if (!strcmp(c, "VOL_DOWN")) |
747 exit(1); | 716 cmd = CMD_VOLDN; |
748 } | 717 else if (!strcmp(c, "AV/TV")) |
749 } | 718 cmd = CMD_FSTOGGLE; |
750 break; | 719 |
751 | 720 free(code); |
752 case CMD_MUTE: | 721 } |
753 if (mute) | 722 } |
754 mute = 0; | 723 } else |
755 else | 724 break; |
756 mute = 1; | 725 } |
757 | 726 } |
758 printf("Mute - %d\n", mute); | 727 switch (cmd) { |
759 if (ioctl(tuner_fd, BT848_SAUDIO, &mute) < 0) { | 728 case CMD_QUIT: |
760 DO_IOCTL_SERR("BT848_SAUDIO", mute); | 729 exitnow = 1; |
761 exit(1); | 730 break; |
762 } | 731 |
763 break; | 732 case CMD_CHNUP: |
764 | 733 case CMD_CHNDN: |
765 case CMD_CURSOR: | 734 if (cmd == CMD_CHNUP) |
766 if (cursor) { | 735 channelidx++; |
767 printf("Cursor hidden\n"); | 736 else |
768 X_HideCursor(); | 737 channelidx--; |
769 cursor = 0; | 738 |
770 } else { | 739 if (channelidx < 0) |
771 printf("Cursor revealed\n"); | 740 channelidx = NUMCHANS - 1; |
772 X_ShowCursor(); | 741 if (channelidx > NUMCHANS - 1) |
773 cursor = 1; | 742 channelidx = 0; |
774 } | 743 |
775 break; | 744 channel = channellist[channelidx]; |
776 | 745 |
777 case CMD_RELOAD: | 746 printf("Channel - %d\n", channel); |
778 printf("Reloading\n"); | 747 if (oldchan != channel) { |
779 Close(); | 748 oldchan = channel; |
780 Open(); | 749 |
781 break; | 750 if (ioctl(tuner_fd, TVTUNER_SETCHNL, &channel) < 0) { |
782 | 751 DO_IOCTL_SERR("TVTUNER_SETCHNL", channel); |
783 case CMD_VOLUP: | 752 exit(1); |
784 case CMD_VOLDN: | 753 } |
785 if (ioctl(mfd, MIXER_READ(SOUND_MIXER_VOLUME), &curvol) == -1) { | 754 } |
786 fprintf(stderr, "Unable to read current volume - %s\n", strerror(errno)); | 755 break; |
787 break; | 756 |
788 } | 757 case CMD_MUTE: |
789 | 758 if (mute) |
790 curvol = curvol & 0x7f; | 759 mute = 0; |
791 | 760 else |
792 if (cmd == CMD_VOLUP) | 761 mute = 1; |
793 curvol += 5; | 762 |
794 else | 763 printf("Mute - %d\n", mute); |
795 curvol -= 5; | 764 if (ioctl(tuner_fd, BT848_SAUDIO, &mute) < 0) { |
796 | 765 DO_IOCTL_SERR("BT848_SAUDIO", mute); |
797 if (curvol < 0) | 766 exit(1); |
798 curvol = 0; | 767 } |
799 if (curvol > 100) | 768 break; |
800 curvol = 100; | 769 |
801 | 770 case CMD_CURSOR: |
802 printf("Setting volume to %d\n", curvol); | 771 if (cursor) { |
803 curvol |= curvol << 8; | 772 printf("Cursor hidden\n"); |
804 | 773 X_HideCursor(); |
805 if (ioctl(mfd, MIXER_WRITE(SOUND_MIXER_VOLUME), &curvol) == -1) { | 774 cursor = 0; |
806 fprintf(stderr, "Unable to write volume - %s\n", strerror(errno)); | 775 } else { |
807 break; | 776 printf("Cursor revealed\n"); |
808 } | 777 X_ShowCursor(); |
809 break; | 778 cursor = 1; |
810 | 779 } |
811 case CMD_FSTOGGLE: | 780 break; |
812 vo_x11_ewmh_fullscreen(_NET_WM_STATE_TOGGLE); | 781 |
813 break; | 782 case CMD_RELOAD: |
814 | 783 printf("Reloading\n"); |
815 } | 784 Close(); |
816 | 785 Open(); |
817 Capture(); | 786 break; |
787 | |
788 case CMD_VOLUP: | |
789 case CMD_VOLDN: | |
790 if (ioctl(mfd, MIXER_READ(SOUND_MIXER_VOLUME), &curvol) == -1) { | |
791 fprintf(stderr, "Unable to read current volume - %s\n", strerror(errno)); | |
792 break; | |
793 } | |
794 curvol = curvol & 0x7f; | |
795 | |
796 if (cmd == CMD_VOLUP) | |
797 curvol += 5; | |
798 else | |
799 curvol -= 5; | |
800 | |
801 if (curvol < 0) | |
802 curvol = 0; | |
803 if (curvol > 100) | |
804 curvol = 100; | |
805 | |
806 printf("Setting volume to %d\n", curvol); | |
807 curvol |= curvol << 8; | |
808 | |
809 if (ioctl(mfd, MIXER_WRITE(SOUND_MIXER_VOLUME), &curvol) == -1) { | |
810 fprintf(stderr, "Unable to write volume - %s\n", strerror(errno)); | |
811 break; | |
812 } | |
813 break; | |
814 | |
815 case CMD_FSTOGGLE: | |
816 vo_x11_ewmh_fullscreen(_NET_WM_STATE_TOGGLE); | |
817 break; | |
818 | |
819 } | |
820 | |
821 Capture(); | |
818 | 822 |
819 #ifdef USE_XVIMAGES | 823 #ifdef USE_XVIMAGES |
820 /* bktr's YUV_12 is planar W*H bytes Y, W/2*H/2 bytes U, */ | 824 /* bktr's YUV_12 is planar W*H bytes Y, W/2*H/2 bytes U, */ |
821 /* W/2*H/2 bytes V. Xv's YV12 is the same with U and V */ | 825 /* W/2*H/2 bytes V. Xv's YV12 is the same with U and V */ |
822 /* planes reversed. */ | 826 /* planes reversed. */ |
823 { | 827 { |
824 int y_off, u_off, v_off; | 828 int y_off , u_off, v_off; |
825 y_off = 0; | 829 y_off = 0; |
826 u_off = width * height; | 830 u_off = width * height; |
827 v_off = u_off + width*height/4; | 831 v_off = u_off + width * height / 4; |
828 | 832 |
829 assert(yuv_image->data_size == width * height * 3 / 2 ); | 833 assert(yuv_image->data_size == width * height * 3 / 2); |
830 memcpy(yuv_image->data , bktr_buffer , u_off-y_off ); | 834 memcpy(yuv_image->data, bktr_buffer, u_off - y_off); |
831 memcpy(yuv_image->data + u_off, bktr_buffer + v_off, v_off-u_off ); | 835 memcpy(yuv_image->data + u_off, bktr_buffer + v_off, v_off - u_off); |
832 memcpy(yuv_image->data + v_off, bktr_buffer + u_off, v_off-u_off ); | 836 memcpy(yuv_image->data + v_off, bktr_buffer + u_off, v_off - u_off); |
833 } | 837 } |
834 #else | 838 #else |
835 /*SaveImage();*/ | 839 /* SaveImage(); */ |
836 | 840 |
837 Hermes_ConverterRequest(conv,&fmt_source,&fmt_dest); | 841 Hermes_ConverterRequest(conv, &fmt_source, &fmt_dest); |
838 Hermes_ConverterCopy(conv,bktr_buffer,0,0,width,height,width*4, | 842 Hermes_ConverterCopy(conv, bktr_buffer, 0, 0, width, height, width * 4, |
839 rgb_image->data,0,0,width,height, | 843 rgb_image->data, 0, 0, width, height, |
840 rgb_image->bytes_per_line); | 844 rgb_image->bytes_per_line); |
841 #endif | 845 #endif |
842 | 846 |
843 X_Display(); | 847 X_Display(); |
844 if (exitnow) { | 848 if (exitnow) { |
845 printf("quitting\n"); | 849 printf("quitting\n"); |
846 break; | 850 break; |
847 } | 851 } |
848 } | 852 } |
849 | 853 |
850 #ifndef USE_XVIMAGES | 854 #ifndef USE_XVIMAGES |
851 Hermes_ConverterReturn(conv); | 855 Hermes_ConverterReturn(conv); |
852 Hermes_Done(); | 856 Hermes_Done(); |
853 #endif | 857 #endif |
854 | 858 |
855 X_Shutdown(); | 859 X_Shutdown(); |
856 lirc_freeconfig(config); | 860 lirc_freeconfig(config); |
857 lirc_deinit(); | 861 lirc_deinit(); |
858 | 862 |
859 return 0; | 863 return 0; |
860 } | 864 } |