#include <sys/shm.h>
#include <string.h>
#include <assert.h>
+#include <stdlib.h>
namespace sw
{
if(!x_display)
{
x_display = libX11->XOpenDisplay(0);
+ assert(x_display);
}
+ validateWindow();
+
int screen = DefaultScreen(x_display);
x_gc = libX11->XDefaultGC(x_display, screen);
int depth = libX11->XDefaultDepth(x_display, screen);
x_image = libX11->XShmCreateImage(x_display, visual, depth, ZPixmap, 0, &shminfo, width, height);
shminfo.shmid = shmget(IPC_PRIVATE, x_image->bytes_per_line * x_image->height, IPC_CREAT | SHM_R | SHM_W);
- shminfo.shmaddr = x_image->data = buffer = (char*)shmat(shminfo.shmid, 0, 0);
+ shminfo.shmaddr = x_image->data = (char*)shmat(shminfo.shmid, 0, 0);
shminfo.readOnly = False;
PreviousXErrorHandler = libX11->XSetErrorHandler(XShmErrorHandler);
{
int bytes_per_line = width * 4;
int bytes_per_image = height * bytes_per_line;
- buffer = new char[bytes_per_image];
+ char *buffer = (char*)malloc(bytes_per_image);
memset(buffer, 0, bytes_per_image);
+
x_image = libX11->XCreateImage(x_display, visual, depth, ZPixmap, 0, buffer, width, height, 32, bytes_per_line);
+ assert(x_image);
+
+ if(!x_image)
+ {
+ free(buffer);
+ }
}
}
{
if(!mit_shm)
{
- x_image->data = 0;
XDestroyImage(x_image);
-
- delete[] buffer;
- buffer = 0;
}
else
{
shmctl(shminfo.shmid, IPC_RMID, 0);
}
+ // Last chance to check the window before we close the display.
+ validateWindow();
+
if(ownX11)
{
libX11->XCloseDisplay(x_display);
void *FrameBufferX11::lock()
{
- stride = x_image->bytes_per_line;
- framebuffer = buffer;
+ if(x_image)
+ {
+ stride = x_image->bytes_per_line;
+ framebuffer = x_image->data;
+ }
return framebuffer;
}
{
copy(source);
+ assert(validateWindow());
+
if(!mit_shm)
{
libX11->XPutImage(x_display, x_window, x_gc, x_image, 0, 0, 0, 0, width, height);
libX11->XDrawString(x_display, x_window, x_gc, 50, 50, string, strlen(string));
}
}
+
+ bool FrameBufferX11::validateWindow()
+ {
+ // Since we don't own the window, it is the external client code's responsibility
+ // to not destroy it until we're done with it. We help out by validating it.
+ XWindowAttributes windowAttributes;
+ Status status = libX11->XGetWindowAttributes(x_display, x_window, &windowAttributes);
+
+ if(status != True)
+ {
+ abort(); // Fail hard if we can't obtain the window's attributes.
+ }
+
+ return true;
+ }
}
NO_SANITIZE_FUNCTION sw::FrameBuffer *createFrameBuffer(void *display, Window window, int width, int height)