[1/2] server: store each window's drop target

Damjan Jovanovic damjan.jov at gmail.com
Wed Feb 3 11:42:43 CST 2010


* server: store each window's drop target

The patch series allows OLE drag and drop to work across process boundaries.

Damjan Jovanovic
-------------- next part --------------
diff --git a/server/protocol.def b/server/protocol.def
index 04f6e2b..e1657b7 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3249,3 +3249,18 @@ enum message_type
 @REQ(free_user_handle)
     user_handle_t  handle;        /* handle to free*/
 @END
+
+
+/* Set a window's drop target */
+ at REQ(set_window_droptarget)
+    user_handle_t  handle;        /* handle to the window */
+    VARARG(droptarget,bytes);     /* marshalled IDropTarget */
+ at END
+
+
+/* Get a window's drop target */
+ at REQ(get_window_droptarget)
+    user_handle_t  handle;        /* handle to the window */
+ at REPLY
+    VARARG(droptarget,bytes);     /* marshalled IDropTarget */
+ at END
diff --git a/server/window.c b/server/window.c
index a0e0788..7aecc00 100644
--- a/server/window.c
+++ b/server/window.c
@@ -89,6 +89,8 @@ struct window
     int              prop_inuse;      /* number of in-use window properties */
     int              prop_alloc;      /* number of allocated window properties */
     struct property *properties;      /* window properties array */
+    char            *drop_target;     /* marshalled IDropTarget */
+    int              drop_target_len; /* size of drop_target */
     int              nb_extra_bytes;  /* number of extra bytes */
     char             extra_bytes[1];  /* extra bytes storage */
 };
@@ -457,6 +459,8 @@ static struct window *create_window( struct window *parent, struct window *owner
     win->prop_inuse     = 0;
     win->prop_alloc     = 0;
     win->properties     = NULL;
+    win->drop_target    = NULL;
+    win->drop_target_len= 0;
     win->nb_extra_bytes = extra_bytes;
     win->window_rect = win->visible_rect = win->client_rect = empty_rect;
     memset( win->extra_bytes, 0, extra_bytes );
@@ -1707,6 +1711,7 @@ void destroy_window( struct window *win )
     if (win->update_region) free_region( win->update_region );
     if (win->class) release_class( win->class );
     free( win->text );
+    free( win->drop_target );
     memset( win, 0x55, sizeof(*win) + win->nb_extra_bytes - 1 );
     free( win );
 }
@@ -2526,3 +2531,51 @@ DECL_HANDLER(set_window_layered_info)
     }
     else set_win32_error( ERROR_INVALID_WINDOW_HANDLE );
 }
+
+
+/* Set a window's drop target */
+DECL_HANDLER(set_window_droptarget)
+{
+    struct window *win = get_window( req->handle );
+
+    if (!win) return;
+
+    if (get_req_data_size() == 0)
+    {
+        /* Clear drop target */
+        if (win->drop_target)
+        {
+            free(win->drop_target);
+            win->drop_target = NULL;
+            win->drop_target_len = 0;
+        }
+        else set_error( STATUS_OBJECT_NAME_NOT_FOUND  );
+    }
+    else
+    {
+        /* Set drop target */
+        if (win->drop_target == NULL)
+        {
+            win->drop_target = mem_alloc(get_req_data_size());
+            if (win->drop_target)
+            {
+                memcpy(win->drop_target, get_req_data(), get_req_data_size());
+                win->drop_target_len = get_req_data_size();
+            }
+            else set_error( STATUS_NO_MEMORY );
+        }
+        else set_error( STATUS_OBJECT_NAME_COLLISION );
+    }
+}
+
+
+/* Get a window's drop target */
+DECL_HANDLER(get_window_droptarget)
+{
+    struct window *win = get_window( req->handle );
+
+    if (!win) return;
+
+    set_reply_data( win->drop_target, min( get_reply_max_size(), win->drop_target_len ) );
+}
+


More information about the wine-patches mailing list