File: | Xext/shm.c |
Location: | line 977, column 17 |
Description: | Potential leak of memory pointed to by 'newPix' |
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 | } |