1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <time.h>
4 #include <string.h>
5 #include <unistd.h>
6
7 #include <sys/mman.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <sys/ioctl.h>
11 #include <fcntl.h>
12 #include <assert.h>
13 #include <errno.h>
14
15 #include <gtk/gtk.h>
16 #include <gdk/gdkx.h>
17
18 #include <SDL.h>
19
20 /*
21 * moronic hack because time.h and linux/time.h, the latter of which
22 * videodev.h apparently includes don't jive with each other.
23 */
24 #define _LINUX_TIME_H
25 #include <linux/videodev.h>
26 #include "hrt.h"
27
28 #include "hrtdemo.h"
29
30 SDL_Surface *screen = NULL;
31 SDL_Color colors[256];
32 int width = WINSIZEX, height = WINSIZEY, bytesperpixel = WINPIXEL;
33 int startx = 0, starty = 0;
34
35 /* chunks pulled from the v4l spec... */
36 struct {
37 void *start;
38 size_t length;
39 } *buffers;
40 struct v4l2_requestbuffers reqbuf;
41
42 char *outfn = NULL;
43 char *infn = NULL;
44 char *memory = NULL;
45
46 int fd;
47 int now;
48 int isfile = 0, readonly = 0, matrix = 0, fps = 0;
49 int mode = HRT_KERNELSPACE;
50
51 /* Added by Sean/ Atulya
52 * --- begin ---
53 * 0 - greyscale, 1 - color
54 * 0 - upsidedown, 1 - downsideup
55 */
56 int tgcolor = 0;
57 int tginvert = 0;
58 /* --- end --- */
59
60 GtkWidget *filew;
61 GtkWidget *fnlabel;
62 GtkWidget *controlw;
63
64 void setstartx(void);
65 void setstarty(void);
66
67 /* called over and over again within gtk_main -- do what we need to do to
68 * get things drawn onto the SDL window */
69 gint updateloop(gpointer data)
70 {
71 char *pixels;
72 static int frames = 0;
73
74 if (!screen)
75 return 0;
76
77 if (fps) {
78 time_t rightnow = time(NULL) / 5;
79 frames++;
80 if (rightnow != now) {
81 now = rightnow;
82 g_print("%.2f frames per second\n",
83 ((float) frames) / 5);
84 frames = 0;
85 }
86 }
87
88 pixels = screen->pixels;
89
90 if (HRT_USERSPACE == mode) {
91 memory[PIXELSMART_CONTROL_REG] = PIXELSMART_LIVE_CMD;
92 if (!matrix)
93 usleep(50000);
94 memory[PIXELSMART_CONTROL_REG] =
95 PIXELSMART_FREEZE_NEXT_CMD;
96 if (!matrix)
97 usleep(50000);
98 }
99
100 SDL_LockSurface(screen);
101
102 switch (mode) {
103 case HRT_KERNELSPACE: {
104 fd_set rdset;
105 struct timeval timeout;
106 int n = 0;
107
108 FD_ZERO(&rdset);
109 FD_SET(fd, &rdset);
110
111 timeout.tv_sec = 1;
112 timeout.tv_usec = 0;
113
114 if (isfile)
115 lseek(fd, 0, SEEK_SET);
116
117 n = select(fd + 1, &rdset, NULL, NULL, &timeout);
118 if (n == -1)
119 fprintf(stderr, "select error.\n");
120 else if (n == 0)
121 fprintf(stderr, "select timeout\n");
122 else if (FD_ISSET(fd, &rdset)) {
123 // printf ("HRT_KERNELSPACE (width * height * bytesperpixel) = %d \n", width * height * bytesperpixel);
124 read(fd, screen->pixels, width * height * bytesperpixel);
125 }
126
127 break;
128 }
129 case HRT_USERSPACE: {
130 int i, j;
131
132 for (i = starty; i < height; i++) {
133 memcpy(pixels + (i - starty) * width,
134 memory + startx, width - startx);
135 memory[PIXELSMART_Y_LOW_REG] = i & 0xff;
136 memory[PIXELSMART_Y_HIGH_REG] =
137 (i & 0x0100) >> 8;
138 }
139 break;
140 }
141 case HRT_STREAMING: {
142 struct v4l2_buffer buffer;
143 fd_set rdset;
144 struct timeval timeout;
145 int n = 0;
146
147 FD_ZERO(&rdset);
148 FD_SET(fd, &rdset);
149
150 timeout.tv_sec = 1;
151 timeout.tv_usec = 0;
152
153 n = select(fd + 1, &rdset, NULL, NULL, &timeout);
154 if (n == -1)
155 fprintf(stderr, "select error.\n");
156 else if (n == 0)
157 fprintf(stderr, "select timeout\n");
158 else if (FD_ISSET(fd, &rdset)) {
159 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
160 if (ioctl(fd, VIDIOC_DQBUF, &buffer) == -1) {
161 perror("VIDIOC_DQBUF");
162 exit(EXIT_FAILURE);
163 }
164 }
165 // fprintf (stderr, "index = %d length = %d buffers[buffer.index].start = %p, pixels = %p\n",buffer.index, buffers[buffer.index].length,buffers[buffer.index].start,pixels);
166 // memcpy(pixels, buffers[buffer.index].start, buffers[buffer.index].length);
167 //printf ("HRT_STREAMING ((width - startx) * (height - starty) * bytesperpixel)) = %d \n", ((width - startx) * (height - starty) * bytesperpixel));
168 memcpy(pixels, buffers[buffer.index].start, ((width - startx) * (height - starty) * bytesperpixel));
169
170 if (ioctl(fd, VIDIOC_QBUF, &buffer) == -1) {
171 perror("VIDIOC_QBUF");
172 exit(EXIT_FAILURE);
173 }
174 break;
175 }
176 }
177
178 SDL_UpdateRect(screen, 0, 0, 0, 0);
179 SDL_UnlockSurface(screen);
180
181 if (screen)
182 gtk_idle_add(updateloop, NULL);
183
184 return 0;
185 }
186
187 /* quitting out -- shut down GTK and SDL */
188 void quit_request(GtkWidget * widget, gpointer data)
189 {
190 if (HRT_STREAMING == mode) {
191 stopstreaming();
192 }
193
194 gtk_main_quit();
195 SDL_Quit();
196 }
197
198
199 /* duh. */
200 int main(int argc, char *argv[])
201 {
202 struct v4l2_format fmt;
203
204
205 GtkWidget *window;
206
207 sdl_init();
208
209 parsecmdline(argc, argv);
210
211 if (fps)
212 now = time(NULL);
213
214 /* Check to see if device is available
215 * exit(-1) is not;
216 */
217 fd = open(infn, O_RDWR);
218
219 if (fd < 0) {
220 perror("open");
221 exit(-1);
222 }
223
224 fmt.fmt.pix.width = height;
225 fmt.fmt.pix.height = width;
226 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
227
228 if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {
229 if (errno == EINVAL)
230 printf("Could not set format" " supported\n");
231 else
232 perror("VIDIOC_S_FMT");
233 quit_request(NULL, NULL);
234 }
235
236
237 if (HRT_USERSPACE == mode) {
238 int offset;
239
240 offset = ioctl(fd, IOC_HRT_GET_MAGIC_MMAP_OFFSET, 0);
241 if (offset < 0) {
242 perror("ioctl");
243 exit(1);
244 }
245
246 memory = mmap(NULL, AREA_SIZE, PROT_READ | PROT_WRITE,
247 MAP_SHARED, fd, offset);
248
249 if (MAP_FAILED == memory) {
250 perror("mmap");
251 exit(1);
252 }
253 }
254
255 outfn = strdup(DEFAULTFN);
256 if (!outfn) {
257 perror("mmap");
258 return 1;
259 }
260
261 gtk_init(&argc, &argv);
262 window = main_window();
263 gtk_widget_show(window);
264
265 gtk_main();
266
267 free(outfn);
268 free(infn);
269
270 //munmap(memory, AREA_SIZE);
271 close(fd);
272 return 0;
273 }
274
275 /* returns the gtk interface window */
276 GtkWidget *main_window()
277 {
278 GtkWidget *out = NULL;
279 GtkWidget *on = NULL;
280 GtkWidget *off = NULL;
281 GtkWidget *save = NULL;
282 GtkWidget *togglecolor = NULL;
283 GtkWidget *toggleinvert = NULL;
284 GtkWidget *quit = NULL;
285 GtkWidget *blank = NULL;
286
287 GtkWidget *mmap16kb = NULL;
288 GtkWidget *readb = NULL;
289 GtkWidget *directb = NULL;
290
291 GtkWidget *matrixb = NULL;
292 GtkWidget *controlwb = NULL;
293
294 GtkWidget *choutfn = NULL;
295
296 GtkWidget *tbar;
297 GtkWidget *main_table;
298
299 // initialize the window itself
300 out = gtk_window_new(GTK_WINDOW_TOPLEVEL);
301 gtk_window_set_title(GTK_WINDOW(out), PROGTITLE);
302 g_signal_connect(G_OBJECT(out), "destroy", G_CALLBACK
303 (quit_request), NULL);
304
305 main_table = gtk_table_new(3, 5, FALSE);
306 gtk_container_add(GTK_CONTAINER(out), main_table);
307
308 // initialize the toolbar
309 tbar = gtk_toolbar_new();
310
311
312 // initialize the on button
313 on = gtk_button_new_with_label("Main Screen Turn On!!");
314 g_signal_connect(G_OBJECT(on), "clicked", G_CALLBACK(msto), NULL);
315
316 // initialize the off button
317 off = gtk_button_new_with_label("Main Screen Turn Off!!");
318 g_signal_connect(G_OBJECT(off), "clicked",
319 G_CALLBACK(mstoff), NULL);
320
321 // save button
322 save = gtk_button_new_with_label("Save Frame");
323 g_signal_connect(G_OBJECT(save), "clicked",
324 G_CALLBACK(saveimage), NULL);
325
326 /* Added by Sean/ Atulya
327 * --- begin ---
328 * color button
329 */
330 togglecolor = gtk_button_new_with_label("Toggle Color");
331 g_signal_connect(G_OBJECT(togglecolor), "clicked",
332 G_CALLBACK(togglecolor_function), NULL);
333 toggleinvert = gtk_button_new_with_label("Toggle Invert");
334 g_signal_connect(G_OBJECT(toggleinvert), "clicked",
335 G_CALLBACK(toggleinvert_function), NULL);
336 /* --- begin ---*/
337
338 // quit button
339 quit = gtk_button_new_with_label("Quit");
340 g_signal_connect(G_OBJECT(quit), "clicked",
341 G_CALLBACK(quit_request), NULL);
342
343 // usermode driver button (mmap 16k)
344 mmap16kb = gtk_button_new_with_label("direct mmap 16k");
345 g_signal_connect(G_OBJECT(mmap16kb), "clicked",
346 G_CALLBACK(userspace), NULL);
347
348 // kernel mode driver (read) button
349 readb = gtk_button_new_with_label("read mode");
350 g_signal_connect(G_OBJECT(readb), "clicked",
351 G_CALLBACK(kernelspace), NULL);
352
353 // mmap'd image?
354 directb = gtk_button_new_with_label("streaming");
355 g_signal_connect(G_OBJECT(directb), "clicked",
356 G_CALLBACK(streaming), NULL);
357
358 // change outfn button
359 choutfn = gtk_button_new_with_label("Change Filename");
360 g_signal_connect(G_OBJECT(choutfn), "clicked",
361 G_CALLBACK(chfn), NULL);
362
363 // outfn label
364 fnlabel = gtk_label_new(outfn);
365
366 // blank space label
367 blank = gtk_label_new("\n\n\n\n\n");
368
369 // "Matrix mode" button
370 matrixb = gtk_button_new_with_label("Toggle Matrix Mode!");
371 g_signal_connect(G_OBJECT(matrixb), "clicked",
372 G_CALLBACK(matrixmode), NULL);
373
374 // control panel button
375 controlwb = gtk_button_new_with_label("Control Panel");
376 g_signal_connect(G_OBJECT(controlwb), "clicked",
377 G_CALLBACK(controlwtoggle), NULL);
378
379 // hook everything up
380 gtk_toolbar_append_widget(GTK_TOOLBAR(tbar), on, NULL, "On!");
381 gtk_toolbar_append_widget(GTK_TOOLBAR(tbar), off, NULL, "Off!");
382 gtk_toolbar_append_widget(GTK_TOOLBAR(tbar), save, NULL, "Save!");
383
384 /* Added by Sean/ Atulya
385 * --- begin ---
386 * toggle color button
387 */
388 gtk_toolbar_append_widget(GTK_TOOLBAR(tbar), togglecolor, NULL, "Greyscale");
389 gtk_toolbar_append_widget(GTK_TOOLBAR(tbar), toggleinvert, NULL, "Invert");
390 /* --- end --- */
391
392 gtk_toolbar_append_widget(GTK_TOOLBAR(tbar), quit, NULL, "Quit!");
393
394 gtk_table_attach_defaults(GTK_TABLE(main_table), tbar, 0, 3, 0, 1);
395
396 gtk_table_attach_defaults(GTK_TABLE(main_table), blank, 0, 3, 2,
397 3);
398
399
400 gtk_table_attach_defaults(GTK_TABLE(main_table), matrixb, 2, 3, 3,
401 4);
402 gtk_table_attach_defaults(GTK_TABLE(main_table), controlwb, 0, 2,
403 3, 4);
404
405 gtk_table_attach_defaults(GTK_TABLE(main_table),
406 mmap16kb, 0, 1, 4, 5);
407 gtk_table_attach_defaults(GTK_TABLE(main_table),
408 readb, 1, 2, 4, 5);
409 gtk_table_attach_defaults(GTK_TABLE(main_table),
410 directb, 2, 3, 4, 5);
411
412
413 gtk_table_attach_defaults(GTK_TABLE(main_table), choutfn,
414 0, 1, 1, 2);
415 gtk_table_attach_defaults(GTK_TABLE(main_table), fnlabel,
416 1, 2, 1, 2);
417
418 gtk_widget_show(on);
419 gtk_widget_show(off);
420 gtk_widget_show(save);
421 /* Added by Sean/ Atulya
422 * --- begin ---
423 * toggle color button
424 */
425 gtk_widget_show(togglecolor);
426 gtk_widget_show(toggleinvert);
427 /* --- end --- */
428 gtk_widget_show(quit);
429 gtk_widget_show(blank);
430 gtk_widget_show(choutfn);
431 gtk_widget_show(fnlabel);
432 gtk_widget_show(tbar);
433
434 gtk_widget_show(mmap16kb);
435 gtk_widget_show(readb);
436 gtk_widget_show(directb);
437 gtk_widget_show(matrixb);
438 gtk_widget_show(controlwb);
439
440 gtk_widget_show(main_table);
441
442 return out;
443 }
444
445 GtkWidget *contrastentry = NULL;
446 GtkWidget *brightnessentry = NULL;
447 GtkWidget *widthentry = NULL;
448 GtkWidget *heightentry = NULL;
449 GtkWidget *startxentry = NULL;
450 GtkWidget *startyentry = NULL;
451
452 GtkWidget *control_window()
453 {
454 GtkWidget *out = NULL;
455 GtkWidget *setcontrastb = NULL;
456 GtkWidget *setbrightnessb = NULL;
457 GtkWidget *setwidthb = NULL;
458 GtkWidget *setheightb = NULL;
459 GtkWidget *setstartxb = NULL;
460 GtkWidget *setstartyb = NULL;
461 GtkWidget *closeb = NULL;
462 GtkWidget *controltable;
463
464 out = gtk_window_new(GTK_WINDOW_TOPLEVEL);
465 controltable = gtk_table_new(2, 8, FALSE);
466 gtk_container_add(GTK_CONTAINER(out), controltable);
467
468 setcontrastb = gtk_button_new_with_label("Set Contrast!");
469 setbrightnessb = gtk_button_new_with_label("Set Brightness!");
470 setwidthb = gtk_button_new_with_label("Set Width!");
471 setheightb = gtk_button_new_with_label("Set Height!");
472 setstartxb = gtk_button_new_with_label("Set Upper Left X!");
473 setstartyb = gtk_button_new_with_label("Set Upper Left Y!");
474 closeb = gtk_button_new_with_label("Close This Window!");
475
476 contrastentry = gtk_entry_new();
477 brightnessentry = gtk_entry_new();
478 widthentry = gtk_entry_new();
479 heightentry = gtk_entry_new();
480 startxentry = gtk_entry_new();
481 startyentry = gtk_entry_new();
482
483 if (!isfile) {
484 char buf[16];
485
486 gtk_entry_set_text((GtkEntry *) brightnessentry,
487 defaultval(V4L2_CID_BRIGHTNESS));
488 gtk_entry_set_text((GtkEntry *) contrastentry,
489 defaultval(V4L2_CID_CONTRAST));
490
491 sprintf(buf, "%d", width);
492 gtk_entry_set_text((GtkEntry *) widthentry, buf);
493 sprintf(buf, "%d", height);
494 gtk_entry_set_text((GtkEntry *) heightentry, buf);
495 sprintf(buf, "%d", startx);
496 gtk_entry_set_text((GtkEntry *) startxentry, buf);
497 sprintf(buf, "%d", starty);
498 gtk_entry_set_text((GtkEntry *) startyentry, buf);
499 }
500
501 gtk_table_attach_defaults(GTK_TABLE(controltable),
502 contrastentry, 0, 1, 0, 1);
503 gtk_table_attach_defaults(GTK_TABLE(controltable),
504 brightnessentry, 0, 1, 1, 2);
505
506 gtk_table_attach_defaults(GTK_TABLE(controltable),
507 widthentry, 0, 1, 2, 3);
508 gtk_table_attach_defaults(GTK_TABLE(controltable),
509 heightentry, 0, 1, 3, 4);
510
511 gtk_table_attach_defaults(GTK_TABLE(controltable),
512 startxentry, 0, 1, 4, 5);
513 gtk_table_attach_defaults(GTK_TABLE(controltable),
514 startyentry, 0, 1, 5, 6);
515
516 gtk_table_attach_defaults(GTK_TABLE(controltable),
517 setcontrastb, 1, 2, 0, 1);
518 g_signal_connect(G_OBJECT(setcontrastb), "clicked", G_CALLBACK
519 (setcontrast), NULL);
520
521 gtk_table_attach_defaults(GTK_TABLE(controltable),
522 setbrightnessb, 1, 2, 1, 2);
523 g_signal_connect(G_OBJECT(setbrightnessb), "clicked", G_CALLBACK
524 (setbrightness), NULL);
525
526 gtk_table_attach_defaults(GTK_TABLE(controltable),
527 setwidthb, 1, 2, 2, 3);
528 g_signal_connect(G_OBJECT(setwidthb), "clicked", G_CALLBACK
529 (setwidth), NULL);
530 gtk_table_attach_defaults(GTK_TABLE(controltable),
531 setheightb, 1, 2, 3, 4);
532 g_signal_connect(G_OBJECT(setheightb), "clicked", G_CALLBACK
533 (setheight), NULL);
534
535 gtk_table_attach_defaults(GTK_TABLE(controltable),
536 setstartxb, 1, 2, 4, 5);
537 g_signal_connect(G_OBJECT(setstartxb), "clicked", G_CALLBACK
538 (setstartx), NULL);
539 gtk_table_attach_defaults(GTK_TABLE(controltable),
540 setstartyb, 1, 2, 5, 6);
541 g_signal_connect(G_OBJECT(setstartyb), "clicked", G_CALLBACK
542 (setstarty), NULL);
543
544 g_signal_connect(G_OBJECT(closeb), "clicked", G_CALLBACK
545 (controlwtoggle), NULL);
546 gtk_table_attach_defaults(GTK_TABLE(controltable),
547 closeb, 0, 2, 7, 8);
548
549 g_signal_connect(G_OBJECT(out), "destroy", G_CALLBACK
550 (controlwtoggle), NULL);
551
552 gtk_widget_show(setcontrastb);
553 gtk_widget_show(setbrightnessb);
554 gtk_widget_show(setwidthb);
555 gtk_widget_show(setheightb);
556 gtk_widget_show(setstartxb);
557 gtk_widget_show(setstartyb);
558 gtk_widget_show(closeb);
559 gtk_widget_show(contrastentry);
560 gtk_widget_show(brightnessentry);
561 gtk_widget_show(widthentry);
562 gtk_widget_show(heightentry);
563 gtk_widget_show(startxentry);
564 gtk_widget_show(startyentry);
565 gtk_widget_show(controltable);
566
567 return out;
568 }
569
570 void setwidth(void)
571 {
572 struct v4l2_crop win;
573
574 if (isfile)
575 return;
576
577 width = atoi(gtk_entry_get_text((GtkEntry *) widthentry));
578 if (ioctl(fd, VIDIOC_G_CROP, &win) < 0) {
579 perror("ioctl");
580 }
581 win.c.width = width;
582 if (ioctl(fd, VIDIOC_S_CROP, &win) < 0) {
583 perror("ioctl");
584 }
585 mstoff();
586 msto();
587 }
588
589 void setstartx(void)
590 {
591 struct v4l2_crop win;
592
593 if (isfile)
594 return;
595
596 startx = atoi(gtk_entry_get_text((GtkEntry *) startxentry));
597 if (ioctl(fd, VIDIOC_G_CROP, &win) < 0) {
598 perror("ioctl");
599 }
600 win.c.left = startx;
601 if (ioctl(fd, VIDIOC_S_CROP, &win) < 0) {
602 perror("ioctl");
603 }
604
605 mstoff();
606 msto();
607 }
608
609 void setstarty(void)
610 {
611 struct v4l2_crop win;
612
613 if (isfile)
614 return;
615
616 starty = atoi(gtk_entry_get_text((GtkEntry *) startyentry));
617 if (ioctl(fd, VIDIOC_G_CROP, &win) < 0) {
618 perror("ioctl");
619 }
620 win.c.top = starty;
621 if (ioctl(fd, VIDIOC_S_CROP, &win) < 0) {
622 perror("ioctl");
623 }
624
625 mstoff();
626 msto();
627 }
628
629 void setheight(void)
630 {
631 struct v4l2_crop win;
632
633 if (isfile)
634 return;
635
636 height = atoi(gtk_entry_get_text((GtkEntry *) heightentry));
637 if (ioctl(fd, VIDIOC_G_CROP, &win) < 0) {
638 perror("ioctl");
639 }
640 win.c.height = height;
641 if (ioctl(fd, VIDIOC_S_CROP, &win) < 0) {
642 perror("ioctl");
643 }
644
645 mstoff();
646 msto();
647 }
648
649 void setbrightness(void)
650 {
651 if (isfile)
652 return;
653
654 doioctl(V4L2_CID_BRIGHTNESS,
655 atoi(gtk_entry_get_text((GtkEntry *) brightnessentry)));
656 }
657
658 void setcontrast(void)
659 {
660 if (isfile)
661 return;
662
663 doioctl(V4L2_CID_CONTRAST,
664 atoi(gtk_entry_get_text((GtkEntry *) contrastentry)));
665 }
666
667 /* main screen turn on!! */
668 void msto(void)
669 {
670 if (screen)
671 return;
672
673 fprintf(stderr, "%d %d %d %d\n", width, height, startx, starty);
674
675 /* COLOR/ GREYSCALE */
676 if (tgcolor == 1)
677 screen = SDL_SetVideoMode(width, height, 16,
678 SDL_HWSURFACE);
679 else
680 screen = SDL_SetVideoMode(width, height, 8,
681 SDL_HWSURFACE);
682
683 if (screen == NULL) {
684 fprintf(stderr, "Couldn't set %dx%d video mode: %s\n",
685 width, height, SDL_GetError());
686 exit(2);
687 }
688
689 SDL_SetColors(screen, colors, 0, 256);
690
691 gtk_idle_add(updateloop, NULL);
692 }
693
694 /* main screen turn off!! */
695 void mstoff(void)
696 {
697 if (!screen)
698 return;
699
700 SDL_Surface *oldscreen = screen;
701
702 SDL_LockSurface(screen);
703
704 screen = NULL;
705 SDL_FreeSurface(oldscreen);
706 SDL_UnlockSurface(oldscreen);
707 SDL_Quit();
708 }
709
710 /* save image to file!! */
711 void saveimage(void)
712 {
713 if (!screen || !outfn)
714 return;
715
716 SDL_SaveBMP(screen, outfn);
717 }
718
719 void togglecolor_function(void)
720 {
721 //tgcolor = !tgcolor;
722 if (bytesperpixel == 1) {
723 tgcolor = 1;
724 bytesperpixel = 2;
725 }
726 else {
727 tgcolor = 0;
728 bytesperpixel = 1;
729 }
730
731 printf("togglecolor_function: tgcolor (%d), bytesperpixel\n", tgcolor, bytesperpixel);
732 mstoff();
733 msto();
734
735 }
736
737 void toggleinvert_function(void)
738 {
739 if (ioctl(fd, IOC_HRT_UPSIDE_DOWN) == -1) {
740 perror("ioctl");
741 printf("toggleinvert_function: Could not invert image\n");
742 return;
743 }
744
745 tginvert = !tginvert;
746 printf("toggleinvert_function: tginvert (%d)\n", tginvert);
747 //toff();
748 //to();
749
750 }
751
752 /* destroy the file choice window */
753 void destroy_filew(GtkWidget * button, gpointer data)
754 {
755 if (!filew)
756 return;
757
758 gtk_widget_destroy(filew);
759 filew = NULL;
760 return;
761 }
762
763 /* change the file name to which we plan on saving */
764 void chfn(GtkWidget * button, gpointer data)
765 {
766 filew = gtk_file_selection_new("Choose path!!");
767
768 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filew)->ok_button),
769 "clicked", G_CALLBACK(store_outfn),
770 (gpointer) filew);
771
772 g_signal_connect(G_OBJECT
773 (GTK_FILE_SELECTION(filew)->cancel_button),
774 "clicked", G_CALLBACK(destroy_filew), NULL);
775
776 gtk_file_selection_set_filename(GTK_FILE_SELECTION(filew),
777 "foo.bmp");
778 gtk_widget_show(filew);
779
780 //gtk_main_quit();
781 }
782
783 /* done choosing a new filename -- do silly string memory management and be
784 * ready to save when the user requests it */
785 void store_outfn(GtkWidget * button, gpointer data)
786 {
787 const char *selection;
788
789 selection =
790 gtk_file_selection_get_filename(GTK_FILE_SELECTION(filew));
791
792 free(outfn);
793 outfn = strdup(selection);
794 gtk_label_set_text((GtkLabel *) fnlabel, outfn);
795 destroy_filew(NULL, NULL);
796 }
797
798 /* fire up SDL -- get ready to display that window */
799 void sdl_init(void)
800 {
801 int i;
802
803 if (SDL_Init(SDL_INIT_VIDEO) < 0) {
804 fprintf(stderr, "Couldn't initialize SDL: %s\n",
805 SDL_GetError());
806 quit_request(NULL, NULL);
807 }
808
809 SDL_WM_SetCaption(PROGTITLE " (video window)", NULL);
810
811 for (i = 0; i < 256; i++) {
812 colors[i].r = i;
813 colors[i].g = i;
814 colors[i].b = i;
815 }
816 }
817
818 /* pretty obvious -- parse command line options */
819 void parsecmdline(int argc, char *argv[])
820 {
821 int c;
822
823 if (argc < 2) {
824 usage();
825 }
826
827 while (-1 != (c = getopt(argc, argv, "hfmrs"))) {
828 switch (c) {
829 case 'h':
830 usage();
831 break;
832 case 'f':
833 isfile = 1;
834 break;
835 case 'm':
836 userspace();
837 break;
838 case 's':
839 fps = 1;
840 break;
841 case 'r':
842 readonly = 1;
843 break;
844 }
845 }
846 fprintf(stderr, "reading from %s: %s\n",
847 isfile ? "file" : "device", argv[argc - 1]);
848 infn = strdup(argv[argc - 1]);
849 }
850
851 /* duh. */
852 void usage(void)
853 {
854 printf("hrtdemo usage!!\n");
855 printf("hrtdemo [options] <path>\n");
856 printf("viable options:\n");
857 printf("-h\tprint this message\n"
858 "-f\tspecify reading a file rather than a device --\n"
859 "\tonly has an effect in read/kernelspace mode\n"
860 "-m\tspecify mmap/userspace mode\n"
861 "-s\tspecify frames per Second count mode\n"
862 "-r\treadonly mode -- don't mmap\n");
863 exit(0);
864 }
865
866 /* called by the "read" button -- rely on Brett's driver and set the mode
867 * to start doing read() system calls! */
868 void kernelspace(void)
869 {
870 if (HRT_STREAMING == mode) {
871 stopstreaming();
872 } else if (HRT_USERSPACE == mode) {
873 memory[PIXELSMART_CONTROL_REG] = PIXELSMART_LIVE_CMD;
874 }
875
876 mode = HRT_KERNELSPACE;
877 }
878
879 /* use the userspace driver mode -- use the mmap'd I/O memory */
880 void userspace(void)
881 {
882 if (HRT_STREAMING == mode) {
883 stopstreaming();
884 }
885
886 if (!readonly) {
887 mode = HRT_USERSPACE;
888 }
889 }
890
891 void streaming(void)
892 {
893 if (isfile)
894 return;
895
896 if (mode != HRT_STREAMING) {
897 if (initstreaming())
898 mode = HRT_STREAMING;
899 else
900 printf ("streaming(): initstreaming() failed.\n");
901 }
902 else {
903 printf ("streaming(): Already in streaming mode.\n");
904 }
905 }
906
907 /* use the silly userspace driver mode -- use the mmap'd I/O memory */
908 void matrixmode(void)
909 {
910 matrix = !matrix;
911 }
912
913 /* toggles existence of the Control Panel Window Thing */
914 void controlwtoggle(void)
915 {
916 if (controlw) {
917 gtk_widget_destroy(controlw);
918 controlw = NULL;
919 } else {
920 controlw = control_window();
921 gtk_widget_show(controlw);
922 }
923 }
924
925 /*
926 * contains code from http://bytesex.org/v4l/spec/r5836.html
927 */
928 void doioctl(int whichioctl, int newval)
929 {
930 struct v4l2_queryctrl queryctrl;
931 struct v4l2_control control;
932
933 if (isfile)
934 return;
935
936 // queryctrl.id = V4L2_CID_BRIGHTNESS;
937 queryctrl.id = whichioctl;
938
939 if (-1 == ioctl(fd, VIDIOC_G_CTRL, &queryctrl)) {
940 if (errno != EINVAL) {
941 perror("invalid ioctl!!");
942 quit_request(NULL, NULL);
943 } else {
944 printf("that ioctl is not supported\n");
945 }
946 } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
947 printf("V4L2_CID_BRIGHTNESS is not supported\n");
948 } else {
949 control.id = whichioctl;
950 // control.value = queryctrl.default_value;
951 control.value = newval;
952
953 if (-1 == ioctl(fd, VIDIOC_S_CTRL, &control)) {
954 perror("VIDIOC_S_CTRL");
955 quit_request(NULL, NULL);
956 }
957 }
958 }
959
960 char *defaultval(int whichioctl)
961 {
962 struct v4l2_queryctrl queryctrl;
963 char *out;
964 int def;
965
966 if (isfile)
967 return;
968
969 queryctrl.id = whichioctl;
970
971 if (-1 == ioctl(fd, VIDIOC_G_CTRL, &queryctrl)) {
972 if (errno != EINVAL) {
973 perror("invalid ioctl!!");
974 quit_request(NULL, NULL);
975 } else {
976 printf("that ioctl is not supported\n");
977 }
978 return NULL;
979 } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
980 printf("V4L2_CID_BRIGHTNESS is not supported\n");
981 return NULL;
982 }
983
984 out = malloc(4);
985
986 if (!out) {
987 fprintf(stderr, "malloc error: couldn't get memory!\n");
988 return NULL;
989 }
990
991 out[3] = '\0';
992 snprintf(out, 4, "%d", queryctrl.default_value);
993
994 return out;
995 }
996
997 /*
998 * Code for initstreaming and stopstreaming comes mostly from the V4L2
999 * spec, particularly from this page:
1000 * http://bytesex.org/v4l/spec/x3036.html
1001 */
1002 int initstreaming(void)
1003 {
1004 unsigned int i;
1005 struct v4l2_format fmt;
1006 int result = 1;
1007
1008 reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1009 reqbuf.memory = V4L2_MEMORY_MMAP;
1010 reqbuf.count = 1;
1011
1012 fmt.fmt.pix.width = height;
1013 fmt.fmt.pix.height = width;
1014 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1015
1016 if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {
1017 if (errno == EINVAL)
1018 printf("Could not set format" " supported\n");
1019 else {
1020 perror("VIDIOC_S_FMT");
1021 result = 0;
1022 }
1023 exit(EXIT_FAILURE);
1024 }
1025
1026 if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) == -1) {
1027 if (errno == EINVAL)
1028 printf("Video capturing or mmap-streaming is not"
1029 " supported\n");
1030 else {
1031 perror("VIDIOC_REQBUFS");
1032 result = 0;
1033 }
1034 exit(EXIT_FAILURE);
1035 }
1036
1037 if (!reqbuf.count) {
1038 printf("Not enough buffer memory\n");
1039 result = 0;
1040 exit(EXIT_FAILURE);
1041 }
1042
1043 buffers = calloc(reqbuf.count, sizeof(*buffers));
1044 assert(buffers != NULL);
1045
1046 for (i = 0; i < reqbuf.count; i++) {
1047 struct v4l2_buffer buffer;
1048
1049 buffer.type = reqbuf.type;
1050 buffer.index = i;
1051
1052 if (ioctl(fd, VIDIOC_QUERYBUF, &buffer) == -1) {
1053 perror("VIDIOC_QUERYBUF");
1054 exit(EXIT_FAILURE);
1055 }
1056
1057 buffers[i].length = buffer.length; /* remember for munmap() */
1058
1059 fprintf(stderr, "mmap(NULL, ..., %d, %d)\n", fd,
1060 buffer.m.offset);
1061
1062 buffers[i].start = mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, /* required */
1063 MAP_SHARED, /* recommended */
1064 fd, buffer.m.offset);
1065
1066 fprintf(stderr, "mmap returned %x\n", buffers[i].start);
1067
1068 if (buffers[i].start == MAP_FAILED) {
1069 /* You may need to free and unmap the so far
1070 mapped buffers here. */
1071 perror("mmap");
1072 exit(EXIT_FAILURE);
1073 }
1074
1075 if (ioctl(fd, VIDIOC_QBUF, &buffer) == -1) {
1076 perror("VIDIOC_QBUF");
1077 exit(EXIT_FAILURE);
1078 }
1079
1080 }
1081
1082 /* Set video stream capture on */
1083 i = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1084 if (ioctl(fd, VIDIOC_STREAMON, &i) == -1) {
1085 perror("VIDIOC_STREAMON");
1086 exit(EXIT_FAILURE);
1087 }
1088
1089 return result;
1090 }
1091
1092 /* Clean stuff up, j0. */
1093 void stopstreaming(void)
1094 {
1095 int i;
1096
1097 /* Set video stream capture off */
1098 i = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1099 if (ioctl(fd, VIDIOC_STREAMOFF, &i) == -1) {
1100 perror("VIDIOC_STREAMOFF");
1101 exit(EXIT_FAILURE);
1102 }
1103
1104 for (i = 0; i < reqbuf.count; i++) {
1105 perror("buffer unmapped\n");
1106 if (munmap(buffers[i].start, buffers[i].length) < 0) {
1107 perror("munmap");
1108 exit(EXIT_FAILURE);
1109 }
1110 }
1111 }
1112
|
This page was automatically generated by the
LXR engine.
|