94
107
old_error_handler = XSetErrorHandler(test_xshm_error_handler);
96
ximage = XShmCreateImage(display,
97
DefaultVisual(display, DefaultScreen(display)),
98
drawing_depth, ZPixmap, NULL, &shminfo,
109
ximage = XShmCreateImage(display, visual,
110
drawing_depth, ZPixmap, NULL, &shminfo,
100
112
XSync(display, False);
101
113
if (!ximage || num_xshm_test_errors)
103
NSLog(@"XShm not supported, XShmCreateImage failed.");
115
NSLog(@"XShm not supported, XShmCreateImage failed.");
107
119
shminfo.shmid = shmget(IPC_PRIVATE,
108
64, /* We don't have exact bytes per row values here, but this
109
should be safe, and we'll probably get a full page anyway.
110
(And if it turns out not to be enough, the X server will notice
111
and give us errors, causing us to think that XShm isn't
120
64, /* We don't have exact bytes per row values here, but this
121
should be safe, and we'll probably get a full page anyway.
122
(And if it turns out not to be enough, the X server will notice
123
and give us errors, causing us to think that XShm isn't
115
127
if (shminfo.shmid == -1 || num_xshm_test_errors)
117
NSLog(@"XShm not supported, shmget() failed: %m.");
118
XDestroyImage(ximage);
129
NSLog(@"XShm not supported, shmget() failed: %m.");
130
XDestroyImage(ximage);
122
134
shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
123
135
if ((intptr_t)shminfo.shmaddr == -1 || num_xshm_test_errors)
125
NSLog(@"XShm not supported, shmat() failed: %m.");
126
XDestroyImage(ximage);
127
shmctl(shminfo.shmid, IPC_RMID, 0);
137
NSLog(@"XShm not supported, shmat() failed: %m.");
138
XDestroyImage(ximage);
139
shmctl(shminfo.shmid, IPC_RMID, 0);
131
143
shminfo.readOnly = 0;
225
254
wi->sx != awindow->xframe.size.width ||
226
255
wi->sy != awindow->xframe.size.height)
228
wi->sx = wi->window->xframe.size.width;
229
/* printf("%@ updating image for %p (%gx%g)\n", wi, wi->window,
230
wi->window->xframe.size.width, wi->window->xframe.size.height);*/
257
/* printf("%@ updating image for %p (%gx%g)\n", wi, wi->window,
258
wi->window->xframe.size.width, wi->window->xframe.size.height);*/
235
XShmDetach(wi->display, &wi->shminfo);
236
XDestroyImage(wi->ximage);
237
shmdt(wi->shminfo.shmaddr);
240
XDestroyImage(wi->ximage);
263
XShmDetach(wi->display, &wi->shminfo);
264
XDestroyImage(wi->ximage);
265
shmdt(wi->shminfo.shmaddr);
268
XDestroyImage(wi->ximage);
244
XFreePixmap(wi->display,wi->pixmap);
245
XSetWindowBackground(wi->display,wi->window->ident,None);
272
XFreePixmap(wi->display,wi->pixmap);
273
XSetWindowBackground(wi->display,wi->window->ident,None);
249
277
wi->has_alpha = 0;
256
284
wi->pending_put = wi->pending_event = 0;
271
299
if (!did_test_xshm)
272
test_xshm(wi->display, aDI->drawing_depth);
300
test_xshm(wi->display, visual, drawing_depth);
277
305
/* Use XShm if possible, else fall back to normal XImage: s */
279
wi->ximage = XShmCreateImage(wi->display,
280
DefaultVisual(wi->display, DefaultScreen(wi->display)),
281
aDI->drawing_depth, ZPixmap, NULL, &wi->shminfo,
282
wi->window->xframe.size.width,
283
wi->window->xframe.size.height);
307
wi->ximage = XShmCreateImage(wi->display, visual,
308
drawing_depth, ZPixmap, NULL, &wi->shminfo,
309
wi->window->xframe.size.width,
310
wi->window->xframe.size.height);
286
NSLog(@"Warning: XShmCreateImage failed!");
313
NSLog(@"Warning: XShmCreateImage failed!");
290
317
wi->shminfo.shmid = shmget(IPC_PRIVATE,
291
wi->ximage->bytes_per_line * wi->ximage->height,
318
wi->ximage->bytes_per_line * wi->ximage->height,
294
321
if (wi->shminfo.shmid == -1)
296
NSLog(@"Warning: shmget() failed: %m.");
298
XDestroyImage(wi->ximage);
323
NSLog(@"Warning: shmget() failed: %m.");
325
XDestroyImage(wi->ximage);
302
329
wi->shminfo.shmaddr = wi->ximage->data = shmat(wi->shminfo.shmid, 0, 0);
303
330
if ((intptr_t)wi->shminfo.shmaddr == -1)
305
NSLog(@"Warning: shmat() failed: %m.");
307
XDestroyImage(wi->ximage);
308
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
332
NSLog(@"Warning: shmat() failed: %m.");
334
XDestroyImage(wi->ximage);
335
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
312
339
wi->shminfo.readOnly = 0;
313
340
if (!XShmAttach(wi->display, &wi->shminfo))
315
NSLog(@"Warning: XShmAttach() failed.");
317
XDestroyImage(wi->ximage);
318
shmdt(wi->shminfo.shmaddr);
319
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
342
NSLog(@"Warning: XShmAttach() failed.");
344
XDestroyImage(wi->ximage);
345
shmdt(wi->shminfo.shmaddr);
346
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
323
350
/* We try to create a shared pixmap using the same buffer, and set
324
it as the background of the window. This allows X to handle expose
325
events all by itself, which avoids white flashing when things are
326
dragged across a window. */
351
it as the background of the window. This allows X to handle expose
352
events all by itself, which avoids white flashing when things are
353
dragged across a window. */
327
354
/* TODO: we still get and handle expose events, although we don't
329
356
wi->pixmap = XShmCreatePixmap(wi->display, wi->drawable,
330
wi->ximage->data, &wi->shminfo,
331
wi->window->xframe.size.width,
332
wi->window->xframe.size.height,
357
wi->ximage->data, &wi->shminfo,
358
wi->window->xframe.size.width,
359
wi->window->xframe.size.height,
334
361
if (wi->pixmap) /* TODO: this doesn't work */
336
XSetWindowBackgroundPixmap(wi->display, wi->window->ident,
363
XSetWindowBackgroundPixmap(wi->display, wi->window->ident,
340
367
/* On some systems (eg. freebsd), X can't attach to the shared segment
341
368
if it's marked for destruction, so we make sure it's attached before
348
375
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
354
wi->ximage = XCreateImage(wi->display, DefaultVisual(wi->display,
355
DefaultScreen(wi->display)), aDI->drawing_depth, ZPixmap, 0, NULL,
356
wi->window->xframe.size.width, wi->window->xframe.size.height,
381
wi->ximage = XCreateImage(wi->display, visual, drawing_depth,
383
wi->window->xframe.size.width,
384
wi->window->xframe.size.height,
359
wi->ximage->data = malloc(wi->ximage->height * wi->ximage->bytes_per_line);
360
if (!wi->ximage->data)
362
XDestroyImage(wi->ximage);
365
/*TODO? wi->ximage = XGetImage(wi->display, wi->drawable,
366
0, 0, wi->window->xframe.size.width, wi->window->xframe.size.height,
387
wi->ximage->data = malloc(wi->ximage->height * wi->ximage->bytes_per_line);
388
if (!wi->ximage->data)
390
XDestroyImage(wi->ximage);
393
/*TODO? wi->ximage = XGetImage(wi->display, wi->drawable,
394
0, 0, wi->window->xframe.size.width, wi->window->xframe.size.height,
402
430
if (pending_rect.x + pending_rect.w > window->xframe.size.width)
404
pending_rect.w = window->xframe.size.width - pending_rect.x;
405
if (pending_rect.w <= 0)
432
pending_rect.w = window->xframe.size.width - pending_rect.x;
433
if (pending_rect.w <= 0)
408
436
if (pending_rect.y + pending_rect.h > window->xframe.size.height)
410
pending_rect.h = window->xframe.size.height - pending_rect.y;
411
if (pending_rect.h <= 0)
438
pending_rect.h = window->xframe.size.height - pending_rect.y;
439
if (pending_rect.h <= 0)
414
442
if (!XShmPutImage(display, drawable, gc, ximage,
415
pending_rect.x, pending_rect.y,
416
pending_rect.x, pending_rect.y,
417
pending_rect.w, pending_rect.h,
420
NSLog(@"XShmPutImage failed?");
443
pending_rect.x, pending_rect.y,
444
pending_rect.x, pending_rect.y,
445
pending_rect.w, pending_rect.h,
448
NSLog(@"XShmPutImage failed?");
427
// XFlush(window->display);
455
// XFlush(window->display);
430
458
- (void) _exposeRect: (NSRect)rect
478
506
/* HACK: lets try to use shaped windows to get some use out of
480
508
if (has_alpha && use_shape_hack)
482
510
static int warn = 0;
484
int dsize = ((sx + 7) / 8) * sy;
485
unsigned char *buf = malloc(dsize);
493
NSLog(@"Warning: activating shaped windows");
496
memset(buf, 0xff, dsize);
512
int dsize = ((sx + 7) / 8) * sy;
513
unsigned char *buf = malloc(dsize);
521
NSLog(@"Warning: activating shaped windows");
524
memset(buf, 0xff, dsize);
498
526
#define CUTOFF 128
502
a = data + DI.inline_alpha_ofs;
503
as = DI.bytes_per_pixel;
530
a = data + DI.inline_alpha_ofs;
531
as = DI.bytes_per_pixel;
511
for (bofs = 0, i = sx * sy, x = sx, dst = buf; i; i--, a += as)
515
*dst = *dst & ~(1 << bofs);
539
for (bofs = 0, i = sx * sy, x = sx, dst = buf; i; i--, a += as)
543
*dst = *dst & ~(1 << bofs);
535
563
//NSLog(@"check shape");
536
if (old_shape_size == dsize && !memcmp(old_shape, buf, dsize))
539
// NSLog(@" same shape");
543
// NSLog(@" updating");
544
p = XCreatePixmapFromBitmapData(display, window->ident,
545
(char *)buf, sx, sy, 1, 0, 1);
548
old_shape_size = dsize;
549
XShapeCombineMask(display, window->ident,
550
ShapeBounding, 0, 0, p, ShapeSet);
551
XFreePixmap(display, p);
564
if (old_shape_size == dsize && !memcmp(old_shape, buf, dsize))
567
// NSLog(@" same shape");
571
// NSLog(@" updating");
572
p = XCreatePixmapFromBitmapData(display, window->ident,
573
(char *)buf, sx, sy, 1, 0, 1);
576
old_shape_size = dsize;
577
XShapeCombineMask(display, window->ident,
578
ShapeBounding, 0, 0, p, ShapeSet);
579
XFreePixmap(display, p);
555
583
if (pending_event)
567
if (x < pending_rect.x)
569
pending_rect.w += pending_rect.x - x;
572
if (x + w > pending_rect.x + pending_rect.w)
574
pending_rect.w = x + w - pending_rect.x;
576
if (y < pending_rect.y)
578
pending_rect.h += pending_rect.y - y;
581
if (y + h > pending_rect.y + pending_rect.h)
583
pending_rect.h = y + h - pending_rect.y;
595
if (x < pending_rect.x)
597
pending_rect.w += pending_rect.x - x;
600
if (x + w > pending_rect.x + pending_rect.w)
602
pending_rect.w = x + w - pending_rect.x;
604
if (y < pending_rect.y)
606
pending_rect.h += pending_rect.y - y;
609
if (y + h > pending_rect.y + pending_rect.h)
611
pending_rect.h = y + h - pending_rect.y;
590
if (!XShmPutImage(display, drawable, gc, ximage,
591
x, y, x, y, w, h, 1))
593
NSLog(@"XShmPutImage failed?");
618
if (!XShmPutImage(display, drawable, gc, ximage,
619
x, y, x, y, w, h, 1))
621
NSLog(@"XShmPutImage failed?");
601
629
/* Performance hack. Check right away for ShmCompletion
606
while (XCheckTypedEvent(window->display,
607
XShmGetEventBase(window->display) + ShmCompletion, &e))
609
[isa _gotShmCompletion: ((XShmCompletionEvent *)&e)->drawable];
634
while (XCheckTypedEvent(window->display,
635
XShmGetEventBase(window->display) + ShmCompletion, &e))
637
[isa _gotShmCompletion: ((XShmCompletionEvent *)&e)->drawable];