comparison simpletv.c @ 8:fc60aa65d85f

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