Added atom_t type for atoms to make sure we use the same type
everywhere. Handle MIN_STR_ATOM offset in the server.

diff --git a/server/atom.c b/server/atom.c
index 63be7b4..a0e0e4b 100644
--- a/server/atom.c
+++ b/server/atom.c
@@ -20,15 +20,16 @@
 #define MAX_HASH_SIZE 0x200
 
 #define MAX_ATOM_LEN  255
+#define MIN_STR_ATOM  0xc000
 #define MAX_ATOMS     0x4000
 
 struct atom_entry
 {
     struct atom_entry *next;   /* hash table list */
     struct atom_entry *prev;   /* hash table list */
-    int                atom;   /* atom handle */
     int                count;  /* reference count */
     int                hash;   /* string hash */
+    atom_t             atom;   /* atom handle */
     WCHAR              str[1]; /* atom string */
 };
 
@@ -107,16 +108,17 @@
 }
 
 /* retrieve an entry pointer from its atom */
-static struct atom_entry *get_atom_entry( struct atom_table *table, int atom )
+static struct atom_entry *get_atom_entry( struct atom_table *table, atom_t atom )
 {
     struct atom_entry *entry = NULL;
-    if (table && (atom >= 0) && (atom <= table->last)) entry = table->handles[atom];
+    if (table && (atom >= MIN_STR_ATOM) && (atom <= MIN_STR_ATOM + table->last))
+        entry = table->handles[atom - MIN_STR_ATOM];
     if (!entry) set_error( STATUS_INVALID_HANDLE );
     return entry;
 }
 
 /* add an atom entry in the table and return its handle */
-static int add_atom_entry( struct atom_table *table, struct atom_entry *entry )
+static atom_t add_atom_entry( struct atom_table *table, struct atom_entry *entry )
 {
     int i;
     for (i = 0; i <= table->last; i++)
@@ -131,7 +133,7 @@
         if (!new_table)
         {
             set_error( STATUS_NO_MEMORY );
-            return -1;
+            return 0;
         }
         table->count = new_size;
         table->handles = new_table;
@@ -139,8 +141,8 @@
     table->last = i;
  found:
     table->handles[i] = entry;
-    entry->atom = i;
-    return i;
+    entry->atom = i + MIN_STR_ATOM;
+    return entry->atom;
 }
 
 /* compute the hash code for a string */
@@ -166,7 +168,7 @@
     {
         struct atom_entry *entry = table->handles[i];
         if (!entry) continue;
-        fprintf( stderr, "  %5d: ref=%d hash=%d \"", i, entry->count, entry->hash );
+        fprintf( stderr, "  %04x: ref=%d hash=%d \"", entry->atom, entry->count, entry->hash );
         dump_strW( entry->str, strlenW(entry->str), stderr, "\"\"");
         fprintf( stderr, "\"\n" );
     }
@@ -205,16 +207,16 @@
 }
 
 /* add an atom to the table */
-static int add_atom( struct atom_table *table, const WCHAR *str )
+static atom_t add_atom( struct atom_table *table, const WCHAR *str )
 {
     struct atom_entry *entry;
     int hash = atom_hash( table, str );
-    int atom = -1;
+    atom_t atom = 0;
 
     if (!*str)
     {
         set_error( STATUS_OBJECT_NAME_INVALID );
-        return -1;
+        return 0;
     }
     if ((entry = find_atom_entry( table, str, hash )))  /* exists already */
     {
@@ -224,7 +226,7 @@
 
     if ((entry = mem_alloc( sizeof(*entry) + strlenW(str) * sizeof(WCHAR) )))
     {
-        if ((atom = add_atom_entry( table, entry )) != -1)
+        if ((atom = add_atom_entry( table, entry )))
         {
             entry->prev  = NULL;
             if ((entry->next = table->entries[hash])) entry->next->prev = entry;
@@ -240,7 +242,7 @@
 }
 
 /* delete an atom from the table */
-static void delete_atom( struct atom_table *table, int atom )
+static void delete_atom( struct atom_table *table, atom_t atom )
 {
     struct atom_entry *entry = get_atom_entry( table, atom );
     if (entry && !--entry->count)
@@ -248,24 +250,25 @@
         if (entry->next) entry->next->prev = entry->prev;
         if (entry->prev) entry->prev->next = entry->next;
         else table->entries[entry->hash] = entry->next;
-        table->handles[atom] = NULL;
+        table->handles[atom - MIN_STR_ATOM] = NULL;
         free( entry );
     }
 }
 
 /* find an atom in the table */
-static int find_atom( struct atom_table *table, const WCHAR *str )
+static atom_t find_atom( struct atom_table *table, const WCHAR *str )
 {
     struct atom_entry *entry;
 
-    if (table && ((entry = find_atom_entry( table, str, atom_hash(table, str) )))) return entry->atom;
+    if (table && ((entry = find_atom_entry( table, str, atom_hash(table, str) ))))
+        return entry->atom;
     if (!*str) set_error( STATUS_OBJECT_NAME_INVALID );
     else set_error( STATUS_OBJECT_NAME_NOT_FOUND );
-    return -1;
+    return 0;
 }
 
 /* get an atom name and refcount*/
-static size_t get_atom_name( struct atom_table *table, int atom,
+static size_t get_atom_name( struct atom_table *table, atom_t atom,
                              WCHAR *str, size_t maxsize, int *count )
 {
     size_t len = 0;
@@ -285,6 +288,20 @@
     return len;
 }
 
+/* increment the ref count of a global atom; used for window properties */
+int grab_global_atom( atom_t atom )
+{
+    struct atom_entry *entry = get_atom_entry( global_table, atom );
+    if (entry) entry->count++;
+    return (entry != NULL);
+}
+
+/* decrement the ref count of a global atom; used for window properties */
+void release_global_atom( atom_t atom )
+{
+    delete_atom( global_table, atom );
+}
+
 /* add a global atom */
 DECL_HANDLER(add_atom)
 {
diff --git a/server/object.h b/server/object.h
index 12cf7c6..8455720 100644
--- a/server/object.h
+++ b/server/object.h
@@ -178,6 +178,8 @@
 /* atom functions */
 
 extern void close_atom_table(void);
+extern int grab_global_atom( atom_t atom );
+extern void release_global_atom( atom_t atom );
 
 /* global variables */
 
diff --git a/server/protocol.def b/server/protocol.def
index d19e694..fa0b81e 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -40,6 +40,7 @@
 #define REQUEST_MAX_VAR_SIZE  1024
 
 typedef int handle_t;
+typedef unsigned short atom_t;
 typedef unsigned int user_handle_t;
 
 #define FIRST_USER_HANDLE 0x0020  /* first possible value for low word of user handle */
@@ -1125,13 +1126,13 @@
     int           local;       /* is atom in local process table? */
     VARARG(name,unicode_str);  /* atom name */
 @REPLY
-    int           atom;        /* resulting atom */
+    atom_t        atom;        /* resulting atom */
 @END
 
 
 /* Delete an atom */
 @REQ(delete_atom)
-    int           atom;        /* atom handle */
+    atom_t        atom;        /* atom handle */
     int           local;       /* is atom in local process table? */
 @END
 
@@ -1141,13 +1142,13 @@
     int          local;        /* is atom in local process table? */
     VARARG(name,unicode_str);  /* atom name */
 @REPLY
-    int          atom;         /* atom handle */
+    atom_t       atom;         /* atom handle */
 @END
 
 
 /* Get an atom name */
 @REQ(get_atom_name)
-    int          atom;         /* atom handle */
+    atom_t       atom;         /* atom handle */
     int          local;        /* is atom in local process table? */
 @REPLY
     int          count;        /* atom lock count */
@@ -1404,7 +1405,7 @@
 @REQ(create_window)
     user_handle_t  parent;      /* parent window */
     user_handle_t  owner;       /* owner window */
-    unsigned int   atom;        /* class atom */
+    atom_t         atom;        /* class atom */
 @REPLY
     user_handle_t  handle;      /* created window */
 @END
@@ -1447,7 +1448,7 @@
 /* Get a list of the window children */
 @REQ(get_window_children)
     user_handle_t  parent;        /* parent window */
-    unsigned int   atom;          /* class atom for the listed children */
+    atom_t         atom;          /* class atom for the listed children */
     void*          tid;           /* thread owning the listed children */
 @REPLY
     int            count;         /* total count of children */
diff --git a/server/trace.c b/server/trace.c
index 58861ed..094ff25 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1382,12 +1382,12 @@
 
 static void dump_add_atom_reply( const struct add_atom_request *req )
 {
-    fprintf( stderr, " atom=%d", req->atom );
+    fprintf( stderr, " atom=%04x", req->atom );
 }
 
 static void dump_delete_atom_request( const struct delete_atom_request *req )
 {
-    fprintf( stderr, " atom=%d,", req->atom );
+    fprintf( stderr, " atom=%04x,", req->atom );
     fprintf( stderr, " local=%d", req->local );
 }
 
@@ -1400,12 +1400,12 @@
 
 static void dump_find_atom_reply( const struct find_atom_request *req )
 {
-    fprintf( stderr, " atom=%d", req->atom );
+    fprintf( stderr, " atom=%04x", req->atom );
 }
 
 static void dump_get_atom_name_request( const struct get_atom_name_request *req )
 {
-    fprintf( stderr, " atom=%d,", req->atom );
+    fprintf( stderr, " atom=%04x,", req->atom );
     fprintf( stderr, " local=%d", req->local );
 }
 
@@ -1668,7 +1668,7 @@
 {
     fprintf( stderr, " parent=%08x,", req->parent );
     fprintf( stderr, " owner=%08x,", req->owner );
-    fprintf( stderr, " atom=%08x", req->atom );
+    fprintf( stderr, " atom=%04x", req->atom );
 }
 
 static void dump_create_window_reply( const struct create_window_request *req )
@@ -1715,7 +1715,7 @@
 static void dump_get_window_children_request( const struct get_window_children_request *req )
 {
     fprintf( stderr, " parent=%08x,", req->parent );
-    fprintf( stderr, " atom=%08x,", req->atom );
+    fprintf( stderr, " atom=%04x,", req->atom );
     fprintf( stderr, " tid=%p", req->tid );
 }