From 66e8674100d15aa30b1cfc1e337112cb01646fb5 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Fri, 29 Aug 2014 17:17:04 -0700 Subject: [PATCH] linux-capture: Add cursor capture to xcomposite --- plugins/linux-capture/xcompcap-main.cpp | 41 +++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/plugins/linux-capture/xcompcap-main.cpp b/plugins/linux-capture/xcompcap-main.cpp index 8b3e6c327..47d29cd7b 100644 --- a/plugins/linux-capture/xcompcap-main.cpp +++ b/plugins/linux-capture/xcompcap-main.cpp @@ -12,6 +12,7 @@ #include "xcompcap-main.hpp" #include "xcompcap-helper.hpp" +#include "xcursor.h" #define xdisp (XCompcap::disp()) #define WIN_STRING_DIV "\r\n" @@ -79,6 +80,9 @@ obs_properties_t XCompcapMain::properties() obs_module_text("SwapRedBlue")); obs_properties_add_bool(props, "lock_x", obs_module_text("LockX")); + obs_properties_add_bool(props, "show_cursor", + obs_module_text("CaptureCursor")); + return props; } @@ -91,6 +95,7 @@ void XCompcapMain::defaults(obs_data_t settings) obs_data_set_default_int(settings, "cut_bot", 0); obs_data_set_default_bool(settings, "swap_redblue", false); obs_data_set_default_bool(settings, "lock_x", false); + obs_data_set_default_bool(settings, "show_cursor", true); } @@ -142,6 +147,10 @@ struct XCompcapMain_private pthread_mutex_t lock; pthread_mutexattr_t lockattr; + + bool show_cursor = true; + bool cursor_outside = false; + xcursor_t *cursor = nullptr; }; @@ -150,6 +159,10 @@ XCompcapMain::XCompcapMain(obs_data_t settings, obs_source_t source) p = new XCompcapMain_private; p->source = source; + obs_enter_graphics(); + p->cursor = xcursor_init(xdisp); + obs_leave_graphics(); + updateSettings(settings); } @@ -166,6 +179,11 @@ XCompcapMain::~XCompcapMain() xcc_cleanup(p); + if (p->cursor) { + xcursor_destroy(p->cursor); + p->cursor = nullptr; + } + delete p; } @@ -256,6 +274,7 @@ void XCompcapMain::updateSettings(obs_data_t settings) p->cut_bot = obs_data_get_int(settings, "cut_bot"); p->lockX = obs_data_get_bool(settings, "lock_x"); p->swapRedBlue = obs_data_get_bool(settings, "swap_redblue"); + p->show_cursor = obs_data_get_bool(settings, "show_cursor"); } else { p->win = prevWin; } @@ -281,6 +300,15 @@ void XCompcapMain::updateSettings(obs_data_t settings) return; } + if (p->cursor && p->show_cursor) { + Window child; + int x, y; + + XTranslateCoordinates(xdisp, p->win, attr.root, 0, 0, &x, &y, + &child); + xcursor_offset(p->cursor, x - attr.x, y - attr.y); + } + gs_color_format cf = GS_RGBA; p->width = attr.width; @@ -424,6 +452,16 @@ void XCompcapMain::tick(float seconds) gs_copy_texture_region(p->tex, 0, 0, p->gltex, p->cur_cut_left, p->cur_cut_top, width(), height()); + if (p->cursor && p->show_cursor) { + xcursor_tick(p->cursor); + + p->cursor_outside = + p->cursor->x < p->cur_cut_left || + p->cursor->y < p->cur_cut_top || + p->cursor->x > int(p->width - p->cur_cut_right) || + p->cursor->y > int(p->height - p->cur_cut_bot); + } + if (p->lockX) XUnlockDisplay(xdisp); @@ -443,6 +481,9 @@ void XCompcapMain::render(gs_effect_t effect) gs_enable_blending(false); gs_draw_sprite(p->tex, 0, 0, 0); + if (p->cursor && p->gltex && p->show_cursor && !p->cursor_outside) + xcursor_render(p->cursor); + gs_reset_blend_state(); }