diff --git a/gfx/display_servers/dispserv_x11.c b/gfx/display_servers/dispserv_x11.c index 7fbfc1510c..5981a5cf7d 100644 --- a/gfx/display_servers/dispserv_x11.c +++ b/gfx/display_servers/dispserv_x11.c @@ -482,6 +482,8 @@ static enum rotation x11_display_server_get_screen_orientation(void) int i, j; Display *dpy = x11_display_server_open_display(); XRRScreenResources *screen = XRRGetScreenResources(dpy, DefaultRootWindow(dpy)); + if (!screen) + return ORIENTATION_NORMAL; XRRScreenConfiguration *config = XRRGetScreenInfo(dpy, DefaultRootWindow(dpy)); enum rotation rotation = ORIENTATION_NORMAL; diff --git a/gfx/drivers/xshm_gfx.c b/gfx/drivers/xshm_gfx.c index 851a8b6270..846d723d93 100644 --- a/gfx/drivers/xshm_gfx.c +++ b/gfx/drivers/xshm_gfx.c @@ -32,17 +32,17 @@ #include "../../menu/menu_driver.h" #endif +#include "../../configuration.h" #include "../font_driver.h" - #include "../common/x11_common.h" +#include "../../verbosity.h" typedef struct xshm { - Display* display; - Window wndw; - int width; int height; + bool use_shm; + uint8_t *fbptr; XShmSegmentInfo shmInfo; XImage* image; @@ -54,44 +54,82 @@ static void *xshm_gfx_init(const video_info_t *video, { xshm_t* xshm = (xshm_t*)malloc(sizeof(xshm_t)); Window parent; + XSetWindowAttributes attributes; XInitThreads(); - xshm->display = XOpenDisplay(NULL); + g_x11_dpy = XOpenDisplay(NULL); + + xshm->use_shm = true; + + if (!XShmQueryExtension(g_x11_dpy)) + { + RARCH_LOG("[X11]: XShm extension not found.\n"); + xshm->use_shm = false; + } #ifdef RARCH_INTERNAL - parent = DefaultRootWindow(xshm->display); + parent = DefaultRootWindow(g_x11_dpy); #else parent = video->parent; #endif - XSetWindowAttributes attributes; attributes.border_pixel=0; - xshm->wndw = XCreateWindow(xshm->display, parent, - 0, 0, video->width, video->height, - 0, 24, CopyFromParent, NULL, CWBorderPixel, &attributes); - XSetWindowBackground(xshm->display, xshm->wndw, 0); - XMapWindow(xshm->display, xshm->wndw); + g_x11_win = XCreateWindow(g_x11_dpy, parent, + 0, 0, video->width, video->height, + 0, 24, CopyFromParent, NULL, CWBorderPixel, &attributes); + XSetWindowBackground(g_x11_dpy, g_x11_win, 0); + XMapWindow(g_x11_dpy, g_x11_win); - xshm->shmInfo.shmid = shmget(IPC_PRIVATE, sizeof(uint32_t) * video->width * video->height, - IPC_CREAT|0600); - if (xshm->shmInfo.shmid<0) abort();//seems like an out of memory situation... let's just blow up + if (xshm->use_shm) + { + xshm->shmInfo.shmid = shmget(IPC_PRIVATE, sizeof(uint32_t) * video->width * video->height, + IPC_CREAT|0600); + if (xshm->shmInfo.shmid<0) abort();/* seems like an out of memory situation... let's just blow up. */ - xshm->shmInfo.shmaddr = (char*)shmat(xshm->shmInfo.shmid, 0, 0); - xshm->shmInfo.readOnly = False; - XShmAttach(xshm->display, &xshm->shmInfo); - XSync(xshm->display, False);//no idea why this is required, but I get weird errors without it - xshm->image = XShmCreateImage(xshm->display, NULL, 24, ZPixmap, - xshm->shmInfo.shmaddr, &xshm->shmInfo, video->width, video->height); + xshm->shmInfo.shmaddr = (char*)shmat(xshm->shmInfo.shmid, 0, 0); + xshm->shmInfo.readOnly = False; + XShmAttach(g_x11_dpy, &xshm->shmInfo); + XSync(g_x11_dpy, False);/* no idea why this is required, but I get weird errors without it. */ + xshm->image = XShmCreateImage(g_x11_dpy, NULL, 24, ZPixmap, + xshm->shmInfo.shmaddr, &xshm->shmInfo, video->width, video->height); + xshm->fbptr = (uint8_t*)xshm->shmInfo.shmaddr; + } else { + size_t pitch = video->width * 4; + void *data = malloc (pitch * video->height); + if (!data) abort();/* seems like an out of memory situation... let's just blow up. */ + xshm->image = XCreateImage(g_x11_dpy, NULL, 24, ZPixmap, 0, + (char *) data, video->width, + video->height, 8, pitch); + xshm->fbptr = (uint8_t*)data; + XSync(g_x11_dpy, False); + } - xshm->gc = XCreateGC(xshm->display, xshm->wndw, 0, NULL); + xshm->gc = XCreateGC(g_x11_dpy, g_x11_win, 0, NULL); xshm->width = video->width; xshm->height = video->height; - if (input) *input = NULL; - if (input_data) *input_data = NULL; + if (!x11_input_ctx_new(true)) + goto error; + + if (input && input_data) + { + void *xinput = NULL; + settings_t *settings = config_get_ptr(); + xinput = input_x.init(settings->arrays.input_joypad_driver); + if (xinput) + { + *input = &input_x; + *input_data = xinput; + } + else + *input = NULL; + } return xshm; + error: + free (xshm); + return NULL; } static bool xshm_gfx_frame(void *data, const void *frame, unsigned width, @@ -103,16 +141,20 @@ static bool xshm_gfx_frame(void *data, const void *frame, unsigned width, bool menu_is_alive = video_info->menu_is_alive; for (y = 0; y < height; y++) - memcpy((uint8_t*)xshm->shmInfo.shmaddr + sizeof(uint32_t)*xshm->width*y, + memcpy(xshm->fbptr + sizeof(uint32_t)*xshm->width*y, (uint8_t*)frame + pitch*y, pitch); #ifdef HAVE_MENU menu_driver_frame(menu_is_alive, video_info); #endif - XShmPutImage(xshm->display, xshm->wndw, xshm->gc, xshm->image, - 0, 0, 0, 0, xshm->width, xshm->height, False); - XFlush(xshm->display); + if (xshm->use_shm) + XShmPutImage(g_x11_dpy, g_x11_win, xshm->gc, xshm->image, + 0, 0, 0, 0, xshm->width, xshm->height, False); + else + XPutImage(g_x11_dpy, g_x11_win, xshm->gc, xshm->image, + 0, 0, 0, 0, xshm->width, xshm->height); + XFlush(g_x11_dpy); return true; } @@ -233,7 +275,7 @@ video_driver_t video_xshm = { NULL, /* has_windowed */ xshm_gfx_set_shader, xshm_gfx_free, - "xshm", + "x11", NULL, NULL, /* set_rotation */ diff --git a/qb/config.libs.sh b/qb/config.libs.sh index a5a8d7d677..4f158f1e4a 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -476,10 +476,10 @@ else die : 'Notice: X11 not present. Skipping X11 code paths.' fi -check_enabled X11 XINERAMA Xinerama 'X11 is' false -check_enabled X11 XSHM XShm 'X11 is' false -check_enabled X11 XRANDR Xrandr 'X11 is' false -check_enabled X11 XVIDEO XVideo 'X11 is' false +check_enabled X11 XINERAMA Xinerama 'Xinerama is' false +check_enabled X11 XSHM XShm 'XShm is' false +check_enabled X11 XRANDR Xrandr 'Xrandr is' false +check_enabled X11 XVIDEO XVideo 'Xvideo is' false check_enabled XEXT XVIDEO XVideo 'Xext is' false check_enabled XF86VM XVIDEO XVideo 'XF86vm is' false diff --git a/qb/config.params.sh b/qb/config.params.sh index f2ace2ee57..bb7e73fd39 100644 --- a/qb/config.params.sh +++ b/qb/config.params.sh @@ -134,7 +134,7 @@ HAVE_IMAGEVIEWER=yes # Built-in image viewer support. HAVE_MMAP=auto # MMAP support HAVE_QT=auto # Qt companion support C89_QT=no -HAVE_XSHM=no # XShm video driver support +HAVE_XSHM=auto # XShm video driver support HAVE_CHEEVOS=yes # Retro Achievements HAVE_LUA=no # Lua support (for Retro Achievements) HAVE_DISCORD=yes # Discord Integration