Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 #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.