File: | Xext/shm.c |
Location: | line 858, column 5 |
Description: | Potential leak of memory pointed to by 'drawables' |
1 | /************************************************************ | |||||
2 | ||||||
3 | Copyright 1989, 1998 The Open Group | |||||
4 | ||||||
5 | Permission to use, copy, modify, distribute, and sell this software and its | |||||
6 | documentation for any purpose is hereby granted without fee, provided that | |||||
7 | the above copyright notice appear in all copies and that both that | |||||
8 | copyright notice and this permission notice appear in supporting | |||||
9 | documentation. | |||||
10 | ||||||
11 | The above copyright notice and this permission notice shall be included in | |||||
12 | all copies or substantial portions of the Software. | |||||
13 | ||||||
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
17 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||||
18 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||||
19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
20 | ||||||
21 | Except as contained in this notice, the name of The Open Group shall not be | |||||
22 | used in advertising or otherwise to promote the sale, use or other dealings | |||||
23 | in this Software without prior written authorization from The Open Group. | |||||
24 | ||||||
25 | ********************************************************/ | |||||
26 | ||||||
27 | /* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */ | |||||
28 | ||||||
29 | #define SHM | |||||
30 | ||||||
31 | #ifdef HAVE_DIX_CONFIG_H1 | |||||
32 | #include <dix-config.h> | |||||
33 | #endif | |||||
34 | ||||||
35 | #include <sys/types.h> | |||||
36 | #include <sys/ipc.h> | |||||
37 | #include <sys/shm.h> | |||||
38 | #include <unistd.h> | |||||
39 | #include <sys/stat.h> | |||||
40 | #include <fcntl.h> | |||||
41 | #include <X11/X.h> | |||||
42 | #include <X11/Xproto.h> | |||||
43 | #include "misc.h" | |||||
44 | #include "os.h" | |||||
45 | #include "dixstruct.h" | |||||
46 | #include "resource.h" | |||||
47 | #include "scrnintstr.h" | |||||
48 | #include "windowstr.h" | |||||
49 | #include "pixmapstr.h" | |||||
50 | #include "gcstruct.h" | |||||
51 | #include "extnsionst.h" | |||||
52 | #include "servermd.h" | |||||
53 | #include "shmint.h" | |||||
54 | #include "xace.h" | |||||
55 | #include <X11/extensions/shmproto.h> | |||||
56 | #include <X11/Xfuncproto.h> | |||||
57 | #include <sys/mman.h> | |||||
58 | #include "protocol-versions.h" | |||||
59 | #include "busfault.h" | |||||
60 | ||||||
61 | /* Needed for Solaris cross-zone shared memory extension */ | |||||
62 | #ifdef HAVE_SHMCTL64 | |||||
63 | #include <sys/ipc_impl.h> | |||||
64 | #define SHMSTAT(id, buf)shmctl(id, 2, buf) shmctl64(id, IPC_STAT64, buf) | |||||
65 | #define SHMSTAT_TYPEstruct __shmid_ds_new struct shmid_ds64 | |||||
66 | #define SHMPERM_TYPEstruct ipc_perm struct ipc_perm64 | |||||
67 | #define SHM_PERM(buf)buf.shm_perm buf.shmx_perm | |||||
68 | #define SHM_SEGSZ(buf)buf.shm_segsz buf.shmx_segsz | |||||
69 | #define SHMPERM_UID(p)p->uid p->ipcx_uid | |||||
70 | #define SHMPERM_CUID(p)p->cuid p->ipcx_cuid | |||||
71 | #define SHMPERM_GID(p)p->gid p->ipcx_gid | |||||
72 | #define SHMPERM_CGID(p)p->cgid p->ipcx_cgid | |||||
73 | #define SHMPERM_MODE(p)p->mode p->ipcx_mode | |||||
74 | #define SHMPERM_ZONEID(p) p->ipcx_zoneid | |||||
75 | #else | |||||
76 | #define SHMSTAT(id, buf)shmctl(id, 2, buf) shmctl(id, IPC_STAT2, buf) | |||||
77 | #define SHMSTAT_TYPEstruct __shmid_ds_new struct shmid_ds__shmid_ds_new | |||||
78 | #define SHMPERM_TYPEstruct ipc_perm struct ipc_perm | |||||
79 | #define SHM_PERM(buf)buf.shm_perm buf.shm_perm | |||||
80 | #define SHM_SEGSZ(buf)buf.shm_segsz buf.shm_segsz | |||||
81 | #define SHMPERM_UID(p)p->uid p->uid | |||||
82 | #define SHMPERM_CUID(p)p->cuid p->cuid | |||||
83 | #define SHMPERM_GID(p)p->gid p->gid | |||||
84 | #define SHMPERM_CGID(p)p->cgid p->cgid | |||||
85 | #define SHMPERM_MODE(p)p->mode p->mode | |||||
86 | #endif | |||||
87 | ||||||
88 | #ifdef PANORAMIX1 | |||||
89 | #include "panoramiX.h" | |||||
90 | #include "panoramiXsrv.h" | |||||
91 | #endif | |||||
92 | ||||||
93 | #include "extinit.h" | |||||
94 | ||||||
95 | typedef struct _ShmScrPrivateRec { | |||||
96 | CloseScreenProcPtr CloseScreen; | |||||
97 | ShmFuncsPtr shmFuncs; | |||||
98 | DestroyPixmapProcPtr destroyPixmap; | |||||
99 | } ShmScrPrivateRec; | |||||
100 | ||||||
101 | static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGSScreenPtr , int , int , int , char *); | |||||
102 | static int ShmDetachSegment(void *value, XID shmseg); | |||||
103 | static void ShmResetProc(ExtensionEntry *extEntry); | |||||
104 | static void SShmCompletionEvent(xShmCompletionEvent *from, | |||||
105 | xShmCompletionEvent *to); | |||||
106 | ||||||
107 | static Bool ShmDestroyPixmap(PixmapPtr pPixmap); | |||||
108 | ||||||
109 | static unsigned char ShmReqCode; | |||||
110 | int ShmCompletionCode; | |||||
111 | int BadShmSegCode; | |||||
112 | RESTYPE ShmSegType; | |||||
113 | static ShmDescPtr Shmsegs; | |||||
114 | static Bool sharedPixmaps; | |||||
115 | static DevPrivateKeyRec shmScrPrivateKeyRec; | |||||
116 | ||||||
117 | #define shmScrPrivateKey(&shmScrPrivateKeyRec) (&shmScrPrivateKeyRec) | |||||
118 | static DevPrivateKeyRec shmPixmapPrivateKeyRec; | |||||
119 | ||||||
120 | #define shmPixmapPrivateKey(&shmPixmapPrivateKeyRec) (&shmPixmapPrivateKeyRec) | |||||
121 | static ShmFuncs miFuncs = { NULL((void*)0), NULL((void*)0) }; | |||||
122 | static ShmFuncs fbFuncs = { fbShmCreatePixmap, NULL((void*)0) }; | |||||
123 | ||||||
124 | #define ShmGetScreenPriv(s)((ShmScrPrivateRec *)dixLookupPrivate(&(s)->devPrivates , (&shmScrPrivateKeyRec))) ((ShmScrPrivateRec *)dixLookupPrivate(&(s)->devPrivates, shmScrPrivateKey(&shmScrPrivateKeyRec))) | |||||
125 | ||||||
126 | #define VERIFY_SHMSEG(shmseg,shmdesc,client){ int tmprc; tmprc = dixLookupResourceByType((void **)&(shmdesc ), shmseg, ShmSegType, client, (1<<0)); if (tmprc != 0) return tmprc; } \ | |||||
127 | { \ | |||||
128 | int tmprc; \ | |||||
129 | tmprc = dixLookupResourceByType((void **)&(shmdesc), shmseg, ShmSegType, \ | |||||
130 | client, DixReadAccess(1<<0)); \ | |||||
131 | if (tmprc != Success0) \ | |||||
132 | return tmprc; \ | |||||
133 | } | |||||
134 | ||||||
135 | #define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client){ { int tmprc; tmprc = dixLookupResourceByType((void **)& (shmdesc), shmseg, ShmSegType, client, (1<<0)); if (tmprc != 0) return tmprc; }; if ((offset & 3) || (offset > shmdesc ->size)) { client->errorValue = offset; return 2; } if ( needwrite && !shmdesc->writable) return 10; } \ | |||||
136 | { \ | |||||
137 | VERIFY_SHMSEG(shmseg, shmdesc, client){ int tmprc; tmprc = dixLookupResourceByType((void **)&(shmdesc ), shmseg, ShmSegType, client, (1<<0)); if (tmprc != 0) return tmprc; }; \ | |||||
138 | if ((offset & 3) || (offset > shmdesc->size)) \ | |||||
139 | { \ | |||||
140 | client->errorValue = offset; \ | |||||
141 | return BadValue2; \ | |||||
142 | } \ | |||||
143 | if (needwrite && !shmdesc->writable) \ | |||||
144 | return BadAccess10; \ | |||||
145 | } | |||||
146 | ||||||
147 | #define VERIFY_SHMSIZE(shmdesc,offset,len,client){ if ((offset + len) > shmdesc->size) { return 10; } } \ | |||||
148 | { \ | |||||
149 | if ((offset + len) > shmdesc->size) \ | |||||
150 | { \ | |||||
151 | return BadAccess10; \ | |||||
152 | } \ | |||||
153 | } | |||||
154 | ||||||
155 | #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__DragonFly__) | |||||
156 | #include <sys/signal.h> | |||||
157 | ||||||
158 | static Bool badSysCall = FALSE0; | |||||
159 | ||||||
160 | static void | |||||
161 | SigSysHandler(int signo) | |||||
162 | { | |||||
163 | badSysCall = TRUE1; | |||||
164 | } | |||||
165 | ||||||
166 | static Bool | |||||
167 | CheckForShmSyscall(void) | |||||
168 | { | |||||
169 | void (*oldHandler) (int); | |||||
170 | int shmid = -1; | |||||
171 | ||||||
172 | /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */ | |||||
173 | oldHandler = signal(SIGSYS12, SigSysHandler); | |||||
174 | ||||||
175 | badSysCall = FALSE0; | |||||
176 | shmid = shmget(IPC_PRIVATE((key_t)0), 4096, IPC_CREAT001000); | |||||
177 | ||||||
178 | if (shmid != -1) { | |||||
179 | /* Successful allocation - clean up */ | |||||
180 | shmctl(shmid, IPC_RMID0, NULL((void*)0)); | |||||
181 | } | |||||
182 | else { | |||||
183 | /* Allocation failed */ | |||||
184 | badSysCall = TRUE1; | |||||
185 | } | |||||
186 | signal(SIGSYS12, oldHandler); | |||||
187 | return !badSysCall; | |||||
188 | } | |||||
189 | ||||||
190 | #define MUST_CHECK_FOR_SHM_SYSCALL | |||||
191 | ||||||
192 | #endif | |||||
193 | ||||||
194 | static Bool | |||||
195 | ShmCloseScreen(ScreenPtr pScreen) | |||||
196 | { | |||||
197 | ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen)((ShmScrPrivateRec *)dixLookupPrivate(&(pScreen)->devPrivates , (&shmScrPrivateKeyRec))); | |||||
198 | ||||||
199 | pScreen->CloseScreen = screen_priv->CloseScreen; | |||||
200 | dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey(&shmScrPrivateKeyRec), NULL((void*)0)); | |||||
201 | free(screen_priv); | |||||
202 | return (*pScreen->CloseScreen) (pScreen); | |||||
203 | } | |||||
204 | ||||||
205 | static ShmScrPrivateRec * | |||||
206 | ShmInitScreenPriv(ScreenPtr pScreen) | |||||
207 | { | |||||
208 | ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen)((ShmScrPrivateRec *)dixLookupPrivate(&(pScreen)->devPrivates , (&shmScrPrivateKeyRec))); | |||||
209 | ||||||
210 | if (!screen_priv) { | |||||
211 | screen_priv = calloc(1, sizeof(ShmScrPrivateRec)); | |||||
212 | screen_priv->CloseScreen = pScreen->CloseScreen; | |||||
213 | dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey(&shmScrPrivateKeyRec), screen_priv); | |||||
214 | pScreen->CloseScreen = ShmCloseScreen; | |||||
215 | } | |||||
216 | return screen_priv; | |||||
217 | } | |||||
218 | ||||||
219 | static Bool | |||||
220 | ShmRegisterPrivates(void) | |||||
221 | { | |||||
222 | if (!dixRegisterPrivateKey(&shmScrPrivateKeyRec, PRIVATE_SCREEN, 0)) | |||||
223 | return FALSE0; | |||||
224 | if (!dixRegisterPrivateKey(&shmPixmapPrivateKeyRec, PRIVATE_PIXMAP, 0)) | |||||
225 | return FALSE0; | |||||
226 | return TRUE1; | |||||
227 | } | |||||
228 | ||||||
229 | /*ARGSUSED*/ static void | |||||
230 | ShmResetProc(ExtensionEntry * extEntry) | |||||
231 | { | |||||
232 | int i; | |||||
233 | ||||||
234 | for (i = 0; i < screenInfo.numScreens; i++) | |||||
235 | ShmRegisterFuncs(screenInfo.screens[i], NULL((void*)0)); | |||||
236 | } | |||||
237 | ||||||
238 | void | |||||
239 | ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs) | |||||
240 | { | |||||
241 | if (!ShmRegisterPrivates()) | |||||
242 | return; | |||||
243 | ShmInitScreenPriv(pScreen)->shmFuncs = funcs; | |||||
244 | } | |||||
245 | ||||||
246 | static Bool | |||||
247 | ShmDestroyPixmap(PixmapPtr pPixmap) | |||||
248 | { | |||||
249 | ScreenPtr pScreen = pPixmap->drawable.pScreen; | |||||
250 | ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen)((ShmScrPrivateRec *)dixLookupPrivate(&(pScreen)->devPrivates , (&shmScrPrivateKeyRec))); | |||||
251 | void *shmdesc = NULL((void*)0); | |||||
252 | Bool ret; | |||||
253 | ||||||
254 | if (pPixmap->refcnt == 1) | |||||
255 | shmdesc = dixLookupPrivate(&pPixmap->devPrivates, shmPixmapPrivateKey(&shmPixmapPrivateKeyRec)); | |||||
256 | ||||||
257 | pScreen->DestroyPixmap = screen_priv->destroyPixmap; | |||||
258 | ret = (*pScreen->DestroyPixmap) (pPixmap); | |||||
259 | screen_priv->destroyPixmap = pScreen->DestroyPixmap; | |||||
260 | pScreen->DestroyPixmap = ShmDestroyPixmap; | |||||
261 | ||||||
262 | if (shmdesc) | |||||
263 | ShmDetachSegment(shmdesc, 0); | |||||
264 | ||||||
265 | return ret; | |||||
266 | } | |||||
267 | ||||||
268 | void | |||||
269 | ShmRegisterFbFuncs(ScreenPtr pScreen) | |||||
270 | { | |||||
271 | ShmRegisterFuncs(pScreen, &fbFuncs); | |||||
272 | } | |||||
273 | ||||||
274 | static int | |||||
275 | ProcShmQueryVersion(ClientPtr client) | |||||
276 | { | |||||
277 | xShmQueryVersionReply rep = { | |||||
278 | .type = X_Reply1, | |||||
279 | .sharedPixmaps = sharedPixmaps, | |||||
280 | .sequenceNumber = client->sequence, | |||||
281 | .length = 0, | |||||
282 | .majorVersion = SERVER_SHM_MAJOR_VERSION1, | |||||
283 | .minorVersion = SERVER_SHM_MINOR_VERSION1, | |||||
284 | .uid = geteuid(), | |||||
285 | .gid = getegid(), | |||||
286 | .pixmapFormat = sharedPixmaps ? ZPixmap2 : 0 | |||||
287 | }; | |||||
288 | ||||||
289 | REQUEST_SIZE_MATCH(xShmQueryVersionReq)if ((sizeof(xShmQueryVersionReq) >> 2) != client->req_len ) return(16); | |||||
290 | ||||||
291 | if (client->swapped) { | |||||
292 | swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber ) & 1) && ((uintptr_t)(&rep.sequenceNumber) & 1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber )); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); } while (0); | |||||
293 | swapl(&rep.length)do { if (sizeof(*(&rep.length)) != 4) wrong_size(); if (__builtin_constant_p ((uintptr_t)(&rep.length) & 3) && ((uintptr_t )(&rep.length) & 3) == 0) *(&rep.length) = lswapl (*(&rep.length)); else swap_uint32((uint32_t *)(&rep. length)); } while (0); | |||||
294 | swaps(&rep.majorVersion)do { if (sizeof(*(&rep.majorVersion)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&rep.majorVersion) & 1) && ((uintptr_t)(&rep.majorVersion) & 1) == 0) *(&rep.majorVersion) = lswaps(*(&rep.majorVersion )); else swap_uint16((uint16_t *)(&rep.majorVersion)); } while (0); | |||||
295 | swaps(&rep.minorVersion)do { if (sizeof(*(&rep.minorVersion)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&rep.minorVersion) & 1) && ((uintptr_t)(&rep.minorVersion) & 1) == 0) *(&rep.minorVersion) = lswaps(*(&rep.minorVersion )); else swap_uint16((uint16_t *)(&rep.minorVersion)); } while (0); | |||||
296 | swaps(&rep.uid)do { if (sizeof(*(&rep.uid)) != 2) wrong_size(); if (__builtin_constant_p ((uintptr_t)(&rep.uid) & 1) && ((uintptr_t)(& rep.uid) & 1) == 0) *(&rep.uid) = lswaps(*(&rep.uid )); else swap_uint16((uint16_t *)(&rep.uid)); } while (0); | |||||
297 | swaps(&rep.gid)do { if (sizeof(*(&rep.gid)) != 2) wrong_size(); if (__builtin_constant_p ((uintptr_t)(&rep.gid) & 1) && ((uintptr_t)(& rep.gid) & 1) == 0) *(&rep.gid) = lswaps(*(&rep.gid )); else swap_uint16((uint16_t *)(&rep.gid)); } while (0); | |||||
298 | } | |||||
299 | WriteToClient(client, sizeof(xShmQueryVersionReply), &rep); | |||||
300 | return Success0; | |||||
301 | } | |||||
302 | ||||||
303 | /* | |||||
304 | * Simulate the access() system call for a shared memory segement, | |||||
305 | * using the credentials from the client if available | |||||
306 | */ | |||||
307 | static int | |||||
308 | shm_access(ClientPtr client, SHMPERM_TYPEstruct ipc_perm * perm, int readonly) | |||||
309 | { | |||||
310 | int uid, gid; | |||||
311 | mode_t mask; | |||||
312 | int uidset = 0, gidset = 0; | |||||
313 | LocalClientCredRec *lcc; | |||||
314 | ||||||
315 | if (GetLocalClientCreds(client, &lcc) != -1) { | |||||
316 | ||||||
317 | if (lcc->fieldsSet & LCC_UID_SET(1 << 0)) { | |||||
318 | uid = lcc->euid; | |||||
319 | uidset = 1; | |||||
320 | } | |||||
321 | if (lcc->fieldsSet & LCC_GID_SET(1 << 1)) { | |||||
322 | gid = lcc->egid; | |||||
323 | gidset = 1; | |||||
324 | } | |||||
325 | ||||||
326 | #if defined(HAVE_GETZONEID) && defined(SHMPERM_ZONEID) | |||||
327 | if (((lcc->fieldsSet & LCC_ZID_SET(1 << 3)) == 0) || (lcc->zoneid == -1) | |||||
328 | || (lcc->zoneid != SHMPERM_ZONEID(perm))) { | |||||
329 | uidset = 0; | |||||
330 | gidset = 0; | |||||
331 | } | |||||
332 | #endif | |||||
333 | FreeLocalClientCreds(lcc); | |||||
334 | ||||||
335 | if (uidset) { | |||||
336 | /* User id 0 always gets access */ | |||||
337 | if (uid == 0) { | |||||
338 | return 0; | |||||
339 | } | |||||
340 | /* Check the owner */ | |||||
341 | if (SHMPERM_UID(perm)perm->uid == uid || SHMPERM_CUID(perm)perm->cuid == uid) { | |||||
342 | mask = S_IRUSR0000400; | |||||
343 | if (!readonly) { | |||||
344 | mask |= S_IWUSR0000200; | |||||
345 | } | |||||
346 | return (SHMPERM_MODE(perm)perm->mode & mask) == mask ? 0 : -1; | |||||
347 | } | |||||
348 | } | |||||
349 | ||||||
350 | if (gidset) { | |||||
351 | /* Check the group */ | |||||
352 | if (SHMPERM_GID(perm)perm->gid == gid || SHMPERM_CGID(perm)perm->cgid == gid) { | |||||
353 | mask = S_IRGRP0000040; | |||||
354 | if (!readonly) { | |||||
355 | mask |= S_IWGRP0000020; | |||||
356 | } | |||||
357 | return (SHMPERM_MODE(perm)perm->mode & mask) == mask ? 0 : -1; | |||||
358 | } | |||||
359 | } | |||||
360 | } | |||||
361 | /* Otherwise, check everyone else */ | |||||
362 | mask = S_IROTH0000004; | |||||
363 | if (!readonly) { | |||||
364 | mask |= S_IWOTH0000002; | |||||
365 | } | |||||
366 | return (SHMPERM_MODE(perm)perm->mode & mask) == mask ? 0 : -1; | |||||
367 | } | |||||
368 | ||||||
369 | static int | |||||
370 | ProcShmAttach(ClientPtr client) | |||||
371 | { | |||||
372 | SHMSTAT_TYPEstruct __shmid_ds_new buf; | |||||
373 | ShmDescPtr shmdesc; | |||||
374 | ||||||
375 | REQUEST(xShmAttachReq)xShmAttachReq *stuff = (xShmAttachReq *)client->requestBuffer; | |||||
376 | ||||||
377 | REQUEST_SIZE_MATCH(xShmAttachReq)if ((sizeof(xShmAttachReq) >> 2) != client->req_len) return(16); | |||||
378 | LEGAL_NEW_RESOURCE(stuff->shmseg, client)if (!LegalNewID(stuff->shmseg,client)) { client->errorValue = stuff->shmseg; return 14; }; | |||||
379 | if ((stuff->readOnly != xTrue1) && (stuff->readOnly != xFalse0)) { | |||||
380 | client->errorValue = stuff->readOnly; | |||||
381 | return BadValue2; | |||||
382 | } | |||||
383 | for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next) { | |||||
384 | if (!SHMDESC_IS_FD(shmdesc)(0) && shmdesc->shmid == stuff->shmid) | |||||
385 | break; | |||||
386 | } | |||||
387 | if (shmdesc) { | |||||
388 | if (!stuff->readOnly && !shmdesc->writable) | |||||
389 | return BadAccess10; | |||||
390 | shmdesc->refcnt++; | |||||
391 | } | |||||
392 | else { | |||||
393 | shmdesc = malloc(sizeof(ShmDescRec)); | |||||
394 | if (!shmdesc) | |||||
395 | return BadAlloc11; | |||||
396 | #ifdef SHM_FD_PASSING | |||||
397 | shmdesc->is_fd = FALSE0; | |||||
398 | #endif | |||||
399 | shmdesc->addr = shmat(stuff->shmid, 0, | |||||
400 | stuff->readOnly ? SHM_RDONLY010000 : 0); | |||||
401 | if ((shmdesc->addr == ((char *) -1)) || SHMSTAT(stuff->shmid, &buf)shmctl(stuff->shmid, 2, &buf)) { | |||||
402 | free(shmdesc); | |||||
403 | return BadAccess10; | |||||
404 | } | |||||
405 | ||||||
406 | /* The attach was performed with root privs. We must | |||||
407 | * do manual checking of access rights for the credentials | |||||
408 | * of the client */ | |||||
409 | ||||||
410 | if (shm_access(client, &(SHM_PERM(buf)buf.shm_perm), stuff->readOnly) == -1) { | |||||
411 | shmdt(shmdesc->addr); | |||||
412 | free(shmdesc); | |||||
413 | return BadAccess10; | |||||
414 | } | |||||
415 | ||||||
416 | shmdesc->shmid = stuff->shmid; | |||||
417 | shmdesc->refcnt = 1; | |||||
418 | shmdesc->writable = !stuff->readOnly; | |||||
419 | shmdesc->size = SHM_SEGSZ(buf)buf.shm_segsz; | |||||
420 | shmdesc->next = Shmsegs; | |||||
421 | Shmsegs = shmdesc; | |||||
422 | } | |||||
423 | if (!AddResourceDarwin_X_AddResource(stuff->shmseg, ShmSegType, (void *) shmdesc)) | |||||
424 | return BadAlloc11; | |||||
425 | return Success0; | |||||
426 | } | |||||
427 | ||||||
428 | /*ARGSUSED*/ static int | |||||
429 | ShmDetachSegment(void *value, /* must conform to DeleteType */ | |||||
430 | XID unused) | |||||
431 | { | |||||
432 | ShmDescPtr shmdesc = (ShmDescPtr) value; | |||||
433 | ShmDescPtr *prev; | |||||
434 | ||||||
435 | if (--shmdesc->refcnt) | |||||
436 | return TRUE1; | |||||
437 | #if SHM_FD_PASSING | |||||
438 | if (shmdesc->is_fd) { | |||||
439 | if (shmdesc->busfault) | |||||
440 | busfault_unregister(shmdesc->busfault); | |||||
441 | munmap(shmdesc->addr, shmdesc->size); | |||||
442 | } else | |||||
443 | #endif | |||||
444 | shmdt(shmdesc->addr); | |||||
445 | for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next); | |||||
446 | *prev = shmdesc->next; | |||||
447 | free(shmdesc); | |||||
448 | return Success0; | |||||
449 | } | |||||
450 | ||||||
451 | static int | |||||
452 | ProcShmDetach(ClientPtr client) | |||||
453 | { | |||||
454 | ShmDescPtr shmdesc; | |||||
455 | ||||||
456 | REQUEST(xShmDetachReq)xShmDetachReq *stuff = (xShmDetachReq *)client->requestBuffer; | |||||
457 | ||||||
458 | REQUEST_SIZE_MATCH(xShmDetachReq)if ((sizeof(xShmDetachReq) >> 2) != client->req_len) return(16); | |||||
459 | VERIFY_SHMSEG(stuff->shmseg, shmdesc, client){ int tmprc; tmprc = dixLookupResourceByType((void **)&(shmdesc ), stuff->shmseg, ShmSegType, client, (1<<0)); if (tmprc != 0) return tmprc; }; | |||||
460 | FreeResource(stuff->shmseg, RT_NONE((RESTYPE)0)); | |||||
461 | return Success0; | |||||
462 | } | |||||
463 | ||||||
464 | /* | |||||
465 | * If the given request doesn't exactly match PutImage's constraints, | |||||
466 | * wrap the image in a scratch pixmap header and let CopyArea sort it out. | |||||
467 | */ | |||||
468 | static void | |||||
469 | doShmPutImage(DrawablePtr dst, GCPtr pGC, | |||||
470 | int depth, unsigned int format, | |||||
471 | int w, int h, int sx, int sy, int sw, int sh, int dx, int dy, | |||||
472 | char *data) | |||||
473 | { | |||||
474 | PixmapPtr pPixmap; | |||||
475 | ||||||
476 | if (format == ZPixmap2 || (format == XYPixmap1 && depth == 1)) { | |||||
477 | pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth, | |||||
478 | BitsPerPixel(depth)(PixmapWidthPaddingInfo[depth].bitsPerPixel), | |||||
479 | PixmapBytePad(w, depth)((PixmapWidthPaddingInfo[depth].notPower2 ? (((int)(w) * PixmapWidthPaddingInfo [depth].bytesPerPixel + PixmapWidthPaddingInfo[depth].bytesPerPixel ) >> PixmapWidthPaddingInfo[depth].padBytesLog2) : ((int )((w) + PixmapWidthPaddingInfo[depth].padRoundUp) >> PixmapWidthPaddingInfo [depth].padPixelsLog2)) << PixmapWidthPaddingInfo[depth ].padBytesLog2), data); | |||||
480 | if (!pPixmap) | |||||
481 | return; | |||||
482 | pGC->ops->CopyArea((DrawablePtr) pPixmap, dst, pGC, sx, sy, sw, sh, dx, | |||||
483 | dy); | |||||
484 | FreeScratchPixmapHeader(pPixmap); | |||||
485 | } | |||||
486 | else { | |||||
487 | GCPtr putGC = GetScratchGC(depth, dst->pScreen); | |||||
488 | ||||||
489 | if (!putGC) | |||||
490 | return; | |||||
491 | ||||||
492 | pPixmap = (*dst->pScreen->CreatePixmap) (dst->pScreen, sw, sh, depth, | |||||
493 | CREATE_PIXMAP_USAGE_SCRATCH1); | |||||
494 | if (!pPixmap) { | |||||
495 | FreeScratchGC(putGC); | |||||
496 | return; | |||||
497 | } | |||||
498 | ValidateGC(&pPixmap->drawable, putGC); | |||||
499 | (*putGC->ops->PutImage) (&pPixmap->drawable, putGC, depth, -sx, -sy, w, | |||||
500 | h, 0, | |||||
501 | (format == XYPixmap1) ? XYPixmap1 : ZPixmap2, | |||||
502 | data); | |||||
503 | FreeScratchGC(putGC); | |||||
504 | if (format == XYBitmap0) | |||||
505 | (void) (*pGC->ops->CopyPlane) (&pPixmap->drawable, dst, pGC, 0, 0, | |||||
506 | sw, sh, dx, dy, 1L); | |||||
507 | else | |||||
508 | (void) (*pGC->ops->CopyArea) (&pPixmap->drawable, dst, pGC, 0, 0, | |||||
509 | sw, sh, dx, dy); | |||||
510 | (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap); | |||||
511 | } | |||||
512 | } | |||||
513 | ||||||
514 | static int | |||||
515 | ProcShmPutImage(ClientPtr client) | |||||
516 | { | |||||
517 | GCPtr pGC; | |||||
518 | DrawablePtr pDraw; | |||||
519 | long length; | |||||
520 | ShmDescPtr shmdesc; | |||||
521 | ||||||
522 | REQUEST(xShmPutImageReq)xShmPutImageReq *stuff = (xShmPutImageReq *)client->requestBuffer; | |||||
523 | ||||||
524 | REQUEST_SIZE_MATCH(xShmPutImageReq)if ((sizeof(xShmPutImageReq) >> 2) != client->req_len ) return(16); | |||||
525 | VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess){ int tmprc = dixLookupDrawable(&(pDraw), stuff->drawable , client, (-1), (1<<1)); if (tmprc != 0) return tmprc; tmprc = dixLookupGC(&(pGC), stuff->gc, client, (1<<24 )); if (tmprc != 0) return tmprc; if ((pGC->depth != pDraw ->depth) || (pGC->pScreen != pDraw->pScreen)) return 8; } if (pGC->serialNumber != pDraw->serialNumber) ValidateGC (pDraw, pGC);; | |||||
526 | VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client){ { int tmprc; tmprc = dixLookupResourceByType((void **)& (shmdesc), stuff->shmseg, ShmSegType, client, (1<<0) ); if (tmprc != 0) return tmprc; }; if ((stuff->offset & 3) || (stuff->offset > shmdesc->size)) { client-> errorValue = stuff->offset; return 2; } if (0 && ! shmdesc->writable) return 10; }; | |||||
527 | if ((stuff->sendEvent != xTrue1) && (stuff->sendEvent != xFalse0)) | |||||
528 | return BadValue2; | |||||
529 | if (stuff->format == XYBitmap0) { | |||||
530 | if (stuff->depth != 1) | |||||
531 | return BadMatch8; | |||||
532 | length = PixmapBytePad(stuff->totalWidth, 1)((PixmapWidthPaddingInfo[1].notPower2 ? (((int)(stuff->totalWidth ) * PixmapWidthPaddingInfo[1].bytesPerPixel + PixmapWidthPaddingInfo [1].bytesPerPixel) >> PixmapWidthPaddingInfo[1].padBytesLog2 ) : ((int)((stuff->totalWidth) + PixmapWidthPaddingInfo[1] .padRoundUp) >> PixmapWidthPaddingInfo[1].padPixelsLog2 )) << PixmapWidthPaddingInfo[1].padBytesLog2); | |||||
533 | } | |||||
534 | else if (stuff->format == XYPixmap1) { | |||||
535 | if (pDraw->depth != stuff->depth) | |||||
536 | return BadMatch8; | |||||
537 | length = PixmapBytePad(stuff->totalWidth, 1)((PixmapWidthPaddingInfo[1].notPower2 ? (((int)(stuff->totalWidth ) * PixmapWidthPaddingInfo[1].bytesPerPixel + PixmapWidthPaddingInfo [1].bytesPerPixel) >> PixmapWidthPaddingInfo[1].padBytesLog2 ) : ((int)((stuff->totalWidth) + PixmapWidthPaddingInfo[1] .padRoundUp) >> PixmapWidthPaddingInfo[1].padPixelsLog2 )) << PixmapWidthPaddingInfo[1].padBytesLog2); | |||||
538 | length *= stuff->depth; | |||||
539 | } | |||||
540 | else if (stuff->format == ZPixmap2) { | |||||
541 | if (pDraw->depth != stuff->depth) | |||||
542 | return BadMatch8; | |||||
543 | length = PixmapBytePad(stuff->totalWidth, stuff->depth)((PixmapWidthPaddingInfo[stuff->depth].notPower2 ? (((int) (stuff->totalWidth) * PixmapWidthPaddingInfo[stuff->depth ].bytesPerPixel + PixmapWidthPaddingInfo[stuff->depth].bytesPerPixel ) >> PixmapWidthPaddingInfo[stuff->depth].padBytesLog2 ) : ((int)((stuff->totalWidth) + PixmapWidthPaddingInfo[stuff ->depth].padRoundUp) >> PixmapWidthPaddingInfo[stuff ->depth].padPixelsLog2)) << PixmapWidthPaddingInfo[stuff ->depth].padBytesLog2); | |||||
544 | } | |||||
545 | else { | |||||
546 | client->errorValue = stuff->format; | |||||
547 | return BadValue2; | |||||
548 | } | |||||
549 | ||||||
550 | /* | |||||
551 | * There's a potential integer overflow in this check: | |||||
552 | * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight, | |||||
553 | * client); | |||||
554 | * the version below ought to avoid it | |||||
555 | */ | |||||
556 | if (stuff->totalHeight != 0 && | |||||
557 | length > (shmdesc->size - stuff->offset) / stuff->totalHeight) { | |||||
558 | client->errorValue = stuff->totalWidth; | |||||
559 | return BadValue2; | |||||
560 | } | |||||
561 | if (stuff->srcX > stuff->totalWidth) { | |||||
562 | client->errorValue = stuff->srcX; | |||||
563 | return BadValue2; | |||||
564 | } | |||||
565 | if (stuff->srcY > stuff->totalHeight) { | |||||
566 | client->errorValue = stuff->srcY; | |||||
567 | return BadValue2; | |||||
568 | } | |||||
569 | if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth) { | |||||
570 | client->errorValue = stuff->srcWidth; | |||||
571 | return BadValue2; | |||||
572 | } | |||||
573 | if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight) { | |||||
574 | client->errorValue = stuff->srcHeight; | |||||
575 | return BadValue2; | |||||
576 | } | |||||
577 | ||||||
578 | if ((((stuff->format == ZPixmap2) && (stuff->srcX == 0)) || | |||||
579 | ((stuff->format != ZPixmap2) && | |||||
580 | (stuff->srcX < screenInfo.bitmapScanlinePad) && | |||||
581 | ((stuff->format == XYBitmap0) || | |||||
582 | ((stuff->srcY == 0) && | |||||
583 | (stuff->srcHeight == stuff->totalHeight))))) && | |||||
584 | ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth)) | |||||
585 | (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, | |||||
586 | stuff->dstX, stuff->dstY, | |||||
587 | stuff->totalWidth, stuff->srcHeight, | |||||
588 | stuff->srcX, stuff->format, | |||||
589 | shmdesc->addr + stuff->offset + | |||||
590 | (stuff->srcY * length)); | |||||
591 | else | |||||
592 | doShmPutImage(pDraw, pGC, stuff->depth, stuff->format, | |||||
593 | stuff->totalWidth, stuff->totalHeight, | |||||
594 | stuff->srcX, stuff->srcY, | |||||
595 | stuff->srcWidth, stuff->srcHeight, | |||||
596 | stuff->dstX, stuff->dstY, shmdesc->addr + stuff->offset); | |||||
597 | ||||||
598 | if (stuff->sendEvent) { | |||||
599 | xShmCompletionEvent ev = { | |||||
600 | .type = ShmCompletionCode, | |||||
601 | .drawable = stuff->drawable, | |||||
602 | .minorEvent = X_ShmPutImage3, | |||||
603 | .majorEvent = ShmReqCode, | |||||
604 | .shmseg = stuff->shmseg, | |||||
605 | .offset = stuff->offset | |||||
606 | }; | |||||
607 | WriteEventsToClient(client, 1, (xEvent *) &ev); | |||||
608 | } | |||||
609 | ||||||
610 | return Success0; | |||||
611 | } | |||||
612 | ||||||
613 | static int | |||||
614 | ProcShmGetImage(ClientPtr client) | |||||
615 | { | |||||
616 | DrawablePtr pDraw; | |||||
617 | long lenPer = 0, length; | |||||
618 | Mask plane = 0; | |||||
619 | xShmGetImageReply xgi; | |||||
620 | ShmDescPtr shmdesc; | |||||
621 | VisualID visual = None0L; | |||||
622 | int rc; | |||||
623 | ||||||
624 | REQUEST(xShmGetImageReq)xShmGetImageReq *stuff = (xShmGetImageReq *)client->requestBuffer; | |||||
625 | ||||||
626 | REQUEST_SIZE_MATCH(xShmGetImageReq)if ((sizeof(xShmGetImageReq) >> 2) != client->req_len ) return(16); | |||||
627 | if ((stuff->format != XYPixmap1) && (stuff->format != ZPixmap2)) { | |||||
628 | client->errorValue = stuff->format; | |||||
629 | return BadValue2; | |||||
630 | } | |||||
631 | rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReadAccess(1<<0)); | |||||
632 | if (rc != Success0) | |||||
633 | return rc; | |||||
634 | VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client){ { int tmprc; tmprc = dixLookupResourceByType((void **)& (shmdesc), stuff->shmseg, ShmSegType, client, (1<<0) ); if (tmprc != 0) return tmprc; }; if ((stuff->offset & 3) || (stuff->offset > shmdesc->size)) { client-> errorValue = stuff->offset; return 2; } if (1 && ! shmdesc->writable) return 10; }; | |||||
635 | if (pDraw->type == DRAWABLE_WINDOW0) { | |||||
636 | if ( /* check for being viewable */ | |||||
637 | !((WindowPtr) pDraw)->realized || | |||||
638 | /* check for being on screen */ | |||||
639 | pDraw->x + stuff->x < 0 || | |||||
640 | pDraw->x + stuff->x + (int) stuff->width > pDraw->pScreen->width | |||||
641 | || pDraw->y + stuff->y < 0 || | |||||
642 | pDraw->y + stuff->y + (int) stuff->height > | |||||
643 | pDraw->pScreen->height || | |||||
644 | /* check for being inside of border */ | |||||
645 | stuff->x < -wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) || | |||||
646 | stuff->x + (int) stuff->width > | |||||
647 | wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) + (int) pDraw->width || | |||||
648 | stuff->y < -wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) || | |||||
649 | stuff->y + (int) stuff->height > | |||||
650 | wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) + (int) pDraw->height) | |||||
651 | return BadMatch8; | |||||
652 | visual = wVisual(((WindowPtr) pDraw))((((WindowPtr) pDraw))->optional ? (((WindowPtr) pDraw))-> optional->visual : FindWindowWithOptional(((WindowPtr) pDraw ))->optional->visual); | |||||
653 | } | |||||
654 | else { | |||||
655 | if (stuff->x < 0 || | |||||
656 | stuff->x + (int) stuff->width > pDraw->width || | |||||
657 | stuff->y < 0 || stuff->y + (int) stuff->height > pDraw->height) | |||||
658 | return BadMatch8; | |||||
659 | visual = None0L; | |||||
660 | } | |||||
661 | xgi = (xShmGetImageReply) { | |||||
662 | .type = X_Reply1, | |||||
663 | .sequenceNumber = client->sequence, | |||||
664 | .length = 0, | |||||
665 | .visual = visual, | |||||
666 | .depth = pDraw->depth | |||||
667 | }; | |||||
668 | if (stuff->format == ZPixmap2) { | |||||
669 | length = PixmapBytePad(stuff->width, pDraw->depth)((PixmapWidthPaddingInfo[pDraw->depth].notPower2 ? (((int) (stuff->width) * PixmapWidthPaddingInfo[pDraw->depth].bytesPerPixel + PixmapWidthPaddingInfo[pDraw->depth].bytesPerPixel) >> PixmapWidthPaddingInfo[pDraw->depth].padBytesLog2) : ((int )((stuff->width) + PixmapWidthPaddingInfo[pDraw->depth] .padRoundUp) >> PixmapWidthPaddingInfo[pDraw->depth] .padPixelsLog2)) << PixmapWidthPaddingInfo[pDraw->depth ].padBytesLog2) * stuff->height; | |||||
670 | } | |||||
671 | else { | |||||
672 | lenPer = PixmapBytePad(stuff->width, 1)((PixmapWidthPaddingInfo[1].notPower2 ? (((int)(stuff->width ) * PixmapWidthPaddingInfo[1].bytesPerPixel + PixmapWidthPaddingInfo [1].bytesPerPixel) >> PixmapWidthPaddingInfo[1].padBytesLog2 ) : ((int)((stuff->width) + PixmapWidthPaddingInfo[1].padRoundUp ) >> PixmapWidthPaddingInfo[1].padPixelsLog2)) << PixmapWidthPaddingInfo[1].padBytesLog2) * stuff->height; | |||||
673 | plane = ((Mask) 1) << (pDraw->depth - 1); | |||||
674 | /* only planes asked for */ | |||||
675 | length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1))); | |||||
676 | } | |||||
677 | ||||||
678 | VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client){ if ((stuff->offset + length) > shmdesc->size) { return 10; } }; | |||||
679 | xgi.size = length; | |||||
680 | ||||||
681 | if (length == 0) { | |||||
682 | /* nothing to do */ | |||||
683 | } | |||||
684 | else if (stuff->format == ZPixmap2) { | |||||
685 | (*pDraw->pScreen->GetImage) (pDraw, stuff->x, stuff->y, | |||||
686 | stuff->width, stuff->height, | |||||
687 | stuff->format, stuff->planeMask, | |||||
688 | shmdesc->addr + stuff->offset); | |||||
689 | } | |||||
690 | else { | |||||
691 | ||||||
692 | length = stuff->offset; | |||||
693 | for (; plane; plane >>= 1) { | |||||
694 | if (stuff->planeMask & plane) { | |||||
695 | (*pDraw->pScreen->GetImage) (pDraw, | |||||
696 | stuff->x, stuff->y, | |||||
697 | stuff->width, stuff->height, | |||||
698 | stuff->format, plane, | |||||
699 | shmdesc->addr + length); | |||||
700 | length += lenPer; | |||||
701 | } | |||||
702 | } | |||||
703 | } | |||||
704 | ||||||
705 | if (client->swapped) { | |||||
706 | swaps(&xgi.sequenceNumber)do { if (sizeof(*(&xgi.sequenceNumber)) != 2) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&xgi.sequenceNumber ) & 1) && ((uintptr_t)(&xgi.sequenceNumber) & 1) == 0) *(&xgi.sequenceNumber) = lswaps(*(&xgi.sequenceNumber )); else swap_uint16((uint16_t *)(&xgi.sequenceNumber)); } while (0); | |||||
707 | swapl(&xgi.length)do { if (sizeof(*(&xgi.length)) != 4) wrong_size(); if (__builtin_constant_p ((uintptr_t)(&xgi.length) & 3) && ((uintptr_t )(&xgi.length) & 3) == 0) *(&xgi.length) = lswapl (*(&xgi.length)); else swap_uint32((uint32_t *)(&xgi. length)); } while (0); | |||||
708 | swapl(&xgi.visual)do { if (sizeof(*(&xgi.visual)) != 4) wrong_size(); if (__builtin_constant_p ((uintptr_t)(&xgi.visual) & 3) && ((uintptr_t )(&xgi.visual) & 3) == 0) *(&xgi.visual) = lswapl (*(&xgi.visual)); else swap_uint32((uint32_t *)(&xgi. visual)); } while (0); | |||||
709 | swapl(&xgi.size)do { if (sizeof(*(&xgi.size)) != 4) wrong_size(); if (__builtin_constant_p ((uintptr_t)(&xgi.size) & 3) && ((uintptr_t)( &xgi.size) & 3) == 0) *(&xgi.size) = lswapl(*(& xgi.size)); else swap_uint32((uint32_t *)(&xgi.size)); } while (0); | |||||
710 | } | |||||
711 | WriteToClient(client, sizeof(xShmGetImageReply), &xgi); | |||||
712 | ||||||
713 | return Success0; | |||||
714 | } | |||||
715 | ||||||
716 | #ifdef PANORAMIX1 | |||||
717 | static int | |||||
718 | ProcPanoramiXShmPutImage(ClientPtr client) | |||||
719 | { | |||||
720 | int j, result, orig_x, orig_y; | |||||
721 | PanoramiXRes *draw, *gc; | |||||
722 | Bool sendEvent, isRoot; | |||||
723 | ||||||
724 | REQUEST(xShmPutImageReq)xShmPutImageReq *stuff = (xShmPutImageReq *)client->requestBuffer; | |||||
725 | REQUEST_SIZE_MATCH(xShmPutImageReq)if ((sizeof(xShmPutImageReq) >> 2) != client->req_len ) return(16); | |||||
726 | ||||||
727 | result = dixLookupResourceByClass((void **) &draw, stuff->drawable, | |||||
728 | XRC_DRAWABLE, client, DixWriteAccess(1<<1)); | |||||
729 | if (result != Success0) | |||||
730 | return (result == BadValue2) ? BadDrawable9 : result; | |||||
731 | ||||||
732 | result = dixLookupResourceByType((void **) &gc, stuff->gc, | |||||
733 | XRT_GC, client, DixReadAccess(1<<0)); | |||||
734 | if (result != Success0) | |||||
735 | return result; | |||||
736 | ||||||
737 | isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; | |||||
738 | ||||||
739 | orig_x = stuff->dstX; | |||||
740 | orig_y = stuff->dstY; | |||||
741 | sendEvent = stuff->sendEvent; | |||||
742 | stuff->sendEvent = 0; | |||||
743 | FOR_NSCREENS(j)for(j = 0; j < PanoramiXNumScreens; j++) { | |||||
744 | if (!j) | |||||
745 | stuff->sendEvent = sendEvent; | |||||
746 | stuff->drawable = draw->info[j].id; | |||||
747 | stuff->gc = gc->info[j].id; | |||||
748 | if (isRoot) { | |||||
749 | stuff->dstX = orig_x - screenInfo.screens[j]->x; | |||||
750 | stuff->dstY = orig_y - screenInfo.screens[j]->y; | |||||
751 | } | |||||
752 | result = ProcShmPutImage(client); | |||||
753 | if (result != Success0) | |||||
754 | break; | |||||
755 | } | |||||
756 | return result; | |||||
757 | } | |||||
758 | ||||||
759 | static int | |||||
760 | ProcPanoramiXShmGetImage(ClientPtr client) | |||||
761 | { | |||||
762 | PanoramiXRes *draw; | |||||
763 | DrawablePtr *drawables; | |||||
764 | DrawablePtr pDraw; | |||||
765 | xShmGetImageReply xgi; | |||||
766 | ShmDescPtr shmdesc; | |||||
767 | int i, x, y, w, h, format, rc; | |||||
768 | Mask plane = 0, planemask; | |||||
769 | long lenPer = 0, length, widthBytesLine; | |||||
770 | Bool isRoot; | |||||
771 | ||||||
772 | REQUEST(xShmGetImageReq)xShmGetImageReq *stuff = (xShmGetImageReq *)client->requestBuffer; | |||||
773 | ||||||
774 | REQUEST_SIZE_MATCH(xShmGetImageReq)if ((sizeof(xShmGetImageReq) >> 2) != client->req_len ) return(16); | |||||
775 | ||||||
776 | if ((stuff->format != XYPixmap1) && (stuff->format != ZPixmap2)) { | |||||
| ||||||
777 | client->errorValue = stuff->format; | |||||
778 | return BadValue2; | |||||
779 | } | |||||
780 | ||||||
781 | rc = dixLookupResourceByClass((void **) &draw, stuff->drawable, | |||||
782 | XRC_DRAWABLE, client, DixWriteAccess(1<<1)); | |||||
783 | if (rc != Success0) | |||||
784 | return (rc == BadValue2) ? BadDrawable9 : rc; | |||||
785 | ||||||
786 | if (draw->type == XRT_PIXMAP) | |||||
787 | return ProcShmGetImage(client); | |||||
788 | ||||||
789 | rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReadAccess(1<<0)); | |||||
790 | if (rc != Success0) | |||||
791 | return rc; | |||||
792 | ||||||
793 | VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client){ { int tmprc; tmprc = dixLookupResourceByType((void **)& (shmdesc), stuff->shmseg, ShmSegType, client, (1<<0) ); if (tmprc != 0) return tmprc; }; if ((stuff->offset & 3) || (stuff->offset > shmdesc->size)) { client-> errorValue = stuff->offset; return 2; } if (1 && ! shmdesc->writable) return 10; }; | |||||
794 | ||||||
795 | x = stuff->x; | |||||
796 | y = stuff->y; | |||||
797 | w = stuff->width; | |||||
798 | h = stuff->height; | |||||
799 | format = stuff->format; | |||||
800 | planemask = stuff->planeMask; | |||||
801 | ||||||
802 | isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; | |||||
803 | ||||||
804 | if (isRoot) { | |||||
805 | if ( /* check for being onscreen */ | |||||
806 | x < 0 || x + w > PanoramiXPixWidth || | |||||
807 | y < 0 || y + h > PanoramiXPixHeight) | |||||
808 | return BadMatch8; | |||||
809 | } | |||||
810 | else { | |||||
811 | if ( /* check for being onscreen */ | |||||
812 | screenInfo.screens[0]->x + pDraw->x + x < 0 || | |||||
813 | screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth | |||||
814 | || screenInfo.screens[0]->y + pDraw->y + y < 0 || | |||||
815 | screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight | |||||
816 | || | |||||
817 | /* check for being inside of border */ | |||||
818 | x < -wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) || | |||||
819 | x + w > wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) + (int) pDraw->width || | |||||
820 | y < -wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) || | |||||
821 | y + h > wBorderWidth((WindowPtr) pDraw)((int) ((WindowPtr) pDraw)->borderWidth) + (int) pDraw->height) | |||||
822 | return BadMatch8; | |||||
823 | } | |||||
824 | ||||||
825 | drawables = calloc(PanoramiXNumScreens, sizeof(DrawablePtr)); | |||||
826 | if (!drawables) | |||||
827 | return BadAlloc11; | |||||
828 | ||||||
829 | drawables[0] = pDraw; | |||||
830 | FOR_NSCREENS_FORWARD_SKIP(i)for(i = 1; i < PanoramiXNumScreens; i++) { | |||||
831 | rc = dixLookupDrawable(drawables + i, draw->info[i].id, client, 0, | |||||
832 | DixReadAccess(1<<0)); | |||||
833 | if (rc != Success0) { | |||||
834 | free(drawables); | |||||
835 | return rc; | |||||
836 | } | |||||
837 | } | |||||
838 | ||||||
839 | xgi = (xShmGetImageReply) { | |||||
840 | .type = X_Reply1, | |||||
841 | .sequenceNumber = client->sequence, | |||||
842 | .length = 0, | |||||
843 | .visual = wVisual(((WindowPtr) pDraw))((((WindowPtr) pDraw))->optional ? (((WindowPtr) pDraw))-> optional->visual : FindWindowWithOptional(((WindowPtr) pDraw ))->optional->visual), | |||||
844 | .depth = pDraw->depth | |||||
845 | }; | |||||
846 | ||||||
847 | if (format == ZPixmap2) { | |||||
848 | widthBytesLine = PixmapBytePad(w, pDraw->depth)((PixmapWidthPaddingInfo[pDraw->depth].notPower2 ? (((int) (w) * PixmapWidthPaddingInfo[pDraw->depth].bytesPerPixel + PixmapWidthPaddingInfo[pDraw->depth].bytesPerPixel) >> PixmapWidthPaddingInfo[pDraw->depth].padBytesLog2) : ((int )((w) + PixmapWidthPaddingInfo[pDraw->depth].padRoundUp) >> PixmapWidthPaddingInfo[pDraw->depth].padPixelsLog2)) << PixmapWidthPaddingInfo[pDraw->depth].padBytesLog2); | |||||
849 | length = widthBytesLine * h; | |||||
850 | } | |||||
851 | else { | |||||
852 | widthBytesLine = PixmapBytePad(w, 1)((PixmapWidthPaddingInfo[1].notPower2 ? (((int)(w) * PixmapWidthPaddingInfo [1].bytesPerPixel + PixmapWidthPaddingInfo[1].bytesPerPixel) >> PixmapWidthPaddingInfo[1].padBytesLog2) : ((int)((w) + PixmapWidthPaddingInfo [1].padRoundUp) >> PixmapWidthPaddingInfo[1].padPixelsLog2 )) << PixmapWidthPaddingInfo[1].padBytesLog2); | |||||
853 | lenPer = widthBytesLine * h; | |||||
854 | plane = ((Mask) 1) << (pDraw->depth - 1); | |||||
855 | length = lenPer * Ones(planemask & (plane | (plane - 1))); | |||||
856 | } | |||||
857 | ||||||
858 | VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client){ if ((stuff->offset + length) > shmdesc->size) { return 10; } }; | |||||
| ||||||
859 | xgi.size = length; | |||||
860 | ||||||
861 | if (length == 0) { /* nothing to do */ | |||||
862 | } | |||||
863 | else if (format == ZPixmap2) { | |||||
864 | XineramaGetImageData(drawables, x, y, w, h, format, planemask, | |||||
865 | shmdesc->addr + stuff->offset, | |||||
866 | widthBytesLine, isRoot); | |||||
867 | } | |||||
868 | else { | |||||
869 | ||||||
870 | length = stuff->offset; | |||||
871 | for (; plane; plane >>= 1) { | |||||
872 | if (planemask & plane) { | |||||
873 | XineramaGetImageData(drawables, x, y, w, h, | |||||
874 | format, plane, shmdesc->addr + length, | |||||
875 | widthBytesLine, isRoot); | |||||
876 | length += lenPer; | |||||
877 | } | |||||
878 | } | |||||
879 | } | |||||
880 | free(drawables); | |||||
881 | ||||||
882 | if (client->swapped) { | |||||
883 | swaps(&xgi.sequenceNumber)do { if (sizeof(*(&xgi.sequenceNumber)) != 2) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&xgi.sequenceNumber ) & 1) && ((uintptr_t)(&xgi.sequenceNumber) & 1) == 0) *(&xgi.sequenceNumber) = lswaps(*(&xgi.sequenceNumber )); else swap_uint16((uint16_t *)(&xgi.sequenceNumber)); } while (0); | |||||
884 | swapl(&xgi.length)do { if (sizeof(*(&xgi.length)) != 4) wrong_size(); if (__builtin_constant_p ((uintptr_t)(&xgi.length) & 3) && ((uintptr_t )(&xgi.length) & 3) == 0) *(&xgi.length) = lswapl (*(&xgi.length)); else swap_uint32((uint32_t *)(&xgi. length)); } while (0); | |||||
885 | swapl(&xgi.visual)do { if (sizeof(*(&xgi.visual)) != 4) wrong_size(); if (__builtin_constant_p ((uintptr_t)(&xgi.visual) & 3) && ((uintptr_t )(&xgi.visual) & 3) == 0) *(&xgi.visual) = lswapl (*(&xgi.visual)); else swap_uint32((uint32_t *)(&xgi. visual)); } while (0); | |||||
886 | swapl(&xgi.size)do { if (sizeof(*(&xgi.size)) != 4) wrong_size(); if (__builtin_constant_p ((uintptr_t)(&xgi.size) & 3) && ((uintptr_t)( &xgi.size) & 3) == 0) *(&xgi.size) = lswapl(*(& xgi.size)); else swap_uint32((uint32_t *)(&xgi.size)); } while (0); | |||||
887 | } | |||||
888 | WriteToClient(client, sizeof(xShmGetImageReply), &xgi); | |||||
889 | ||||||
890 | return Success0; | |||||
891 | } | |||||
892 | ||||||
893 | static int | |||||
894 | ProcPanoramiXShmCreatePixmap(ClientPtr client) | |||||
895 | { | |||||
896 | ScreenPtr pScreen = NULL((void*)0); | |||||
897 | PixmapPtr pMap = NULL((void*)0); | |||||
898 | DrawablePtr pDraw; | |||||
899 | DepthPtr pDepth; | |||||
900 | int i, j, result, rc; | |||||
901 | ShmDescPtr shmdesc; | |||||
902 | ||||||
903 | REQUEST(xShmCreatePixmapReq)xShmCreatePixmapReq *stuff = (xShmCreatePixmapReq *)client-> requestBuffer; | |||||
904 | unsigned int width, height, depth; | |||||
905 | unsigned long size; | |||||
906 | PanoramiXRes *newPix; | |||||
907 | ||||||
908 | REQUEST_SIZE_MATCH(xShmCreatePixmapReq)if ((sizeof(xShmCreatePixmapReq) >> 2) != client->req_len ) return(16); | |||||
909 | client->errorValue = stuff->pid; | |||||
910 | if (!sharedPixmaps) | |||||
911 | return BadImplementation17; | |||||
912 | LEGAL_NEW_RESOURCE(stuff->pid, client)if (!LegalNewID(stuff->pid,client)) { client->errorValue = stuff->pid; return 14; }; | |||||
913 | rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY(-1), | |||||
914 | DixGetAttrAccess(1<<4)); | |||||
915 | if (rc != Success0) | |||||
916 | return rc; | |||||
917 | ||||||
918 | VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client){ { int tmprc; tmprc = dixLookupResourceByType((void **)& (shmdesc), stuff->shmseg, ShmSegType, client, (1<<0) ); if (tmprc != 0) return tmprc; }; if ((stuff->offset & 3) || (stuff->offset > shmdesc->size)) { client-> errorValue = stuff->offset; return 2; } if (1 && ! shmdesc->writable) return 10; }; | |||||
919 | ||||||
920 | width = stuff->width; | |||||
921 | height = stuff->height; | |||||
922 | depth = stuff->depth; | |||||
923 | if (!width || !height || !depth) { | |||||
924 | client->errorValue = 0; | |||||
925 | return BadValue2; | |||||
926 | } | |||||
927 | if (width > 32767 || height > 32767) | |||||
928 | return BadAlloc11; | |||||
929 | ||||||
930 | if (stuff->depth != 1) { | |||||
931 | pDepth = pDraw->pScreen->allowedDepths; | |||||
932 | for (i = 0; i < pDraw->pScreen->numDepths; i++, pDepth++) | |||||
933 | if (pDepth->depth == stuff->depth) | |||||
934 | goto CreatePmap; | |||||
935 | client->errorValue = stuff->depth; | |||||
936 | return BadValue2; | |||||
937 | } | |||||
938 | ||||||
939 | CreatePmap: | |||||
940 | size = PixmapBytePad(width, depth)((PixmapWidthPaddingInfo[depth].notPower2 ? (((int)(width) * PixmapWidthPaddingInfo [depth].bytesPerPixel + PixmapWidthPaddingInfo[depth].bytesPerPixel ) >> PixmapWidthPaddingInfo[depth].padBytesLog2) : ((int )((width) + PixmapWidthPaddingInfo[depth].padRoundUp) >> PixmapWidthPaddingInfo[depth].padPixelsLog2)) << PixmapWidthPaddingInfo [depth].padBytesLog2) * height; | |||||
941 | if (sizeof(size) == 4 && BitsPerPixel(depth)(PixmapWidthPaddingInfo[depth].bitsPerPixel) > 8) { | |||||
942 | if (size < width * height) | |||||
943 | return BadAlloc11; | |||||
944 | } | |||||
945 | /* thankfully, offset is unsigned */ | |||||
946 | if (stuff->offset + size < size) | |||||
947 | return BadAlloc11; | |||||
948 | ||||||
949 | VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client){ if ((stuff->offset + size) > shmdesc->size) { return 10; } }; | |||||
950 | ||||||
951 | if (!(newPix = malloc(sizeof(PanoramiXRes)))) | |||||
952 | return BadAlloc11; | |||||
953 | ||||||
954 | newPix->type = XRT_PIXMAP; | |||||
955 | newPix->u.pix.shared = TRUE1; | |||||
956 | panoramix_setup_ids(newPix, client, stuff->pid); | |||||
957 | ||||||
958 | result = Success0; | |||||
959 | ||||||
960 | FOR_NSCREENS(j)for(j = 0; j < PanoramiXNumScreens; j++) { | |||||
961 | ShmScrPrivateRec *screen_priv; | |||||
962 | ||||||
963 | pScreen = screenInfo.screens[j]; | |||||
964 | ||||||
965 | screen_priv = ShmGetScreenPriv(pScreen)((ShmScrPrivateRec *)dixLookupPrivate(&(pScreen)->devPrivates , (&shmScrPrivateKeyRec))); | |||||
966 | pMap = (*screen_priv->shmFuncs->CreatePixmap) (pScreen, | |||||
967 | stuff->width, | |||||
968 | stuff->height, | |||||
969 | stuff->depth, | |||||
970 | shmdesc->addr + | |||||
971 | stuff->offset); | |||||
972 | ||||||
973 | if (pMap) { | |||||
974 | result = XaceHook(XACE_RESOURCE_ACCESS2, client, stuff->pid, | |||||
975 | RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), pMap, RT_NONE((RESTYPE)0), NULL((void*)0), DixCreateAccess(1<<3)); | |||||
976 | if (result != Success0) { | |||||
977 | pDraw->pScreen->DestroyPixmap(pMap); | |||||
978 | return result; | |||||
979 | } | |||||
980 | dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey(&shmPixmapPrivateKeyRec), shmdesc); | |||||
981 | shmdesc->refcnt++; | |||||
982 | pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER((++globalSerialNumber) > (1L<<28) ? (globalSerialNumber = 1): globalSerialNumber); | |||||
983 | pMap->drawable.id = newPix->info[j].id; | |||||
984 | if (!AddResourceDarwin_X_AddResource(newPix->info[j].id, RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), (void *) pMap)) { | |||||
985 | result = BadAlloc11; | |||||
986 | break; | |||||
987 | } | |||||
988 | } | |||||
989 | else { | |||||
990 | result = BadAlloc11; | |||||
991 | break; | |||||
992 | } | |||||
993 | } | |||||
994 | ||||||
995 | if (result == BadAlloc11) { | |||||
996 | while (j--) | |||||
997 | FreeResource(newPix->info[j].id, RT_NONE((RESTYPE)0)); | |||||
998 | free(newPix); | |||||
999 | } | |||||
1000 | else | |||||
1001 | AddResourceDarwin_X_AddResource(stuff->pid, XRT_PIXMAP, newPix); | |||||
1002 | ||||||
1003 | return result; | |||||
1004 | } | |||||
1005 | #endif | |||||
1006 | ||||||
1007 | static PixmapPtr | |||||
1008 | fbShmCreatePixmap(ScreenPtr pScreen, | |||||
1009 | int width, int height, int depth, char *addr) | |||||
1010 | { | |||||
1011 | PixmapPtr pPixmap; | |||||
1012 | ||||||
1013 | pPixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0); | |||||
1014 | if (!pPixmap) | |||||
1015 | return NullPixmap((PixmapPtr)0); | |||||
1016 | ||||||
1017 | if (!(*pScreen->ModifyPixmapHeader) (pPixmap, width, height, depth, | |||||
1018 | BitsPerPixel(depth)(PixmapWidthPaddingInfo[depth].bitsPerPixel), | |||||
1019 | PixmapBytePad(width, depth)((PixmapWidthPaddingInfo[depth].notPower2 ? (((int)(width) * PixmapWidthPaddingInfo [depth].bytesPerPixel + PixmapWidthPaddingInfo[depth].bytesPerPixel ) >> PixmapWidthPaddingInfo[depth].padBytesLog2) : ((int )((width) + PixmapWidthPaddingInfo[depth].padRoundUp) >> PixmapWidthPaddingInfo[depth].padPixelsLog2)) << PixmapWidthPaddingInfo [depth].padBytesLog2), | |||||
1020 | (void *) addr)) { | |||||
1021 | (*pScreen->DestroyPixmap) (pPixmap); | |||||
1022 | return NullPixmap((PixmapPtr)0); | |||||
1023 | } | |||||
1024 | return pPixmap; | |||||
1025 | } | |||||
1026 | ||||||
1027 | static int | |||||
1028 | ProcShmCreatePixmap(ClientPtr client) | |||||
1029 | { | |||||
1030 | PixmapPtr pMap; | |||||
1031 | DrawablePtr pDraw; | |||||
1032 | DepthPtr pDepth; | |||||
1033 | int i, rc; | |||||
1034 | ShmDescPtr shmdesc; | |||||
1035 | ShmScrPrivateRec *screen_priv; | |||||
1036 | ||||||
1037 | REQUEST(xShmCreatePixmapReq)xShmCreatePixmapReq *stuff = (xShmCreatePixmapReq *)client-> requestBuffer; | |||||
1038 | unsigned int width, height, depth; | |||||
1039 | unsigned long size; | |||||
1040 | ||||||
1041 | REQUEST_SIZE_MATCH(xShmCreatePixmapReq)if ((sizeof(xShmCreatePixmapReq) >> 2) != client->req_len ) return(16); | |||||
1042 | client->errorValue = stuff->pid; | |||||
1043 | if (!sharedPixmaps) | |||||
1044 | return BadImplementation17; | |||||
1045 | LEGAL_NEW_RESOURCE(stuff->pid, client)if (!LegalNewID(stuff->pid,client)) { client->errorValue = stuff->pid; return 14; }; | |||||
1046 | rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY(-1), | |||||
1047 | DixGetAttrAccess(1<<4)); | |||||
1048 | if (rc != Success0) | |||||
1049 | return rc; | |||||
1050 | ||||||
1051 | VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client){ { int tmprc; tmprc = dixLookupResourceByType((void **)& (shmdesc), stuff->shmseg, ShmSegType, client, (1<<0) ); if (tmprc != 0) return tmprc; }; if ((stuff->offset & 3) || (stuff->offset > shmdesc->size)) { client-> errorValue = stuff->offset; return 2; } if (1 && ! shmdesc->writable) return 10; }; | |||||
1052 | ||||||
1053 | width = stuff->width; | |||||
1054 | height = stuff->height; | |||||
1055 | depth = stuff->depth; | |||||
1056 | if (!width || !height || !depth) { | |||||
1057 | client->errorValue = 0; | |||||
1058 | return BadValue2; | |||||
1059 | } | |||||
1060 | if (width > 32767 || height > 32767) | |||||
1061 | return BadAlloc11; | |||||
1062 | ||||||
1063 | if (stuff->depth != 1) { | |||||
1064 | pDepth = pDraw->pScreen->allowedDepths; | |||||
1065 | for (i = 0; i < pDraw->pScreen->numDepths; i++, pDepth++) | |||||
1066 | if (pDepth->depth == stuff->depth) | |||||
1067 | goto CreatePmap; | |||||
1068 | client->errorValue = stuff->depth; | |||||
1069 | return BadValue2; | |||||
1070 | } | |||||
1071 | ||||||
1072 | CreatePmap: | |||||
1073 | size = PixmapBytePad(width, depth)((PixmapWidthPaddingInfo[depth].notPower2 ? (((int)(width) * PixmapWidthPaddingInfo [depth].bytesPerPixel + PixmapWidthPaddingInfo[depth].bytesPerPixel ) >> PixmapWidthPaddingInfo[depth].padBytesLog2) : ((int )((width) + PixmapWidthPaddingInfo[depth].padRoundUp) >> PixmapWidthPaddingInfo[depth].padPixelsLog2)) << PixmapWidthPaddingInfo [depth].padBytesLog2) * height; | |||||
1074 | if (sizeof(size) == 4 && BitsPerPixel(depth)(PixmapWidthPaddingInfo[depth].bitsPerPixel) > 8) { | |||||
1075 | if (size < width * height) | |||||
1076 | return BadAlloc11; | |||||
1077 | } | |||||
1078 | /* thankfully, offset is unsigned */ | |||||
1079 | if (stuff->offset + size < size) | |||||
1080 | return BadAlloc11; | |||||
1081 | ||||||
1082 | VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client){ if ((stuff->offset + size) > shmdesc->size) { return 10; } }; | |||||
1083 | screen_priv = ShmGetScreenPriv(pDraw->pScreen)((ShmScrPrivateRec *)dixLookupPrivate(&(pDraw->pScreen )->devPrivates, (&shmScrPrivateKeyRec))); | |||||
1084 | pMap = (*screen_priv->shmFuncs->CreatePixmap) (pDraw->pScreen, stuff->width, | |||||
1085 | stuff->height, stuff->depth, | |||||
1086 | shmdesc->addr + | |||||
1087 | stuff->offset); | |||||
1088 | if (pMap) { | |||||
1089 | rc = XaceHook(XACE_RESOURCE_ACCESS2, client, stuff->pid, RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), | |||||
1090 | pMap, RT_NONE((RESTYPE)0), NULL((void*)0), DixCreateAccess(1<<3)); | |||||
1091 | if (rc != Success0) { | |||||
1092 | pDraw->pScreen->DestroyPixmap(pMap); | |||||
1093 | return rc; | |||||
1094 | } | |||||
1095 | dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey(&shmPixmapPrivateKeyRec), shmdesc); | |||||
1096 | shmdesc->refcnt++; | |||||
1097 | pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER((++globalSerialNumber) > (1L<<28) ? (globalSerialNumber = 1): globalSerialNumber); | |||||
1098 | pMap->drawable.id = stuff->pid; | |||||
1099 | if (AddResourceDarwin_X_AddResource(stuff->pid, RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), (void *) pMap)) { | |||||
1100 | return Success0; | |||||
1101 | } | |||||
1102 | } | |||||
1103 | return BadAlloc11; | |||||
1104 | } | |||||
1105 | ||||||
1106 | #ifdef SHM_FD_PASSING | |||||
1107 | ||||||
1108 | static void | |||||
1109 | ShmBusfaultNotify(void *context) | |||||
1110 | { | |||||
1111 | ShmDescPtr shmdesc = context; | |||||
1112 | ||||||
1113 | ErrorF("shared memory 0x%x truncated by client\n", | |||||
1114 | (unsigned int) shmdesc->resource); | |||||
1115 | busfault_unregister(shmdesc->busfault); | |||||
1116 | shmdesc->busfault = NULL((void*)0); | |||||
1117 | FreeResource (shmdesc->resource, RT_NONE((RESTYPE)0)); | |||||
1118 | } | |||||
1119 | ||||||
1120 | static int | |||||
1121 | ProcShmAttachFd(ClientPtr client) | |||||
1122 | { | |||||
1123 | int fd; | |||||
1124 | ShmDescPtr shmdesc; | |||||
1125 | REQUEST(xShmAttachFdReq)xShmAttachFdReq *stuff = (xShmAttachFdReq *)client->requestBuffer; | |||||
1126 | struct stat statb; | |||||
1127 | ||||||
1128 | SetReqFds(client, 1); | |||||
1129 | REQUEST_SIZE_MATCH(xShmAttachFdReq)if ((sizeof(xShmAttachFdReq) >> 2) != client->req_len ) return(16); | |||||
1130 | LEGAL_NEW_RESOURCE(stuff->shmseg, client)if (!LegalNewID(stuff->shmseg,client)) { client->errorValue = stuff->shmseg; return 14; }; | |||||
1131 | if ((stuff->readOnly != xTrue1) && (stuff->readOnly != xFalse0)) { | |||||
1132 | client->errorValue = stuff->readOnly; | |||||
1133 | return BadValue2; | |||||
1134 | } | |||||
1135 | fd = ReadFdFromClient(client); | |||||
1136 | if (fd < 0) | |||||
1137 | return BadMatch8; | |||||
1138 | ||||||
1139 | if (fstat(fd, &statb) < 0 || statb.st_size == 0) { | |||||
1140 | close(fd); | |||||
1141 | return BadMatch8; | |||||
1142 | } | |||||
1143 | ||||||
1144 | shmdesc = malloc(sizeof(ShmDescRec)); | |||||
1145 | if (!shmdesc) { | |||||
1146 | close(fd); | |||||
1147 | return BadAlloc11; | |||||
1148 | } | |||||
1149 | shmdesc->is_fd = TRUE1; | |||||
1150 | shmdesc->addr = mmap(NULL((void*)0), statb.st_size, | |||||
1151 | stuff->readOnly ? PROT_READ0x01 : PROT_READ0x01|PROT_WRITE0x02, | |||||
1152 | MAP_SHARED0x0001, | |||||
1153 | fd, 0); | |||||
1154 | ||||||
1155 | close(fd); | |||||
1156 | if (shmdesc->addr == ((char *) -1)) { | |||||
1157 | free(shmdesc); | |||||
1158 | return BadAccess10; | |||||
1159 | } | |||||
1160 | ||||||
1161 | shmdesc->refcnt = 1; | |||||
1162 | shmdesc->writable = !stuff->readOnly; | |||||
1163 | shmdesc->size = statb.st_size; | |||||
1164 | shmdesc->resource = stuff->shmseg; | |||||
1165 | ||||||
1166 | shmdesc->busfault = busfault_register_mmap(shmdesc->addr, shmdesc->size, ShmBusfaultNotify, shmdesc); | |||||
1167 | if (!shmdesc->busfault) { | |||||
1168 | munmap(shmdesc->addr, shmdesc->size); | |||||
1169 | free(shmdesc); | |||||
1170 | return BadAlloc11; | |||||
1171 | } | |||||
1172 | ||||||
1173 | shmdesc->next = Shmsegs; | |||||
1174 | Shmsegs = shmdesc; | |||||
1175 | ||||||
1176 | if (!AddResourceDarwin_X_AddResource(stuff->shmseg, ShmSegType, (void *) shmdesc)) | |||||
1177 | return BadAlloc11; | |||||
1178 | return Success0; | |||||
1179 | } | |||||
1180 | ||||||
1181 | static int | |||||
1182 | shm_tmpfile(void) | |||||
1183 | { | |||||
1184 | #ifdef SHMDIR"/var/tmp" | |||||
1185 | int fd; | |||||
1186 | int flags; | |||||
1187 | char template[] = SHMDIR"/var/tmp" "/shmfd-XXXXXX"; | |||||
1188 | #ifdef O_TMPFILE | |||||
1189 | fd = open(SHMDIR"/var/tmp", O_TMPFILE|O_RDWR0x0002|O_CLOEXEC0x1000000|O_EXCL0x0800, 0666); | |||||
1190 | if (fd >= 0) { | |||||
1191 | ErrorF ("Using O_TMPFILE\n"); | |||||
1192 | return fd; | |||||
1193 | } | |||||
1194 | ErrorF ("Not using O_TMPFILE\n"); | |||||
1195 | #endif | |||||
1196 | fd = mkstemp(template); | |||||
1197 | if (fd < 0) | |||||
1198 | return -1; | |||||
1199 | unlink(template); | |||||
1200 | if (fcntl(fd, F_GETFD1, &flags) >= 0) { | |||||
1201 | flags |= FD_CLOEXEC1; | |||||
1202 | (void) fcntl(fd, F_SETFD2, &flags); | |||||
1203 | } | |||||
1204 | return fd; | |||||
1205 | #else | |||||
1206 | return -1; | |||||
1207 | #endif | |||||
1208 | } | |||||
1209 | ||||||
1210 | static int | |||||
1211 | ProcShmCreateSegment(ClientPtr client) | |||||
1212 | { | |||||
1213 | int fd; | |||||
1214 | ShmDescPtr shmdesc; | |||||
1215 | REQUEST(xShmCreateSegmentReq)xShmCreateSegmentReq *stuff = (xShmCreateSegmentReq *)client-> requestBuffer; | |||||
1216 | xShmCreateSegmentReply rep = { | |||||
1217 | .type = X_Reply1, | |||||
1218 | .nfd = 1, | |||||
1219 | .sequenceNumber = client->sequence, | |||||
1220 | .length = 0, | |||||
1221 | }; | |||||
1222 | ||||||
1223 | REQUEST_SIZE_MATCH(xShmCreateSegmentReq)if ((sizeof(xShmCreateSegmentReq) >> 2) != client->req_len ) return(16); | |||||
1224 | if ((stuff->readOnly != xTrue1) && (stuff->readOnly != xFalse0)) { | |||||
1225 | client->errorValue = stuff->readOnly; | |||||
1226 | return BadValue2; | |||||
1227 | } | |||||
1228 | fd = shm_tmpfile(); | |||||
1229 | if (fd < 0) | |||||
1230 | return BadAlloc11; | |||||
1231 | if (ftruncate(fd, stuff->size) < 0) { | |||||
1232 | close(fd); | |||||
1233 | return BadAlloc11; | |||||
1234 | } | |||||
1235 | shmdesc = malloc(sizeof(ShmDescRec)); | |||||
1236 | if (!shmdesc) { | |||||
1237 | close(fd); | |||||
1238 | return BadAlloc11; | |||||
1239 | } | |||||
1240 | shmdesc->is_fd = TRUE1; | |||||
1241 | shmdesc->addr = mmap(NULL((void*)0), stuff->size, | |||||
1242 | stuff->readOnly ? PROT_READ0x01 : PROT_READ0x01|PROT_WRITE0x02, | |||||
1243 | MAP_SHARED0x0001, | |||||
1244 | fd, 0); | |||||
1245 | ||||||
1246 | if (shmdesc->addr == ((char *) -1)) { | |||||
1247 | close(fd); | |||||
1248 | free(shmdesc); | |||||
1249 | return BadAccess10; | |||||
1250 | } | |||||
1251 | ||||||
1252 | shmdesc->refcnt = 1; | |||||
1253 | shmdesc->writable = !stuff->readOnly; | |||||
1254 | shmdesc->size = stuff->size; | |||||
1255 | ||||||
1256 | shmdesc->busfault = busfault_register_mmap(shmdesc->addr, shmdesc->size, ShmBusfaultNotify, shmdesc); | |||||
1257 | if (!shmdesc->busfault) { | |||||
1258 | close(fd); | |||||
1259 | munmap(shmdesc->addr, shmdesc->size); | |||||
1260 | free(shmdesc); | |||||
1261 | return BadAlloc11; | |||||
1262 | } | |||||
1263 | ||||||
1264 | shmdesc->next = Shmsegs; | |||||
1265 | Shmsegs = shmdesc; | |||||
1266 | ||||||
1267 | if (!AddResourceDarwin_X_AddResource(stuff->shmseg, ShmSegType, (void *) shmdesc)) { | |||||
1268 | close(fd); | |||||
1269 | return BadAlloc11; | |||||
1270 | } | |||||
1271 | ||||||
1272 | if (WriteFdToClient(client, fd, TRUE1) < 0) { | |||||
1273 | FreeResource(stuff->shmseg, RT_NONE((RESTYPE)0)); | |||||
1274 | close(fd); | |||||
1275 | return BadAlloc11; | |||||
1276 | } | |||||
1277 | WriteToClient(client, sizeof (xShmCreateSegmentReply), &rep); | |||||
1278 | return Success0; | |||||
1279 | } | |||||
1280 | #endif /* SHM_FD_PASSING */ | |||||
1281 | ||||||
1282 | static int | |||||
1283 | ProcShmDispatch(ClientPtr client) | |||||
1284 | { | |||||
1285 | REQUEST(xReq)xReq *stuff = (xReq *)client->requestBuffer; | |||||
1286 | switch (stuff->data) { | |||||
1287 | case X_ShmQueryVersion0: | |||||
1288 | return ProcShmQueryVersion(client); | |||||
1289 | case X_ShmAttach1: | |||||
1290 | return ProcShmAttach(client); | |||||
1291 | case X_ShmDetach2: | |||||
1292 | return ProcShmDetach(client); | |||||
1293 | case X_ShmPutImage3: | |||||
1294 | #ifdef PANORAMIX1 | |||||
1295 | if (!noPanoramiXExtension) | |||||
1296 | return ProcPanoramiXShmPutImage(client); | |||||
1297 | #endif | |||||
1298 | return ProcShmPutImage(client); | |||||
1299 | case X_ShmGetImage4: | |||||
1300 | #ifdef PANORAMIX1 | |||||
1301 | if (!noPanoramiXExtension) | |||||
1302 | return ProcPanoramiXShmGetImage(client); | |||||
1303 | #endif | |||||
1304 | return ProcShmGetImage(client); | |||||
1305 | case X_ShmCreatePixmap5: | |||||
1306 | #ifdef PANORAMIX1 | |||||
1307 | if (!noPanoramiXExtension) | |||||
1308 | return ProcPanoramiXShmCreatePixmap(client); | |||||
1309 | #endif | |||||
1310 | return ProcShmCreatePixmap(client); | |||||
1311 | #ifdef SHM_FD_PASSING | |||||
1312 | case X_ShmAttachFd6: | |||||
1313 | return ProcShmAttachFd(client); | |||||
1314 | case X_ShmCreateSegment7: | |||||
1315 | return ProcShmCreateSegment(client); | |||||
1316 | #endif | |||||
1317 | default: | |||||
1318 | return BadRequest1; | |||||
1319 | } | |||||
1320 | } | |||||
1321 | ||||||
1322 | static void | |||||
1323 | SShmCompletionEvent(xShmCompletionEvent * from, xShmCompletionEvent * to) | |||||
1324 | { | |||||
1325 | to->type = from->type; | |||||
1326 | cpswaps(from->sequenceNumber, to->sequenceNumber)do { if (sizeof((from->sequenceNumber)) != 2 || sizeof((to ->sequenceNumber)) != 2) wrong_size(); (to->sequenceNumber ) = lswaps((from->sequenceNumber)); } while (0); | |||||
1327 | cpswapl(from->drawable, to->drawable)do { if (sizeof((from->drawable)) != 4 || sizeof((to->drawable )) != 4) wrong_size(); (to->drawable) = lswapl((from->drawable )); } while (0); | |||||
1328 | cpswaps(from->minorEvent, to->minorEvent)do { if (sizeof((from->minorEvent)) != 2 || sizeof((to-> minorEvent)) != 2) wrong_size(); (to->minorEvent) = lswaps ((from->minorEvent)); } while (0); | |||||
1329 | to->majorEvent = from->majorEvent; | |||||
1330 | cpswapl(from->shmseg, to->shmseg)do { if (sizeof((from->shmseg)) != 4 || sizeof((to->shmseg )) != 4) wrong_size(); (to->shmseg) = lswapl((from->shmseg )); } while (0); | |||||
1331 | cpswapl(from->offset, to->offset)do { if (sizeof((from->offset)) != 4 || sizeof((to->offset )) != 4) wrong_size(); (to->offset) = lswapl((from->offset )); } while (0); | |||||
1332 | } | |||||
1333 | ||||||
1334 | static int | |||||
1335 | SProcShmQueryVersion(ClientPtr client) | |||||
1336 | { | |||||
1337 | REQUEST(xShmQueryVersionReq)xShmQueryVersionReq *stuff = (xShmQueryVersionReq *)client-> requestBuffer; | |||||
1338 | ||||||
1339 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||||
1340 | return ProcShmQueryVersion(client); | |||||
1341 | } | |||||
1342 | ||||||
1343 | static int | |||||
1344 | SProcShmAttach(ClientPtr client) | |||||
1345 | { | |||||
1346 | REQUEST(xShmAttachReq)xShmAttachReq *stuff = (xShmAttachReq *)client->requestBuffer; | |||||
1347 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||||
1348 | REQUEST_SIZE_MATCH(xShmAttachReq)if ((sizeof(xShmAttachReq) >> 2) != client->req_len) return(16); | |||||
1349 | swapl(&stuff->shmseg)do { if (sizeof(*(&stuff->shmseg)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->shmseg) & 3) && ((uintptr_t)(&stuff->shmseg) & 3) == 0) *(&stuff->shmseg) = lswapl(*(&stuff->shmseg )); else swap_uint32((uint32_t *)(&stuff->shmseg)); } while (0); | |||||
1350 | swapl(&stuff->shmid)do { if (sizeof(*(&stuff->shmid)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->shmid) & 3) && ((uintptr_t)(&stuff->shmid) & 3) == 0) *(&stuff->shmid) = lswapl(*(&stuff->shmid)) ; else swap_uint32((uint32_t *)(&stuff->shmid)); } while (0); | |||||
1351 | return ProcShmAttach(client); | |||||
1352 | } | |||||
1353 | ||||||
1354 | static int | |||||
1355 | SProcShmDetach(ClientPtr client) | |||||
1356 | { | |||||
1357 | REQUEST(xShmDetachReq)xShmDetachReq *stuff = (xShmDetachReq *)client->requestBuffer; | |||||
1358 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||||
1359 | REQUEST_SIZE_MATCH(xShmDetachReq)if ((sizeof(xShmDetachReq) >> 2) != client->req_len) return(16); | |||||
1360 | swapl(&stuff->shmseg)do { if (sizeof(*(&stuff->shmseg)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->shmseg) & 3) && ((uintptr_t)(&stuff->shmseg) & 3) == 0) *(&stuff->shmseg) = lswapl(*(&stuff->shmseg )); else swap_uint32((uint32_t *)(&stuff->shmseg)); } while (0); | |||||
1361 | return ProcShmDetach(client); | |||||
1362 | } | |||||
1363 | ||||||
1364 | static int | |||||
1365 | SProcShmPutImage(ClientPtr client) | |||||
1366 | { | |||||
1367 | REQUEST(xShmPutImageReq)xShmPutImageReq *stuff = (xShmPutImageReq *)client->requestBuffer; | |||||
1368 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||||
1369 | REQUEST_SIZE_MATCH(xShmPutImageReq)if ((sizeof(xShmPutImageReq) >> 2) != client->req_len ) return(16); | |||||
1370 | swapl(&stuff->drawable)do { if (sizeof(*(&stuff->drawable)) != 4) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&stuff->drawable ) & 3) && ((uintptr_t)(&stuff->drawable) & 3) == 0) *(&stuff->drawable) = lswapl(*(&stuff-> drawable)); else swap_uint32((uint32_t *)(&stuff->drawable )); } while (0); | |||||
1371 | swapl(&stuff->gc)do { if (sizeof(*(&stuff->gc)) != 4) wrong_size(); if ( __builtin_constant_p((uintptr_t)(&stuff->gc) & 3) && ((uintptr_t)(&stuff->gc) & 3) == 0) *(&stuff-> gc) = lswapl(*(&stuff->gc)); else swap_uint32((uint32_t *)(&stuff->gc)); } while (0); | |||||
1372 | swaps(&stuff->totalWidth)do { if (sizeof(*(&stuff->totalWidth)) != 2) wrong_size (); if (__builtin_constant_p((uintptr_t)(&stuff->totalWidth ) & 1) && ((uintptr_t)(&stuff->totalWidth) & 1) == 0) *(&stuff->totalWidth) = lswaps(*(& stuff->totalWidth)); else swap_uint16((uint16_t *)(&stuff ->totalWidth)); } while (0); | |||||
1373 | swaps(&stuff->totalHeight)do { if (sizeof(*(&stuff->totalHeight)) != 2) wrong_size (); if (__builtin_constant_p((uintptr_t)(&stuff->totalHeight ) & 1) && ((uintptr_t)(&stuff->totalHeight ) & 1) == 0) *(&stuff->totalHeight) = lswaps(*(& stuff->totalHeight)); else swap_uint16((uint16_t *)(&stuff ->totalHeight)); } while (0); | |||||
1374 | swaps(&stuff->srcX)do { if (sizeof(*(&stuff->srcX)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->srcX) & 1) && ((uintptr_t)(&stuff->srcX) & 1) == 0 ) *(&stuff->srcX) = lswaps(*(&stuff->srcX)); else swap_uint16((uint16_t *)(&stuff->srcX)); } while (0); | |||||
1375 | swaps(&stuff->srcY)do { if (sizeof(*(&stuff->srcY)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->srcY) & 1) && ((uintptr_t)(&stuff->srcY) & 1) == 0 ) *(&stuff->srcY) = lswaps(*(&stuff->srcY)); else swap_uint16((uint16_t *)(&stuff->srcY)); } while (0); | |||||
1376 | swaps(&stuff->srcWidth)do { if (sizeof(*(&stuff->srcWidth)) != 2) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&stuff->srcWidth ) & 1) && ((uintptr_t)(&stuff->srcWidth) & 1) == 0) *(&stuff->srcWidth) = lswaps(*(&stuff-> srcWidth)); else swap_uint16((uint16_t *)(&stuff->srcWidth )); } while (0); | |||||
1377 | swaps(&stuff->srcHeight)do { if (sizeof(*(&stuff->srcHeight)) != 2) wrong_size (); if (__builtin_constant_p((uintptr_t)(&stuff->srcHeight ) & 1) && ((uintptr_t)(&stuff->srcHeight) & 1) == 0) *(&stuff->srcHeight) = lswaps(*(&stuff-> srcHeight)); else swap_uint16((uint16_t *)(&stuff->srcHeight )); } while (0); | |||||
1378 | swaps(&stuff->dstX)do { if (sizeof(*(&stuff->dstX)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->dstX) & 1) && ((uintptr_t)(&stuff->dstX) & 1) == 0 ) *(&stuff->dstX) = lswaps(*(&stuff->dstX)); else swap_uint16((uint16_t *)(&stuff->dstX)); } while (0); | |||||
1379 | swaps(&stuff->dstY)do { if (sizeof(*(&stuff->dstY)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->dstY) & 1) && ((uintptr_t)(&stuff->dstY) & 1) == 0 ) *(&stuff->dstY) = lswaps(*(&stuff->dstY)); else swap_uint16((uint16_t *)(&stuff->dstY)); } while (0); | |||||
1380 | swapl(&stuff->shmseg)do { if (sizeof(*(&stuff->shmseg)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->shmseg) & 3) && ((uintptr_t)(&stuff->shmseg) & 3) == 0) *(&stuff->shmseg) = lswapl(*(&stuff->shmseg )); else swap_uint32((uint32_t *)(&stuff->shmseg)); } while (0); | |||||
1381 | swapl(&stuff->offset)do { if (sizeof(*(&stuff->offset)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->offset) & 3) && ((uintptr_t)(&stuff->offset) & 3) == 0) *(&stuff->offset) = lswapl(*(&stuff->offset )); else swap_uint32((uint32_t *)(&stuff->offset)); } while (0); | |||||
1382 | return ProcShmPutImage(client); | |||||
1383 | } | |||||
1384 | ||||||
1385 | static int | |||||
1386 | SProcShmGetImage(ClientPtr client) | |||||
1387 | { | |||||
1388 | REQUEST(xShmGetImageReq)xShmGetImageReq *stuff = (xShmGetImageReq *)client->requestBuffer; | |||||
1389 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||||
1390 | REQUEST_SIZE_MATCH(xShmGetImageReq)if ((sizeof(xShmGetImageReq) >> 2) != client->req_len ) return(16); | |||||
1391 | swapl(&stuff->drawable)do { if (sizeof(*(&stuff->drawable)) != 4) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&stuff->drawable ) & 3) && ((uintptr_t)(&stuff->drawable) & 3) == 0) *(&stuff->drawable) = lswapl(*(&stuff-> drawable)); else swap_uint32((uint32_t *)(&stuff->drawable )); } while (0); | |||||
1392 | swaps(&stuff->x)do { if (sizeof(*(&stuff->x)) != 2) wrong_size(); if ( __builtin_constant_p((uintptr_t)(&stuff->x) & 1) && ((uintptr_t)(&stuff->x) & 1) == 0) *(&stuff-> x) = lswaps(*(&stuff->x)); else swap_uint16((uint16_t * )(&stuff->x)); } while (0); | |||||
1393 | swaps(&stuff->y)do { if (sizeof(*(&stuff->y)) != 2) wrong_size(); if ( __builtin_constant_p((uintptr_t)(&stuff->y) & 1) && ((uintptr_t)(&stuff->y) & 1) == 0) *(&stuff-> y) = lswaps(*(&stuff->y)); else swap_uint16((uint16_t * )(&stuff->y)); } while (0); | |||||
1394 | swaps(&stuff->width)do { if (sizeof(*(&stuff->width)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->width) & 1) && ((uintptr_t)(&stuff->width) & 1) == 0) *(&stuff->width) = lswaps(*(&stuff->width)) ; else swap_uint16((uint16_t *)(&stuff->width)); } while (0); | |||||
1395 | swaps(&stuff->height)do { if (sizeof(*(&stuff->height)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->height) & 1) && ((uintptr_t)(&stuff->height) & 1) == 0) *(&stuff->height) = lswaps(*(&stuff->height )); else swap_uint16((uint16_t *)(&stuff->height)); } while (0); | |||||
1396 | swapl(&stuff->planeMask)do { if (sizeof(*(&stuff->planeMask)) != 4) wrong_size (); if (__builtin_constant_p((uintptr_t)(&stuff->planeMask ) & 3) && ((uintptr_t)(&stuff->planeMask) & 3) == 0) *(&stuff->planeMask) = lswapl(*(&stuff-> planeMask)); else swap_uint32((uint32_t *)(&stuff->planeMask )); } while (0); | |||||
1397 | swapl(&stuff->shmseg)do { if (sizeof(*(&stuff->shmseg)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->shmseg) & 3) && ((uintptr_t)(&stuff->shmseg) & 3) == 0) *(&stuff->shmseg) = lswapl(*(&stuff->shmseg )); else swap_uint32((uint32_t *)(&stuff->shmseg)); } while (0); | |||||
1398 | swapl(&stuff->offset)do { if (sizeof(*(&stuff->offset)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->offset) & 3) && ((uintptr_t)(&stuff->offset) & 3) == 0) *(&stuff->offset) = lswapl(*(&stuff->offset )); else swap_uint32((uint32_t *)(&stuff->offset)); } while (0); | |||||
1399 | return ProcShmGetImage(client); | |||||
1400 | } | |||||
1401 | ||||||
1402 | static int | |||||
1403 | SProcShmCreatePixmap(ClientPtr client) | |||||
1404 | { | |||||
1405 | REQUEST(xShmCreatePixmapReq)xShmCreatePixmapReq *stuff = (xShmCreatePixmapReq *)client-> requestBuffer; | |||||
1406 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||||
1407 | REQUEST_SIZE_MATCH(xShmCreatePixmapReq)if ((sizeof(xShmCreatePixmapReq) >> 2) != client->req_len ) return(16); | |||||
1408 | swapl(&stuff->pid)do { if (sizeof(*(&stuff->pid)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->pid) & 3 ) && ((uintptr_t)(&stuff->pid) & 3) == 0) * (&stuff->pid) = lswapl(*(&stuff->pid)); else swap_uint32 ((uint32_t *)(&stuff->pid)); } while (0); | |||||
1409 | swapl(&stuff->drawable)do { if (sizeof(*(&stuff->drawable)) != 4) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&stuff->drawable ) & 3) && ((uintptr_t)(&stuff->drawable) & 3) == 0) *(&stuff->drawable) = lswapl(*(&stuff-> drawable)); else swap_uint32((uint32_t *)(&stuff->drawable )); } while (0); | |||||
1410 | swaps(&stuff->width)do { if (sizeof(*(&stuff->width)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->width) & 1) && ((uintptr_t)(&stuff->width) & 1) == 0) *(&stuff->width) = lswaps(*(&stuff->width)) ; else swap_uint16((uint16_t *)(&stuff->width)); } while (0); | |||||
1411 | swaps(&stuff->height)do { if (sizeof(*(&stuff->height)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->height) & 1) && ((uintptr_t)(&stuff->height) & 1) == 0) *(&stuff->height) = lswaps(*(&stuff->height )); else swap_uint16((uint16_t *)(&stuff->height)); } while (0); | |||||
1412 | swapl(&stuff->shmseg)do { if (sizeof(*(&stuff->shmseg)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->shmseg) & 3) && ((uintptr_t)(&stuff->shmseg) & 3) == 0) *(&stuff->shmseg) = lswapl(*(&stuff->shmseg )); else swap_uint32((uint32_t *)(&stuff->shmseg)); } while (0); | |||||
1413 | swapl(&stuff->offset)do { if (sizeof(*(&stuff->offset)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->offset) & 3) && ((uintptr_t)(&stuff->offset) & 3) == 0) *(&stuff->offset) = lswapl(*(&stuff->offset )); else swap_uint32((uint32_t *)(&stuff->offset)); } while (0); | |||||
1414 | return ProcShmCreatePixmap(client); | |||||
1415 | } | |||||
1416 | ||||||
1417 | #ifdef SHM_FD_PASSING | |||||
1418 | static int | |||||
1419 | SProcShmAttachFd(ClientPtr client) | |||||
1420 | { | |||||
1421 | REQUEST(xShmAttachFdReq)xShmAttachFdReq *stuff = (xShmAttachFdReq *)client->requestBuffer; | |||||
1422 | SetReqFds(client, 1); | |||||
1423 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||||
1424 | REQUEST_SIZE_MATCH(xShmAttachFdReq)if ((sizeof(xShmAttachFdReq) >> 2) != client->req_len ) return(16); | |||||
1425 | swapl(&stuff->shmseg)do { if (sizeof(*(&stuff->shmseg)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->shmseg) & 3) && ((uintptr_t)(&stuff->shmseg) & 3) == 0) *(&stuff->shmseg) = lswapl(*(&stuff->shmseg )); else swap_uint32((uint32_t *)(&stuff->shmseg)); } while (0); | |||||
1426 | return ProcShmAttachFd(client); | |||||
1427 | } | |||||
1428 | ||||||
1429 | static int | |||||
1430 | SProcShmCreateSegment(ClientPtr client) | |||||
1431 | { | |||||
1432 | REQUEST(xShmCreateSegmentReq)xShmCreateSegmentReq *stuff = (xShmCreateSegmentReq *)client-> requestBuffer; | |||||
1433 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||||
1434 | REQUEST_SIZE_MATCH(xShmCreateSegmentReq)if ((sizeof(xShmCreateSegmentReq) >> 2) != client->req_len ) return(16); | |||||
1435 | swapl(&stuff->shmseg)do { if (sizeof(*(&stuff->shmseg)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->shmseg) & 3) && ((uintptr_t)(&stuff->shmseg) & 3) == 0) *(&stuff->shmseg) = lswapl(*(&stuff->shmseg )); else swap_uint32((uint32_t *)(&stuff->shmseg)); } while (0); | |||||
1436 | swapl(&stuff->size)do { if (sizeof(*(&stuff->size)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->size) & 3) && ((uintptr_t)(&stuff->size) & 3) == 0 ) *(&stuff->size) = lswapl(*(&stuff->size)); else swap_uint32((uint32_t *)(&stuff->size)); } while (0); | |||||
1437 | return ProcShmCreateSegment(client); | |||||
1438 | } | |||||
1439 | #endif /* SHM_FD_PASSING */ | |||||
1440 | ||||||
1441 | static int | |||||
1442 | SProcShmDispatch(ClientPtr client) | |||||
1443 | { | |||||
1444 | REQUEST(xReq)xReq *stuff = (xReq *)client->requestBuffer; | |||||
1445 | switch (stuff->data) { | |||||
1446 | case X_ShmQueryVersion0: | |||||
1447 | return SProcShmQueryVersion(client); | |||||
1448 | case X_ShmAttach1: | |||||
1449 | return SProcShmAttach(client); | |||||
1450 | case X_ShmDetach2: | |||||
1451 | return SProcShmDetach(client); | |||||
1452 | case X_ShmPutImage3: | |||||
1453 | return SProcShmPutImage(client); | |||||
1454 | case X_ShmGetImage4: | |||||
1455 | return SProcShmGetImage(client); | |||||
1456 | case X_ShmCreatePixmap5: | |||||
1457 | return SProcShmCreatePixmap(client); | |||||
1458 | #ifdef SHM_FD_PASSING | |||||
1459 | case X_ShmAttachFd6: | |||||
1460 | return SProcShmAttachFd(client); | |||||
1461 | case X_ShmCreateSegment7: | |||||
1462 | return SProcShmCreateSegment(client); | |||||
1463 | #endif | |||||
1464 | default: | |||||
1465 | return BadRequest1; | |||||
1466 | } | |||||
1467 | } | |||||
1468 | ||||||
1469 | void | |||||
1470 | ShmExtensionInit(void) | |||||
1471 | { | |||||
1472 | ExtensionEntry *extEntry; | |||||
1473 | int i; | |||||
1474 | ||||||
1475 | #ifdef MUST_CHECK_FOR_SHM_SYSCALL | |||||
1476 | if (!CheckForShmSyscall()) { | |||||
1477 | ErrorF("MIT-SHM extension disabled due to lack of kernel support\n"); | |||||
1478 | return; | |||||
1479 | } | |||||
1480 | #endif | |||||
1481 | ||||||
1482 | if (!ShmRegisterPrivates()) | |||||
1483 | return; | |||||
1484 | ||||||
1485 | sharedPixmaps = xFalse0; | |||||
1486 | { | |||||
1487 | sharedPixmaps = xTrue1; | |||||
1488 | for (i = 0; i < screenInfo.numScreens; i++) { | |||||
1489 | ShmScrPrivateRec *screen_priv = | |||||
1490 | ShmInitScreenPriv(screenInfo.screens[i]); | |||||
1491 | if (!screen_priv->shmFuncs) | |||||
1492 | screen_priv->shmFuncs = &miFuncs; | |||||
1493 | if (!screen_priv->shmFuncs->CreatePixmap) | |||||
1494 | sharedPixmaps = xFalse0; | |||||
1495 | } | |||||
1496 | if (sharedPixmaps) | |||||
1497 | for (i = 0; i < screenInfo.numScreens; i++) { | |||||
1498 | ShmScrPrivateRec *screen_priv = | |||||
1499 | ShmGetScreenPriv(screenInfo.screens[i])((ShmScrPrivateRec *)dixLookupPrivate(&(screenInfo.screens [i])->devPrivates, (&shmScrPrivateKeyRec))); | |||||
1500 | screen_priv->destroyPixmap = | |||||
1501 | screenInfo.screens[i]->DestroyPixmap; | |||||
1502 | screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap; | |||||
1503 | } | |||||
1504 | } | |||||
1505 | ShmSegType = CreateNewResourceType(ShmDetachSegment, "ShmSeg"); | |||||
1506 | if (ShmSegType && | |||||
1507 | (extEntry = AddExtension(SHMNAME"MIT-SHM", ShmNumberEvents(0 + 1), ShmNumberErrors(0 + 1), | |||||
1508 | ProcShmDispatch, SProcShmDispatch, | |||||
1509 | ShmResetProc, StandardMinorOpcode))) { | |||||
1510 | ShmReqCode = (unsigned char) extEntry->base; | |||||
1511 | ShmCompletionCode = extEntry->eventBase; | |||||
1512 | BadShmSegCode = extEntry->errorBase; | |||||
1513 | SetResourceTypeErrorValue(ShmSegType, BadShmSegCode); | |||||
1514 | EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent; | |||||
1515 | } | |||||
1516 | } |