Skip to content
Snippets Groups Projects
Commit ea7a6600 authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

More X11 improvements

Use the default visual and depth instead of "best"
Use Xrender for sclaing when library is available and server supports it
Set VisualIsRGB8 when possible
parent ce436546
No related branches found
No related tags found
No related merge requests found
...@@ -78,6 +78,13 @@ else ...@@ -78,6 +78,13 @@ else
endif endif
endif endif
ifndef NO_X
ifeq ($(shell pkg-config xrender --exists && echo YES), YES)
CIOLIB-MT_CFLAGS += $(shell pkg-config xrender --cflags)
CIOLIB-MT_CFLAGS += -DWITH_XRENDER
endif
endif
# Find SDL headers! # Find SDL headers!
ifdef USE_SDL ifdef USE_SDL
ifdef SDL_CONFIG ifdef SDL_CONFIG
......
...@@ -318,6 +318,8 @@ static int try_x_init(int mode) ...@@ -318,6 +318,8 @@ static int try_x_init(int mode)
cio_api.map_rgb = bitmap_map_rgb; cio_api.map_rgb = bitmap_map_rgb;
cio_api.replace_font = bitmap_replace_font; cio_api.replace_font = bitmap_replace_font;
cio_api.mousepointer=x_mousepointer; cio_api.mousepointer=x_mousepointer;
cio_api.setscaling_type=x_setscaling_type;
cio_api.getscaling_type=x_getscaling_type;
return(1); return(1);
} }
return(0); return(0);
......
...@@ -215,7 +215,10 @@ int x_init(void) ...@@ -215,7 +215,10 @@ int x_init(void)
{ {
dll_handle dl; dll_handle dl;
const char *libnames[]={"X11",NULL}; const char *libnames[]={"X11",NULL};
dll_handle dl2;
const char *libnames2[]={"Xrender",NULL};
Status (*xit)(void); Status (*xit)(void);
int *_Xdebug;
/* Ensure we haven't already initialized */ /* Ensure we haven't already initialized */
if(x11_initialized) if(x11_initialized)
...@@ -234,6 +237,8 @@ int x_init(void) ...@@ -234,6 +237,8 @@ int x_init(void)
/* Load X11 functions */ /* Load X11 functions */
if((dl=xp_dlopen(libnames,RTLD_LAZY,7))==NULL) if((dl=xp_dlopen(libnames,RTLD_LAZY,7))==NULL)
return(-1); return(-1);
if ((_Xdebug = xp_dlsym(dl,_Xdebug))!=NULL)
*_Xdebug=1;
if((xit=xp_dlsym(dl,XInitThreads))!=NULL) if((xit=xp_dlsym(dl,XInitThreads))!=NULL)
xit(); xit();
if((x11.XChangeGC=xp_dlsym(dl,XChangeGC))==NULL) { if((x11.XChangeGC=xp_dlsym(dl,XChangeGC))==NULL) {
...@@ -472,6 +477,57 @@ int x_init(void) ...@@ -472,6 +477,57 @@ int x_init(void)
xp_dlclose(dl); xp_dlclose(dl);
return(-1); return(-1);
} }
#ifndef DefaultDepth
if((x11.DefaultDepth=xp_dlsym(dl,DefaultDepth))==NULL) {
xp_dlclose(dl);
return(-1);
}
#endif
#ifndef DefaultVisual
if((x11.DefaultVisual=xp_dlsym(dl,DefaultVisual))==NULL) {
xp_dlclose(dl);
return(-1);
}
#endif
#ifdef WITH_XRENDER
xrender_found = true;
if ((dl2 = xp_dlopen(libnames2,RTLD_LAZY,7)) == NULL) {
xp_dlclose(dl2);
xrender_found = false;
}
if (xrender_found && ((x11.XRenderFindStandardFormat = xp_dlsym(dl2, XRenderFindStandardFormat)) == NULL)) {
xp_dlclose(dl);
xrender_found = false;
}
if (xrender_found && ((x11.XRenderCreatePicture = xp_dlsym(dl2, XRenderCreatePicture)) == NULL)) {
xp_dlclose(dl);
xrender_found = false;
}
if (xrender_found && ((x11.XRenderFreePicture = xp_dlsym(dl2, XRenderFreePicture)) == NULL)) {
xp_dlclose(dl);
xrender_found = false;
}
if (xrender_found && ((x11.XRenderSetPictureTransform = xp_dlsym(dl2, XRenderSetPictureTransform)) == NULL)) {
xp_dlclose(dl);
xrender_found = false;
}
if (xrender_found && ((x11.XRenderComposite = xp_dlsym(dl2, XRenderComposite)) == NULL)) {
xp_dlclose(dl);
xrender_found = false;
}
if (xrender_found && ((x11.XRenderFindVisualFormat = xp_dlsym(dl2, XRenderFindVisualFormat)) == NULL)) {
xp_dlclose(dl);
xrender_found = false;
}
if (xrender_found && ((x11.XRenderQueryVersion = xp_dlsym(dl2, XRenderQueryVersion)) == NULL)) {
xp_dlclose(dl);
xrender_found = false;
}
if (xrender_found && ((x11.XRenderSetPictureFilter = xp_dlsym(dl2, XRenderSetPictureFilter)) == NULL)) {
xp_dlclose(dl);
xrender_found = false;
}
#endif
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
x11.XSetLocaleModifiers("@im=none"); x11.XSetLocaleModifiers("@im=none");
...@@ -574,3 +630,24 @@ int x_mousepointer(enum ciolib_mouse_ptr type) ...@@ -574,3 +630,24 @@ int x_mousepointer(enum ciolib_mouse_ptr type)
} }
return 0; return 0;
} }
enum ciolib_scaling
x_getscaling_type(void)
{
enum ciolib_scaling ret;
ret = (x_internal_scaling ? CIOLIB_SCALING_INTERNAL : CIOLIB_SCALING_EXTERNAL);
return ret;
}
void
x_setscaling_type(enum ciolib_scaling newval)
{
struct x11_local_event ev = {0};
if ((newval == CIOLIB_SCALING_INTERNAL) != x_internal_scaling) {
ev.type = X11_LOCAL_SETSCALING_TYPE;
ev.data.st = newval;
write_event(&ev);
}
}
...@@ -82,6 +82,8 @@ void x_setscaling(double newval); ...@@ -82,6 +82,8 @@ void x_setscaling(double newval);
double x_getscaling(void); double x_getscaling(void);
void x_seticon(const void *icon, unsigned long size); void x_seticon(const void *icon, unsigned long size);
int x_mousepointer(enum ciolib_mouse_ptr type); int x_mousepointer(enum ciolib_mouse_ptr type);
enum ciolib_scaling x_getscaling_type(void);
void x_setscaling_type(enum ciolib_scaling newval);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -56,6 +56,8 @@ sem_t event_thread_complete; ...@@ -56,6 +56,8 @@ sem_t event_thread_complete;
int terminate = 0; int terminate = 0;
Atom copybuf_format; Atom copybuf_format;
Atom pastebuf_format; Atom pastebuf_format;
bool xrender_found;
bool x_internal_scaling = true;
/* /*
* Local variables * Local variables
...@@ -68,7 +70,7 @@ static Atom WM_DELETE_WINDOW=0; ...@@ -68,7 +70,7 @@ static Atom WM_DELETE_WINDOW=0;
static Display *dpy=NULL; static Display *dpy=NULL;
static Window win; static Window win;
static Cursor curs = None; static Cursor curs = None;
static Visual visual; static Visual *visual;
static bool VisualIsRGB8 = false; static bool VisualIsRGB8 = false;
static XImage *xim; static XImage *xim;
static XIM im; static XIM im;
...@@ -83,6 +85,12 @@ static int r_shift; ...@@ -83,6 +85,12 @@ static int r_shift;
static int g_shift; static int g_shift;
static int b_shift; static int b_shift;
static struct graphics_buffer *last = NULL; static struct graphics_buffer *last = NULL;
#ifdef WITH_XRENDER
static XRenderPictFormat *xrender_pf = NULL;
static Pixmap xrender_pm = None;
static Picture xrender_src_pict = None;
static Picture xrender_dst_pict = None;
#endif
/* Array of Graphics Contexts */ /* Array of Graphics Contexts */
static GC gc; static GC gc;
...@@ -261,13 +269,55 @@ x11_get_maxsize(int *w, int *h) ...@@ -261,13 +269,55 @@ x11_get_maxsize(int *w, int *h)
return false; return false;
} }
static void resize_xim(void) static void
resize_pictures(void)
{ {
int width, height; #ifdef WITH_XRENDER
if (xrender_pf == NULL)
xrender_pf = x11.XRenderFindStandardFormat(dpy, PictStandardRGB24);
if (xrender_pf == NULL)
xrender_pf = x11.XRenderFindVisualFormat(dpy, visual);
if (xrender_pf == NULL)
xrender_pf = x11.XRenderFindVisualFormat(dpy, DefaultVisual(dpy, DefaultScreen(dpy)));
if (xrender_pm != None)
x11.XFreePixmap(dpy, xrender_pm);
xrender_pm = x11.XCreatePixmap(dpy, win, x_cvstat.scrnwidth, x_cvstat.scrnheight, depth);
if (xrender_src_pict != None)
x11.XRenderFreePicture(dpy, xrender_src_pict);
if (xrender_dst_pict != None)
x11.XRenderFreePicture(dpy, xrender_dst_pict);
XRenderPictureAttributes pa;
xrender_src_pict = x11.XRenderCreatePicture(dpy, xrender_pm, xrender_pf, 0, &pa);
xrender_dst_pict = x11.XRenderCreatePicture(dpy, win, xrender_pf, 0, &pa);
x11.XRenderSetPictureFilter(dpy, xrender_src_pict, "best", NULL, 0);
pthread_mutex_lock(&vstatlock); pthread_mutex_lock(&vstatlock);
bitmap_get_scaled_win_size(x_cvstat.scaling, &width, &height, 0, 0); XTransform transform_matrix = {{
{XDoubleToFixed((double)vstat.scrnwidth / vstat.winwidth), XDoubleToFixed(0), XDoubleToFixed(0)},
{XDoubleToFixed(0), XDoubleToFixed((double)vstat.scrnheight / vstat.winheight), XDoubleToFixed(0)},
{XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1.0)}
}};
pthread_mutex_unlock(&vstatlock); pthread_mutex_unlock(&vstatlock);
x11.XRenderSetPictureTransform(dpy, xrender_src_pict, &transform_matrix);
#endif
}
static void resize_xim(void)
{
int width, height;
resize_pictures();
if (x_internal_scaling) {
pthread_mutex_lock(&vstatlock);
bitmap_get_scaled_win_size(x_cvstat.scaling, &width, &height, 0, 0);
pthread_mutex_unlock(&vstatlock);
}
else {
width = x_cvstat.scrnwidth;
height = x_cvstat.scrnheight;
}
if (xim) { if (xim) {
if (width == xim->width if (width == xim->width
...@@ -289,7 +339,7 @@ static void resize_xim(void) ...@@ -289,7 +339,7 @@ static void resize_xim(void)
release_buffer(last); release_buffer(last);
last = NULL; last = NULL;
} }
xim = x11.XCreateImage(dpy, &visual, depth, ZPixmap, 0, NULL, width, height, 32, 0); xim = x11.XCreateImage(dpy, visual, depth, ZPixmap, 0, NULL, width, height, 32, 0);
xim->data=(char *)calloc(1, xim->bytes_per_line*xim->height); xim->data=(char *)calloc(1, xim->bytes_per_line*xim->height);
x11.XFillRectangle(dpy, win, gc, 0, 0, width, height); x11.XFillRectangle(dpy, win, gc, 0, 0, width, height);
} }
...@@ -359,59 +409,48 @@ static void map_window() ...@@ -359,59 +409,48 @@ static void map_window()
static int init_window() static int init_window()
{ {
XGCValues gcv; XGCValues gcv;
int i;
XWMHints *wmhints; XWMHints *wmhints;
XClassHint *classhints; XClassHint *classhints;
int ret;
int best=-1;
int best_depth=0;
int best_cmap=0;
XVisualInfo template = {0};
XVisualInfo *vi;
int w, h; int w, h;
int mw, mh; int mw, mh;
int screen;
int major, minor;
dpy = x11.XOpenDisplay(NULL); dpy = x11.XOpenDisplay(NULL);
if (dpy == NULL) { if (dpy == NULL) {
return(-1); return(-1);
} }
#ifdef WITH_XRENDER
if (xrender_found && x11.XRenderQueryVersion(dpy, &major, &minor) == 0)
xrender_found = false;
#endif
xfd = ConnectionNumber(dpy); xfd = ConnectionNumber(dpy);
x11.utf8 = x11.XInternAtom(dpy, "UTF8_STRING", False); x11.utf8 = x11.XInternAtom(dpy, "UTF8_STRING", False);
x11.targets = x11.XInternAtom(dpy, "TARGETS", False); x11.targets = x11.XInternAtom(dpy, "TARGETS", False);
x11.workarea = x11.XInternAtom(dpy, "_NET_WORKAREA", True); x11.workarea = x11.XInternAtom(dpy, "_NET_WORKAREA", True);
template.screen = DefaultScreen(dpy); screen = DefaultScreen(dpy);
template.class = TrueColor; #ifdef DefaultVisual
vi = x11.XGetVisualInfo(dpy, VisualScreenMask | VisualClassMask, &template, &ret); visual = DefaultVisual(dpy, screen);
for (i=0; i<ret; i++) { #else
if (vi[i].depth >= best_depth && vi[i].colormap_size >= best_cmap) { visual = x11.DefaultVisual(dpy, screen);
best = i; #endif
best_depth = vi[i].depth; #ifdef DefaultDepth
} depth = DefaultDepth(dpy, screen);
} #else
if (best != -1) { depth = x11.DefaultDepth(dpy, screen);
visual = *vi[best].visual; #endif
/* base_pixel = ULONG_MAX;
* TODO: Set VisualIsRGB8 if appropriate... base_pixel &= ~visual->red_mask;
* "appropriate" in this context means it's a sequence of base_pixel &= ~visual->green_mask;
* unpadded uint32_t values in XXRRGGBB format where XX is base_pixel &= ~visual->blue_mask;
* ignored, and RR, GG, and BB are Red, Green, Blue values r_shift = my_fls(visual->red_mask)-16;
* respectively. g_shift = my_fls(visual->green_mask)-16;
*/ b_shift = my_fls(visual->blue_mask)-16;
base_pixel = ULONG_MAX; if (visual->red_mask == 0xff0000 && visual->green_mask == 0xff00 && visual->blue_mask == 0xff)
base_pixel &= ~visual.red_mask; VisualIsRGB8 = true;
base_pixel &= ~visual.green_mask;
base_pixel &= ~visual.blue_mask;
r_shift = my_fls(visual.red_mask)-16;
g_shift = my_fls(visual.green_mask)-16;
b_shift = my_fls(visual.blue_mask)-16;
}
else {
fprintf(stderr, "Unable to find TrueColor visual\n");
x11.XFree(vi);
return -1;
}
x11.XFree(vi);
/* Allocate black and white */ /* Allocate black and white */
black=BlackPixel(dpy, DefaultScreen(dpy)); black=BlackPixel(dpy, DefaultScreen(dpy));
...@@ -419,10 +458,9 @@ static int init_window() ...@@ -419,10 +458,9 @@ static int init_window()
/* Create window, but defer setting a size and GC. */ /* Create window, but defer setting a size and GC. */
XSetWindowAttributes wa = {0}; XSetWindowAttributes wa = {0};
wa.colormap = x11.XCreateColormap(dpy, DefaultRootWindow(dpy), &visual, AllocNone); wa.colormap = x11.XCreateColormap(dpy, DefaultRootWindow(dpy), visual, AllocNone);
wa.background_pixel = black; wa.background_pixel = black;
wa.border_pixel = black; wa.border_pixel = black;
depth = best_depth;
x11_get_maxsize(&mw, &mh); x11_get_maxsize(&mw, &mh);
pthread_mutex_lock(&vstatlock); pthread_mutex_lock(&vstatlock);
bitmap_get_scaled_win_size(x_cvstat.scaling, &w, &h, mw, mh); bitmap_get_scaled_win_size(x_cvstat.scaling, &w, &h, mw, mh);
...@@ -431,7 +469,7 @@ static int init_window() ...@@ -431,7 +469,7 @@ static int init_window()
vstat.scaling = x_cvstat.scaling; vstat.scaling = x_cvstat.scaling;
pthread_mutex_unlock(&vstatlock); pthread_mutex_unlock(&vstatlock);
win = x11.XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, win = x11.XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0,
w, h, 2, depth, InputOutput, &visual, CWColormap | CWBorderPixel | CWBackPixel, &wa); w, h, 2, depth, InputOutput, visual, CWColormap | CWBorderPixel | CWBackPixel, &wa);
classhints=x11.XAllocClassHint(); classhints=x11.XAllocClassHint();
if (classhints) if (classhints)
...@@ -558,6 +596,7 @@ static int video_init() ...@@ -558,6 +596,7 @@ static int video_init()
lot easier. */ lot easier. */
pthread_mutex_lock(&vstatlock); pthread_mutex_lock(&vstatlock);
x_internal_scaling = (ciolib_initial_scaling_type == CIOLIB_SCALING_INTERNAL);
if (ciolib_initial_scaling != 0.0) if (ciolib_initial_scaling != 0.0)
x_cvstat.scaling = vstat.scaling = ciolib_initial_scaling; x_cvstat.scaling = vstat.scaling = ciolib_initial_scaling;
if (x_cvstat.scaling < 1.0 || vstat.scaling < 1.0) if (x_cvstat.scaling < 1.0 || vstat.scaling < 1.0)
...@@ -595,6 +634,8 @@ local_draw_rect(struct rectlist *rect) ...@@ -595,6 +634,8 @@ local_draw_rect(struct rectlist *rect)
uint32_t last_pixel = 0x55555555; uint32_t last_pixel = 0x55555555;
struct graphics_buffer *source; struct graphics_buffer *source;
int w, h; int w, h;
int dw, dh;
uint32_t *source_data;
if (x_cvstat.scrnwidth != rect->rect.width || x_cvstat.scrnheight != rect->rect.height || xim == NULL) { if (x_cvstat.scrnwidth != rect->rect.width || x_cvstat.scrnheight != rect->rect.height || xim == NULL) {
bitmap_drv_free_rect(rect); bitmap_drv_free_rect(rect);
...@@ -609,25 +650,37 @@ local_draw_rect(struct rectlist *rect) ...@@ -609,25 +650,37 @@ local_draw_rect(struct rectlist *rect)
bitmap_drv_free_rect(rect); bitmap_drv_free_rect(rect);
return; return;
} }
source = do_scale(rect, w, h); if (x_internal_scaling) {
bitmap_drv_free_rect(rect); source = do_scale(rect, w, h);
if (source == NULL) bitmap_drv_free_rect(rect);
return; if (source == NULL)
cleft = source->w; return;
ctop = source->h; cleft = source->w;
ctop = source->h;
source_data = source->data;
dw = source->w;
dh = source->h;
}
else {
cleft = w;
ctop = h;
source_data = rect->data;
dw = rect->rect.width;
dh = rect->rect.height;
}
pthread_mutex_lock(&vstatlock); pthread_mutex_lock(&vstatlock);
w = vstat.winwidth; w = vstat.winwidth;
h = vstat.winheight; h = vstat.winheight;
pthread_mutex_unlock(&vstatlock); pthread_mutex_unlock(&vstatlock);
xoff = (w - source->w) / 2; xoff = (w - cleft) / 2;
if (xoff < 0) if (xoff < 0)
xoff = 0; xoff = 0;
yoff = (h - source->h) / 2; yoff = (h - ctop) / 2;
if (yoff < 0) if (yoff < 0)
yoff = 0; yoff = 0;
if (last && (last->w != source->w || last->h != source->h)) { if (last && (last->w != dw || last->h != dh)) {
release_buffer(last); release_buffer(last);
last = NULL; last = NULL;
} }
...@@ -635,10 +688,10 @@ local_draw_rect(struct rectlist *rect) ...@@ -635,10 +688,10 @@ local_draw_rect(struct rectlist *rect)
/* TODO: Translate into local colour depth */ /* TODO: Translate into local colour depth */
idx = 0; idx = 0;
for (y = 0; y < source->h; y++) { for (y = 0; y < dh; y++) {
for (x = 0; x < source->w; x++) { for (x = 0; x < dw; x++) {
if (last) { if (last) {
if (last->data[idx] != source->data[idx]) { if (last->data[idx] != source_data[idx]) {
if (x < cleft) if (x < cleft)
cleft = x; cleft = x;
if (x > cright) if (x > cright)
...@@ -654,31 +707,31 @@ local_draw_rect(struct rectlist *rect) ...@@ -654,31 +707,31 @@ local_draw_rect(struct rectlist *rect)
} }
} }
if (VisualIsRGB8) { if (VisualIsRGB8) {
pixel = source->data[idx]; pixel = source_data[idx];
((uint32_t*)xim->data)[idx] = pixel; ((uint32_t*)xim->data)[idx] = pixel;
} }
else { else {
if (last_pixel != source->data[idx]) { if (last_pixel != source_data[idx]) {
last_pixel = source->data[idx]; last_pixel = source_data[idx];
r = source->data[idx] >> 16 & 0xff; r = source_data[idx] >> 16 & 0xff;
g = source->data[idx] >> 8 & 0xff; g = source_data[idx] >> 8 & 0xff;
b = source->data[idx] & 0xff; b = source_data[idx] & 0xff;
r = (r<<8)|r; r = (r<<8)|r;
g = (g<<8)|g; g = (g<<8)|g;
b = (b<<8)|b; b = (b<<8)|b;
pixel = base_pixel; pixel = base_pixel;
if (r_shift >= 0) if (r_shift >= 0)
pixel |= (r << r_shift) & visual.red_mask; pixel |= (r << r_shift) & visual->red_mask;
else else
pixel |= (r >> (0-r_shift)) & visual.red_mask; pixel |= (r >> (0-r_shift)) & visual->red_mask;
if (g_shift >= 0) if (g_shift >= 0)
pixel |= (g << g_shift) & visual.green_mask; pixel |= (g << g_shift) & visual->green_mask;
else else
pixel |= (g >> (0-g_shift)) & visual.green_mask; pixel |= (g >> (0-g_shift)) & visual->green_mask;
if (b_shift >= 0) if (b_shift >= 0)
pixel |= (b << b_shift) & visual.blue_mask; pixel |= (b << b_shift) & visual->blue_mask;
else else
pixel |= (b >> (0-b_shift)) & visual.blue_mask; pixel |= (b >> (0-b_shift)) & visual->blue_mask;
} }
#ifdef XPutPixel #ifdef XPutPixel
XPutPixel(xim, x, y, pixel); XPutPixel(xim, x, y, pixel);
...@@ -688,15 +741,17 @@ local_draw_rect(struct rectlist *rect) ...@@ -688,15 +741,17 @@ local_draw_rect(struct rectlist *rect)
} }
idx++; idx++;
} }
/* This line was changed */ if (x_internal_scaling) {
// TODO: Previously this did one update per display line... /* This line was changed */
if (last && cright >= 0 && (cbottom != y || y == source->h - 1)) { // TODO: Previously this did one update per display line...
x11.XPutImage(dpy, win, gc, xim, cleft, ctop if (last && cright >= 0 && (cbottom != y || y == source->h - 1)) {
, cleft + xoff, ctop + yoff x11.XPutImage(dpy, win, gc, xim, cleft, ctop
, (cright - cleft + 1), (cbottom - ctop + 1)); , cleft + xoff, ctop + yoff
cleft = source->w; , (cright - cleft + 1), (cbottom - ctop + 1));
cright = cbottom = -100; cleft = source->w;
ctop = source->h; cright = cbottom = -100;
ctop = source->h;
}
} }
} }
...@@ -707,10 +762,25 @@ local_draw_rect(struct rectlist *rect) ...@@ -707,10 +762,25 @@ local_draw_rect(struct rectlist *rect)
x11.XFillRectangle(dpy, win, gc, xoff+xim->width, yoff, w, yoff + xim->height); x11.XFillRectangle(dpy, win, gc, xoff+xim->width, yoff, w, yoff + xim->height);
x11.XFillRectangle(dpy, win, gc, 0, yoff + xim->height, w, h); x11.XFillRectangle(dpy, win, gc, 0, yoff + xim->height, w, h);
} }
if (last == NULL) if (x_internal_scaling || xrender_found == false) {
x11.XPutImage(dpy, win, gc, xim, 0, 0, xoff, yoff, source->w, source->h); if (last == NULL)
else x11.XPutImage(dpy, win, gc, xim, 0, 0, xoff, yoff, source->w, source->h);
release_buffer(last); else
release_buffer(last);
}
else {
#ifdef WITH_XRENDER
bitmap_drv_free_rect(rect);
if (last != NULL)
release_buffer(last);
x11.XPutImage(dpy, xrender_pm, gc, xim, 0, 0, 0, 0, dw, dh);
x11.XRenderComposite(dpy, PictOpSrc, xrender_src_pict, 0, xrender_dst_pict,
0, 0, 0, 0, 0, 0,
cleft, ctop);
#else
fprintf(stderr, "External scaling enabled without XRender support compiled in!\n");
#endif
}
last = source; last = source;
} }
...@@ -1492,6 +1562,10 @@ void x11_event_thread(void *args) ...@@ -1492,6 +1562,10 @@ void x11_event_thread(void *args)
x11.XFreeCursor(dpy, oc); x11.XFreeCursor(dpy, oc);
break; break;
} }
case X11_LOCAL_SETSCALING_TYPE:
x_internal_scaling = (lev.data.st == CIOLIB_SCALING_INTERNAL);
resize_xim();
break;
} }
} }
} }
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#ifdef WITH_XRENDER
#include <X11/extensions/Xrender.h>
#endif
enum x11_local_events { enum x11_local_events {
X11_LOCAL_SETMODE X11_LOCAL_SETMODE
...@@ -18,17 +21,19 @@ enum x11_local_events { ...@@ -18,17 +21,19 @@ enum x11_local_events {
,X11_LOCAL_BEEP ,X11_LOCAL_BEEP
,X11_LOCAL_SETICON ,X11_LOCAL_SETICON
,X11_LOCAL_MOUSEPOINTER ,X11_LOCAL_MOUSEPOINTER
,X11_LOCAL_SETSCALING_TYPE
}; };
struct x11_local_event { struct x11_local_event {
enum x11_local_events type; enum x11_local_events type;
union { union {
int mode; int mode;
char name[81]; char name[81];
char title[81]; char title[81];
struct rectlist *rect; struct rectlist *rect;
unsigned long *icon_data; unsigned long *icon_data;
enum ciolib_mouse_ptr ptr; enum ciolib_mouse_ptr ptr;
enum ciolib_scaling st;
} data; } data;
}; };
...@@ -97,6 +102,22 @@ struct x11 { ...@@ -97,6 +102,22 @@ struct x11 {
int (*XDefineCursor)(Display *display, Window w, Cursor cursor); int (*XDefineCursor)(Display *display, Window w, Cursor cursor);
int (*XFreeCursor)(Display *display, Cursor cursor); int (*XFreeCursor)(Display *display, Cursor cursor);
Status (*XGetGeometry)(Display *, Drawable, Window *, int *, int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *); Status (*XGetGeometry)(Display *, Drawable, Window *, int *, int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *);
#ifndef DefaultDepth
int (*DefaultDepth)(Display *, int);
#endif
#ifndef Defaultvisual
Visual *(*DefaultVisual)(Display *, int);
#endif
#ifdef WITH_XRENDER
XRenderPictFormat *(*XRenderFindStandardFormat)(Display *dpy, int format);
Picture (*XRenderCreatePicture)(Display *dpy, Drawable drawable, _Xconst XRenderPictFormat *format, unsigned long valuemask, _Xconst XRenderPictureAttributes *attributes);
void (*XRenderFreePicture)(Display *dpy, Picture picture);
void (*XRenderSetPictureTransform)(Display *dpy, Picture picture, XTransform *transform);
void (*XRenderComposite)(Display *dpy, int op, Picture src, Picture mask, Picture dst, int src_x, int src_y, int mask_x, int mask_y, int dst_x, int dst_y, unsigned int width, unsigned int height);
XRenderPictFormat *(*XRenderFindVisualFormat)(Display *dpy, _Xconst Visual *visual);
Status (*XRenderQueryVersion)(Display *, int *, int *);
void (*XRenderSetPictureFilter)(Display *, Picture, const char *, XFixed *, int);
#endif
Atom utf8; Atom utf8;
Atom targets; Atom targets;
Atom workarea; Atom workarea;
...@@ -122,6 +143,8 @@ extern int x11_window_xpos; ...@@ -122,6 +143,8 @@ extern int x11_window_xpos;
extern int x11_window_ypos; extern int x11_window_ypos;
extern int x11_initialized; extern int x11_initialized;
extern struct video_stats x_cvstat; extern struct video_stats x_cvstat;
extern bool xrender_found;
extern bool x_internal_scaling;
void x11_event_thread(void *args); void x11_event_thread(void *args);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment