[Spice-devel] [PATCH] DrvSetPointerShape: handle surface which is not bitmap

Yonit Halperin yhalperi at redhat.com
Tue Apr 13 05:00:51 PDT 2010


---
 display/res.c |   99 +++++++++++++++++++++++++++++++++++++++++++++++---------
 display/rop.c |    2 +-
 display/rop.h |    3 ++
 3 files changed, 87 insertions(+), 17 deletions(-)

diff --git a/display/res.c b/display/res.c
index 318ea9c..2ea9565 100644
--- a/display/res.c
+++ b/display/res.c
@@ -27,6 +27,7 @@
 #include "murmur_hash2a.h"
 #include "surface.h"
 #include "dd.h"
+#include "rop.h"
 
 #if (WINVER < 0x0501)
 #define WAIT_FOR_EVENT(pdev, event, timeout) (pdev)->WaitForEvent(event, timeout)
@@ -2738,7 +2739,7 @@ typedef struct NewCursorInfo {
 #define CURSOR_ALLOC_SIZE (PAGE_SIZE << 1)
 
 static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFOBJ *surf,
-                            UINT16 type, NewCursorInfo *info)
+                            UINT16 type, NewCursorInfo *info, BOOL *in_cach)
 {
     InternalCursor *internal;
     QXLCursor *cursor;
@@ -2747,19 +2748,59 @@ static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_
     UINT8 *src;
     UINT8 *src_end;
     int line_size;
-
+    HSURF bitmap = 0;
+    SURFOBJ *local_surf = surf;
 
     DEBUG_PRINT((pdev, 9, "%s\n", __FUNCTION__));
-
+    *in_cach = FALSE;
     unique = (surf->fjBitmap & BMF_DONTCACHE) ? 0 : surf->iUniq;
 
     if ((internal = CursorCacheGet(pdev, surf->hsurf, unique))) {
         res = (Resource *)((UINT8 *)internal - sizeof(Resource));
         CursorCmdAddRes(pdev, cmd, res);
         cmd->u.set.shape = PA(pdev, &internal->cursor, pdev->main_mem_slot);
+        *in_cach = TRUE;
         return TRUE;
     }
 
+    if (surf->iType != STYPE_BITMAP) {
+        RECTL dest_rect;
+        POINTL src_pos;
+        ASSERT(pdev, surf->iBitmapFormat == BMF_32BPP || surf->iBitmapFormat == BMF_16BPP);
+
+        /* copying the surface to a bitmap */
+
+        bitmap = (HSURF)EngCreateBitmap(surf->sizlBitmap, surf->lDelta, surf->iBitmapFormat,
+                                        0, NULL);
+        if (!bitmap) {
+            DEBUG_PRINT((pdev, 0, "%s: EngCreateBitmap failed\n", __FUNCTION__));
+            return FALSE;
+        }
+
+        if (!EngAssociateSurface(bitmap, pdev->eng, 0)) {
+            DEBUG_PRINT((pdev, 0, "%s: EngAssociateSurface failed\n", __FUNCTION__));
+            goto error;
+        }
+
+        if (!(local_surf = EngLockSurface(bitmap))) {
+            DEBUG_PRINT((pdev, 0, "%s: EngLockSurface failed\n", __FUNCTION__));
+            goto error;
+        }
+
+        dest_rect.top = 0;
+        dest_rect.left = 0;
+        dest_rect.bottom = surf->sizlBitmap.cy;
+        dest_rect.right = surf->sizlBitmap.cx;
+
+        src_pos.x = 0;
+        src_pos.y = 0;
+            
+        if (!BitBltFromDev(pdev, surf, local_surf, NULL, NULL, NULL, &dest_rect, src_pos,
+                           NULL, NULL, NULL, 0xcccc)) {
+            goto error;
+        }
+    }
+
     ASSERT(pdev, sizeof(Resource) + sizeof(InternalCursor) < CURSOR_ALLOC_SIZE);
     res = (Resource *)AllocMem(pdev, CURSOR_ALLOC_SIZE);
     ONDBG(pdev->Res.num_cursor_pages++);
@@ -2774,9 +2815,9 @@ static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_
     cursor = info->cursor = &internal->cursor;
     cursor->header.type = type;
     cursor->header.unique = unique ? ++pdev->Res.last_cursor_id : 0;
-    cursor->header.width = (UINT16)surf->sizlBitmap.cx;
-    cursor->header.height = (type == SPICE_CURSOR_TYPE_MONO) ? (UINT16)surf->sizlBitmap.cy >> 1 :
-                            (UINT16)surf->sizlBitmap.cy;
+    cursor->header.width = (UINT16)local_surf->sizlBitmap.cx;
+    cursor->header.height = (type == SPICE_CURSOR_TYPE_MONO) ? (UINT16)local_surf->sizlBitmap.cy >> 1 :
+                            (UINT16)local_surf->sizlBitmap.cy;
     cursor->header.hot_spot_x = (UINT16)hot_x;
     cursor->header.hot_spot_y = (UINT16)hot_y;
 
@@ -2812,10 +2853,10 @@ static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_
         break;
     }
 
-    cursor->data_size = line_size * surf->sizlBitmap.cy;
-    src = surf->pvScan0;
-    src_end = src + (surf->lDelta * surf->sizlBitmap.cy);
-    for (; src != src_end; src += surf->lDelta) {
+    cursor->data_size = line_size * local_surf->sizlBitmap.cy;
+    src = local_surf->pvScan0;
+    src_end = src + (local_surf->lDelta * local_surf->sizlBitmap.cy);
+    for (; src != src_end; src += local_surf->lDelta) {
         PutBytes(pdev, &info->chunk, &info->now, &info->end, src, line_size,
                  &pdev->Res.num_cursor_pages, PAGE_SIZE, FALSE);
     }
@@ -2825,25 +2866,42 @@ static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_
     RELEASE_RES(pdev, res);
     cmd->u.set.shape = PA(pdev, &internal->cursor, pdev->main_mem_slot);
     DEBUG_PRINT((pdev, 11, "%s: done, data_size %u\n", __FUNCTION__, cursor->data_size));
+
+    if (local_surf != surf) {
+        EngUnlockSurface(local_surf);
+        EngDeleteSurface(bitmap);
+    }
+
+    return TRUE;
+error:
+    if (bitmap) {
+        ASSERT(pdev, local_surf != surf);
+        EngDeleteSurface(bitmap);
+    }
+
     return FALSE;
 }
 
 BOOL GetAlphaCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFOBJ *surf)
 {
     NewCursorInfo info;
+    BOOL ret;
+    BOOL in_cache;
 
     ASSERT(pdev, surf->iBitmapFormat == BMF_32BPP);
     ASSERT(pdev, surf->sizlBitmap.cx > 0 && surf->sizlBitmap.cy > 0);
 
     DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__));
-    GetCursorCommon(pdev, cmd, hot_x, hot_y, surf, SPICE_CURSOR_TYPE_ALPHA, &info);
+    ret = GetCursorCommon(pdev, cmd, hot_x, hot_y, surf, SPICE_CURSOR_TYPE_ALPHA, &info, &in_cache);
     DEBUG_PRINT((pdev, 8, "%s: done\n", __FUNCTION__));
-    return TRUE;
+    return ret;
 }
 
 BOOL GetMonoCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFOBJ *surf)
 {
     NewCursorInfo info;
+    BOOL ret;
+    BOOL in_cache;
 
     ASSERT(pdev, surf->iBitmapFormat == BMF_1BPP);
     ASSERT(pdev, surf->sizlBitmap.cy > 0 && (surf->sizlBitmap.cy & 1) == 0);
@@ -2851,9 +2909,9 @@ BOOL GetMonoCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFOB
 
     DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__));
 
-    GetCursorCommon(pdev, cmd, hot_x, hot_y, surf, SPICE_CURSOR_TYPE_MONO, &info);
+    ret = GetCursorCommon(pdev, cmd, hot_x, hot_y, surf, SPICE_CURSOR_TYPE_MONO, &info, &in_cache);
     DEBUG_PRINT((pdev, 8, "%s: done\n", __FUNCTION__));
-    return TRUE;
+    return ret;
 }
 
 BOOL GetColorCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFOBJ *surf,
@@ -2861,7 +2919,7 @@ BOOL GetColorCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFO
 {
     NewCursorInfo info;
     UINT16 type;
-
+    BOOL in_cache;
 
     DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__));
 
@@ -2899,7 +2957,12 @@ BOOL GetColorCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFO
         DEBUG_PRINT((pdev, 0, "%s: unexpected format\n", __FUNCTION__));
         return FALSE;
     }
-    if (!GetCursorCommon(pdev, cmd, hot_x, hot_y, surf, type, &info)) {
+
+    if (!GetCursorCommon(pdev, cmd, hot_x, hot_y, surf, type, &info, &in_cache)) {
+        return FALSE;
+    }
+
+    if (!in_cache) {
         int line_size;
         UINT8 *src;
         UINT8 *src_end;
@@ -2946,6 +3009,10 @@ BOOL GetColorCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFO
             }
             info.cursor->data_size += 16 << 2;
         }
+
+        ASSERT(pdev, mask->iBitmapFormat == BMF_1BPP);
+        ASSERT(pdev, mask->iType == STYPE_BITMAP);
+
         line_size = ALIGN(mask->sizlBitmap.cx, 8) >> 3;
         info.cursor->data_size += line_size * surf->sizlBitmap.cy;
         src = mask->pvScan0;
diff --git a/display/rop.c b/display/rop.c
index 57a92ab..59b63d5 100644
--- a/display/rop.c
+++ b/display/rop.c
@@ -995,7 +995,7 @@ error:
 
 }
 
-static BOOL BitBltFromDev(PDev *pdev, SURFOBJ *src, SURFOBJ *dest, SURFOBJ *mask, CLIPOBJ *clip,
+BOOL BitBltFromDev(PDev *pdev, SURFOBJ *src, SURFOBJ *dest, SURFOBJ *mask, CLIPOBJ *clip,
                    XLATEOBJ *color_trans, RECTL *dest_rect, POINTL src_pos,
                    POINTL *mask_pos, BRUSHOBJ *brush, POINTL *brush_pos, ROP4 rop4)
 {
diff --git a/display/rop.h b/display/rop.h
index 7519e63..5b3f241 100644
--- a/display/rop.h
+++ b/display/rop.h
@@ -32,4 +32,7 @@ typedef struct ROP3Info {
 
 extern ROP3Info rops2[];
 
+BOOL BitBltFromDev(PDev *pdev, SURFOBJ *src, SURFOBJ *dest, SURFOBJ *mask, CLIPOBJ *clip,
+                   XLATEOBJ *color_trans, RECTL *dest_rect, POINTL src_pos,
+                   POINTL *mask_pos, BRUSHOBJ *brush, POINTL *brush_pos, ROP4 rop4);
 #endif
-- 
1.6.6.1



More information about the Spice-devel mailing list