From e243614db820e587c6405717f2c8220ccb7694e9 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 7 Sep 2016 13:38:01 +0200 Subject: [PATCH] Create half-broken XShm driver, to perform evil experiments on --- Makefile.common | 4 + gfx/drivers/xshm_gfx.c | 274 +++++++++++++++++++++++++++++++++++++++++ gfx/video_driver.c | 3 + qb/config.params.sh | 2 +- 4 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 gfx/drivers/xshm_gfx.c diff --git a/Makefile.common b/Makefile.common index 7c56d336d0..d091566bfe 100644 --- a/Makefile.common +++ b/Makefile.common @@ -816,6 +816,10 @@ ifeq ($(HAVE_SDL2), 1) HAVE_SDL = 0 endif +ifeq ($(HAVE_XSHM), 1) + OBJ += gfx/drivers/xshm_gfx.o +endif + ifeq ($(HAVE_VULKAN), 1) ifneq ($(findstring Win32,$(OS)),) GLSLANG_PLATFORM := Windows diff --git a/gfx/drivers/xshm_gfx.c b/gfx/drivers/xshm_gfx.c new file mode 100644 index 0000000000..06bacc6196 --- /dev/null +++ b/gfx/drivers/xshm_gfx.c @@ -0,0 +1,274 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2016-2016 - Alfred Agrell + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "../../configuration.h" +#include "../../driver.h" +#include "../../retroarch.h" +#include "../../runloop.h" +#include "../../performance_counters.h" +#include "../../verbosity.h" +#include "../video_context_driver.h" +#include "../font_driver.h" + +#include "../common/x11_common.h" + +#ifdef HAVE_MENU +#include "../../menu/menu_driver.h" +#endif + +#include +#include +#include +#include + + +typedef struct xshm +{ + Display* display; + Window wndw; + + int width; + int height; + + XShmSegmentInfo shmInfo; + XImage* image; + GC gc; +} xshm_t; + +static void *xshm_gfx_init(const video_info_t *video, + const input_driver_t **input, void **input_data) +{ + xshm_t* xshm = (xshm_t*)malloc(sizeof(xshm_t)); + + XInitThreads(); + + xshm->display = XOpenDisplay(NULL); + + XSetWindowAttributes attributes; + attributes.border_pixel=0; + xshm->wndw = XCreateWindow(xshm->display, DefaultRootWindow(xshm->display)/*xshm->parentwindow*/, + 0, 0, video->width, video->height, + 0, 24, CopyFromParent, NULL, CWBorderPixel, &attributes); + XSetWindowBackground(xshm->display, xshm->wndw, 0); + XMapWindow(xshm->display, xshm->wndw); + + 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->gc = XCreateGC(xshm->display, xshm->wndw, 0, NULL); + + xshm->width = video->width; + xshm->height = video->height; + + *input = NULL; + *input_data = NULL; + + return xshm; +} + +static bool xshm_gfx_frame(void *data, const void *frame, unsigned width, + unsigned height, uint64_t frame_count, + unsigned pitch, const char *msg) +{ + xshm_t* xshm = (xshm_t*)data; + int x, y; + + for (y=0;yshmInfo.shmaddr + sizeof(uint32_t)*xshm->width*y, (uint8_t*)frame + pitch*y, pitch); + } + + XShmPutImage(xshm->display, xshm->wndw, xshm->gc, xshm->image, + 0, 0, 0, 0, xshm->width, xshm->height, False); + XFlush(xshm->display); + + return true; +} + +static void xshm_gfx_set_nonblock_state(void *data, bool toggle) +{ + +} + +static bool xshm_gfx_alive(void *data) +{ + return true; +} + +static bool xshm_gfx_focus(void *data) +{ + return true; +} + +static bool xshm_gfx_suppress_screensaver(void *data, bool enable) +{ + return false; +} + +static bool xshm_gfx_has_windowed(void *data) +{ + return true; +} + +static void xshm_gfx_free(void *data) +{ + +} + +static void xshm_gfx_set_rotation(void *data, unsigned rotation) +{ + +} + +static void xshm_gfx_viewport_info(void *data, struct video_viewport *vp) +{ + +} + +static bool xshm_gfx_read_viewport(void *data, uint8_t *buffer) +{ + return false; +} + +static void xshm_poke_set_filtering(void *data, unsigned index, bool smooth) +{ + +} + +static void xshm_poke_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) +{ + +} + +static void xshm_poke_apply_state_changes(void *data) +{ + +} + +#ifdef HAVE_MENU +static void xshm_poke_set_texture_frame(void *data, const void *frame, bool rgb32, + unsigned width, unsigned height, float alpha) +{ + +} + +static void xshm_poke_texture_enable(void *data, bool enable, bool full_screen) +{ + +} + +static void xshm_poke_set_osd_msg(void *data, const char *msg, + const struct font_params *params, void *font) +{ + +} + +static void xshm_show_mouse(void *data, bool state) +{ + +} + +static void xshm_grab_mouse_toggle(void *data) +{ + +} +#endif + +static video_poke_interface_t xshm_video_poke_interface = { + NULL, + NULL, + NULL, + xshm_poke_set_filtering, + NULL, /* get_video_output_size */ + NULL, /* get_video_output_prev */ + NULL, /* get_video_output_next */ + NULL, /* get_current_framebuffer */ + NULL, /* get_proc_address */ + xshm_poke_set_aspect_ratio, + xshm_poke_apply_state_changes, +#ifdef HAVE_MENU + xshm_poke_set_texture_frame, + xshm_poke_texture_enable, + xshm_poke_set_osd_msg, + xshm_show_mouse, + xshm_grab_mouse_toggle, +#else + NULL, + NULL, + NULL, + NULL, + NULL, +#endif + NULL, +}; + +static void xshm_gfx_poke_interface(void *data, const video_poke_interface_t **iface) +{ + (void)data; + *iface = &xshm_video_poke_interface; +} + +static bool xshm_gfx_set_shader(void *data, + enum rarch_shader_type type, const char *path) +{ + (void)data; + (void)type; + (void)path; + + return false; +} + +video_driver_t video_xshm = { + xshm_gfx_init, + xshm_gfx_frame, + xshm_gfx_set_nonblock_state, + xshm_gfx_alive, + xshm_gfx_focus, + xshm_gfx_suppress_screensaver, + xshm_gfx_has_windowed, + xshm_gfx_set_shader, + xshm_gfx_free, + "xshm", + + NULL, + xshm_gfx_set_rotation, + xshm_gfx_viewport_info, + xshm_gfx_read_viewport, + NULL, /* read_frame_raw */ +#ifdef HAVE_OVERLAY + NULL, +#endif + xshm_gfx_poke_interface +}; + diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 54e513367a..4860ed25ab 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -203,6 +203,9 @@ static const video_driver_t *video_drivers[] = { #endif #ifdef HAVE_PLAIN_DRM &video_drm, +#endif +#ifdef HAVE_XSHM + &video_xshm, #endif &video_null, NULL, diff --git a/qb/config.params.sh b/qb/config.params.sh index 84ae7c17a0..91fbb8d517 100644 --- a/qb/config.params.sh +++ b/qb/config.params.sh @@ -79,7 +79,7 @@ HAVE_PARPORT=auto # Parallel port joypad support HAVE_IMAGEVIEWER=yes # Built-in image viewer support. HAVE_MMAP=auto # MMAP support HAVE_QT=no # QT companion support -HAVE_XSHM=no # XShm video driver support (disabled because it's just a dummied out stub) +HAVE_XSHM=auto # XShm video driver support HAVE_CHEEVOS=yes # Retro Achievements HAVE_SHADERPIPELINE=yes # Additional shader-based pipelines C89_SHADERPIPELINE=no