Skip to content
Snippets Groups Projects
  • Albert  Babí Oller's avatar
    7f7e4b22
    misc: change the way of manipulating window's display screen · 7f7e4b22
    Albert Babí Oller authored and Ming Rui Zhang's avatar Ming Rui Zhang committed
    - avoid using screen number as display number on Linux
    - support for area selection over multiple screens on Linux
    - make getFrame null safe
    - make video-full-screen mode show in the correct screen
    - add the option of "share all screens"
    - use x11 api for unix system for sharing screen areas
    
    Gitlab: #160
    
    Change-Id: Ibe47a4150b6a213950a0533d85e8cd7d5d159482
    7f7e4b22
    History
    misc: change the way of manipulating window's display screen
    Albert Babí Oller authored and Ming Rui Zhang's avatar Ming Rui Zhang committed
    - avoid using screen number as display number on Linux
    - support for area selection over multiple screens on Linux
    - make getFrame null safe
    - make video-full-screen mode show in the correct screen
    - add the option of "share all screens"
    - use x11 api for unix system for sharing screen areas
    
    Gitlab: #160
    
    Change-Id: Ibe47a4150b6a213950a0533d85e8cd7d5d159482
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
xrectsel.c 3.43 KiB
/*
 * This code is based and adapted from:
 * https://github.com/lolilolicon/FFcast2/blob/master/xrectsel.c
 *
 * now located at:
 * https://github.com/lolilolicon/xrectsel/blob/master/xrectsel.c
 *
 * xrectsel.c -- print the geometry of a rectangular screen region.
 * Copyright (C) 2011-2014 lolilolicon <lolilolicon@gmail.com>
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * 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 <http://www.gnu.org/licenses/>.
 */

#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void
xrectsel(unsigned* x_sel, unsigned* y_sel, unsigned* w_sel, unsigned* h_sel)
{
    Display* dpy = XOpenDisplay(NULL);
    if (!dpy)
        return;

    Window root = DefaultRootWindow(dpy);

    XEvent ev;

    GC sel_gc;
    XGCValues sel_gv;

    int btn_pressed = 0;
    int x = 0, y = 0;
    unsigned int width = 0, height = 0;
    int start_x = 0, start_y = 0;

    Cursor cursor;
    cursor = XCreateFontCursor(dpy, XC_crosshair);

    /* Grab pointer for these events */
    XGrabPointer(dpy,
                 root,
                 True,
                 PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
                 GrabModeAsync,
                 GrabModeAsync,
                 None,
                 cursor,
                 CurrentTime);

    sel_gv.function = GXinvert;
    sel_gv.subwindow_mode = IncludeInferiors;
    sel_gv.line_width = 1;
    sel_gc = XCreateGC(dpy, root, GCFunction | GCSubwindowMode | GCLineWidth, &sel_gv);

    for (;;) {
        XNextEvent(dpy, &ev);

        if (ev.type == ButtonPress) {
            btn_pressed = 1;
            x = start_x = ev.xbutton.x_root;
            y = start_y = ev.xbutton.y_root;
            width = height = 0;

        } else if (ev.type == MotionNotify) {
            if (!btn_pressed)
                continue; /* Draw only if button is pressed */

            /* Re-draw last Rectangle to clear it */
            XDrawRectangle(dpy, root, sel_gc, x, y, width, height);

            x = ev.xbutton.x_root;
            y = ev.xbutton.y_root;

            if (x > start_x) {
                width = x - start_x;
                x = start_x;
            } else {
                width = start_x - x;
            }

            if (y > start_y) {
                height = y - start_y;
                y = start_y;
            } else {
                height = start_y - y;
            }

            /* Draw Rectangle */
            XDrawRectangle(dpy, root, sel_gc, x, y, width, height);
            XFlush(dpy);

        } else if (ev.type == ButtonRelease)
            break;
    }

    /* Re-draw last Rectangle to clear it */
    XDrawRectangle(dpy, root, sel_gc, x, y, width, height);
    XFlush(dpy);

    XUngrabPointer(dpy, CurrentTime);
    XFreeCursor(dpy, cursor);
    XFreeGC(dpy, sel_gc);
    XSync(dpy, 1);

    *x_sel = x;
    *y_sel = y;
    *w_sel = width;
    *h_sel = height;

    XCloseDisplay(dpy);
}