Jacek Caban : server: Make window struct a server object.

Alexandre Julliard julliard at winehq.org
Wed Feb 9 16:03:49 CST 2022


Module: wine
Branch: master
Commit: 5b56bad50b85acb05244894990053f8b0de2e458
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5b56bad50b85acb05244894990053f8b0de2e458

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Feb  8 13:12:43 2022 +0100

server: Make window struct a server object.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 server/user.h       |  2 +-
 server/window.c     | 94 ++++++++++++++++++++++++++++++++++++++++-------------
 server/winstation.c |  4 +--
 3 files changed, 75 insertions(+), 25 deletions(-)

diff --git a/server/user.h b/server/user.h
index 80f7e91f12c..55a0d35feff 100644
--- a/server/user.h
+++ b/server/user.h
@@ -154,7 +154,7 @@ extern struct process *get_top_window_owner( struct desktop *desktop );
 extern void get_top_window_rectangle( struct desktop *desktop, rectangle_t *rect );
 extern void post_desktop_message( struct desktop *desktop, unsigned int message,
                                   lparam_t wparam, lparam_t lparam );
-extern void destroy_window( struct window *win );
+extern void free_window_handle( struct window *win );
 extern void destroy_thread_windows( struct thread *thread );
 extern int is_child_window( user_handle_t parent, user_handle_t child );
 extern int is_valid_foreground_window( user_handle_t window );
diff --git a/server/window.c b/server/window.c
index 8fc4022a3ee..4373297b152 100644
--- a/server/window.c
+++ b/server/window.c
@@ -56,6 +56,7 @@ enum property_type
 
 struct window
 {
+    struct object    obj;             /* object header */
     struct window   *parent;          /* parent window */
     user_handle_t    owner;           /* owner of this window */
     struct list      children;        /* list of children in Z-order */
@@ -96,6 +97,33 @@ struct window
     char            *extra_bytes;     /* extra bytes storage */
 };
 
+static void window_dump( struct object *obj, int verbose );
+static void window_destroy( struct object *obj );
+
+static const struct object_ops window_ops =
+{
+    sizeof(struct window),    /* size */
+    &no_type,                 /* type */
+    window_dump,              /* dump */
+    no_add_queue,             /* add_queue */
+    NULL,                     /* remove_queue */
+    NULL,                     /* signaled */
+    NULL,                     /* satisfied */
+    no_signal,                /* signal */
+    no_get_fd,                /* get_fd */
+    default_map_access,       /* map_access */
+    default_get_sd,           /* get_sd */
+    default_set_sd,           /* set_sd */
+    no_get_full_name,         /* get_full_name */
+    no_lookup_name,           /* lookup_name */
+    no_link_name,             /* link_name */
+    NULL,                     /* unlink_name */
+    no_open_file,             /* open_file */
+    no_kernel_obj_list,       /* get_kernel_obj_list */
+    no_close_handle,          /* close_handle */
+    window_destroy            /* destroy */
+};
+
 /* flags that can be set by the client */
 #define PAINT_HAS_SURFACE        SET_WINPOS_PAINT_SURFACE
 #define PAINT_HAS_PIXEL_FORMAT   SET_WINPOS_PIXEL_FORMAT
@@ -129,6 +157,31 @@ static struct window *taskman_window;
 #define WINPTR_TOPMOST   ((struct window *)3L)
 #define WINPTR_NOTOPMOST ((struct window *)4L)
 
+static void window_dump( struct object *obj, int verbose )
+{
+    struct window *win = (struct window *)obj;
+    assert( obj->ops == &window_ops );
+    fprintf( stderr, "window %p handle %x\n", win, win->handle );
+}
+
+static void window_destroy( struct object *obj )
+{
+    struct window *win = (struct window *)obj;
+
+    assert( !win->handle );
+
+    if (win->win_region) free_region( win->win_region );
+    if (win->update_region) free_region( win->update_region );
+    if (win->class) release_class( win->class );
+    free( win->text );
+
+    if (win->nb_extra_bytes)
+    {
+        memset( win->extra_bytes, 0x55, win->nb_extra_bytes );
+        free( win->extra_bytes );
+    }
+}
+
 /* retrieve a pointer to a window from its handle */
 static inline struct window *get_window( user_handle_t handle )
 {
@@ -483,9 +536,7 @@ static struct window *create_window( struct window *parent, struct window *owner
         goto failed;
     }
 
-    if (!(win = mem_alloc( sizeof(*win) ))) goto failed;
-    if (!(win->handle = alloc_user_handle( win, USER_WINDOW ))) goto failed;
-
+    if (!(win = alloc_object( &window_ops ))) goto failed;
     win->parent         = parent;
     win->owner          = owner ? owner->handle : 0;
     win->thread         = current;
@@ -523,6 +574,7 @@ static struct window *create_window( struct window *parent, struct window *owner
         memset( win->extra_bytes, 0, extra_bytes );
         win->nb_extra_bytes = extra_bytes;
     }
+    if (!(win->handle = alloc_user_handle( win, USER_WINDOW ))) goto failed;
 
     /* if parent belongs to a different thread and the window isn't */
     /* top-level, attach the two threads */
@@ -559,9 +611,12 @@ static struct window *create_window( struct window *parent, struct window *owner
 failed:
     if (win)
     {
-        if (win->handle) free_user_handle( win->handle );
-        free( win->extra_bytes );
-        free( win );
+        if (win->handle)
+        {
+            free_user_handle( win->handle );
+            win->handle = 0;
+        }
+        release_object( win );
     }
     release_object( desktop );
     release_class( class );
@@ -578,7 +633,7 @@ void destroy_thread_windows( struct thread *thread )
     {
         if (win->thread != thread) continue;
         if (is_desktop_window( win )) detach_window_thread( win );
-        else destroy_window( win );
+        else free_window_handle( win );
     }
 }
 
@@ -1878,8 +1933,10 @@ static void set_window_region( struct window *win, struct region *region, int re
 
 
 /* destroy a window */
-void destroy_window( struct window *win )
+void free_window_handle( struct window *win )
 {
+    assert( win->handle );
+
     /* hide the window */
     if (is_visible(win))
     {
@@ -1897,9 +1954,9 @@ void destroy_window( struct window *win )
 
     /* destroy all children */
     while (!list_empty(&win->children))
-        destroy_window( LIST_ENTRY( list_head(&win->children), struct window, entry ));
+        free_window_handle( LIST_ENTRY( list_head(&win->children), struct window, entry ));
     while (!list_empty(&win->unlinked))
-        destroy_window( LIST_ENTRY( list_head(&win->unlinked), struct window, entry ));
+        free_window_handle( LIST_ENTRY( list_head(&win->unlinked), struct window, entry ));
 
     /* reset global window pointers, if the corresponding window is destroyed */
     if (win == shell_window) shell_window = NULL;
@@ -1908,7 +1965,6 @@ void destroy_window( struct window *win )
     if (win == taskman_window) taskman_window = NULL;
     free_hotkeys( win->desktop, win->handle );
     cleanup_clipboard_window( win->desktop, win->handle );
-    free_user_handle( win->handle );
     destroy_properties( win );
     list_remove( &win->entry );
     if (is_desktop_window(win))
@@ -1924,16 +1980,10 @@ void destroy_window( struct window *win )
     }
 
     detach_window_thread( win );
-    if (win->win_region) free_region( win->win_region );
-    if (win->update_region) free_region( win->update_region );
-    if (win->class) release_class( win->class );
-    free( win->text );
-    if (win->nb_extra_bytes)
-    {
-        memset( win->extra_bytes, 0x55, win->nb_extra_bytes );
-        free( win->extra_bytes );
-    }
-    free( win );
+
+    free_user_handle( win->handle );
+    win->handle = 0;
+    release_object( win );
 }
 
 
@@ -2016,7 +2066,7 @@ DECL_HANDLER(destroy_window)
     struct window *win = get_window( req->handle );
     if (win)
     {
-        if (!is_desktop_window(win)) destroy_window( win );
+        if (!is_desktop_window(win)) free_window_handle( win );
         else if (win->thread == current) detach_window_thread( win );
         else set_error( STATUS_ACCESS_DENIED );
     }
diff --git a/server/winstation.c b/server/winstation.c
index 854affead77..1408e1a9e65 100644
--- a/server/winstation.c
+++ b/server/winstation.c
@@ -287,8 +287,8 @@ static void desktop_destroy( struct object *obj )
     struct desktop *desktop = (struct desktop *)obj;
 
     free_hotkeys( desktop, 0 );
-    if (desktop->top_window) destroy_window( desktop->top_window );
-    if (desktop->msg_window) destroy_window( desktop->msg_window );
+    if (desktop->top_window) free_window_handle( desktop->top_window );
+    if (desktop->msg_window) free_window_handle( desktop->msg_window );
     if (desktop->global_hooks) release_object( desktop->global_hooks );
     if (desktop->close_timeout) remove_timeout_user( desktop->close_timeout );
     list_remove( &desktop->entry );




More information about the wine-cvs mailing list