diff options
Diffstat (limited to 'src/cursor.c')
-rw-r--r-- | src/cursor.c | 43 |
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; |