diff --git a/test/linux/linux.c b/test/linux/linux.c
index 41c7258d4..294e21d47 100644
--- a/test/linux/linux.c
+++ b/test/linux/linux.c
@@ -23,8 +23,8 @@ extern struct obs_source_info pulse_input;
bool obs_module_load(uint32_t obs_version)
{
- UNUSED_PARAMETER(obs_version);
- obs_register_source(&xshm_input);
- obs_register_source(&pulse_input);
- return true;
+ UNUSED_PARAMETER(obs_version);
+ obs_register_source(&xshm_input);
+ obs_register_source(&pulse_input);
+ return true;
}
diff --git a/test/linux/xcursor.c b/test/linux/xcursor.c
index 4ac187fbf..cc7c7aa78 100644
--- a/test/linux/xcursor.c
+++ b/test/linux/xcursor.c
@@ -14,106 +14,99 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-#include
-#include
+
+#include
#include
+
+#include
#include "xcursor.h"
-uint32_t *xcursor_pixels(XFixesCursorImage *xc) {
- int size = xc->width * xc->height;
- uint32_t *pixels = bmalloc(size * 4);
-
- // pixel data from XFixes is defined as unsigned long ...
- // TODO: check why everybody is making a fuss about this
- for (int i = 0; i < size; ++i)
- pixels[i] = (uint32_t) xc->pixels[i];
-
- return pixels;
+/*
+ * Get pixel data for the cursor
+ *
+ * XFixes has the data defined as unsigned long, so we can not use memcpy.
+ * Theres a lot of talk about this in other implementation and they tend to
+ * be really complicated, but this naive approach seems to work fine ...
+ */
+static uint32_t *xcursor_pixels(XFixesCursorImage *xc) {
+ uint_fast32_t size = xc->width * xc->height;
+ uint32_t *pixels = bmalloc(size * sizeof(uint32_t));
+
+ for (uint_fast32_t i = 0; i < size; ++i)
+ pixels[i] = (uint32_t) xc->pixels[i];
+
+ return pixels;
}
-void xcursor_create(xcursor_t *data, XFixesCursorImage *xc) {
- // get cursor pixel data
- uint32_t *pixels = xcursor_pixels(xc);
-
- // if the cursor has the same size as the last one we can simply update
- if (data->tex
- && data->last_height == xc->width
- && data->last_width == xc->height) {
- texture_setimage(data->tex, (void **) pixels, xc->width * 4, False);
- }
- else {
- if (data->tex)
- texture_destroy(data->tex);
-
- data->tex = gs_create_texture(
- xc->width, xc->height,
- GS_RGBA, 1,
- (const void **) &pixels,
- GS_DYNAMIC
- );
- }
- bfree(pixels);
-
- // set some data
- data->last_serial = xc->cursor_serial;
- data->last_width = xc->width;
- data->last_height = xc->height;
+/*
+ * Create the cursor texture, either by updating if the new cursor has the same
+ * size or by creating a new texture if the size is different
+ */
+static void xcursor_create(xcursor_t *data, XFixesCursorImage *xc) {
+ uint32_t *pixels = xcursor_pixels(xc);
+
+ if (data->tex
+ && data->last_height == xc->width
+ && data->last_width == xc->height) {
+ texture_setimage(data->tex, (void **) pixels,
+ xc->width * sizeof(uint32_t), False);
+ } else {
+ if (data->tex)
+ texture_destroy(data->tex);
+
+ data->tex = gs_create_texture(xc->width, xc->height,
+ GS_RGBA, 1, (const void **) &pixels, GS_DYNAMIC);
+ }
+
+ bfree(pixels);
+
+ data->last_serial = xc->cursor_serial;
+ data->last_width = xc->width;
+ data->last_height = xc->height;
}
xcursor_t *xcursor_init(Display *dpy) {
- xcursor_t *data = bmalloc(sizeof(xcursor_t));
- memset(data, 0, sizeof(xcursor_t));
-
- data->dpy = dpy;
-
- // initialize texture so we don't crash
- xcursor_tick(data);
-
- return data;
+ xcursor_t *data = bmalloc(sizeof(xcursor_t));
+ memset(data, 0, sizeof(xcursor_t));
+
+ data->dpy = dpy;
+ xcursor_tick(data);
+
+ return data;
}
void xcursor_destroy(xcursor_t *data) {
- if (data->tex)
- texture_destroy(data->tex);
- bfree(data);
+ if (data->tex)
+ texture_destroy(data->tex);
+ bfree(data);
}
void xcursor_tick(xcursor_t *data) {
- // get cursor data
- XFixesCursorImage *xc = XFixesGetCursorImage(data->dpy);
-
- // update cursor if necessary
- if (!data->tex || data->last_serial != xc->cursor_serial)
- xcursor_create(data, xc);
-
- // update cursor position
- data->pos_x = -1.0 * (xc->x - xc->xhot);
- data->pos_y = -1.0 * (xc->y - xc->yhot);
-
- XFree(xc);
+ XFixesCursorImage *xc = XFixesGetCursorImage(data->dpy);
+
+ if (!data->tex || data->last_serial != xc->cursor_serial)
+ xcursor_create(data, xc);
+ data->pos_x = -1.0 * (xc->x - xc->xhot);
+ data->pos_y = -1.0 * (xc->y - xc->yhot);
+
+ XFree(xc);
}
void xcursor_render(xcursor_t *data) {
- // TODO: why do i need effects ?
- effect_t effect = gs_geteffect();
- eparam_t image = effect_getparambyname(effect, "image");
-
- effect_settexture(effect, image, data->tex);
-
- gs_matrix_push();
-
- // move cursor to the right position
- gs_matrix_translate3f(
- data->pos_x,
- data->pos_y,
- 0
- );
-
- // blend cursor
- gs_enable_blending(True);
- gs_blendfunction(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
- gs_draw_sprite(data->tex, 0, 0, 0);
- gs_enable_blending(False);
-
- gs_matrix_pop();
+ /* TODO: why do i need effects ? */
+ effect_t effect = gs_geteffect();
+ eparam_t image = effect_getparambyname(effect, "image");
+
+ effect_settexture(effect, image, data->tex);
+
+ gs_matrix_push();
+
+ gs_matrix_translate3f(data->pos_x, data->pos_y, 0);
+
+ gs_enable_blending(True);
+ gs_blendfunction(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
+ gs_draw_sprite(data->tex, 0, 0, 0);
+ gs_enable_blending(False);
+
+ gs_matrix_pop();
}
diff --git a/test/linux/xcursor.h b/test/linux/xcursor.h
index 72436f2fb..69dfe4297 100644
--- a/test/linux/xcursor.h
+++ b/test/linux/xcursor.h
@@ -14,6 +14,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
+
#pragma once
#include
@@ -23,13 +24,13 @@ extern "C" {
#endif
typedef struct {
- Display *dpy;
- float pos_x;
- float pos_y;
- unsigned long last_serial;
- unsigned short int last_width;
- unsigned short int last_height;
- texture_t tex;
+ Display *dpy;
+ float pos_x;
+ float pos_y;
+ unsigned long last_serial;
+ unsigned short int last_width;
+ unsigned short int last_height;
+ texture_t tex;
} xcursor_t;
/**
@@ -60,4 +61,4 @@ void xcursor_render(xcursor_t *data);
#ifdef __cplusplus
}
-#endif
\ No newline at end of file
+#endif
diff --git a/test/linux/xshm-input.c b/test/linux/xshm-input.c
index fb4d59f35..51914c406 100644
--- a/test/linux/xshm-input.c
+++ b/test/linux/xshm-input.c
@@ -28,191 +28,179 @@ along with this program. If not, see .
#define XSHM_DATA(voidptr) struct xshm_data *data = voidptr;
struct xshm_data {
- Display *dpy;
- Window root_window;
- uint32_t width, height;
- int shm_attached;
- XShmSegmentInfo shm_info;
- XImage *image;
- texture_t texture;
- xcursor_t *cursor;
+ Display *dpy;
+ Window root_window;
+ uint32_t width, height;
+ int shm_attached;
+ XShmSegmentInfo shm_info;
+ XImage *image;
+ texture_t texture;
+ xcursor_t *cursor;
};
-static const char* xshm_input_getname(const char* locale)
+static const char* xshm_getname(const char* locale)
{
- UNUSED_PARAMETER(locale);
- return "X11 Shared Memory Screen Input";
+ UNUSED_PARAMETER(locale);
+ return "X11 Shared Memory Screen Input";
}
-static void xshm_input_destroy(void *vptr)
+static void xshm_destroy(void *vptr)
{
- XSHM_DATA(vptr);
-
- if (data) {
- gs_entercontext(obs_graphics());
-
- texture_destroy(data->texture);
- xcursor_destroy(data->cursor);
-
- gs_leavecontext();
-
- // detach xshm
- if (data->shm_attached)
- XShmDetach(data->dpy, &data->shm_info);
-
- // detach shared memory
- if (data->shm_info.shmaddr != (char *) -1) {
- shmdt(data->shm_info.shmaddr);
- data->shm_info.shmaddr = (char *) -1;
- }
-
- // remove shared memory
- if (data->shm_info.shmid != -1)
- shmctl(data->shm_info.shmid, IPC_RMID, NULL);
-
- // destroy image
- if (data->image)
- XDestroyImage(data->image);
-
- // close display
- if (data->dpy)
- XCloseDisplay(data->dpy);
-
- bfree(data);
- }
+ XSHM_DATA(vptr);
+
+ if (!data)
+ return;
+
+ gs_entercontext(obs_graphics());
+
+ texture_destroy(data->texture);
+ xcursor_destroy(data->cursor);
+
+ gs_leavecontext();
+
+ if (data->shm_attached)
+ XShmDetach(data->dpy, &data->shm_info);
+
+ if (data->shm_info.shmaddr != (char *) -1) {
+ shmdt(data->shm_info.shmaddr);
+ data->shm_info.shmaddr = (char *) -1;
+ }
+
+ if (data->shm_info.shmid != -1)
+ shmctl(data->shm_info.shmid, IPC_RMID, NULL);
+
+ if (data->image)
+ XDestroyImage(data->image);
+
+ if (data->dpy)
+ XCloseDisplay(data->dpy);
+
+ bfree(data);
}
-static void *xshm_input_create(obs_data_t settings, obs_source_t source)
+static void *xshm_create(obs_data_t settings, obs_source_t source)
{
- UNUSED_PARAMETER(settings);
- UNUSED_PARAMETER(source);
-
- // create data structure
- struct xshm_data *data = bmalloc(sizeof(struct xshm_data));
- memset(data, 0, sizeof(struct xshm_data));
-
- // try to open display and all the good stuff
- data->dpy = XOpenDisplay(NULL);
- if (!data->dpy)
- goto fail;
-
- Screen *screen = XDefaultScreenOfDisplay(data->dpy);
- data->width = WidthOfScreen(screen);
- data->height = HeightOfScreen(screen);
- data->root_window = XRootWindowOfScreen(screen);
- Visual *visual = DefaultVisualOfScreen(screen);
- int depth = DefaultDepthOfScreen(screen);
-
- // query for shm extension
- if (!XShmQueryExtension(data->dpy))
- goto fail;
-
- // create xshm image
- data->image = XShmCreateImage(data->dpy, visual, depth,
- ZPixmap, NULL, &data->shm_info,
- data->width, data->height);
- if (!data->image)
- goto fail;
-
- // create shared memory
- data->shm_info.shmid = shmget(IPC_PRIVATE, data->image->bytes_per_line *
- data->image->height, IPC_CREAT | 0700);
- if (data->shm_info.shmid < 0)
- goto fail;
-
- // attach shared memory
- data->shm_info.shmaddr = data->image->data
- = (char *) shmat(data->shm_info.shmid, 0, 0);
- if (data->shm_info.shmaddr == (char *) -1)
- goto fail;
- // set shared memory as read only
- data->shm_info.readOnly = False;
-
- // attach shm
- if (!XShmAttach(data->dpy, &data->shm_info))
- goto fail;
- data->shm_attached = 1;
-
- // get image
- if (!XShmGetImage(data->dpy, data->root_window, data->image,
- 0, 0, AllPlanes))
- goto fail;
-
- // create obs texture
- gs_entercontext(obs_graphics());
- data->texture = gs_create_texture(data->width, data->height, GS_BGRA, 1,
- (const void**) &data->image->data,
- GS_DYNAMIC);
- data->cursor = xcursor_init(data->dpy);
- gs_leavecontext();
-
- if (!data->texture)
- goto fail;
-
- return data;
-
+ UNUSED_PARAMETER(settings);
+ UNUSED_PARAMETER(source);
+
+
+ struct xshm_data *data = bmalloc(sizeof(struct xshm_data));
+ memset(data, 0, sizeof(struct xshm_data));
+
+ data->dpy = XOpenDisplay(NULL);
+ if (!data->dpy)
+ goto fail;
+
+ Screen *screen = XDefaultScreenOfDisplay(data->dpy);
+ data->width = WidthOfScreen(screen);
+ data->height = HeightOfScreen(screen);
+ data->root_window = XRootWindowOfScreen(screen);
+ Visual *visual = DefaultVisualOfScreen(screen);
+ int depth = DefaultDepthOfScreen(screen);
+
+ if (!XShmQueryExtension(data->dpy))
+ goto fail;
+
+ data->image = XShmCreateImage(data->dpy, visual, depth,
+ ZPixmap, NULL, &data->shm_info, data->width, data->height);
+ if (!data->image)
+ goto fail;
+
+ data->shm_info.shmid = shmget(IPC_PRIVATE,
+ data->image->bytes_per_line * data->image->height,
+ IPC_CREAT | 0700);
+ if (data->shm_info.shmid < 0)
+ goto fail;
+
+ data->shm_info.shmaddr
+ = data->image->data
+ = (char *) shmat(data->shm_info.shmid, 0, 0);
+ if (data->shm_info.shmaddr == (char *) -1)
+ goto fail;
+ data->shm_info.readOnly = False;
+
+
+ if (!XShmAttach(data->dpy, &data->shm_info))
+ goto fail;
+ data->shm_attached = 1;
+
+ if (!XShmGetImage(data->dpy, data->root_window, data->image,
+ 0, 0, AllPlanes)) {
+ goto fail;
+ }
+
+
+ gs_entercontext(obs_graphics());
+ data->texture = gs_create_texture(data->width, data->height,
+ GS_BGRA, 1, (const void**) &data->image->data, GS_DYNAMIC);
+ data->cursor = xcursor_init(data->dpy);
+ gs_leavecontext();
+
+ if (!data->texture)
+ goto fail;
+
+ return data;
+
fail:
- // clean up and return null
- xshm_input_destroy(data);
- return NULL;
+ xshm_destroy(data);
+ return NULL;
}
-static void xshm_input_video_tick(void *vptr, float seconds)
+static void xshm_video_tick(void *vptr, float seconds)
{
- UNUSED_PARAMETER(seconds);
- XSHM_DATA(vptr);
-
- gs_entercontext(obs_graphics());
-
- // update screen texture
- XShmGetImage(data->dpy, data->root_window, data->image, 0, 0, AllPlanes);
- texture_setimage(data->texture, (void *) data->image->data,
- data->width * 4, False);
-
- // update mouse cursor
- xcursor_tick(data->cursor);
-
- gs_leavecontext();
+ UNUSED_PARAMETER(seconds);
+ XSHM_DATA(vptr);
+
+ gs_entercontext(obs_graphics());
+
+
+ XShmGetImage(data->dpy, data->root_window, data->image,
+ 0, 0, AllPlanes);
+ texture_setimage(data->texture, (void *) data->image->data,
+ data->width * 4, False);
+
+ xcursor_tick(data->cursor);
+
+ gs_leavecontext();
}
-static void xshm_input_video_render(void *vptr, effect_t effect)
+static void xshm_video_render(void *vptr, effect_t effect)
{
- XSHM_DATA(vptr);
-
- eparam_t image = effect_getparambyname(effect, "image");
- effect_settexture(effect, image, data->texture);
-
- gs_enable_blending(False);
-
- gs_draw_sprite(data->texture, 0, 0, 0);
-
- // render the cursor
- xcursor_render(data->cursor);
+ XSHM_DATA(vptr);
+
+ eparam_t image = effect_getparambyname(effect, "image");
+ effect_settexture(effect, image, data->texture);
+
+ gs_enable_blending(False);
+
+ gs_draw_sprite(data->texture, 0, 0, 0);
+
+ xcursor_render(data->cursor);
}
-static uint32_t xshm_input_getwidth(void *vptr)
+static uint32_t xshm_getwidth(void *vptr)
{
- XSHM_DATA(vptr);
-
- return texture_getwidth(data->texture);
+ XSHM_DATA(vptr);
+
+ return texture_getwidth(data->texture);
}
-static uint32_t xshm_input_getheight(void *vptr)
+static uint32_t xshm_getheight(void *vptr)
{
- XSHM_DATA(vptr);
-
- return texture_getheight(data->texture);
+ XSHM_DATA(vptr);
+
+ return texture_getheight(data->texture);
}
struct obs_source_info xshm_input = {
.id = "xshm_input",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO,
- .getname = xshm_input_getname,
- .create = xshm_input_create,
- .destroy = xshm_input_destroy,
- .video_tick = xshm_input_video_tick,
- .video_render = xshm_input_video_render,
- .getwidth = xshm_input_getwidth,
- .getheight = xshm_input_getheight
+ .getname = xshm_getname,
+ .create = xshm_create,
+ .destroy = xshm_destroy,
+ .video_tick = xshm_video_tick,
+ .video_render = xshm_video_render,
+ .getwidth = xshm_getwidth,
+ .getheight = xshm_getheight
};