diff --git a/gfx/display_servers/dispserv_x11.c b/gfx/display_servers/dispserv_x11.c index dea810ee2f..be53cefd73 100644 --- a/gfx/display_servers/dispserv_x11.c +++ b/gfx/display_servers/dispserv_x11.c @@ -40,33 +40,30 @@ #include "../../retroarch.h" #include "../video_crt_switch.h" /* needed to set aspect for low res in linux */ -#ifdef HAVE_XRANDR -/* TODO/FIXME - static globals */ -static char xrandr[1024] = {0}; -static char crt_name[16] = {0}; -static int crt_name_id = 0; -static bool crt_en = false; -static unsigned crt_id = 20; -static char orig_output[256] = {0}; -static char old_mode[256] = {0}; -static char new_mode[256] = {0}; -static int x11_monitor_index = 0; -static XRRModeInfo crt_rrmode; -#endif - -static bool x11_display_server_using_global_dpy = false; - typedef struct { +#ifdef HAVE_XRANDR + XRRModeInfo crt_rrmode; +#endif + int crt_name_id; + int monitor_index; unsigned opacity; + char crt_name[16]; + char new_mode[256]; + char old_mode[256]; + char orig_output[256]; + bool using_global_dpy; + bool crt_en; bool decorations; } dispserv_x11_t; #ifdef HAVE_XRANDR -static Display* x11_display_server_open_display(void) +static Display* x11_display_server_open_display(dispserv_x11_t *dispserv) { Display *dpy = g_x11_dpy; - x11_display_server_using_global_dpy = (dpy != NULL); + if (!dispserv) + return NULL; + dispserv->using_global_dpy = (dpy != NULL); /* SDL might use X11 but doesn't use g_x11_dpy, so open it manually */ if (!dpy) @@ -75,9 +72,10 @@ static Display* x11_display_server_open_display(void) return dpy; } -static void x11_display_server_close_display(Display *dpy) +static void x11_display_server_close_display(dispserv_x11_t *dispserv, + Display *dpy) { - if (!dpy || x11_display_server_using_global_dpy || dpy == g_x11_dpy) + if (!dpy || !dispserv || dispserv->using_global_dpy || dpy == g_x11_dpy) return; XCloseDisplay(dpy); @@ -87,8 +85,7 @@ static bool x11_display_server_set_resolution(void *data, unsigned width, unsigned height, int int_hz, float hz, int center, int monitor_index, int xoffset, int padjust) { - int m; - int screen; + int m, screen; Window window; XRRScreenResources *resources = NULL; @@ -111,15 +108,15 @@ static bool x11_display_server_set_resolution(void *data, int crt_mode_flag = 0; bool crt_exists = false; XRRModeInfo *swmode = NULL; + dispserv_x11_t *dispserv = (dispserv_x11_t*)data; - x11_monitor_index = monitor_index; + dispserv->monitor_index = monitor_index; + dispserv->crt_en = true; + dispserv->crt_name_id += 1; + snprintf(dispserv->crt_name, sizeof(dispserv->crt_name), + "CRT%d", dispserv->crt_name_id); - - crt_en = true; - crt_name_id += 1; - snprintf(crt_name, sizeof(crt_name), "CRT%d", crt_name_id); - - strlcpy(old_mode, new_mode, sizeof(old_mode)); + strlcpy(dispserv->old_mode, new_mode, sizeof(dispserv->old_mode)); dpy = XOpenDisplay(0); screen = DefaultScreen(dpy); @@ -131,53 +128,52 @@ static bool x11_display_server_set_resolution(void *data, /* following code is the mode line generator */ if (width < 700) { - hfp = (width * 1.033)+(padjust*2); - hbp = (width * 1.225)+(padjust*2); + hfp = (width * 1.033)+(padjust*2); + hbp = (width * 1.225)+(padjust*2); } else { - hfp = ((width * 1.033) + (width / 112))+(padjust*4); - hbp = ((width * 1.225) + (width /58))+(padjust*4); - xoffset = xoffset*2; + hfp = ((width * 1.033) + (width / 112))+(padjust*4); + hbp = ((width * 1.225) + (width /58))+(padjust*4); + xoffset = xoffset*2; } - hsp = (width * 1.117) - (xoffset*4); - - hmax = hbp; + hsp = (width * 1.117) - (xoffset*4); + hmax = hbp; if (height < 241) - vmax = 261; + vmax = 261; if (height < 241 && hz > 56 && hz < 58) - vmax = 280; + vmax = 280; if (height < 241 && hz < 55) - vmax = 313; + vmax = 313; if (height > 250 && height < 260 && hz > 54) - vmax = 296; + vmax = 296; if (height > 250 && height < 260 && hz > 52 && hz < 54) - vmax = 285; + vmax = 285; if (height > 250 && height < 260 && hz < 52) - vmax = 313; + vmax = 313; if (height > 260 && height < 300) - vmax = 318; + vmax = 318; if (height > 400 && hz > 56) - vmax = 533; + vmax = 533; if (height > 520 && hz < 57) - vmax = 580; + vmax = 580; if (height > 300 && hz < 56) - vmax = 615; + vmax = 615; if (height > 500 && hz < 56) - vmax = 624; + vmax = 624; if (height > 300) - pdefault = pdefault * 2; + pdefault = pdefault * 2; - vfp = height + ((vmax - height) / 2) - pdefault; + vfp = height + ((vmax - height) / 2) - pdefault; if (height < 300) - vsp = vfp + 3; /* needs to be 3 for progressive */ + vsp = vfp + 3; /* needs to be 3 for progressive */ if (height > 300) - vsp = vfp + 6; /* needs to be 6 for interlaced */ + vsp = vfp + 6; /* needs to be 6 for interlaced */ - vbp = vmax; + vbp = vmax; if (height < 300) pixel_clock = (hmax * vmax * hz) ; @@ -192,35 +188,35 @@ static bool x11_display_server_set_resolution(void *data, /* create interlaced newmode from modline variables */ if (height > 300) crt_mode_flag = 26; - strlcpy(old_mode, new_mode, sizeof(old_mode)); + strlcpy(dispserv->old_mode, dispserv->new_mode, sizeof(dispserv->old_mode)); /* variable for new mode */ - strlcpy(new_mode, crt_name, sizeof(new_mode)); + strlcpy(dispserv->new_mode, dispserv->crt_name, sizeof(dispserv->new_mode)); /* need to run loops for DVI0 - DVI-2 and VGA0 - VGA-2 outputs to * add and delete modes */ - crt_rrmode.name = new_mode; - crt_rrmode.nameLength = strlen(crt_name); - crt_rrmode.dotClock = pixel_clock; - crt_rrmode.width = width; - crt_rrmode.hSyncStart = hfp; - crt_rrmode.hSyncEnd = hsp; - crt_rrmode.hTotal = hmax; - crt_rrmode.height = height; - crt_rrmode.vSyncStart = vfp; - crt_rrmode.vSyncEnd = vsp; - crt_rrmode.vTotal = vbp; - crt_rrmode.modeFlags = crt_mode_flag; /* 10 for -hsync -vsync. 26 for -hsync -vsync interlaced */ - crt_rrmode.hSkew = 0; + dispserv->crt_rrmode.name = dispserv->new_mode; + dispserv->crt_rrmode.nameLength = strlen(dispserv->crt_name); + dispserv->crt_rrmode.dotClock = pixel_clock; + dispserv->crt_rrmode.width = width; + dispserv->crt_rrmode.hSyncStart = hfp; + dispserv->crt_rrmode.hSyncEnd = hsp; + dispserv->crt_rrmode.hTotal = hmax; + dispserv->crt_rrmode.height = height; + dispserv->crt_rrmode.vSyncStart = vfp; + dispserv->crt_rrmode.vSyncEnd = vsp; + dispserv->crt_rrmode.vTotal = vbp; + dispserv->crt_rrmode.modeFlags = crt_mode_flag; /* 10 for -hsync -vsync. 26 for -hsync -vsync interlaced */ + dispserv->crt_rrmode.hSkew = 0; - res = XRRGetScreenResources(dpy, window); + res = XRRGetScreenResources(dpy, window); XSync(dpy, False); resources = XRRGetScreenResourcesCurrent(dpy, window); for (m = 0; m < resources->nmode; m++) { - if (string_is_equal(resources->modes[m].name, new_mode)) + if (string_is_equal(resources->modes[m].name, dispserv->new_mode)) { crt_exists = true; break; @@ -230,20 +226,20 @@ static bool x11_display_server_set_resolution(void *data, XRRFreeScreenResources(resources); if (!crt_exists) - XRRCreateMode(dpy, window, &crt_rrmode); + XRRCreateMode(dpy, window, &dispserv->crt_rrmode); resources = XRRGetScreenResourcesCurrent(dpy, window); for (m = 0; m < resources->nmode; m++) { - if (string_is_equal(resources->modes[m].name, new_mode)) + if (string_is_equal(resources->modes[m].name, dispserv->new_mode)) { swmode = &resources->modes[m]; break; } } - if (monitor_index == 20) + if (dispserv->monitor_index == 20) { for (i = 0; i < res->noutput; i++) { @@ -255,7 +251,8 @@ static bool x11_display_server_set_resolution(void *data, XRRAddOutputMode(dpy, res->outputs[i], swmode->id); XSync(dpy, False); - strlcpy(orig_output, outputs->name, sizeof(orig_output)); + strlcpy(dispserv->orig_output, outputs->name, + sizeof(dispserv->orig_output)); crtc = XRRGetCrtcInfo(dpy, resources, outputs->crtc); crtc->mode = swmode->id; crtc->width = swmode->width; @@ -285,7 +282,8 @@ static bool x11_display_server_set_resolution(void *data, XRRAddOutputMode(dpy, res->outputs[monitor_index], swmode->id); XSync(dpy, False); - strlcpy(orig_output, outputs->name, sizeof(orig_output)); + strlcpy(dispserv->orig_output, outputs->name, + sizeof(dispserv->orig_output)); crtc = XRRGetCrtcInfo(dpy, resources, outputs->crtc); crtc->mode = swmode->id; crtc->width = swmode->width; @@ -406,7 +404,8 @@ static enum rotation x11_display_server_get_screen_orientation(void *data) int i, j; XRRScreenConfiguration *config = NULL; enum rotation rotation = ORIENTATION_NORMAL; - Display *dpy = x11_display_server_open_display(); + dispserv_x11_t *dispserv = (dispserv_x11_t*)data; + Display *dpy = x11_display_server_open_display(dispserv); XRRScreenResources *screen = XRRGetScreenResources(dpy, DefaultRootWindow(dpy)); if (!screen) return ORIENTATION_NORMAL; @@ -458,7 +457,7 @@ static enum rotation x11_display_server_get_screen_orientation(void *data) XRRFreeScreenResources(screen); XRRFreeScreenConfigInfo(config); - x11_display_server_close_display(dpy); + x11_display_server_close_display(dispserv, dpy); return rotation; } @@ -476,11 +475,16 @@ static void* x11_display_server_init(void) static void x11_display_server_destroy(void *data) { - dispserv_x11_t *dispserv = (dispserv_x11_t*)data; - #ifdef HAVE_XRANDR int m, j, i; - if (crt_en) +#endif + dispserv_x11_t *dispserv = (dispserv_x11_t*)data; + + if (!dispserv) + return; + +#ifdef HAVE_XRANDR + if (dispserv->crt_en) { XRRModeInfo *swoldmode = NULL; XRRModeInfo *swdeskmode = NULL; @@ -495,20 +499,20 @@ static void x11_display_server_destroy(void *data) strlcpy(dmode, "d_mo", sizeof(dmode)); - crt_rrmode.name = dmode; - crt_rrmode.nameLength = strlen(crt_name); - crt_rrmode.dotClock = 13849698; - crt_rrmode.width = 700; - crt_rrmode.hSyncStart = 742; - crt_rrmode.hSyncEnd = 801; - crt_rrmode.hTotal = 867; - crt_rrmode.height = 480; - crt_rrmode.vSyncStart = 490; - crt_rrmode.vSyncEnd = 496; - crt_rrmode.vTotal = 533; - crt_rrmode.modeFlags = 26; + dispserv->crt_rrmode.name = dmode; + dispserv->crt_rrmode.nameLength = strlen(dispserv->crt_name); + dispserv->crt_rrmode.dotClock = 13849698; + dispserv->crt_rrmode.width = 700; + dispserv->crt_rrmode.hSyncStart = 742; + dispserv->crt_rrmode.hSyncEnd = 801; + dispserv->crt_rrmode.hTotal = 867; + dispserv->crt_rrmode.height = 480; + dispserv->crt_rrmode.vSyncStart = 490; + dispserv->crt_rrmode.vSyncEnd = 496; + dispserv->crt_rrmode.vTotal = 533; + dispserv->crt_rrmode.modeFlags = 26; /* 10 for -hsync -vsync. ?? for -hsync -vsync interlaced */ - crt_rrmode.hSkew = 0; + dispserv->crt_rrmode.hSkew = 0; res = XRRGetScreenResources(dpy, window); resources = XRRGetScreenResourcesCurrent(dpy, window); @@ -529,7 +533,7 @@ static void x11_display_server_destroy(void *data) if (!crt_exists) - XRRCreateMode(dpy, window, &crt_rrmode); + XRRCreateMode(dpy, window, &dispserv->crt_rrmode); resources = XRRGetScreenResourcesCurrent(dpy, window); @@ -542,7 +546,7 @@ static void x11_display_server_destroy(void *data) } } - if (x11_monitor_index == 20) + if (dispserv->monitor_index == 20) { for (i = 0; i < res->noutput; i++) { @@ -555,7 +559,8 @@ static void x11_display_server_destroy(void *data) XRRAddOutputMode(dpy, res->outputs[i], swdeskmode->id); XSync(dpy, False); - strlcpy(orig_output, outputs->name, sizeof(orig_output)); + strlcpy(dispserv->orig_output, outputs->name, + sizeof(dispserv->orig_output)); crtc = XRRGetCrtcInfo(dpy, resources, outputs->crtc); crtc->mode = swdeskmode->id; crtc->width = swdeskmode->width; @@ -577,25 +582,26 @@ static void x11_display_server_destroy(void *data) else { XRROutputInfo *outputs = XRRGetOutputInfo(dpy, res, - res->outputs[x11_monitor_index]); + res->outputs[dispserv->monitor_index]); if (outputs->connection == RR_Connected) { XRRCrtcInfo *crtc = NULL; XRRAddOutputMode(dpy, - res->outputs[x11_monitor_index], swdeskmode->id); + res->outputs[dispserv->monitor_index], swdeskmode->id); XSync(dpy, False); - strlcpy(orig_output, outputs->name, sizeof(orig_output)); + strlcpy(dispserv->orig_output, outputs->name, + sizeof(dispserv->orig_output)); crtc = XRRGetCrtcInfo(dpy, resources, outputs->crtc); crtc->mode = swdeskmode->id; crtc->width = swdeskmode->width; crtc->height = swdeskmode->height; XRRSetCrtcConfig(dpy, res, - res->crtcs[x11_monitor_index], + res->crtcs[dispserv->monitor_index], CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0); XSync(dpy, False); XRRSetCrtcConfig(dpy, res, - res->crtcs[x11_monitor_index], + res->crtcs[dispserv->monitor_index], CurrentTime, crtc->x, crtc->y, crtc->mode, crtc->rotation, crtc->outputs, crtc->noutput); @@ -610,13 +616,15 @@ static void x11_display_server_destroy(void *data) { for (j = 0; j < res->noutput; j++) { - for (i = 1 ; i <= crt_name_id; i++ ) + for (i = 1 ; i <= dispserv->crt_name_id; i++ ) { XRROutputInfo *outputs = XRRGetOutputInfo(dpy, res, res->outputs[j]); if (outputs->connection == RR_Connected) { - snprintf(old_mode, sizeof(old_mode), "CRT%d", i); - if (string_is_equal(resources->modes[m].name, old_mode)) + snprintf(dispserv->old_mode, sizeof(dispserv->old_mode), + "CRT%d", i); + if (string_is_equal(resources->modes[m].name, + dispserv->old_mode)) { swoldmode = &resources->modes[m]; XRRDeleteOutputMode(dpy, res->outputs[j], swoldmode->id);