[1/10] server: Add functions for storing icons and cursors in the server

H. Verbeet hverbeet at gmail.com
Sat Aug 5 16:38:38 CDT 2006


This allows cursors and icons to be stored in the server.
-------------- next part --------------
diff --git a/server/Makefile.in b/server/Makefile.in
index 3e87bb6..7c1a2d0 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -16,6 +16,7 @@ C_SRCS = \
 	context_powerpc.c \
 	context_sparc.c \
 	context_x86_64.c \
+	cursoricon.c \
 	debugger.c \
 	directory.c \
 	event.c \
diff --git a/server/cursoricon.c b/server/cursoricon.c
new file mode 100644
index 0000000..be3298d
--- /dev/null
+++ b/server/cursoricon.c
@@ -0,0 +1,167 @@
+/*
+ * Server-side cursors / icons
+ *
+ * Copyright (C) 2006 Henri Verbeet
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "winternl.h"
+#include "object.h"
+#include "request.h"
+#include "user.h"
+
+typedef struct {
+    unsigned short xhot;
+    unsigned short yhot;
+    unsigned short width;
+    unsigned short height;
+    unsigned short and_width_bytes;
+    unsigned short xor_width_bytes;
+    unsigned char planes;
+    unsigned char bpp;
+    /* bits contains both the AND and XOR bitmap data, in that order */
+    unsigned char *bits;
+} cursor_frame_t;
+
+typedef struct {
+    struct process *process;
+    unsigned int num_frames;
+    unsigned int delay;
+    cursor_frame_t *frames;
+} cursor_t;
+
+void destroy_cursor( cursor_t *cursor )
+{
+    unsigned int i;
+
+    for (i = 0; i < cursor->num_frames; ++i)
+    {
+        if (cursor->frames[i].bits) free( cursor->frames[i].bits );
+    }
+
+    free( cursor->frames );
+}
+
+/* destroy all cursors belonging to a given process */
+void destroy_process_cursors( struct process *process )
+{
+    user_handle_t handle = 0;
+    cursor_t *cursor;
+
+    while ((cursor = next_user_handle( &handle, USER_CURSOR )))
+    {
+        if (cursor->process != process) continue;
+
+        destroy_cursor( cursor );
+        free_user_handle( handle );
+    }
+}
+
+/* Create a cursor */
+DECL_HANDLER(create_cursor)
+{
+    cursor_t *cursor = mem_alloc( sizeof(cursor_t) );
+    cursor->process = current->process;
+    cursor->num_frames = req->num_frames;
+    cursor->delay = req->delay;
+    cursor->frames = mem_alloc( req->num_frames * sizeof(cursor_frame_t) );
+    memset( cursor->frames, 0, req->num_frames * sizeof(cursor_frame_t) );
+
+    reply->handle = alloc_user_handle( cursor, USER_CURSOR );
+}
+
+/* Destroy a cursor */
+DECL_HANDLER(destroy_cursor)
+{
+    cursor_t *cursor = free_user_handle( req->handle );
+
+    if (cursor) destroy_cursor( cursor );
+}
+
+/* Get cursor info */
+DECL_HANDLER(get_cursor_info)
+{
+    cursor_t *cursor = get_user_object( req->handle, USER_CURSOR );
+
+    if (!cursor) return;
+
+    reply->num_frames = cursor->num_frames;
+    reply->delay = cursor->delay;
+}
+
+/* Get frame info & bitmap bits */
+DECL_HANDLER(get_cursor_frame)
+{
+    unsigned int data_size;
+    unsigned int frame_idx = req->frame_idx;
+    cursor_t *cursor = get_user_object( req->handle, USER_CURSOR );
+    cursor_frame_t *frame;
+
+    if (!cursor || cursor->num_frames < frame_idx)
+    {
+        reply->height = 0;
+        return;
+    }
+
+    frame = &cursor->frames[frame_idx];
+
+    reply->xhot = frame->xhot;
+    reply->yhot = frame->yhot;
+    reply->width = frame->width;
+    reply->height = frame->height;
+    reply->and_width_bytes = frame->and_width_bytes;
+    reply->xor_width_bytes = frame->xor_width_bytes;
+    reply->planes = frame->planes;
+    reply->bpp = frame->bpp;
+
+    data_size = (frame->and_width_bytes + frame->xor_width_bytes) * frame->height;
+    if (data_size > get_reply_max_size())
+    {
+        set_error( STATUS_BUFFER_OVERFLOW );
+        return;
+    }
+
+    set_reply_data( frame->bits, data_size );
+}
+
+/* Set frame info & bitmap bits */
+DECL_HANDLER(set_cursor_frame)
+{
+    size_t data_size = get_req_data_size();
+    unsigned int frame_idx = req->frame_idx;
+    cursor_t *cursor = get_user_object( req->handle, USER_CURSOR );
+    cursor_frame_t *frame;
+
+    if (!cursor || cursor->num_frames < frame_idx || !data_size) return;
+
+    frame = &cursor->frames[frame_idx];
+
+    frame->xhot = req->xhot;
+    frame->yhot = req->yhot;
+    frame->width = req->width;
+    frame->height = req->height;
+    frame->and_width_bytes = req->and_width_bytes;
+    frame->xor_width_bytes = req->xor_width_bytes;
+    frame->planes = req->planes;
+    frame->bpp = req->bpp;
+
+    if (frame->bits) free( frame->bits );
+    frame->bits = memdup( get_req_data(), data_size );
+}
diff --git a/server/process.c b/server/process.c
index 3e5ef97..d274a00 100644
--- a/server/process.c
+++ b/server/process.c
@@ -526,6 +526,7 @@ static void process_killed( struct proce
         free( dll );
     }
     destroy_process_classes( process );
+    destroy_process_cursors( process );
     remove_process_locks( process );
     set_process_startup_state( process, STARTUP_ABORTED );
     wake_up( &process->obj, 0 );
diff --git a/server/protocol.def b/server/protocol.def
index 25e93e9..550a622 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1790,6 +1790,63 @@ #define NAMED_PIPE_SERVER_END           
 @END
 
 
+/* Create a cursor */
+ at REQ(create_cursor)
+    unsigned int    num_frames;
+    unsigned short  delay;
+ at REPLY
+    user_handle_t   handle;
+ at END
+
+
+/* Destroy a cursor */
+ at REQ(destroy_cursor)
+    user_handle_t   handle;
+ at END
+
+
+/* Get cursor info */
+ at REQ(get_cursor_info)
+    user_handle_t   handle;
+ at REPLY
+    unsigned int    num_frames;
+    unsigned short  delay;
+ at END
+
+
+/* Get cursor frame */
+ at REQ(get_cursor_frame)
+    user_handle_t   handle;
+    unsigned int    frame_idx;
+ at REPLY
+    unsigned short  xhot;
+    unsigned short  yhot;
+    unsigned short  width;
+    unsigned short  height;
+    unsigned short  and_width_bytes;
+    unsigned short  xor_width_bytes;
+    unsigned char   planes;
+    unsigned char   bpp;
+    VARARG(data,bytes);
+ at END
+
+
+/* Set cursor frame */
+ at REQ(set_cursor_frame)
+    user_handle_t   handle;
+    unsigned int    frame_idx;
+    unsigned short  xhot;
+    unsigned short  yhot;
+    unsigned short  width;
+    unsigned short  height;
+    unsigned short  and_width_bytes;
+    unsigned short  xor_width_bytes;
+    unsigned char   planes;
+    unsigned char   bpp;
+    VARARG(data,bytes);
+ at END
+
+
 /* Create a window */
 @REQ(create_window)
     user_handle_t  parent;      /* parent window */
diff --git a/server/user.h b/server/user.h
index 946b578..938adf8 100644
--- a/server/user.h
+++ b/server/user.h
@@ -35,7 +35,8 @@ struct clipboard;
 enum user_object
 {
     USER_WINDOW = 1,
-    USER_HOOK
+    USER_HOOK,
+    USER_CURSOR
 };
 
 #define DESKTOP_ATOM  ((atom_t)32769)
@@ -75,6 +76,10 @@ extern void *next_user_handle( user_hand
 
 extern void cleanup_clipboard_thread( struct thread *thread );
 
+/* cursor functions */
+
+extern void destroy_process_cursors( struct process *process );
+
 /* hook functions */
 
 extern void remove_thread_hooks( struct thread *thread );


More information about the wine-patches mailing list