Commit 0762d98f authored by Alexandre Julliard's avatar Alexandre Julliard

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

parent bfe88a00
...@@ -295,16 +295,15 @@ static CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance ) ...@@ -295,16 +295,15 @@ static CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance )
* CLASS_RegisterClass * CLASS_RegisterClass
* *
* The real RegisterClass() functionality. * 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 ) DWORD style, INT classExtra, INT winExtra )
{ {
CLASS *classPtr; CLASS *classPtr;
BOOL ret; BOOL ret;
TRACE("atom=0x%x hinst=%p style=0x%x clExtr=0x%x winExtr=0x%x\n", TRACE("name=%s hinst=%p style=0x%x clExtr=0x%x winExtr=0x%x\n",
atom, hInstance, style, classExtra, winExtra ); debugstr_w(name), hInstance, style, classExtra, winExtra );
/* Fix the extra bytes value */ /* Fix the extra bytes value */
...@@ -319,25 +318,22 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, BOOL local, ...@@ -319,25 +318,22 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, BOOL local,
WARN("Win extra bytes %d is > 40\n", winExtra ); WARN("Win extra bytes %d is > 40\n", winExtra );
classPtr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLASS) + classExtra ); classPtr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLASS) + classExtra );
if (!classPtr) if (!classPtr) return NULL;
{
GlobalDeleteAtom( atom );
return NULL;
}
SERVER_START_REQ( create_class ) SERVER_START_REQ( create_class )
{ {
req->local = local; req->local = local;
req->atom = atom;
req->style = style; req->style = style;
req->instance = hInstance; req->instance = hInstance;
req->extra = classExtra; req->extra = classExtra;
req->win_extra = winExtra; req->win_extra = winExtra;
req->client_ptr = classPtr; 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 ); ret = !wine_server_call_err( req );
classPtr->atomName = reply->atom;
} }
SERVER_END_REQ; SERVER_END_REQ;
GlobalDeleteAtom( atom ); /* the server increased the atom ref count */
if (!ret) if (!ret)
{ {
HeapFree( GetProcessHeap(), 0, classPtr ); HeapFree( GetProcessHeap(), 0, classPtr );
...@@ -349,7 +345,6 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, BOOL local, ...@@ -349,7 +345,6 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, BOOL local,
classPtr->cbWndExtra = winExtra; classPtr->cbWndExtra = winExtra;
classPtr->cbClsExtra = classExtra; classPtr->cbClsExtra = classExtra;
classPtr->hInstance = hInstance; classPtr->hInstance = hInstance;
classPtr->atomName = atom;
/* Other non-null values must be set by caller */ /* Other non-null values must be set by caller */
...@@ -368,12 +363,9 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, BOOL local, ...@@ -368,12 +363,9 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, BOOL local,
*/ */
static WNDPROC register_builtin( const struct builtin_class_descr *descr ) static WNDPROC register_builtin( const struct builtin_class_descr *descr )
{ {
ATOM atom;
CLASS *classPtr; CLASS *classPtr;
if (!(atom = GlobalAddAtomW( descr->name ))) return 0; if (!(classPtr = CLASS_RegisterClass( descr->name, user32_module, FALSE,
if (!(classPtr = CLASS_RegisterClass( atom, user32_module, FALSE,
descr->style, 0, descr->extra ))) return 0; descr->style, 0, descr->extra ))) return 0;
classPtr->hCursor = LoadCursorA( 0, (LPSTR)descr->cursor ); classPtr->hCursor = LoadCursorA( 0, (LPSTR)descr->cursor );
...@@ -506,14 +498,25 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc ) ...@@ -506,14 +498,25 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
} }
if (!(instance = wc->hInstance)) instance = GetModuleHandleW( NULL ); 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), if (!MultiByteToWideChar( CP_ACP, 0, wc->lpszClassName, -1, name, MAX_ATOM_LEN + 1 )) return 0;
wc->style, wc->cbClsExtra, wc->cbWndExtra ))) classPtr = CLASS_RegisterClass( name, instance, !(wc->style & CS_GLOBALCLASS),
return 0; 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", TRACE("name=%s atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
atom, wc->lpfnWndProc, instance, wc->hbrBackground, debugstr_a(wc->lpszClassName), atom, wc->lpfnWndProc, instance, wc->hbrBackground,
wc->style, wc->cbClsExtra, wc->cbWndExtra, classPtr ); wc->style, wc->cbClsExtra, wc->cbWndExtra, classPtr );
classPtr->hIcon = wc->hIcon; classPtr->hIcon = wc->hIcon;
...@@ -544,14 +547,14 @@ ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc ) ...@@ -544,14 +547,14 @@ ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
} }
if (!(instance = wc->hInstance)) instance = GetModuleHandleW( NULL ); if (!(instance = wc->hInstance)) instance = GetModuleHandleW( NULL );
if (!(atom = GlobalAddAtomW( wc->lpszClassName ))) return 0; if (!(classPtr = CLASS_RegisterClass( wc->lpszClassName, instance, !(wc->style & CS_GLOBALCLASS),
if (!(classPtr = CLASS_RegisterClass( atom, instance, !(wc->style & CS_GLOBALCLASS),
wc->style, wc->cbClsExtra, wc->cbWndExtra ))) wc->style, wc->cbClsExtra, wc->cbWndExtra )))
return 0; return 0;
TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n", atom = classPtr->atomName;
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_w(wc->lpszClassName), atom, wc->lpfnWndProc, instance, wc->hbrBackground,
wc->style, wc->cbClsExtra, wc->cbWndExtra, classPtr ); wc->style, wc->cbClsExtra, wc->cbWndExtra, classPtr );
classPtr->hIcon = wc->hIcon; classPtr->hIcon = wc->hIcon;
......
...@@ -3594,10 +3594,12 @@ struct create_class_request ...@@ -3594,10 +3594,12 @@ struct create_class_request
int extra; int extra;
int win_extra; int win_extra;
void* client_ptr; void* client_ptr;
/* VARARG(name,unicode_str); */
}; };
struct create_class_reply struct create_class_reply
{ {
struct reply_header __header; struct reply_header __header;
atom_t atom;
}; };
...@@ -4880,6 +4882,6 @@ union generic_reply ...@@ -4880,6 +4882,6 @@ union generic_reply
struct set_completion_info_reply set_completion_info_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 */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -142,32 +142,45 @@ void *get_class_client_ptr( struct window_class *class ) ...@@ -142,32 +142,45 @@ void *get_class_client_ptr( struct window_class *class )
DECL_HANDLER(create_class) DECL_HANDLER(create_class)
{ {
struct window_class *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) if (class && !class->local == !req->local)
{ {
set_win32_error( ERROR_CLASS_ALREADY_EXISTS ); set_win32_error( ERROR_CLASS_ALREADY_EXISTS );
release_global_atom( NULL, atom );
return; return;
} }
if (req->extra < 0 || req->extra > 4096 || req->win_extra < 0 || req->win_extra > 4096) if (req->extra < 0 || req->extra > 4096 || req->win_extra < 0 || req->win_extra > 4096)
{ {
/* don't allow stupid values here */ /* don't allow stupid values here */
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
release_global_atom( NULL, atom );
return; return;
} }
if (!grab_global_atom( NULL, req->atom )) return;
if (!(class = create_class( current->process, req->extra, req->local ))) if (!(class = create_class( current->process, req->extra, req->local )))
{ {
release_global_atom( NULL, req->atom ); release_global_atom( NULL, atom );
return; return;
} }
class->atom = req->atom; class->atom = atom;
class->instance = req->instance; class->instance = req->instance;
class->style = req->style; class->style = req->style;
class->win_extra = req->win_extra; class->win_extra = req->win_extra;
class->client_ptr = req->client_ptr; class->client_ptr = req->client_ptr;
reply->atom = atom;
} }
/* destroy a window class */ /* destroy a window class */
......
...@@ -2600,6 +2600,9 @@ enum message_type ...@@ -2600,6 +2600,9 @@ enum message_type
int extra; /* number of extra class bytes */ int extra; /* number of extra class bytes */
int win_extra; /* number of window extra bytes */ int win_extra; /* number of window extra bytes */
void* client_ptr; /* pointer to class in client address space */ void* client_ptr; /* pointer to class in client address space */
VARARG(name,unicode_str); /* class name */
@REPLY
atom_t atom; /* resulting class atom */
@END @END
......
...@@ -3192,7 +3192,14 @@ static void dump_create_class_request( const struct create_class_request *req ) ...@@ -3192,7 +3192,14 @@ static void dump_create_class_request( const struct create_class_request *req )
fprintf( stderr, " instance=%p,", req->instance ); fprintf( stderr, " instance=%p,", req->instance );
fprintf( stderr, " extra=%d,", req->extra ); fprintf( stderr, " extra=%d,", req->extra );
fprintf( stderr, " win_extra=%d,", req->win_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 ) 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] = { ...@@ -4106,7 +4113,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_start_hook_chain_reply, (dump_func)dump_start_hook_chain_reply,
(dump_func)0, (dump_func)0,
(dump_func)dump_get_hook_info_reply, (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_destroy_class_reply,
(dump_func)dump_set_class_info_reply, (dump_func)dump_set_class_info_reply,
(dump_func)dump_set_clipboard_info_reply, (dump_func)dump_set_clipboard_info_reply,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment