Commit 8f9aba92 authored by Sam Lantinga's avatar Sam Lantinga

The X11 window and all pixmaps and images share the same visual and depth.

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403332
parent 9e64157a
...@@ -57,19 +57,72 @@ get_visualinfo(Display * display, int screen, XVisualInfo * vinfo) ...@@ -57,19 +57,72 @@ get_visualinfo(Display * display, int screen, XVisualInfo * vinfo)
return -1; return -1;
} }
static Uint32
X11_GetPixelFormatFromVisualInfo(Display *display, XVisualInfo *vinfo)
{
if (vinfo->class == DirectColor || vinfo->class == TrueColor) {
int bpp;
Uint32 Rmask, Gmask, Bmask, Amask;
Rmask = vinfo->visual->red_mask;
Gmask = vinfo->visual->green_mask;
Bmask = vinfo->visual->blue_mask;
if (vinfo->depth == 32) {
Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask));
} else {
Amask = 0;
}
bpp = vinfo->depth;
if (bpp == 24) {
int i, n;
XPixmapFormatValues *p = XListPixmapFormats(display, &n);
if (p) {
for (i = 0; i < n; ++i) {
if (p[i].depth == 24) {
bpp = p[i].bits_per_pixel;
break;
}
}
XFree(p);
}
}
return SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
}
if (vinfo->class == PseudoColor || vinfo->class == StaticColor) {
switch (vinfo->depth) {
case 8:
return SDL_PIXELTYPE_INDEX8;
case 4:
if (BitmapBitOrder(display) == LSBFirst) {
return SDL_PIXELFORMAT_INDEX4LSB;
} else {
return SDL_PIXELFORMAT_INDEX4MSB;
}
break;
case 1:
if (BitmapBitOrder(display) == LSBFirst) {
return SDL_PIXELFORMAT_INDEX1LSB;
} else {
return SDL_PIXELFORMAT_INDEX1MSB;
}
break;
}
}
return SDL_PIXELFORMAT_UNKNOWN;
}
void void
X11_InitModes(_THIS) X11_InitModes(_THIS)
{ {
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
int screen; int screen;
int n;
XPixmapFormatValues *p;
p = XListPixmapFormats(data->display, &n);
for (screen = 0; screen < ScreenCount(data->display); ++screen) { for (screen = 0; screen < ScreenCount(data->display); ++screen) {
XVisualInfo vinfo; XVisualInfo vinfo;
int i, bpp;
Uint32 Rmask, Gmask, Bmask, Amask;
SDL_VideoDisplay display; SDL_VideoDisplay display;
SDL_DisplayData *displaydata; SDL_DisplayData *displaydata;
SDL_DisplayMode mode; SDL_DisplayMode mode;
...@@ -78,23 +131,7 @@ X11_InitModes(_THIS) ...@@ -78,23 +131,7 @@ X11_InitModes(_THIS)
continue; continue;
} }
bpp = vinfo.depth; mode.format = X11_GetPixelFormatFromVisualInfo(data->display, &vinfo);
for (i = 0; i < n; ++i) {
if (p[i].depth == vinfo.depth) {
bpp = p[i].bits_per_pixel;
break;
}
}
Rmask = vinfo.visual->red_mask;
Gmask = vinfo.visual->green_mask;
Bmask = vinfo.visual->blue_mask;
if (vinfo.depth == 32) {
Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask));
} else {
Amask = 0;
}
mode.format =
SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
mode.w = DisplayWidth(data->display, screen); mode.w = DisplayWidth(data->display, screen);
mode.h = DisplayHeight(data->display, screen); mode.h = DisplayHeight(data->display, screen);
mode.refresh_rate = 0; mode.refresh_rate = 0;
...@@ -114,15 +151,15 @@ X11_InitModes(_THIS) ...@@ -114,15 +151,15 @@ X11_InitModes(_THIS)
display.driverdata = displaydata; display.driverdata = displaydata;
SDL_AddVideoDisplay(&display); SDL_AddVideoDisplay(&display);
} }
XFree(p);
} }
void void
X11_GetDisplayModes(_THIS) X11_GetDisplayModes(_THIS)
{ {
Display *display = ((SDL_VideoData *) _this->driverdata)->display;
SDL_DisplayData *data = (SDL_DisplayData *) SDL_CurrentDisplay.driverdata; SDL_DisplayData *data = (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;
SDL_DisplayMode mode; SDL_DisplayMode mode;
//SDL_AddDisplayMode(_this->current_display, &mode);
} }
int int
......
...@@ -31,12 +31,6 @@ typedef struct ...@@ -31,12 +31,6 @@ typedef struct
int depth; int depth;
} SDL_DisplayData; } SDL_DisplayData;
//typedef struct
//{
// TCHAR DeviceName[32];
// DEVMODE DeviceMode;
//} SDL_DisplayModeData;
extern void X11_InitModes(_THIS); extern void X11_InitModes(_THIS);
extern void X11_GetDisplayModes(_THIS); extern void X11_GetDisplayModes(_THIS);
extern int X11_SetDisplayMode(_THIS, SDL_DisplayMode * mode); extern int X11_SetDisplayMode(_THIS, SDL_DisplayMode * mode);
......
...@@ -77,6 +77,8 @@ typedef struct ...@@ -77,6 +77,8 @@ typedef struct
{ {
Display *display; Display *display;
int screen; int screen;
Visual *visual;
int depth;
Window window; Window window;
Pixmap pixmaps[3]; Pixmap pixmaps[3];
int current_pixmap; int current_pixmap;
...@@ -132,97 +134,19 @@ UpdateYUVTextureData(SDL_Texture * texture) ...@@ -132,97 +134,19 @@ UpdateYUVTextureData(SDL_Texture * texture)
texture->h, data->pixels, data->pitch); texture->h, data->pixels, data->pitch);
} }
static int
X11_GetDepthFromPixelFormat(Uint32 format)
{
int depth, order;
depth = SDL_BITSPERPIXEL(format);
order = SDL_PIXELORDER(format);
if (depth == 32
&& (order == SDL_PACKEDORDER_XRGB || order == SDL_PACKEDORDER_RGBX
|| SDL_PACKEDORDER_XBGR || order == SDL_PACKEDORDER_BGRX)) {
depth = 24;
}
return depth;
}
static Uint32
X11_GetPixelFormatFromDepth(Display * display, int screen, int depth, int bpp)
{
XVisualInfo vinfo;
if (XMatchVisualInfo(display, screen, depth, DirectColor, &vinfo) ||
XMatchVisualInfo(display, screen, depth, TrueColor, &vinfo)) {
Uint32 Rmask, Gmask, Bmask, Amask;
Rmask = vinfo.visual->red_mask;
Gmask = vinfo.visual->green_mask;
Bmask = vinfo.visual->blue_mask;
if (vinfo.depth == 32) {
Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask));
} else {
Amask = 0;
}
return SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
}
/* No matching visual, try to pick a safe default */
switch (depth) {
case 15:
return SDL_PIXELFORMAT_RGB555;
case 16:
return SDL_PIXELFORMAT_RGB565;
default:
break;
}
return SDL_PIXELFORMAT_UNKNOWN;
}
void void
X11_AddRenderDriver(_THIS) X11_AddRenderDriver(_THIS)
{ {
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
SDL_RendererInfo *info = &X11_RenderDriver.info; SDL_RendererInfo *info = &X11_RenderDriver.info;
XPixmapFormatValues *pixmapFormats; SDL_DisplayMode *mode = &SDL_CurrentDisplay.desktop_mode;
int i, n, bpp;
/* Query the available texture formats */
pixmapFormats = XListPixmapFormats(data->display, &n);
if (pixmapFormats) {
info->num_texture_formats = 0;
for (i = 0; i < n; ++i) {
Uint32 format;
if (pixmapFormats[i].depth == 24) {
bpp = pixmapFormats[i].bits_per_pixel;
} else {
bpp = pixmapFormats[i].depth;
}
format =
X11_GetPixelFormatFromDepth(data->display,
DefaultScreen(data->display),
pixmapFormats[i].depth, bpp);
if (format != SDL_PIXELFORMAT_UNKNOWN) {
info->texture_formats[info->num_texture_formats++] = format;
}
}
XFree(pixmapFormats);
if (info->num_texture_formats == 0) { info->texture_formats[info->num_texture_formats++] = mode->format;
return; info->texture_formats[info->num_texture_formats++] = SDL_PIXELFORMAT_YV12;
} info->texture_formats[info->num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
info->texture_formats[info->num_texture_formats++] = info->texture_formats[info->num_texture_formats++] = SDL_PIXELFORMAT_YUY2;
SDL_PIXELFORMAT_YV12; info->texture_formats[info->num_texture_formats++] = SDL_PIXELFORMAT_UYVY;
info->texture_formats[info->num_texture_formats++] = info->texture_formats[info->num_texture_formats++] = SDL_PIXELFORMAT_YVYU;
SDL_PIXELFORMAT_IYUV;
info->texture_formats[info->num_texture_formats++] =
SDL_PIXELFORMAT_YUY2;
info->texture_formats[info->num_texture_formats++] =
SDL_PIXELFORMAT_UYVY;
info->texture_formats[info->num_texture_formats++] =
SDL_PIXELFORMAT_YVYU;
}
SDL_AddRenderDriver(0, &X11_RenderDriver); SDL_AddRenderDriver(0, &X11_RenderDriver);
} }
...@@ -230,13 +154,12 @@ X11_AddRenderDriver(_THIS) ...@@ -230,13 +154,12 @@ X11_AddRenderDriver(_THIS)
SDL_Renderer * SDL_Renderer *
X11_CreateRenderer(SDL_Window * window, Uint32 flags) X11_CreateRenderer(SDL_Window * window, Uint32 flags)
{ {
SDL_DisplayData *displaydata = SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
(SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata; SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
SDL_Renderer *renderer; SDL_Renderer *renderer;
SDL_RendererInfo *info; SDL_RendererInfo *info;
X11_RenderData *data; X11_RenderData *data;
XWindowAttributes attributes;
XGCValues gcv; XGCValues gcv;
int i, n; int i, n;
int bpp; int bpp;
...@@ -256,6 +179,8 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -256,6 +179,8 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
} }
data->display = windowdata->videodata->display; data->display = windowdata->videodata->display;
data->screen = displaydata->screen; data->screen = displaydata->screen;
data->visual = displaydata->visual;
data->depth = displaydata->depth;
data->window = windowdata->window; data->window = windowdata->window;
renderer->DisplayModeChanged = X11_DisplayModeChanged; renderer->DisplayModeChanged = X11_DisplayModeChanged;
...@@ -291,11 +216,10 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -291,11 +216,10 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; renderer->info.flags |= SDL_RENDERER_PRESENTCOPY;
n = 1; n = 1;
} }
XGetWindowAttributes(data->display, data->window, &attributes);
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
data->pixmaps[i] = data->pixmaps[i] =
XCreatePixmap(data->display, data->window, window->w, window->h, XCreatePixmap(data->display, data->window, window->w, window->h,
attributes.depth); displaydata->depth);
if (data->pixmaps[i] == None) { if (data->pixmaps[i] == None) {
X11_DestroyRenderer(renderer); X11_DestroyRenderer(renderer);
SDL_SetError("XCreatePixmap() failed"); SDL_SetError("XCreatePixmap() failed");
...@@ -312,26 +236,10 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -312,26 +236,10 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
data->current_pixmap = 0; data->current_pixmap = 0;
/* Get the format of the window */ /* Get the format of the window */
bpp = attributes.depth; if (!SDL_PixelFormatEnumToMasks(display->current_mode.format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
if (bpp == 24) { SDL_SetError("Unknown display format");
XPixmapFormatValues *p = XListPixmapFormats(data->display, &n); X11_DestroyRenderer(renderer);
if (p) { return NULL;
for (i = 0; i < n; ++i) {
if (p[i].depth == 24) {
bpp = p[i].bits_per_pixel;
break;
}
}
XFree(p);
}
}
Rmask = attributes.visual->red_mask;
Gmask = attributes.visual->green_mask;
Bmask = attributes.visual->blue_mask;
if (attributes.depth == 32) {
Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask));
} else {
Amask = 0;
} }
data->format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); data->format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
if (!data->format) { if (!data->format) {
...@@ -357,7 +265,6 @@ X11_DisplayModeChanged(SDL_Renderer * renderer) ...@@ -357,7 +265,6 @@ X11_DisplayModeChanged(SDL_Renderer * renderer)
{ {
X11_RenderData *data = (X11_RenderData *) renderer->driverdata; X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
SDL_Window *window = SDL_GetWindowFromID(renderer->window); SDL_Window *window = SDL_GetWindowFromID(renderer->window);
XWindowAttributes attributes;
int i, n; int i, n;
if (renderer->info.flags & SDL_RENDERER_SINGLEBUFFER) { if (renderer->info.flags & SDL_RENDERER_SINGLEBUFFER) {
...@@ -375,11 +282,10 @@ X11_DisplayModeChanged(SDL_Renderer * renderer) ...@@ -375,11 +282,10 @@ X11_DisplayModeChanged(SDL_Renderer * renderer)
data->pixmaps[i] = None; data->pixmaps[i] = None;
} }
} }
XGetWindowAttributes(data->display, data->window, &attributes);
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
data->pixmaps[i] = data->pixmaps[i] =
XCreatePixmap(data->display, data->window, window->w, window->h, XCreatePixmap(data->display, data->window, window->w, window->h,
attributes.depth); data->depth);
if (data->pixmaps[i] == None) { if (data->pixmaps[i] == None) {
SDL_SetError("XCreatePixmap() failed"); SDL_SetError("XCreatePixmap() failed");
return -1; return -1;
...@@ -400,8 +306,6 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -400,8 +306,6 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
SDL_Window *window = SDL_GetWindowFromID(renderer->window); SDL_Window *window = SDL_GetWindowFromID(renderer->window);
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
X11_TextureData *data; X11_TextureData *data;
XWindowAttributes attributes;
int depth;
data = (X11_TextureData *) SDL_calloc(1, sizeof(*data)); data = (X11_TextureData *) SDL_calloc(1, sizeof(*data));
if (!data) { if (!data) {
...@@ -419,23 +323,17 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -419,23 +323,17 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
} }
data->format = display->current_mode.format; data->format = display->current_mode.format;
} else { } else {
/* The image/pixmap depth must be the same as the window or you
get a BadMatch error when trying to putimage or copyarea.
*/
if (texture->format != display->current_mode.format) {
SDL_SetError("Texture format doesn't match window format");
return -1;
}
data->format = texture->format; data->format = texture->format;
} }
data->pitch = texture->w * SDL_BYTESPERPIXEL(data->format); data->pitch = texture->w * SDL_BYTESPERPIXEL(data->format);
XGetWindowAttributes(renderdata->display, renderdata->window,
&attributes);
depth = X11_GetDepthFromPixelFormat(data->format);
/* The image/pixmap depth must be the same as the window or you
get a BadMatch error when trying to putimage or copyarea.
*/
if (depth != attributes.depth) {
X11_DestroyTexture(renderer, texture);
SDL_SetError("Texture format doesn't match window format");
return -1;
}
if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING) { if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING) {
#ifndef NO_SHARED_MEMORY #ifndef NO_SHARED_MEMORY
XShmSegmentInfo *shminfo = &data->shminfo; XShmSegmentInfo *shminfo = &data->shminfo;
...@@ -466,9 +364,7 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -466,9 +364,7 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
data->pixels = shminfo->shmaddr; data->pixels = shminfo->shmaddr;
data->image = data->image =
XShmCreateImage(renderdata->display, attributes.visual, depth, XShmCreateImage(renderdata->display, renderdata->visual, renderdata->depth, ZPixmap, shminfo->shmaddr, shminfo, texture->w, texture->h);
ZPixmap, shminfo->shmaddr, shminfo,
texture->w, texture->h);
if (!data->image) { if (!data->image) {
XShmDetach(renderdata->display, shminfo); XShmDetach(renderdata->display, shminfo);
XSync(renderdata->display, False); XSync(renderdata->display, False);
...@@ -490,10 +386,7 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -490,10 +386,7 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
} }
data->image = data->image =
XCreateImage(renderdata->display, attributes.visual, depth, XCreateImage(renderdata->display, renderdata->visual, renderdata->depth, ZPixmap, 0, data->pixels, texture->w, texture->h, SDL_BYTESPERPIXEL(data->format) * 8, data->pitch);
ZPixmap, 0, data->pixels, texture->w, texture->h,
SDL_BYTESPERPIXEL(data->format) * 8,
data->pitch);
if (!data->image) { if (!data->image) {
X11_DestroyTexture(renderer, texture); X11_DestroyTexture(renderer, texture);
SDL_SetError("XCreateImage() failed"); SDL_SetError("XCreateImage() failed");
...@@ -503,7 +396,7 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -503,7 +396,7 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
} else { } else {
data->pixmap = data->pixmap =
XCreatePixmap(renderdata->display, renderdata->window, texture->w, XCreatePixmap(renderdata->display, renderdata->window, texture->w,
texture->h, depth); texture->h, renderdata->depth);
if (data->pixmap == None) { if (data->pixmap == None) {
X11_DestroyTexture(renderer, texture); X11_DestroyTexture(renderer, texture);
SDL_SetError("XCteatePixmap() failed"); SDL_SetError("XCteatePixmap() failed");
...@@ -511,9 +404,7 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -511,9 +404,7 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
} }
data->image = data->image =
XCreateImage(renderdata->display, attributes.visual, depth, XCreateImage(renderdata->display, renderdata->visual, renderdata->depth, ZPixmap, 0, NULL, texture->w, texture->h, SDL_BYTESPERPIXEL(data->format) * 8, data->pitch);
ZPixmap, 0, NULL, texture->w, texture->h,
SDL_BYTESPERPIXEL(data->format) * 8, data->pitch);
if (!data->image) { if (!data->image) {
X11_DestroyTexture(renderer, texture); X11_DestroyTexture(renderer, texture);
SDL_SetError("XCreateImage() failed"); SDL_SetError("XCreateImage() failed");
...@@ -703,13 +594,10 @@ X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -703,13 +594,10 @@ X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
XImage *image = texturedata->scaling_image; XImage *image = texturedata->scaling_image;
if (!image) { if (!image) {
XWindowAttributes attributes;
int depth; int depth;
void *pixels; void *pixels;
int pitch; int pitch;
XGetWindowAttributes(data->display, data->window, &attributes);
pitch = dstrect->w * SDL_BYTESPERPIXEL(texturedata->format); pitch = dstrect->w * SDL_BYTESPERPIXEL(texturedata->format);
pixels = SDL_malloc(dstrect->h * pitch); pixels = SDL_malloc(dstrect->h * pitch);
if (!pixels) { if (!pixels) {
...@@ -717,9 +605,8 @@ X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -717,9 +605,8 @@ X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
return -1; return -1;
} }
depth = X11_GetDepthFromPixelFormat(texturedata->format);
image = image =
XCreateImage(data->display, attributes.visual, depth, ZPixmap, XCreateImage(data->display, data->visual, data->depth, ZPixmap,
0, pixels, dstrect->w, dstrect->h, 0, pixels, dstrect->w, dstrect->h,
SDL_BYTESPERPIXEL(texturedata->format) * 8, SDL_BYTESPERPIXEL(texturedata->format) * 8,
pitch); pitch);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment