changeset 1218:e0c748e0a46b

Add region masks, cursor in demo - from Chris Garry
author gthomas
date Tue, 16 Sep 2003 14:15:12 +0000
parents 0e1c2770aa9d
children f2d548ecdbde
files packages/net/vnc_server/current/ChangeLog packages/net/vnc_server/current/doc/vnc-server.html packages/net/vnc_server/current/include/vnc-server.h packages/net/vnc_server/current/src/vnc-server.c packages/net/vnc_server/current/tests/vnc-test.c
diffstat 5 files changed, 220 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/packages/net/vnc_server/current/ChangeLog
+++ b/packages/net/vnc_server/current/ChangeLog
@@ -1,3 +1,13 @@
+2003-09-16  Chris Garry  <cgarry@sweeneydesign.co.uk>
+
+    * doc/vnc-server.html:
+    * src/vnc-server.c:
+    * include/vnc-server.h:
+    Added new function VncCopyBuffer2RectMask().
+
+    * tests/vnc-test.c:
+    Modifed to include a cursor.
+
 2003-09-02  Chris Garry  <cgarry@sweeneydesign.co.uk>
 
     * tests/vnc-test.c:
--- a/packages/net/vnc_server/current/doc/vnc-server.html
+++ b/packages/net/vnc_server/current/doc/vnc-server.html
@@ -246,8 +246,6 @@
         &nbsp;/* rectangle width on display */</font></font> <br>
         <font face="Courier New, Courier, mono"><font size="-1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;20, 
         &nbsp;/* rectangle heigth on display */</font></font> <br>
-        <font face="Courier New, Courier, mono"><font size="-1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;20, 
-        &nbsp;/* rectangle heigth on display */</font></font> <br>
         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="Courier New, Courier, mono"><font size="-1">(void 
         *)my_buffer, /* Address of buffer */<br>
         </font><font face="Courier New, Courier, mono"><font size="-1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;50, 
@@ -268,7 +266,8 @@
       </td>
   </tr>
 </table>
-<p>&nbsp;</p><table width="91%" border="1" cellspacing="0" cellpadding="0" bgcolor="#FFFFCC">
+<p>&nbsp; </p>
+<table width="91%" border="1" cellspacing="0" cellpadding="0" bgcolor="#FFFFCC">
   <tr> 
     <td> 
       <p><font face="Courier New, Courier, mono"><font face="Courier New, Courier, mono"></font><b>void 
@@ -325,6 +324,37 @@
       </td>
   </tr>
 </table>
+<p>&nbsp;</p><table width="91%" border="1" cellspacing="0" cellpadding="0" bgcolor="#FFFFCC">
+  <tr> 
+    <td> 
+      <p><font face="Courier New, Courier, mono"><font face="Courier New, Courier, mono"></font><b>void 
+        VncCopyBuffer2RectMask(void *buffer,<br>
+        &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
+        cyg_uint16 buff_w,<br>
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
+        cyg_uint16 buff_h, <br>
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
+        cyg_uint16 x_off,<br>
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
+        cyg_uint16 y_off,<br>
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
+        cyg_uint16 x, <br>
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
+        cyg_uint16 y,<br>
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
+        cyg_uint16 width,<br>
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
+        cyg_uint16 height,<br>
+        <font face="Courier New, Courier, mono">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vnc_colour_t 
+        mask_colour</font> )</b></font></p>
+      <p>The VNC copy buffer to rectangle with mask function works exactly like 
+        VncCopyRect2Buffer(), except that a mask colour is also specified. Any 
+        pixels in the buffer that have the value mask_colour, will not be copied 
+        to the frame buffer - leaving the original pixels untouched.<font face="Courier New, Courier, mono"><font size="-1"> 
+        </font></font></p>
+    </td>
+  </tr>
+</table>
 <p>&nbsp;</p>
 <table width="91%" border="1" cellspacing="0" cellpadding="0" bgcolor="#FFFFCC">
   <tr> 
@@ -590,7 +620,7 @@
   </tr>
 </table>
 <p>The cyg_io_read() function is a non-blocking function and each keystroke event 
-  generates 4bytes of data:</p>
+  generates 4 bytes of data:</p>
 <p>Byte 0: Padding - always zero<br>
   Byte 1: Key pressed/released (1 when key pressed)<br>
   Byte 2: Keysym value for key MSB<br>
--- a/packages/net/vnc_server/current/include/vnc-server.h
+++ b/packages/net/vnc_server/current/include/vnc-server.h
@@ -119,6 +119,8 @@ void VncCopyRect2Buffer(cyg_uint16 x, cy
                         void *buffer, cyg_uint16 buff_w, cyg_uint16 buff_h, cyg_uint16 x_off, cyg_uint16 y_off);
 void VncCopyBuffer2Rect(void *buffer, cyg_uint16 buff_w, cyg_uint16 buff_h, cyg_uint16 x_off, cyg_uint16 y_off,
                          cyg_uint16 x, cyg_uint16 y, cyg_uint16 width, cyg_uint16 height);
+void VncCopyBuffer2RectMask( void *buffer, cyg_uint16 buff_w, cyg_uint16 buff_h ,cyg_uint16 x_off, cyg_uint16 y_off,
+                             cyg_uint16 x, cyg_uint16 y, cyg_uint16 width, cyg_uint16 height, vnc_colour_t col);
 void VncSoundBell(void);
 #ifdef CYGNUM_VNC_SERVER_INCLUDE_VNC_PRINTF
 vnc_printf_return_t VncPrintf(MWCFONT* font, int do_print, vnc_colour_t colour, int x, int y, const char *fmt, ... );
--- a/packages/net/vnc_server/current/src/vnc-server.c
+++ b/packages/net/vnc_server/current/src/vnc-server.c
@@ -1535,7 +1535,7 @@ void VncCopyBuffer2Rect( void *buffer, c
         src_buffer += x_off;  /* Allow for an x offset into supplied buffer */
         for (j = x; j < x + width; j++)
         {
-            /* Copy each pixel in the rectangle to the supplied buffer */
+            /* Copy each pixel in the supplied buffer to the frame buffer */
             frame_buffer[i][j] = *src_buffer;
             src_buffer++;
         }
@@ -1554,6 +1554,48 @@ void VncCopyBuffer2Rect( void *buffer, c
 }
 
 
+/* Function to copy data from a supplied buffer to a rectangle in the frame buffer with mask */
+void VncCopyBuffer2RectMask( void *buffer, cyg_uint16 buff_w, cyg_uint16 buff_h ,cyg_uint16 x_off, cyg_uint16 y_off,
+                             cyg_uint16 x, cyg_uint16 y, cyg_uint16 width, cyg_uint16 height, vnc_colour_t col)
+{
+    int i, j;
+    cyg_uint16 eol_padding = buff_w - width - x_off;
+
+#if (BITS_PER_PIXEL == 8)
+    cyg_uint8 *src_buffer = (cyg_uint8 *)buffer;
+#else
+    cyg_uint16 *src_buffer = (cyg_uint16 *)buffer;
+#endif
+
+    src_buffer += ((x_off + width) * y_off);  /* Allow for a y offset into supplied buffer */
+    for (i = y; i < y + height; i++)
+    {
+        src_buffer += x_off;  /* Allow for an x offset into supplied buffer */
+        for (j = x; j < x + width; j++)
+        {
+            /* Copy each non-mask pixel in the supplied buffer to the frame buffer */
+            if (*src_buffer != col)
+            {
+                frame_buffer[i][j] = *src_buffer;
+            }
+
+            src_buffer++;
+        }
+
+        src_buffer += eol_padding;  /* Allow for unused space at the end of each line */
+    }
+
+    /* Mark the required tiles for update */
+    for (i = y/TILE_SIZE; i <= (y + height - 1) /TILE_SIZE; i++)
+    {
+        for (j = x/TILE_SIZE; j <= (x + width - 1)/TILE_SIZE; j++)
+        {
+            tile_updated[i][j] = 1;
+        }
+    }
+}
+
+
 void VncSoundBell(void)
 {
     cyg_mutex_lock(&SoundBell_lock);
@@ -1646,14 +1688,13 @@ vnc_printf_return_t VncPrintf(MWCFONT* f
 
         y_max = y_pos;
 
+        if (do_print)
+        {
         /* Draw the character in the frame buffer */
         for (i = char_offset; i < (char_offset + sel_font->height); i++)
         {
             if ((y_pos + i - char_offset) < CYGNUM_VNC_SERVER_FRAME_HEIGHT)
             {
-                if (do_print)
-                {
-                    /* Actually print the text */
                     /* This has not gone off the bottom of the frame */
                     for (j = 0; j < char_width; j++)
                     {
--- a/packages/net/vnc_server/current/tests/vnc-test.c
+++ b/packages/net/vnc_server/current/tests/vnc-test.c
@@ -29,6 +29,12 @@
 #include <unistd.h>           /* read() */
 #include <stdlib.h>           /* rand() */
 
+void DrawCursor(void);
+void HideCursor(void);
+
+int cursor_x, cursor_y;  /* Cursor position */
+vnc_frame_format_t *display_info;  /* Display Info */
+
 int main()
 {
     int mouse_handle = -1;
@@ -47,8 +53,6 @@ int main()
     fd_set  sock_desc;  /* Set of descriptors for select */
     int max_handle;
 
-    vnc_frame_format_t *display_info;
-
     int bell_text_state = 0;
     char bell_message[] = "***** Click on a yellow pixel to sound the bell *****";
 
@@ -196,6 +200,11 @@ int main()
     /* Write the text on the background */
     VncPrintf(0, 1, VNC_YELLOW, bell_text_x_pos, bell_text_y_pos, "%s", bell_message);
 
+    /* Initialise the cursor */
+    cursor_x = display_info->frame_width / 2;
+    cursor_y = display_info->frame_height / 2;
+    DrawCursor();
+
     /* Initialse the max handle variable */
     max_handle = -1;
     if (kbd_handle > max_handle)
@@ -266,6 +275,10 @@ int main()
 
                 if (mouse_len == 8)
                 {
+                    HideCursor();  /* Hide the old cursor */
+                    cursor_x = mouse_data[2]*256 + mouse_data[3];
+                    cursor_y = mouse_data[4]*256 + mouse_data[5];
+
                     if (mouse_data[1] && !last_mouse_button)
                     {
                         /* Ring bell and change colours of bell message text if the */
@@ -304,6 +317,7 @@ int main()
                     }
 
                     last_mouse_button = mouse_data[1];  /* Save mouse button data */
+                    DrawCursor();  /* Draw the new cursor */
                 }
             }
 
@@ -312,3 +326,116 @@ int main()
 
     return 1;
 }
+
+
+vnc_colour_t under_cursor[16][16];  /* Buffer to hold display area under cursor */
+
+    /* Buffer holding cursor data */
+#define BLK VNC_BLACK
+#define TRN VNC_BLUE
+#define WHT VNC_WHITE
+#define GRY VNC_LTGRAY
+vnc_colour_t cursor[16][16] = {{BLK, BLK, BLK, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN},
+                               {BLK, GRY, GRY, BLK, BLK, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN},
+                               {BLK, WHT, GRY, GRY, GRY, BLK, BLK, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN},
+                               {TRN, BLK, WHT, GRY, GRY, GRY, GRY, BLK, BLK, TRN, TRN, TRN, TRN, TRN, TRN, TRN},
+                               {TRN, BLK, WHT, WHT, GRY, GRY, GRY, GRY, GRY, BLK, BLK, TRN, TRN, TRN, TRN, TRN},
+                               {TRN, TRN, BLK, WHT, WHT, GRY, GRY, GRY, GRY, GRY, GRY, BLK, BLK, TRN, TRN, TRN},
+                               {TRN, TRN, BLK, WHT, WHT, WHT, GRY, GRY, GRY, GRY, GRY, GRY, GRY, BLK, TRN, TRN},
+                               {TRN, TRN, TRN, BLK, WHT, WHT, WHT, GRY, GRY, BLK, BLK, BLK, BLK, BLK, TRN, TRN},
+                               {TRN, TRN, TRN, BLK, WHT, WHT, WHT, WHT, GRY, GRY, BLK, TRN, TRN, TRN, TRN, TRN},
+                               {TRN, TRN, TRN, TRN, BLK, WHT, WHT, BLK, WHT, GRY, GRY, BLK, TRN, TRN, TRN, TRN},
+                               {TRN, TRN, TRN, TRN, BLK, WHT, WHT, BLK, BLK, WHT, GRY, GRY, BLK, TRN, TRN, TRN},
+                               {TRN, TRN, TRN, TRN, TRN, BLK, WHT, BLK, TRN, BLK, WHT, GRY, GRY, BLK, TRN, TRN},
+                               {TRN, TRN, TRN, TRN, TRN, BLK, WHT, BLK, TRN, TRN, BLK, WHT, GRY, GRY, BLK, TRN},
+                               {TRN, TRN, TRN, TRN, TRN, TRN, BLK, TRN, TRN, TRN, TRN, BLK, WHT, GRY, GRY, BLK},
+                               {TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, BLK, WHT, BLK, TRN},
+                               {TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, TRN, BLK, TRN, TRN}};
+#undef BLK
+#undef TRN
+#undef WHT
+#undef GRY
+
+void DrawCursor(void)
+{
+    int rect_width, rect_height;
+
+    if (cursor_x >= display_info->frame_width)
+    {
+        /* Cursor is off the screen */
+        return;
+    }
+    else if ((cursor_x + 16) >= display_info->frame_width)
+    {
+        /* Cursor is partially off the screen */
+        rect_width = display_info->frame_width - cursor_x;
+    }
+    else
+    {
+        /* Cursor is fully on the screen */
+        rect_width = 16;
+    }
+
+    if (cursor_y >= display_info->frame_height)
+    {
+        /* Cursor is off the screen */
+        return;
+    }
+    else if ((cursor_y + 16) >= display_info->frame_height)
+    {
+        /* Cursor is partially off the screen */
+        rect_height = display_info->frame_height - cursor_y;
+    }
+    else
+    {
+        /* Cursor is fully on the screen */
+        rect_height = 16;
+    }
+
+    /* Save the area under the cursor */
+    VncCopyRect2Buffer(cursor_x, cursor_y, rect_width, rect_height, under_cursor, 16, 16, 0, 0);
+
+    /* Draw the new cursor */
+    VncCopyBuffer2RectMask(cursor, 16, 16, 0, 0, cursor_x, cursor_y, rect_width, rect_height, VNC_BLUE);
+}
+
+
+void HideCursor(void)
+{
+    int rect_width, rect_height;
+
+    if (cursor_x >= display_info->frame_width)
+    {
+        /* Cursor is off the screen */
+        return;
+    }
+    else if ((cursor_x + 16) >= display_info->frame_width)
+    {
+        /* Cursor is partially off the screen */
+        rect_width = display_info->frame_width - cursor_x;
+    }
+    else
+    {
+        /* Cursor is fully on the screen */
+        rect_width = 16;
+    }
+
+    if (cursor_y >= display_info->frame_height)
+    {
+        /* Cursor is off the screen */
+        return;
+    }
+    else if ((cursor_y + 16) >= display_info->frame_height)
+    {
+        /* Cursor is partially off the screen */
+        rect_height = display_info->frame_height - cursor_y;
+    }
+    else
+    {
+        /* Cursor is fully on the screen */
+        rect_height = 16;
+    }
+
+    /* Restore the saved area under the cursor */
+    VncCopyBuffer2Rect(under_cursor, 16, 16, 0, 0, cursor_x, cursor_y, rect_width, rect_height);
+}