1ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston/*
2ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston Copyright (c) 2008, 2009 Apple Inc.
3ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
4ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston Permission is hereby granted, free of charge, to any person
5ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston obtaining a copy of this software and associated documentation files
6ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston (the "Software"), to deal in the Software without restriction,
7ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston including without limitation the rights to use, copy, modify, merge,
8ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston publish, distribute, sublicense, and/or sell copies of the Software,
9ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston and to permit persons to whom the Software is furnished to do so,
10ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston subject to the following conditions:
11ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
12ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston The above copyright notice and this permission notice shall be
13ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston included in all copies or substantial portions of the Software.
14ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
15ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston NONINFRINGEMENT.  IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
19ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston DEALINGS IN THE SOFTWARE.
23ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
24ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston Except as contained in this notice, the name(s) of the above
25ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston copyright holders shall not be used in advertising or otherwise to
26ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston promote the sale, use or other dealings in this Software without
27ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston prior written authorization.
28ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston*/
29ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
30ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <stdbool.h>
31ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <stdio.h>
32ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <stdlib.h>
33ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <assert.h>
34ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <pthread.h>
35cf5db0a418b63d71385b43897a7ea9be7bb785d1Jeremy Huddleston#include <string.h>
36ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include "apple_glx.h"
37ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include "apple_glx_context.h"
38ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include "apple_glx_drawable.h"
39ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include "appledri.h"
40ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
41ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic pthread_mutex_t drawables_lock = PTHREAD_MUTEX_INITIALIZER;
42ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic struct apple_glx_drawable *drawables_list = NULL;
43ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
44ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
45ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonlock_drawables_list(void)
46ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
47ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int err;
48ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
49ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   err = pthread_mutex_lock(&drawables_lock);
50ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
51ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err) {
52cf5db0a418b63d71385b43897a7ea9be7bb785d1Jeremy Huddleston      fprintf(stderr, "pthread_mutex_lock failure in %s: %s\n",
53cf5db0a418b63d71385b43897a7ea9be7bb785d1Jeremy Huddleston              __func__, strerror(err));
54ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
55ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
56ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
57ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
58ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
59ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonunlock_drawables_list(void)
60ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
61ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int err;
62ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
63ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   err = pthread_mutex_unlock(&drawables_lock);
64ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
65ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err) {
66cf5db0a418b63d71385b43897a7ea9be7bb785d1Jeremy Huddleston      fprintf(stderr, "pthread_mutex_unlock failure in %s: %s\n",
67cf5db0a418b63d71385b43897a7ea9be7bb785d1Jeremy Huddleston              __func__, strerror(err));
68ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
69ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
70ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
71ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
72ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstruct apple_glx_drawable *
73ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_find_drawable(Display * dpy, GLXDrawable drawable)
74ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
75ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *i, *agd = NULL;
76ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
77ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
78ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
79ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   for (i = drawables_list; i; i = i->next) {
80ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      if (i->drawable == drawable) {
81ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         agd = i;
82ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         break;
83ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      }
84ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
85ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
86ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
87ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
88ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return agd;
89ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
90ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
91ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
92ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestondrawable_lock(struct apple_glx_drawable *agd)
93ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
94ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int err;
95ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
96ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   err = pthread_mutex_lock(&agd->mutex);
97ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
98ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err) {
99cf5db0a418b63d71385b43897a7ea9be7bb785d1Jeremy Huddleston      fprintf(stderr, "pthread_mutex_lock error: %s\n", strerror(err));
100ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
101ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
102ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
103ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
104ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
105ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestondrawable_unlock(struct apple_glx_drawable *d)
106ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
107ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int err;
108ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
109ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   err = pthread_mutex_unlock(&d->mutex);
110ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
111ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err) {
112cf5db0a418b63d71385b43897a7ea9be7bb785d1Jeremy Huddleston      fprintf(stderr, "pthread_mutex_unlock error: %s\n", strerror(err));
113ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
114ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
115ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
116ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
117ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
118ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
119ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonreference_drawable(struct apple_glx_drawable *d)
120ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
121ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->lock(d);
122ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->reference_count++;
123ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->unlock(d);
124ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
125ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
126ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
127ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonrelease_drawable(struct apple_glx_drawable *d)
128ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
129ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->lock(d);
130ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->reference_count--;
131ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->unlock(d);
132ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
133ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
134ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston/* The drawables list must be locked prior to calling this. */
135ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston/* Return true if the drawable was destroyed. */
136ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic bool
137ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestondestroy_drawable(struct apple_glx_drawable *d)
138ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
1391a33c1b2b895566299ec76643659adacc239a3dcJeremy Huddleston   int err;
140ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
141ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->lock(d);
142ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
143ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (d->reference_count > 0) {
144ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d->unlock(d);
145ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      return false;
146ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
147ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
148ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->unlock(d);
149ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
150ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (d->previous) {
151ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d->previous->next = d->next;
152ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
153ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   else {
154ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      /*
155ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * The item must be at the head of the list, if it
156ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * has no previous pointer.
157ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       */
158ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      drawables_list = d->next;
159ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
160ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
161ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (d->next)
162ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d->next->previous = d->previous;
163ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
164ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
165ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
166ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (d->callbacks.destroy) {
167ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      /*
168ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * Warning: this causes other routines to be called (potentially)
169ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * from surface_notify_handler.  It's probably best to not have
170ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * any locks at this point locked.
171ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       */
172ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d->callbacks.destroy(d->display, d);
173ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
174ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
175ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   apple_glx_diagnostic("%s: freeing %p\n", __func__, (void *) d);
176ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
177a73a800b3200d21c32fac9f28e2f86919bc0a2baJeremy Huddleston   /* Stupid recursive locks */
178a73a800b3200d21c32fac9f28e2f86919bc0a2baJeremy Huddleston   while (pthread_mutex_unlock(&d->mutex) == 0);
179a73a800b3200d21c32fac9f28e2f86919bc0a2baJeremy Huddleston
1801a33c1b2b895566299ec76643659adacc239a3dcJeremy Huddleston   err = pthread_mutex_destroy(&d->mutex);
1811a33c1b2b895566299ec76643659adacc239a3dcJeremy Huddleston   if (err) {
1821a33c1b2b895566299ec76643659adacc239a3dcJeremy Huddleston      fprintf(stderr, "pthread_mutex_destroy error: %s\n", strerror(err));
1831a33c1b2b895566299ec76643659adacc239a3dcJeremy Huddleston      abort();
1841a33c1b2b895566299ec76643659adacc239a3dcJeremy Huddleston   }
1851a33c1b2b895566299ec76643659adacc239a3dcJeremy Huddleston
186ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   free(d);
187ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
188ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   /* So that the locks are balanced and the caller correctly unlocks. */
189ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
190ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
191ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return true;
192ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
193ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
194ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston/*
195ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston * This is typically called when a context is destroyed or the current
196ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston * drawable is made None.
197ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston */
198ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic bool
199ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestondestroy_drawable_callback(struct apple_glx_drawable *d)
200ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
201ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   bool result;
202ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
203ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->lock(d);
204ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
205ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   apple_glx_diagnostic("%s: %p ->reference_count before -- %d\n", __func__,
206ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                        (void *) d, d->reference_count);
207ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
208ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->reference_count--;
209ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
210ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (d->reference_count > 0) {
211ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d->unlock(d);
212ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      return false;
213ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
214ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
215ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->unlock(d);
216ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
217ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
218ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
219ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   result = destroy_drawable(d);
220ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
221ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
222ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
223ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return result;
224ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
225ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
226ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic bool
227ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonis_pbuffer(struct apple_glx_drawable *d)
228ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
229ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return APPLE_GLX_DRAWABLE_PBUFFER == d->type;
230ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
231ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
232ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic bool
233ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonis_pixmap(struct apple_glx_drawable *d)
234ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
235ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return APPLE_GLX_DRAWABLE_PIXMAP == d->type;
236ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
237ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
238ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
239ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestoncommon_init(Display * dpy, GLXDrawable drawable, struct apple_glx_drawable *d)
240ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
241ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int err;
242ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   pthread_mutexattr_t attr;
243ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
244ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->display = dpy;
245ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->reference_count = 0;
246ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->drawable = drawable;
247ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->type = -1;
248ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
249ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   err = pthread_mutexattr_init(&attr);
250ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
251ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err) {
252cf5db0a418b63d71385b43897a7ea9be7bb785d1Jeremy Huddleston      fprintf(stderr, "pthread_mutexattr_init error: %s\n", strerror(err));
253ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
254ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
255ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
256ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   /*
257ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston    * There are some patterns that require a recursive mutex,
258ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston    * when working with locks that protect the apple_glx_drawable,
259ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston    * and reference functions like ->reference, and ->release.
260ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston    */
261ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
262ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
263ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err) {
264cf5db0a418b63d71385b43897a7ea9be7bb785d1Jeremy Huddleston      fprintf(stderr, "error: setting pthread mutex type: %s\n", strerror(err));
265ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
266ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
267ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
268ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   err = pthread_mutex_init(&d->mutex, &attr);
269ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
270ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err) {
271cf5db0a418b63d71385b43897a7ea9be7bb785d1Jeremy Huddleston      fprintf(stderr, "pthread_mutex_init error: %s\n", strerror(err));
272ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
273ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
274ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
275ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   (void) pthread_mutexattr_destroy(&attr);
276ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
277ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->lock = drawable_lock;
278ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->unlock = drawable_unlock;
279ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
280ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->reference = reference_drawable;
281ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->release = release_drawable;
282ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
283ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->destroy = destroy_drawable_callback;
284ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
285ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->is_pbuffer = is_pbuffer;
286ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->is_pixmap = is_pixmap;
287ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
288ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->width = -1;
289ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->height = -1;
290ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->row_bytes = 0;
291ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->path[0] = '\0';
292ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->fd = -1;
293ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->buffer = NULL;
294ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->buffer_length = 0;
295ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
296ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->previous = NULL;
297ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->next = NULL;
298ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
299ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
300ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
301ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonlink_tail(struct apple_glx_drawable *agd)
302ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
303ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
304ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
305ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   /* Link the new drawable into the global list. */
306ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   agd->next = drawables_list;
307ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
308ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (drawables_list)
309ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      drawables_list->previous = agd;
310ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
311ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   drawables_list = agd;
312ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
313ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
314ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
315ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
316ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston/*WARNING: this returns a locked and referenced object. */
317ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonbool
318ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_drawable_create(Display * dpy,
319ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                          int screen,
320ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                          GLXDrawable drawable,
321ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                          struct apple_glx_drawable **agdResult,
322ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                          struct apple_glx_drawable_callbacks *callbacks)
323ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
324ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *d;
325ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
326ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d = calloc(1, sizeof *d);
327ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
328ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (NULL == d) {
329ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      perror("malloc");
330ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      return true;
331ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
332ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
333ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   common_init(dpy, drawable, d);
334ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->type = callbacks->type;
335ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->callbacks = *callbacks;
336ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
337ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->reference(d);
338ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->lock(d);
339ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
340ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   link_tail(d);
341ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
342ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   apple_glx_diagnostic("%s: new drawable %p\n", __func__, (void *) d);
343ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
344ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   *agdResult = d;
345ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
346ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return false;
347ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
348ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
349ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic int error_count = 0;
350ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
351ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic int
352ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonerror_handler(Display * dpy, XErrorEvent * err)
353ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
354ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err->error_code == BadWindow) {
355ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      ++error_count;
356ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
357ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
358ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return 0;
359ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
360ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
361ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonvoid
362ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_garbage_collect_drawables(Display * dpy)
363ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
364ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *d, *dnext;
365ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   Window root;
366ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int x, y;
367ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unsigned int width, height, bd, depth;
368ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int (*old_handler) (Display *, XErrorEvent *);
369ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
370ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
371ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (NULL == drawables_list)
372ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      return;
373ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
374ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   old_handler = XSetErrorHandler(error_handler);
375ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
376ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   XSync(dpy, False);
377ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
378ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
379ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
380ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   for (d = drawables_list; d;) {
381ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      dnext = d->next;
382ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
383ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d->lock(d);
384ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
385ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      if (d->reference_count > 0) {
386ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         /*
387ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * Skip this, because some context still retains a reference
388ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * to the drawable.
389ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          */
390ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         d->unlock(d);
391ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         d = dnext;
392ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         continue;
393ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      }
394ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
395ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d->unlock(d);
396ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
397ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      error_count = 0;
398ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
399ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      /*
400ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * Mesa uses XGetWindowAttributes, but some of these things are
401ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * most definitely not Windows, and that's against the rules.
402ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * XGetGeometry on the other hand is legal with a Pixmap and Window.
403ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       */
404ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      XGetGeometry(dpy, d->drawable, &root, &x, &y, &width, &height, &bd,
405ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                   &depth);
406ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
407ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      if (error_count > 0) {
408ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         /*
409ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * Note: this may not actually destroy the drawable.
410ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * If another context retains a reference to the drawable
411ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * after the reference count test above.
412ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          */
413ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         (void) destroy_drawable(d);
414ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         error_count = 0;
415ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      }
416ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
417ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d = dnext;
418ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
419ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
420ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   XSetErrorHandler(old_handler);
421ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
422ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
423ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
424ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
425ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonunsigned int
426ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_get_drawable_count(void)
427ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
428ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unsigned int result = 0;
429ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *d;
430ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
431ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
432ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
433ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   for (d = drawables_list; d; d = d->next)
434ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      ++result;
435ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
436ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
437ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
438ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return result;
439ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
440ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
441ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstruct apple_glx_drawable *
442ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_drawable_find_by_type(GLXDrawable drawable, int type, int flags)
443ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
444ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *d;
445ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
446ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
447ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
448ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   for (d = drawables_list; d; d = d->next) {
449ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      if (d->type == type && d->drawable == drawable) {
450ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         if (flags & APPLE_GLX_DRAWABLE_REFERENCE)
451ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            d->reference(d);
452ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
453ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         if (flags & APPLE_GLX_DRAWABLE_LOCK)
454ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            d->lock(d);
455ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
456ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         unlock_drawables_list();
457ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
458ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         return d;
459ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      }
460ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
461ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
462ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
463ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
464ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return NULL;
465ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
466ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
467ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstruct apple_glx_drawable *
468ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_drawable_find(GLXDrawable drawable, int flags)
469ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
470ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *d;
471ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
472ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
473ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
474ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   for (d = drawables_list; d; d = d->next) {
475ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      if (d->drawable == drawable) {
476ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         if (flags & APPLE_GLX_DRAWABLE_REFERENCE)
477ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            d->reference(d);
478ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
479ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         if (flags & APPLE_GLX_DRAWABLE_LOCK)
480ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            d->lock(d);
481ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
482ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         unlock_drawables_list();
483ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
484ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         return d;
485ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      }
486ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
487ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
488ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
489ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
490ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return NULL;
491ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
492ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
493ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston/* Return true if the type is valid for the drawable. */
494ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonbool
495ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_drawable_destroy_by_type(Display * dpy,
496ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                                   GLXDrawable drawable, int type)
497ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
498ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *d;
499ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
500ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
501ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
502ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   for (d = drawables_list; d; d = d->next) {
503ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      if (drawable == d->drawable && type == d->type) {
504ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         /*
505ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * The user has requested that we destroy this resource.
506ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * However, there may be references in the contexts to it, so
507ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * release it, and call destroy_drawable which doesn't destroy
508ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * if the reference_count is > 0.
509ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          */
510ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         d->release(d);
511ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
512ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         apple_glx_diagnostic("%s d->reference_count %d\n",
513ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                              __func__, d->reference_count);
514ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
515ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         destroy_drawable(d);
516ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         unlock_drawables_list();
517ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         return true;
518ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      }
519ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
520ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
521ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
522ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
523ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return false;
524ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
525ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
526ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstruct apple_glx_drawable *
527ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_drawable_find_by_uid(unsigned int uid, int flags)
528ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
529ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *d;
530ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
531ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
532ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
533ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   for (d = drawables_list; d; d = d->next) {
534ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      /* Only surfaces have a uid. */
535ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      if (APPLE_GLX_DRAWABLE_SURFACE == d->type) {
536ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         if (d->types.surface.uid == uid) {
537ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            if (flags & APPLE_GLX_DRAWABLE_REFERENCE)
538ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston               d->reference(d);
539ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
540ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            if (flags & APPLE_GLX_DRAWABLE_LOCK)
541ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston               d->lock(d);
542ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
543ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            unlock_drawables_list();
544ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
545ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            return d;
546ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         }
547ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      }
548ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
549ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
550ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
551ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
552ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return NULL;
553ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
554