Added window classes in the server, and support for inter-process
GetClassWord/Long (based on a patch by Mike McCormack).
Various fixes to the class instance handling.

diff --git a/server/window.c b/server/window.c
index 6373068..d6a1b6f 100644
--- a/server/window.c
+++ b/server/window.c
@@ -63,6 +63,7 @@
     struct window   *prev;            /* prev window in Z-order */
     user_handle_t    handle;          /* full handle for this window */
     struct thread   *thread;          /* thread owning the window */
+    struct window_class *class;       /* window class */
     atom_t           atom;            /* class atom */
     user_handle_t    last_active;     /* last active popup */
     rectangle_t      window_rect;     /* window rectangle */
@@ -260,6 +261,7 @@
     free_user_handle( win->handle );
     destroy_properties( win );
     unlink_window( win );
+    release_class( win->class );
     if (win->text) free( win->text );
     memset( win, 0x55, sizeof(*win) );
     free( win );
@@ -267,13 +269,23 @@
 
 /* create a new window structure (note: the window is not linked in the window tree) */
 static struct window *create_window( struct window *parent, struct window *owner, atom_t atom,
-                                     int extra_bytes )
+                                     void *instance, int extra_bytes )
 {
-    struct window *win = mem_alloc( sizeof(*win) + extra_bytes - 1 );
-    if (!win) return NULL;
+    struct window *win;
+    struct window_class *class = grab_class( current->process, atom, instance );
+
+    if (!class) return NULL;
+
+    win = mem_alloc( sizeof(*win) + extra_bytes - 1 );
+    if (!win)
+    {
+        release_class( class );
+        return NULL;
+    }
 
     if (!(win->handle = alloc_user_handle( win, USER_WINDOW )))
     {
+        release_class( class );
         free( win );
         return NULL;
     }
@@ -283,6 +295,7 @@
     win->last_child     = NULL;
     win->first_unlinked = NULL;
     win->thread         = current;
+    win->class          = class;
     win->atom           = atom;
     win->last_active    = win->handle;
     win->style          = 0;
@@ -449,6 +462,15 @@
 }
 
 
+/* get the window class of a window */
+struct window_class* get_window_class( user_handle_t window )
+{
+    struct window *win;
+    if (!(win = get_window( window ))) return NULL;
+    return win->class;
+}
+
+
 /* create a window */
 DECL_HANDLER(create_window)
 {
@@ -462,7 +484,7 @@
     {
         if (!top_window)
         {
-            if (!(top_window = create_window( NULL, NULL, req->atom, req->extra ))) return;
+            if (!(top_window = create_window( NULL, NULL, req->atom, req->instance, req->extra ))) return;
             top_window->thread = NULL;  /* no thread owns the desktop */
             top_window->style  = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
         }
@@ -481,7 +503,7 @@
             set_error( STATUS_ACCESS_DENIED );
             return;
         }
-        if (!(win = create_window( parent, owner, req->atom, req->extra ))) return;
+        if (!(win = create_window( parent, owner, req->atom, req->instance, req->extra ))) return;
         reply->handle = win->handle;
     }
 }
@@ -569,7 +591,7 @@
         {
             reply->tid  = get_thread_id( win->thread );
             reply->pid  = get_process_id( win->thread->process );
-            reply->atom = win->atom;
+            reply->atom = get_class_atom( win->class );
         }
     }
 }
@@ -648,7 +670,7 @@
     if (parent)
         for (ptr = parent->first_child, total = 0; ptr; ptr = ptr->next)
         {
-            if (req->atom && ptr->atom != req->atom) continue;
+            if (req->atom && get_class_atom(ptr->class) != req->atom) continue;
             if (req->tid && get_thread_id(ptr->thread) != req->tid) continue;
             total++;
         }
@@ -659,7 +681,7 @@
     {
         for (ptr = parent->first_child; ptr && len; ptr = ptr->next)
         {
-            if (req->atom && ptr->atom != req->atom) continue;
+            if (req->atom && get_class_atom(ptr->class) != req->atom) continue;
             if (req->tid && get_thread_id(ptr->thread) != req->tid) continue;
             *data++ = ptr->handle;
             len -= sizeof(*data);