aboutsummaryrefslogtreecommitdiff
path: root/src/cursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cursor.c')
-rw-r--r--src/cursor.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/src/cursor.c b/src/cursor.c
index 737c33b..e818d72 100644
--- a/src/cursor.c
+++ b/src/cursor.c
@@ -7,9 +7,12 @@
#include <X11/extensions/Xfixes.h>
-static bool gsr_cursor_set_from_x11_cursor_image(gsr_cursor *self, XFixesCursorImage *x11_cursor_image) {
+// TODO: Test cursor visibility with XFixesHideCursor
+
+static bool gsr_cursor_set_from_x11_cursor_image(gsr_cursor *self, XFixesCursorImage *x11_cursor_image, bool *visible) {
uint8_t *cursor_data = NULL;
uint8_t *out = NULL;
+ *visible = false;
if(!x11_cursor_image)
goto err;
@@ -34,21 +37,25 @@ static bool gsr_cursor_set_from_x11_cursor_image(gsr_cursor *self, XFixesCursorI
uint32_t pixel = *pixels++;
uint8_t *in = (uint8_t*)&pixel;
uint8_t alpha = in[3];
- if(alpha == 0)
+ if(alpha == 0) {
alpha = 1;
-
- *out++ = (unsigned)*in++ * 255/alpha;
- *out++ = (unsigned)*in++ * 255/alpha;
- *out++ = (unsigned)*in++ * 255/alpha;
- *out++ = *in++;
+ } else {
+ *visible = true;
+ }
+
+ out[0] = (float)in[2] * 255.0/(float)alpha;
+ out[1] = (float)in[1] * 255.0/(float)alpha;
+ out[2] = (float)in[0] * 255.0/(float)alpha;
+ out[3] = in[3];
+ out += 4;
+ in += 4;
}
}
+ // TODO: glTextureSubImage2D if same size
self->egl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, self->size.x, self->size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, cursor_data);
free(cursor_data);
- self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -82,7 +89,7 @@ int gsr_cursor_init(gsr_cursor *self, gsr_egl *egl, Display *display) {
self->egl->glGenTextures(1, &self->texture_id);
XFixesSelectCursorInput(self->display, DefaultRootWindow(self->display), XFixesDisplayCursorNotifyMask);
- gsr_cursor_set_from_x11_cursor_image(self, XFixesGetCursorImage(self->display));
+ gsr_cursor_set_from_x11_cursor_image(self, XFixesGetCursorImage(self->display), &self->visible);
self->cursor_image_set = true;
return 0;
@@ -97,29 +104,33 @@ void gsr_cursor_deinit(gsr_cursor *self) {
self->texture_id = 0;
}
- XFixesSelectCursorInput(self->display, DefaultRootWindow(self->display), 0);
+ if(self->display)
+ XFixesSelectCursorInput(self->display, DefaultRootWindow(self->display), 0);
self->display = NULL;
self->egl = NULL;
}
-void gsr_cursor_update(gsr_cursor *self, XEvent *xev) {
+bool gsr_cursor_on_event(gsr_cursor *self, XEvent *xev) {
+ bool updated = false;
+
if(xev->type == self->x_fixes_event_base + XFixesCursorNotify) {
XFixesCursorNotifyEvent *cursor_notify_event = (XFixesCursorNotifyEvent*)xev;
if(cursor_notify_event->subtype == XFixesDisplayCursorNotify && cursor_notify_event->window == DefaultRootWindow(self->display)) {
- self->cursor_image_set = true;
- gsr_cursor_set_from_x11_cursor_image(self, XFixesGetCursorImage(self->display));
+ self->cursor_image_set = false;
}
}
if(!self->cursor_image_set) {
self->cursor_image_set = true;
- gsr_cursor_set_from_x11_cursor_image(self, XFixesGetCursorImage(self->display));
+ gsr_cursor_set_from_x11_cursor_image(self, XFixesGetCursorImage(self->display), &self->visible);
+ updated = true;
}
+
+ return updated;
}
void gsr_cursor_tick(gsr_cursor *self, Window relative_to) {
- /* TODO: Use XInput2 instead. However that doesn't work when the pointer is grabbed. Maybe check for focused window change and XSelectInput PointerMask */
Window dummy_window;
int dummy_i;
unsigned int dummy_u;