Module: wine Branch: master Commit: 0762d98f7c16cca89882b20e72211b0d6df5331c URL: http://source.winehq.org/git/wine.git/?a=commit;h=0762d98f7c16cca89882b20e72...
Author: Alexandre Julliard julliard@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 */ +@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,