Alexandre Julliard : server: Allow to send a name instead of an atom when creating a window class.

Alexandre Julliard julliard at winehq.org
Thu Nov 1 07:39:50 CDT 2007


Module: wine
Branch: master
Commit: 0762d98f7c16cca89882b20e72211b0d6df5331c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0762d98f7c16cca89882b20e72211b0d6df5331c

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Nov  1 13:02:01 2007 +0100

server: Allow to send a name instead of an atom when creating a window class.

---

 dlls/user32/class.c            |   57 +++++++++++++++++++++-------------------
 include/wine/server_protocol.h |    4 ++-
 server/class.c                 |   23 ++++++++++++---
 server/protocol.def            |    3 ++
 server/trace.c                 |   11 ++++++-
 5 files changed, 63 insertions(+), 35 deletions(-)

diff --git a/dlls/user32/class.c b/dlls/user32/class.c
index 0f2e8a8..5d97823 100644
--- a/dlls/user32/class.c
+++ b/dlls/user32/class.c
@@ -295,16 +295,15 @@ static CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance )
  *           CLASS_RegisterClass
  *
  * The real RegisterClass() functionality.
- * The atom is deleted no matter what.
  */
-static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, BOOL local,
+static CLASS *CLASS_RegisterClass( LPCWSTR name, HINSTANCE hInstance, BOOL local,
                                    DWORD style, INT classExtra, INT winExtra )
 {
     CLASS *classPtr;
     BOOL ret;
 
-    TRACE("atom=0x%x hinst=%p style=0x%x clExtr=0x%x winExtr=0x%x\n",
-          atom, hInstance, style, classExtra, winExtra );
+    TRACE("name=%s hinst=%p style=0x%x clExtr=0x%x winExtr=0x%x\n",
+          debugstr_w(name), hInstance, style, classExtra, winExtra );
 
     /* Fix the extra bytes value */
 
@@ -319,25 +318,22 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, BOOL local,
         WARN("Win extra bytes %d is > 40\n", winExtra );
 
     classPtr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLASS) + classExtra );
-    if (!classPtr)
-    {
-        GlobalDeleteAtom( atom );
-        return NULL;
-    }
+    if (!classPtr) return NULL;
 
     SERVER_START_REQ( create_class )
     {
         req->local      = local;
-        req->atom       = atom;
         req->style      = style;
         req->instance   = hInstance;
         req->extra      = classExtra;
         req->win_extra  = winExtra;
         req->client_ptr = classPtr;
+        if (IS_INTRESOURCE(name)) req->atom = LOWORD(name);
+        else wine_server_add_data( req, name, strlenW(name) * sizeof(WCHAR) );
         ret = !wine_server_call_err( req );
+        classPtr->atomName = reply->atom;
     }
     SERVER_END_REQ;
-    GlobalDeleteAtom( atom );  /* the server increased the atom ref count */
     if (!ret)
     {
         HeapFree( GetProcessHeap(), 0, classPtr );
@@ -349,7 +345,6 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, BOOL local,
     classPtr->cbWndExtra  = winExtra;
     classPtr->cbClsExtra  = classExtra;
     classPtr->hInstance   = hInstance;
-    classPtr->atomName    = atom;
 
     /* Other non-null values must be set by caller */
 
@@ -368,12 +363,9 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, BOOL local,
  */
 static WNDPROC register_builtin( const struct builtin_class_descr *descr )
 {
-    ATOM atom;
     CLASS *classPtr;
 
-    if (!(atom = GlobalAddAtomW( descr->name ))) return 0;
-
-    if (!(classPtr = CLASS_RegisterClass( atom, user32_module, FALSE,
+    if (!(classPtr = CLASS_RegisterClass( descr->name, user32_module, FALSE,
                                           descr->style, 0, descr->extra ))) return 0;
 
     classPtr->hCursor       = LoadCursorA( 0, (LPSTR)descr->cursor );
@@ -506,14 +498,25 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
     }
     if (!(instance = wc->hInstance)) instance = GetModuleHandleW( NULL );
 
-    if (!(atom = GlobalAddAtomA( wc->lpszClassName ))) return 0;
+    if (!IS_INTRESOURCE(wc->lpszClassName))
+    {
+        WCHAR name[MAX_ATOM_LEN + 1];
 
-    if (!(classPtr = CLASS_RegisterClass( atom, instance, !(wc->style & CS_GLOBALCLASS),
-                                          wc->style, wc->cbClsExtra, wc->cbWndExtra )))
-        return 0;
+        if (!MultiByteToWideChar( CP_ACP, 0, wc->lpszClassName, -1, name, MAX_ATOM_LEN + 1 )) return 0;
+        classPtr = CLASS_RegisterClass( name, instance, !(wc->style & CS_GLOBALCLASS),
+                                        wc->style, wc->cbClsExtra, wc->cbWndExtra );
+    }
+    else
+    {
+        classPtr = CLASS_RegisterClass( (LPCWSTR)wc->lpszClassName, instance,
+                                        !(wc->style & CS_GLOBALCLASS), wc->style,
+                                        wc->cbClsExtra, wc->cbWndExtra );
+    }
+    if (!classPtr) return 0;
+    atom = classPtr->atomName;
 
-    TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
-          atom, wc->lpfnWndProc, instance, wc->hbrBackground,
+    TRACE("name=%s atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
+          debugstr_a(wc->lpszClassName), atom, wc->lpfnWndProc, instance, wc->hbrBackground,
           wc->style, wc->cbClsExtra, wc->cbWndExtra, classPtr );
 
     classPtr->hIcon         = wc->hIcon;
@@ -544,14 +547,14 @@ ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
     }
     if (!(instance = wc->hInstance)) instance = GetModuleHandleW( NULL );
 
-    if (!(atom = GlobalAddAtomW( wc->lpszClassName ))) return 0;
-
-    if (!(classPtr = CLASS_RegisterClass( atom, instance, !(wc->style & CS_GLOBALCLASS),
+    if (!(classPtr = CLASS_RegisterClass( wc->lpszClassName, instance, !(wc->style & CS_GLOBALCLASS),
                                           wc->style, wc->cbClsExtra, wc->cbWndExtra )))
         return 0;
 
-    TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
-          atom, wc->lpfnWndProc, instance, wc->hbrBackground,
+    atom = classPtr->atomName;
+
+    TRACE("name=%s atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
+          debugstr_w(wc->lpszClassName), atom, wc->lpfnWndProc, instance, wc->hbrBackground,
           wc->style, wc->cbClsExtra, wc->cbWndExtra, classPtr );
 
     classPtr->hIcon         = wc->hIcon;
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 606e814..da3c45b 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -3594,10 +3594,12 @@ struct create_class_request
     int            extra;
     int            win_extra;
     void*          client_ptr;
+    /* VARARG(name,unicode_str); */
 };
 struct create_class_reply
 {
     struct reply_header __header;
+    atom_t         atom;
 };
 
 
@@ -4880,6 +4882,6 @@ union generic_reply
     struct set_completion_info_reply set_completion_info_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 324
+#define SERVER_PROTOCOL_VERSION 325
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/class.c b/server/class.c
index e0cfbbd..ff39dc0 100644
--- a/server/class.c
+++ b/server/class.c
@@ -142,32 +142,45 @@ void *get_class_client_ptr( struct window_class *class )
 DECL_HANDLER(create_class)
 {
     struct window_class *class;
+    atom_t atom;
 
-    class = find_class( current->process, req->atom, req->instance );
+    if (get_req_data_size())
+    {
+        atom = add_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
+        if (!atom) return;
+    }
+    else
+    {
+        atom = req->atom;
+        if (!grab_global_atom( NULL, atom )) return;
+    }
+
+    class = find_class( current->process, atom, req->instance );
     if (class && !class->local == !req->local)
     {
         set_win32_error( ERROR_CLASS_ALREADY_EXISTS );
+        release_global_atom( NULL, atom );
         return;
     }
     if (req->extra < 0 || req->extra > 4096 || req->win_extra < 0 || req->win_extra > 4096)
     {
         /* don't allow stupid values here */
         set_error( STATUS_INVALID_PARAMETER );
+        release_global_atom( NULL, atom );
         return;
     }
 
-    if (!grab_global_atom( NULL, req->atom )) return;
-
     if (!(class = create_class( current->process, req->extra, req->local )))
     {
-        release_global_atom( NULL, req->atom );
+        release_global_atom( NULL, atom );
         return;
     }
-    class->atom       = req->atom;
+    class->atom       = atom;
     class->instance   = req->instance;
     class->style      = req->style;
     class->win_extra  = req->win_extra;
     class->client_ptr = req->client_ptr;
+    reply->atom = atom;
 }
 
 /* destroy a window class */
diff --git a/server/protocol.def b/server/protocol.def
index c91e8db..aa06bd5 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2600,6 +2600,9 @@ enum message_type
     int            extra;          /* number of extra class bytes */
     int            win_extra;      /* number of window extra bytes */
     void*          client_ptr;     /* pointer to class in client address space */
+    VARARG(name,unicode_str);      /* class name */
+ at REPLY
+    atom_t         atom;           /* resulting class atom */
 @END
 
 
diff --git a/server/trace.c b/server/trace.c
index e63cad9..3d5a3c5 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3192,7 +3192,14 @@ static void dump_create_class_request( const struct create_class_request *req )
     fprintf( stderr, " instance=%p,", req->instance );
     fprintf( stderr, " extra=%d,", req->extra );
     fprintf( stderr, " win_extra=%d,", req->win_extra );
-    fprintf( stderr, " client_ptr=%p", req->client_ptr );
+    fprintf( stderr, " client_ptr=%p,", req->client_ptr );
+    fprintf( stderr, " name=" );
+    dump_varargs_unicode_str( cur_size );
+}
+
+static void dump_create_class_reply( const struct create_class_reply *req )
+{
+    fprintf( stderr, " atom=%04x", req->atom );
 }
 
 static void dump_destroy_class_request( const struct destroy_class_request *req )
@@ -4106,7 +4113,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_start_hook_chain_reply,
     (dump_func)0,
     (dump_func)dump_get_hook_info_reply,
-    (dump_func)0,
+    (dump_func)dump_create_class_reply,
     (dump_func)dump_destroy_class_reply,
     (dump_func)dump_set_class_info_reply,
     (dump_func)dump_set_clipboard_info_reply,




More information about the wine-cvs mailing list