Coder Social home page Coder Social logo

andykitchen / swcursor Goto Github PK

View Code? Open in Web Editor NEW
24.0 2.0 6.0 64 KB

Large software cursor for screen recording on X11

License: GNU General Public License v3.0

Makefile 2.73% C 97.27%
xlib x11-cursor gtk gtk3 gtk-3 gdk screencast screensaver

swcursor's Introduction

swcursor

swcursor example screenshot

This is a simple software cursor for X11 environments, it creates an overlay window with an (large) image that follows the cursor around. You will need to arrange for your normal cursor to be hidden, or screen record using ffmpeg's kmsgrab which often does not capture harware cursors at all.

This is largely for screen recording where you would like a very large cursor that visually highlights when you click, Also when screen recording directly from the KMS scanout buffer using kmsgrab with ffmpeg, hardware cursors won't show up, so running this program you get a nice large cursor.

Installation and Usage

You will need to have working development libraries for gtk-3.0, gdk and xlib.

$ make
$ ./swcursor

# You can display any transparent PNG image you like for the cursor
$ ./swcursor grumpy-cat.png

Implementation

It's suprisingly difficult to find documentation on the interaction between GTK, GDK and X11 and there are some pitfalls, this is a reasonably minimal example of creating a GTK window and then manipulating it with lower level commands from GDK and Xlib. The non-trivial parts are:

  • making the window transparent
  • removing all decoration, and
  • hiding the window from the window manager;
  • using the X11 shape extension to make the window click-through.

The other trick is integrating with the GTK/GDK lifecycle. Here is the order I found with directed trial and error:

  • window_init
    • gtk_widget_set_app_paintable
    • gdk_screen_get_rgba_visual / gtk_widget_set_visual
  • window_realize
    • gtk_window_set_decorated / gdk_window_set_decorations etc.
    • gdk_window_set_override_redirect
  • window_map
    • XShapeCombineRegion(..., ShapeInput, ...)

In hindsight, it may have been easier to use Xlib directly. But I also wanted to learn more about GTK and GDK when I started this project.

Screen Recording with FFMPEG

Below is the command I use to record my screen with ffmpeg when using swcursor. It should work on a recent Intel chipset running an up-to-date Linux kernel, with VAAPI installed. Read more about ffmpeg and VAAPI here.

#!/bin/sh

ffmpeg \
        -v verbose \
        -thread_queue_size 128 \
        -f pulse -i default \
        -device /dev/dri/card0 \
        -crtc_id 0 -plane_id 0 -framerate 30 \
        -f kmsgrab -i - \
        -af "asetpts=N/SR/TB" \
        -vf "hwmap=derive_device=vaapi,scale_vaapi=w=1920:h=1080:format=nv12" \
        -c:a aac \
        -c:v h264_vaapi -b:v 3200k \
        -- out.mp4

This setup is great because it reads the whole screen from video memory and compresses it directly in hardware, I can record my 4K desktop at 30fps with very few dropped frames and 20% CPU usage on one core.

You will need to set the admin capability on ffmpeg (or use sudo):

$ sudo setcap cap_sys_admin+ep /usr/bin/ffmpeg

If you want to do live steaming or have an NVIDIA Graphics Card, you might want to check out this gist and the ffmpeg wiki page on hardware acceleration.

swcursor's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

swcursor's Issues

Release under Free Software License?

Hi there. I couldn't find a license. So this can't be used in any other projects. Any chance you could release this under a free software license?

Wont follow cursor

It creates an overlay window with an (large) image that do Not follows the cursor around.

swcursor

More Info:

$ uname -a ; lsb_release -a
Linux x 4.20.10-arch1-1-ARCH #1 SMP PREEMPT Fri Feb 15 17:49:06 UTC 2019 x86_64 GNU/Linux
LSB Version:    1.4
Distributor ID: Antergos
Description:    Antergos Linux
Release:        rolling
Codename:       n/a

Desktop is vanilla KDE5 (Qt5) default configs.
It creates an Xwindow on the list of windows on the bottom taskbar.
Inside the window it does follow mouse cursor but it leaves a trail of the image.
I can not drag around the window, it just like fixed at (0, 0).
Hardware is just a generic vanilla mouse.

wayland support

I use kmsgrab with wayland, but swcursor does not work so well with this combination.
Using gnome 3.38.2 with gtk-3.24.24 on Fedora 33.

(swcursor:963185): Gdk-WARNING **: 15:27:32.717: gdkwindow-x11.c:5650 drawable is not a native X11 window

Thread 1 "swcursor" received signal SIGSEGV, Segmentation fault.
0x00007ffff7e1f5ad in require_socket.part.0.lto_priv.0 (dpy=0x55555557f810) at xcb_io.c:66
66			if(dpy->xcb->event_owner != XlibOwnsEventQueue)
(gdb) bt
#0  0x00007ffff7e1f5ad in require_socket.part.0.lto_priv.0 (dpy=0x55555557f810) at xcb_io.c:66
#1  0x00007ffff7e223fd in require_socket (dpy=0x55555557f810) at xcb_io.c:579
#2  _XFlush (dpy=0x55555557f810) at xcb_io.c:576
#3  0x00007ffff7e2264d in _XGetRequest (dpy=0x55555557f810, type=<optimized out>, len=8) at XlibInt.c:1764
#4  0x00007ffff7e15f0f in XQueryExtension
    (dpy=0x55555557f810, name=0x7ffff7dd00e9 "SHAPE", major_opcode=0x7fffffffb754, first_event=0x7fffffffb758, first_error=0x7fffffffb75c) at QuExt.c:44
#5  0x00007ffff7e09e87 in XInitExtension (dpy=dpy@entry=0x55555557f810, name=name@entry=0x7ffff7dd00e9 "SHAPE") at InitExt.c:47
#6  0x00007ffff7dc758d in XextAddDisplay
    (extinfo=0x7ffff7dd5550 <_shape_info_data>, dpy=dpy@entry=0x55555557f810, ext_name=ext_name@entry=0x7ffff7dd00e9 "SHAPE", hooks=hooks@entry=
    0x7ffff7dd5200 <shape_extension_hooks>, nevents=nevents@entry=1, data=data@entry=0x0) at extutil.c:110
#7  0x00007ffff7dc7ee0 in find_display (dpy=0x55555557f810) at XShape.c:73
#8  0x00007ffff7dcb92c in XShapeCombineRegion (dpy=0x55555557f810, dest=0, destKind=2, xOff=0, yOff=0, r=0x55555558e3d0, op=0) at XShape.c:195
#9  0x0000555555557514 in swcursor_window_map (widget=0x5555558583b0) at swcursor-window.c:143
#10 0x00007ffff7061080 in _g_closure_invoke_va
    (param_types=0x0, n_params=<optimized out>, args=0x7fffffffba30, instance=0x5555558583b0, return_value=0x0, closure=0x5555555c3b90)
    at ../gobject/gclosure.c:873
#11 g_signal_emit_valist (instance=0x5555558583b0, signal_id=<optimized out>, detail=0, var_args=var_args@entry=0x7fffffffba30) at ../gobject/gsignal.c:3403
#12 0x00007ffff70611a3 in g_signal_emit (instance=instance@entry=0x5555558583b0, signal_id=<optimized out>, detail=detail@entry=0) at ../gobject/gsignal.c:3550
#13 0x00007ffff79b9dd8 in gtk_widget_map (widget=0x5555558583b0) at gtkwidget.c:5047
#14 0x00007ffff79d96df in gtk_window_show (widget=0x5555558583b0) at gtkwindow.c:6185
#15 0x00007ffff7043e2a in g_closure_invoke
    (closure=0x5555555c3db0, return_value=0x0, n_param_values=1, param_values=0x7fffffffbce0, invocation_hint=0x7fffffffbc60) at ../gobject/gclosure.c:810
#16 0x00007ffff706cf0a in signal_emit_unlocked_R.isra.0
    (node=node@entry=0x5555555eb010, detail=detail@entry=0, instance=instance@entry=0x5555558583b0, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffbce0) at ../gobject/gsignal.c:3668
#17 0x00007ffff7060f82 in g_signal_emit_valist
    (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fffffffbe90) at ../gobject/gsignal.c:3494
#18 0x00007ffff70611a3 in g_signal_emit (instance=instance@entry=0x5555558583b0, signal_id=<optimized out>, detail=detail@entry=0) at ../gobject/gsignal.c:3550
#19 0x00007ffff79ba476 in gtk_widget_show (widget=0x5555558583b0) at gtkwidget.c:4848
#20 0x0000555555556ac5 in show_main_window (image=0x5555555e8820) at swcursor.c:56
#21 0x0000555555556978 in main (argc=1, argv=0x7fffffffc0d8) at swcursor.c:29

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.