Made all 16<->32 HWND conversions use explicit functions instead of
[wine/multimedia.git] / server / user.c
blob88c7fd71d586da837146dc17847340d451ec391b
1 /*
2 * Server-side USER handles
4 * Copyright (C) 2001 Alexandre Julliard
5 */
7 #include "thread.h"
8 #include "user.h"
10 struct user_handle
12 void *ptr; /* pointer to object */
13 unsigned short type; /* object type (0 if free) */
14 unsigned short generation; /* generation counter */
17 static struct user_handle *handles;
18 static struct user_handle *freelist;
19 static int nb_handles;
20 static int allocated_handles;
22 #define FIRST_HANDLE 32 /* handle value for first table entry */
23 #define LAST_HANDLE (65536 - 16)
24 #define MAX_HANDLES (LAST_HANDLE - FIRST_HANDLE)
26 static struct user_handle *handle_to_entry( user_handle_t handle )
28 int index = (handle & 0xffff) - FIRST_HANDLE;
29 if (index < 0 || index >= nb_handles) return NULL;
30 if (!handles[index].type) return NULL;
31 if ((handle >> 16) && (handle >> 16 != handles[index].generation)) return NULL;
32 return &handles[index];
35 inline static user_handle_t entry_to_handle( struct user_handle *ptr )
37 int index = ptr - handles;
38 return (index + FIRST_HANDLE) + (ptr->generation << 16);
41 inline static struct user_handle *alloc_user_entry(void)
43 struct user_handle *handle;
45 if (freelist)
47 handle = freelist;
48 freelist = handle->ptr;
49 return handle;
51 if (nb_handles >= allocated_handles) /* need to grow the array */
53 struct user_handle *new_handles;
54 /* grow array by 50% (but at minimum 32 entries) */
55 int growth = max( 32, allocated_handles / 2 );
56 int new_size = min( allocated_handles + growth, MAX_HANDLES );
57 if (new_size <= allocated_handles) return NULL;
58 if (!(new_handles = realloc( handles, new_size * sizeof(*handles) )))
59 return NULL;
60 handles = new_handles;
61 allocated_handles = new_size;
63 handle = &handles[nb_handles++];
64 handle->generation = 0;
65 return handle;
68 inline static void *free_user_entry( struct user_handle *ptr )
70 void *ret;
71 ret = ptr->ptr;
72 ptr->ptr = freelist;
73 ptr->type = 0;
74 freelist = ptr;
75 return ret;
78 /* allocate a user handle for a given object */
79 user_handle_t alloc_user_handle( void *ptr, enum user_object type )
81 struct user_handle *entry = alloc_user_entry();
82 if (!entry) return 0;
83 entry->ptr = ptr;
84 entry->type = type;
85 if (++entry->generation >= 0xffff) entry->generation = 1;
86 return entry_to_handle( entry );
89 /* return a pointer to a user object from its handle */
90 void *get_user_object( user_handle_t handle, enum user_object type )
92 struct user_handle *entry;
94 if (!(entry = handle_to_entry( handle )) || entry->type != type)
96 set_error( STATUS_INVALID_HANDLE );
97 return NULL;
99 return entry->ptr;
102 /* get the full handle for a possibly truncated handle */
103 user_handle_t get_user_full_handle( user_handle_t handle )
105 struct user_handle *entry;
107 if (handle >> 16) return handle;
108 if (!(entry = handle_to_entry( handle ))) return handle;
109 return entry_to_handle( entry );
112 /* same as get_user_object plus set the handle to the full 32-bit value */
113 void *get_user_object_handle( user_handle_t *handle, enum user_object type )
115 struct user_handle *entry;
117 if (!(entry = handle_to_entry( *handle )) || entry->type != type)
119 set_error( STATUS_INVALID_HANDLE );
120 return NULL;
122 *handle = entry_to_handle( entry );
123 return entry->ptr;
126 /* free a user handle and return a pointer to the object */
127 void *free_user_handle( user_handle_t handle )
129 struct user_handle *entry;
131 if (!(entry = handle_to_entry( handle )))
133 set_error( STATUS_INVALID_HANDLE );
134 return NULL;
136 return free_user_entry( entry );
139 /* return the next user handle after 'handle' that is of a given type */
140 void *next_user_handle( user_handle_t *handle, enum user_object type )
142 struct user_handle *entry;
144 if (!*handle) entry = handles;
145 else
147 if (!(entry = handle_to_entry( *handle ))) return NULL;
148 entry++; /* start from the next one */
150 while (entry < handles + nb_handles)
152 if (!type || entry->type == type)
154 *handle = entry_to_handle( entry );
155 return entry->ptr;
157 entry++;
159 return NULL;