gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog gui/fb.cpp gui/fbsup.h


From: Udo Giacomozzi
Subject: [Gnash-commit] gnash ChangeLog gui/fb.cpp gui/fbsup.h
Date: Tue, 13 Feb 2007 10:25:17 +0000

CVSROOT:        /cvsroot/gnash
Module name:    gnash
Changes by:     Udo Giacomozzi <udog>   07/02/13 10:25:17

Modified files:
        .              : ChangeLog 
        gui            : fb.cpp fbsup.h 

Log message:
        Initial support for mice

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2336&r2=1.2337
http://cvs.savannah.gnu.org/viewcvs/gnash/gui/fb.cpp?cvsroot=gnash&r1=1.23&r2=1.24
http://cvs.savannah.gnu.org/viewcvs/gnash/gui/fbsup.h?cvsroot=gnash&r1=1.14&r2=1.15

Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/gnash/gnash/ChangeLog,v
retrieving revision 1.2336
retrieving revision 1.2337
diff -u -b -r1.2336 -r1.2337
--- ChangeLog   13 Feb 2007 09:57:37 -0000      1.2336
+++ ChangeLog   13 Feb 2007 10:25:16 -0000      1.2337
@@ -9,6 +9,7 @@
 
        * gui/gui.cpp: Make full redraw on ENABLE_REGION_UPDATES_DEBUGGING 
          configurable
+       * gui/fb.cpp, gui/fbsup.h: Initial support for mouse
  
 2007-02-13  Rob Savoye  <address@hidden>
 

Index: gui/fb.cpp
===================================================================
RCS file: /cvsroot/gnash/gnash/gui/fb.cpp,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -b -r1.23 -r1.24
--- gui/fb.cpp  10 Feb 2007 17:19:23 -0000      1.23
+++ gui/fb.cpp  13 Feb 2007 10:25:16 -0000      1.24
@@ -14,9 +14,6 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-//
-//
-
 // 
-----------------------------------------------------------------------------
    
 
@@ -110,6 +107,8 @@
        buffer  = NULL;
        #endif
        
+  input_fd=-1;
+       
        signal(SIGINT, terminate_signal);
        signal(SIGTERM, terminate_signal);
 }
@@ -123,6 +122,8 @@
                close(fd);
        }
 
+       close(input_fd);
+
   #ifdef DOUBLE_BUFFER
        if (buffer) {
                log_msg("Free'ing offscreen buffer\n");
@@ -173,6 +174,13 @@
 
 bool FBGui::init(int /*argc*/, char *** /*argv*/)
 {
+
+  // Initialize mouse (don't abort if no mouse found)
+  if (!init_mouse()) {
+    // just report to the user, keep on going...
+    log_msg("You won't have any input device, sorry.");
+  }
+
   // Open the framebuffer device
   fd = open("/dev/fb0", O_RDWR);
   if (fd<0) {
@@ -328,6 +336,8 @@
                
                  usleep(1); // task switch
                  
+                 check_mouse();
+                 
       struct timeval tv;
       if (!gettimeofday(&tv, NULL))
         timer = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
@@ -360,6 +370,7 @@
   // copy each row
   const int minx = _drawbounds.getMinX();
   const int maxy = _drawbounds.getMaxY();
+
   for (int y=_drawbounds.getMinY(); y<maxy; ++y) {
   
     const unsigned int pixel_index = y * scanline_size + minx*pixel_size;
@@ -420,7 +431,8 @@
   return y;
 }
 
-void FBGui::setInvalidatedRegion(const rect& bounds) {
+void FBGui::setInvalidatedRegion(const rect& bounds) 
+{
 
 #ifdef DOUBLE_BUFFER
   
@@ -438,7 +450,8 @@
   
 }  // setInvalidatedRegion
 
-void FBGui::disable_terminal() {
+void FBGui::disable_terminal() 
+{
   /*
   --> doesn't work as this hides the cursor of the *current* terminal (which
   --> doesn't have to be the fb one). Maybe just detach from terminal?
@@ -446,10 +459,137 @@
   fflush(stdout);*/
 }
 
-void FBGui::enable_terminal() {
+void FBGui::enable_terminal() 
+{
   /*printf("\033[?25h");  
   fflush(stdout);*/
 }
 
+bool FBGui::mouse_command(unsigned char cmd, unsigned char *buf, int count) {
+  int n;
+  
+  write(input_fd, &cmd, 1);
+  
+  while (count>0) {
+    usleep(250*1000); // 250 ms inter-char timeout (simple method)
+    // TODO: use select() instead
+    
+    n = read(input_fd, buf, count);
+    if (n<=0) return false;
+    count-=n;
+    buf+=n;
+  }
+  return true;
+  
+} //command()
+
+bool FBGui::init_mouse() 
+{
+
+  // see http://www.computer-engineering.org/ps2mouse/
+  
+
+  // Try to open mouse device, be error tolerant (FD is kept open all the time)
+  // TODO: Make device name configurable
+  input_fd = open("/dev/input/mice", O_RDWR);
+  
+  if (input_fd<0) {
+    log_msg("Could not open /dev/input/mice: %s", strerror(errno));    
+    return false;
+  }
+  
+  unsigned char buf[10], byte;
+
+  if (fcntl(input_fd, F_SETFL, fcntl(input_fd, F_GETFL) | O_NONBLOCK)<0) {
+    log_error("Could not set non-blocking mode for mouse device: %s", 
strerror(errno));
+    close(input_fd);
+    input_fd=-1;
+    return false; 
+  }
+  
+  // Clear input buffer
+  while ( read(input_fd, buf, sizeof buf) > 0 ) { }
+  
+  // Reset mouse
+  if ((!mouse_command(0xFF, buf, 3)) || (buf[0]!=0xFA)) {
+    log_msg("Mouse reset failed");
+    close(input_fd);
+    input_fd=-1;
+    return false; 
+  }
+  
+  // Enable mouse data reporting
+  if ((!mouse_command(0xF4, &byte, 1)) || (byte!=0xFA)) {
+    log_msg("Could not activate Data Reporting mode for mouse");
+    close(input_fd);
+    input_fd=-1;
+    return false; 
+  }
+  
+  
+  log_msg("Mouse enabled.");
+      
+  mouse_x = 0;
+  mouse_y = 0;
+  mouse_btn = 0;
+  
+  return true;
+}
+
+void FBGui::check_mouse() 
+{
+  if (input_fd<0) return;   // no mouse available
+  
+  unsigned char buf[3];
+  int i;
+  int xmove, ymove, btn, btn_changed;
+  
+  while ( read(input_fd, buf, 1) == 1 ) {
+  
+    if (buf[0] & 8 == 0) continue; // bit 3 must be high for the first byte
+    
+    if (read(input_fd, buf+1, 2) != 2) continue; // expect total 3 bytes
+    
+    // TODO: The method above can loose data. Use a permanent buffer instead!
+    
+    xmove = buf[1];
+    ymove = buf[2];
+    btn = buf[0] & 1;
+    
+    if (buf[0] & 0x10) xmove = -(256-xmove);
+    if (buf[0] & 0x20) ymove = -(256-ymove);
+    
+    ymove *= -1; // vertical movement is upside-down
+    
+    //log_msg("x/y %d/%d btn %d", xmove, ymove, btn);
+
+    // movement    
+    mouse_x += xmove;
+    mouse_y += ymove;
+    
+    if (mouse_x<0) mouse_x=0;
+    if (mouse_y<0) mouse_y=0;
+    if (mouse_x>m_stage_width) mouse_x=m_stage_width;
+    if (mouse_y>m_stage_height) mouse_y=m_stage_height;
+    
+    //log_msg("mouse @ %d / %d, btn %d", mouse_x, mouse_y, mouse_btn);
+    
+    float xscale = getXScale();
+    float yscale = getYScale();
+    notify_mouse_moved(int(mouse_x / xscale), int(mouse_y / yscale));
+    
+    // button
+    if (btn != mouse_btn) {
+      mouse_btn = btn;
+      
+      notify_mouse_clicked(btn, 1);  // mark=??
+      //log_msg("mouse click! %d", btn);
+    }    
+
+  
+  }
+  
+}
+
 // end of namespace gnash
 }

Index: gui/fbsup.h
===================================================================
RCS file: /cvsroot/gnash/gnash/gui/fbsup.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- gui/fbsup.h 10 Feb 2007 17:01:28 -0000      1.14
+++ gui/fbsup.h 13 Feb 2007 10:25:16 -0000      1.15
@@ -38,11 +38,27 @@
 
 
 /// A Framebuffer-based GUI for Gnash.
-//
-/// It currently requires the AGG backend to render the frames.
-/// It operates in fullscreen mode and uses the screen mode 
-/// currently active.
+/// ----------------------------------
+///
+/// This is a simple "GUI" that works with any framebuffer device (/dev/fb0).
+/// No window system is required, it will run straigt from a console. 
 ///
+/// The current version requires that your system boots in graphics mode (that
+/// is, with a framebuffer driver - like vesafb - and most probably the 
+/// virtual console enabled). Which graphics mode Gnash runs in depends on the 
+/// mode your machine boots in and can be choosen using the kernel command 
line.
+/// With other words: Gnash does not change the graphics mode.
+/// Refer to the framebuffer docs for more information.
+///
+/// The fb gui now also supports pointing devices like mice or touchscreens, 
but
+/// it is not required. It works with /dev/input/mice so any PS/2 compatible 
+/// mouse should do. Your kernel can emulate the "mice" device for other 
devices
+/// (like touchscreens and tablets) so this method is very flexible.
+///
+/// There is currently no visible mouse pointer built in, which is fine for 
+/// touchscreens but will make it difficult for standard mice. This will be 
+/// fixed in near time.
+//
 /// Supported graphics modes:
 ///
 ///   Resolution: any
@@ -52,13 +68,15 @@
 ///     15 bit: R5/G5/B5
 ///     16 bit: R5/G6/B5
 ///     24 bit: R8/G8/B8, B8/G8/R8
-///     32 bit: none yet!
+///     32 bit: R8/G8/B8/A8, B8/G8/R8/A8
 ///
 ///
 /// Supported input devices:
 ///
-///   None, yet. But may be added easily.    
-///
+///   any PS/2 compatible mouse (may be emulated by the kernel) talking 
+///   to /dev/input/mice
+
+
 class FBGui : public Gui
 {
        private:
@@ -73,6 +91,9 @@
     int m_stage_width;
     int m_stage_height;
 
+       int input_fd; /// file descriptor for /dev/input/mice
+       int mouse_x, mouse_y, mouse_btn;
+
     struct fb_var_screeninfo var_screeninfo;
        struct fb_fix_screeninfo fix_screeninfo;
 
@@ -90,6 +111,15 @@
        /// reverts disable_terminal() changes
        void enable_terminal();
        
+       /// Sends a command to the mouse and waits for the response
+       bool mouse_command(unsigned char cmd, unsigned char *buf, int count);
+       
+       /// Initializes mouse routines
+       bool init_mouse();
+       
+       /// Checks for any mouse activity
+       void check_mouse();
+       
        int valid_x(int x);
        int valid_y(int y);
        




reply via email to

[Prev in Thread] Current Thread [Next in Thread]