• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

examples/example7/OverlayWidget.cpp

00001 #include "OverlayWidget.h"
00002 #include <QEvent>
00003 #include <stdlib.h>
00004 #include <stdio.h>
00005 #include <unistd.h>
00006 
00007 OverlayWidget::OverlayWidget(QWidget *par) : QWidget(par)  {
00008     /* Make QT do the work of keeping the overlay the magic color  */
00009     QWidget::setBackgroundRole(QPalette::Window); 
00010     QWidget::setAutoFillBackground(true); 
00011     QPalette overlayPalette = QWidget::palette(); 
00012     overlayPalette.setColor 
00013         (QPalette::Window,  
00014          colorKey()); 
00015     QWidget::setPalette(overlayPalette); 
00016 
00017     // Open the overlay device
00018     overlay_fd = open("/dev/fb1", O_RDWR);
00019 
00020     if (overlay_fd == -1) {
00021         perror("open");
00022     }
00023 
00024     // Get the current overlay and plane settings
00025     if (ioctl(overlay_fd, FBIOGET_VSCREENINFO, &overlay_info)) {
00026         perror("FBIO_VSCREENINFO");
00027     }
00028     if (ioctl(overlay_fd, OMAPFB_QUERY_PLANE, &plane_info)) {
00029         perror("OMAPFB_QUERY_PLANE");
00030     }
00031 
00032     // Disable the plane so we can allocate memory for it. 
00033     plane_info.enabled = 0;
00034     plane_info.pos_x = 0; 
00035     plane_info.pos_y = 0; 
00036     plane_info.out_width = 640;
00037     plane_info.out_height = 480;
00038     if (ioctl(overlay_fd, OMAPFB_SETUP_PLANE, &plane_info)) {
00039         perror("OMAPFB_SETUP_PLANE");
00040     }
00041 
00042     // Allocate the memory
00043     mem_info.size = 640*480*2;
00044     mem_info.type = 0;
00045     if (ioctl(overlay_fd, OMAPFB_SETUP_MEM, &mem_info)) {
00046         perror("OMAPFB_SETUP_MEM");
00047     }
00048 
00049     // mmap it into an FCam image
00050     void *ptr = mmap(NULL, mem_info.size, PROT_WRITE, MAP_SHARED, overlay_fd, 0);
00051     if (ptr == MAP_FAILED) {
00052         perror("mmap");
00053     }
00054     framebuffer_ = FCam::Image(640, 480, FCam::UYVY, (unsigned char *)ptr);
00055 
00056     // Clear the memory in case there was something hanging around from an earlier invocation
00057     memset(ptr, 128, 640*480*2);
00058 
00059     // Set the overlay properties
00060     overlay_info.xres = 640;
00061     overlay_info.yres = 480;
00062     overlay_info.xres_virtual = 640;
00063     overlay_info.yres_virtual = 480;
00064     overlay_info.xoffset = 0;
00065     overlay_info.yoffset = 0;
00066     overlay_info.nonstd = OMAPFB_COLOR_YUV422;    
00067     if (ioctl(overlay_fd, FBIOPUT_VSCREENINFO, &overlay_info)) {
00068         perror("FBIOPUT_VSCREENINFO");
00069     }
00070 
00071     // Set up the color key
00072     struct omapfb_color_key color_key;
00073     color_key.key_type = OMAPFB_COLOR_KEY_GFX_DST;
00074     QColor key = colorKey();
00075     color_key.trans_key = ((key.red() >> 3) << 11) | ((key.green() >> 2) << 5) | ((key.blue() >> 3));
00076     if (ioctl(overlay_fd, OMAPFB_SET_COLOR_KEY, &color_key)) {
00077         perror("OMAPFB_SET_COLOR_KEY");
00078     }
00079 
00080     filterInstalled = false;
00081 }
00082 
00083 bool OverlayWidget::eventFilter(QObject *, QEvent *event) {
00084     if (event->type() == QEvent::Move ||
00085         event->type() == QEvent::Resize ||
00086         event->type() == QEvent::Show) {
00087         enable();
00088     } else if (event->type() == QEvent::Hide) {
00089         disable();
00090     }
00091 
00092     // We don't capture this event, it should be propagated as normal
00093     return false;
00094 }
00095 
00096 void OverlayWidget::showEvent(QShowEvent *) {
00097     enable();
00098 }
00099 
00100 void OverlayWidget::hideEvent(QHideEvent *) {
00101     disable();
00102 }
00103 
00104 void OverlayWidget::resizeEvent(QResizeEvent *) {
00105     enable();
00106 }
00107 
00108 void OverlayWidget::moveEvent(QMoveEvent *) {
00109     enable();
00110 }
00111 
00112 
00113 OverlayWidget::~OverlayWidget() {
00114     disable();
00115     ::close(overlay_fd);
00116 }
00117 
00118 void OverlayWidget::enable() {
00119     // Shift the plane according to where the widget is, but keep it
00120     // at 640x480
00121 
00122     QPoint global = mapToGlobal(QPoint(0, 0));
00123 
00124     // round to even X
00125     global.setX(global.x()/2);
00126     global.setX(global.x()*2);
00127 
00128     int xoff = global.x() > 0 ? global.x() : 0;
00129     int yoff = global.y() > 0 ? global.y() : 0;
00130     int xcrop = global.x() < 0 ? -global.x() : 0;
00131     int ycrop = global.y() < 0 ? -global.y() : 0;
00132 
00133     if (xcrop > 640 || ycrop > 480) {
00134         disable();
00135         return;
00136     }
00137 
00138     // Set the size and position on screen
00139     plane_info.enabled = 1;
00140     plane_info.pos_x = xoff;
00141     plane_info.pos_y = yoff;
00142     plane_info.out_width = 640 - xcrop;
00143     plane_info.out_height = 480 - ycrop;
00144 
00145     if (ioctl(overlay_fd, OMAPFB_SETUP_PLANE, &plane_info)) {
00146         perror("OMAPFB_SETUP_PLANE");
00147     }
00148 
00149     // The image is always 640x480
00150     overlay_info.xres_virtual = 640;
00151     overlay_info.yres_virtual = 480;
00152     // Set the portion of it that's visible on screen
00153     overlay_info.xres = plane_info.out_width;
00154     overlay_info.yres = plane_info.out_height;
00155     overlay_info.xoffset = xcrop;
00156     overlay_info.yoffset = ycrop;
00157     overlay_info.nonstd = OMAPFB_COLOR_YUV422;    
00158     if (ioctl(overlay_fd, FBIOPUT_VSCREENINFO, &overlay_info)) {
00159         perror("FBIOPUT_VSCREENINFO");
00160     }
00161 
00162     if (!filterInstalled) {
00163         // if anything moves above me, we need to know about it to update the overlay
00164         for (QObject *obj = parent(); obj; obj = obj->parent()) {
00165             obj->installEventFilter(this);
00166         }
00167         filterInstalled = true;
00168     }
00169 }
00170 
00171 void OverlayWidget::disable() {
00172     plane_info.enabled = 0;
00173     if (ioctl(overlay_fd, OMAPFB_SETUP_PLANE, &plane_info)) {
00174         perror("OMAPFB_SETUP_PLANE");
00175     }
00176 }
00177 
00178 FCam::Image OverlayWidget::framebuffer() {
00179     return framebuffer_;
00180 }

Generated on Fri Sep 24 2010 15:52:59 for FCam by  doxygen 1.7.1