[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