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 );
}