2019-07-06 05:51:52 +03:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2019 cyclopsian
|
|
|
|
* Copyright (C) 2017-2019 emersion
|
|
|
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
* a copy of this software and associated documentation files (the
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
* the following conditions:
|
|
|
|
|
|
|
|
* The above copyright notice and this permission notice shall be
|
|
|
|
* included in all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY
|
|
|
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
|
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
|
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Parts of this file are taken from emersion/kanshi:
|
|
|
|
* https://github.com/emersion/kanshi/blob/38d27474b686fcc8324cc5e454741a49577c0988/include/kanshi.h
|
|
|
|
* https://github.com/emersion/kanshi/blob/38d27474b686fcc8324cc5e454741a49577c0988/include/config.h
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef WDISPLAY_WDISPLAY_H
|
|
|
|
#define WDISPLAY_WDISPLAY_H
|
|
|
|
|
2019-07-27 03:26:37 +03:00
|
|
|
#define HEADS_MAX 64
|
|
|
|
#define HOVER_USECS (100 * 1000)
|
|
|
|
|
2019-07-06 05:51:52 +03:00
|
|
|
#include <stdbool.h>
|
|
|
|
#include <wayland-client.h>
|
|
|
|
|
2019-07-27 03:26:37 +03:00
|
|
|
struct zxdg_output_v1;
|
|
|
|
struct zxdg_output_manager_v1;
|
2019-07-06 05:51:52 +03:00
|
|
|
struct zwlr_output_mode_v1;
|
|
|
|
struct zwlr_output_head_v1;
|
|
|
|
struct zwlr_output_manager_v1;
|
2019-07-27 03:26:37 +03:00
|
|
|
struct zwlr_screencopy_manager_v1;
|
|
|
|
struct zwlr_screencopy_frame_v1;
|
2019-08-13 01:38:46 +03:00
|
|
|
struct zwlr_layer_shell_v1;
|
|
|
|
struct zwlr_layer_surface_v1;
|
2019-07-27 03:26:37 +03:00
|
|
|
|
2019-07-06 05:51:52 +03:00
|
|
|
struct _GtkWidget;
|
|
|
|
typedef struct _GtkWidget GtkWidget;
|
|
|
|
struct _GtkBuilder;
|
|
|
|
typedef struct _GtkBuilder GtkBuilder;
|
2019-07-27 03:26:37 +03:00
|
|
|
struct _GdkCursor;
|
|
|
|
typedef struct _GdkCursor GdkCursor;
|
|
|
|
struct _cairo_surface;
|
|
|
|
typedef struct _cairo_surface cairo_surface_t;
|
2019-07-06 05:51:52 +03:00
|
|
|
|
|
|
|
enum wd_head_fields {
|
|
|
|
WD_FIELD_NAME = 1 << 0,
|
|
|
|
WD_FIELD_ENABLED = 1 << 1,
|
|
|
|
WD_FIELD_DESCRIPTION = 1 << 2,
|
|
|
|
WD_FIELD_PHYSICAL_SIZE = 1 << 3,
|
|
|
|
WD_FIELD_SCALE = 1 << 4,
|
|
|
|
WD_FIELD_POSITION = 1 << 5,
|
|
|
|
WD_FIELD_MODE = 1 << 6,
|
|
|
|
WD_FIELD_TRANSFORM = 1 << 7,
|
|
|
|
WD_FIELDS_ALL = (1 << 8) - 1
|
|
|
|
};
|
|
|
|
|
2019-07-27 03:26:37 +03:00
|
|
|
struct wd_output {
|
|
|
|
struct wd_state *state;
|
|
|
|
struct zxdg_output_v1 *xdg_output;
|
|
|
|
struct wl_output *wl_output;
|
|
|
|
struct wl_list link;
|
|
|
|
|
|
|
|
char *name;
|
|
|
|
struct wl_list frames;
|
2019-08-13 01:38:46 +03:00
|
|
|
GtkWidget *overlay_window;
|
|
|
|
struct zwlr_layer_surface_v1 *overlay_layer_surface;
|
2019-07-27 03:26:37 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
struct wd_frame {
|
|
|
|
struct wd_output *output;
|
|
|
|
struct zwlr_screencopy_frame_v1 *wlr_frame;
|
|
|
|
|
|
|
|
struct wl_list link;
|
|
|
|
int capture_fd;
|
|
|
|
unsigned stride;
|
|
|
|
unsigned width;
|
|
|
|
unsigned height;
|
|
|
|
struct wl_shm_pool *pool;
|
|
|
|
struct wl_buffer *buffer;
|
|
|
|
uint8_t *pixels;
|
|
|
|
uint64_t tick;
|
|
|
|
bool y_invert;
|
2019-08-01 18:07:00 +03:00
|
|
|
bool swap_rgb;
|
2019-07-27 03:26:37 +03:00
|
|
|
};
|
|
|
|
|
2019-07-06 05:51:52 +03:00
|
|
|
struct wd_head_config {
|
|
|
|
struct wl_list link;
|
|
|
|
|
|
|
|
struct wd_head *head;
|
|
|
|
bool enabled;
|
|
|
|
int32_t width;
|
|
|
|
int32_t height;
|
|
|
|
int32_t refresh; // mHz
|
|
|
|
int32_t x;
|
|
|
|
int32_t y;
|
|
|
|
double scale;
|
|
|
|
enum wl_output_transform transform;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct wd_mode {
|
|
|
|
struct wd_head *head;
|
|
|
|
struct zwlr_output_mode_v1 *wlr_mode;
|
|
|
|
struct wl_list link;
|
|
|
|
|
|
|
|
int32_t width, height;
|
|
|
|
int32_t refresh; // mHz
|
|
|
|
bool preferred;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct wd_head {
|
|
|
|
struct wd_state *state;
|
|
|
|
struct zwlr_output_head_v1 *wlr_head;
|
|
|
|
struct wl_list link;
|
|
|
|
|
2019-07-27 03:26:37 +03:00
|
|
|
struct wd_output *output;
|
|
|
|
struct wd_render_head_data *render;
|
|
|
|
cairo_surface_t *surface;
|
|
|
|
|
2019-08-13 01:38:46 +03:00
|
|
|
uint32_t id;
|
2019-07-06 05:51:52 +03:00
|
|
|
char *name, *description;
|
|
|
|
int32_t phys_width, phys_height; // mm
|
|
|
|
struct wl_list modes;
|
|
|
|
|
|
|
|
bool enabled;
|
|
|
|
struct wd_mode *mode;
|
|
|
|
struct {
|
|
|
|
int32_t width, height;
|
|
|
|
int32_t refresh;
|
|
|
|
} custom_mode;
|
|
|
|
int32_t x, y;
|
|
|
|
enum wl_output_transform transform;
|
|
|
|
double scale;
|
|
|
|
};
|
|
|
|
|
2019-07-27 03:26:37 +03:00
|
|
|
struct wd_gl_data;
|
|
|
|
|
|
|
|
struct wd_render_head_data {
|
2019-08-06 20:26:25 +03:00
|
|
|
struct wl_list link;
|
|
|
|
|
2019-07-27 03:26:37 +03:00
|
|
|
float x1;
|
|
|
|
float y1;
|
|
|
|
float x2;
|
|
|
|
float y2;
|
|
|
|
|
|
|
|
uint8_t *pixels;
|
|
|
|
unsigned tex_stride;
|
|
|
|
unsigned tex_width;
|
|
|
|
unsigned tex_height;
|
|
|
|
bool preview;
|
|
|
|
bool y_invert;
|
2019-08-01 18:07:00 +03:00
|
|
|
bool swap_rgb;
|
2019-07-27 03:26:37 +03:00
|
|
|
uint64_t updated_at;
|
|
|
|
|
|
|
|
bool hovered;
|
|
|
|
uint64_t transition_begin;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct wd_render_data {
|
|
|
|
float fg_color[4];
|
|
|
|
float bg_color[4];
|
|
|
|
float border_color[4];
|
|
|
|
float selection_color[4];
|
|
|
|
unsigned int viewport_width;
|
|
|
|
unsigned int viewport_height;
|
|
|
|
unsigned int width;
|
|
|
|
unsigned int height;
|
|
|
|
int scroll_x;
|
|
|
|
int scroll_y;
|
|
|
|
int x_origin;
|
|
|
|
int y_origin;
|
|
|
|
uint64_t updated_at;
|
|
|
|
|
2019-08-06 20:26:25 +03:00
|
|
|
struct wl_list heads;
|
2019-07-27 03:26:37 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
struct wd_point {
|
|
|
|
double x;
|
|
|
|
double y;
|
|
|
|
};
|
|
|
|
|
2019-07-06 05:51:52 +03:00
|
|
|
struct wd_state {
|
2019-07-27 03:26:37 +03:00
|
|
|
struct zxdg_output_manager_v1 *xdg_output_manager;
|
2019-07-06 05:51:52 +03:00
|
|
|
struct zwlr_output_manager_v1 *output_manager;
|
2019-07-27 03:26:37 +03:00
|
|
|
struct zwlr_screencopy_manager_v1 *copy_manager;
|
2019-08-13 01:38:46 +03:00
|
|
|
struct zwlr_layer_shell_v1 *layer_shell;
|
2019-07-27 03:26:37 +03:00
|
|
|
struct wl_shm *shm;
|
2019-07-06 05:51:52 +03:00
|
|
|
struct wl_list heads;
|
2019-07-27 03:26:37 +03:00
|
|
|
struct wl_list outputs;
|
2019-07-06 05:51:52 +03:00
|
|
|
uint32_t serial;
|
|
|
|
|
2019-07-06 20:12:28 +03:00
|
|
|
bool apply_pending;
|
|
|
|
bool autoapply;
|
2019-07-27 03:26:37 +03:00
|
|
|
bool capture;
|
2019-08-13 01:38:46 +03:00
|
|
|
bool show_overlay;
|
2019-07-06 05:51:52 +03:00
|
|
|
double zoom;
|
2019-07-27 03:26:37 +03:00
|
|
|
|
2019-08-06 20:26:25 +03:00
|
|
|
struct wd_render_head_data *clicked;
|
2019-07-27 03:26:37 +03:00
|
|
|
/* top left, bottom right */
|
|
|
|
struct wd_point click_offset;
|
|
|
|
bool panning;
|
|
|
|
struct wd_point pan_last;
|
2019-07-06 05:51:52 +03:00
|
|
|
|
|
|
|
GtkWidget *header_stack;
|
|
|
|
GtkWidget *stack_switcher;
|
|
|
|
GtkWidget *stack;
|
|
|
|
GtkWidget *scroller;
|
|
|
|
GtkWidget *canvas;
|
|
|
|
GtkWidget *spinner;
|
|
|
|
GtkWidget *zoom_out;
|
|
|
|
GtkWidget *zoom_reset;
|
|
|
|
GtkWidget *zoom_in;
|
|
|
|
GtkWidget *overlay;
|
|
|
|
GtkWidget *info_bar;
|
|
|
|
GtkWidget *info_label;
|
2019-07-06 20:12:28 +03:00
|
|
|
GtkWidget *menu_button;
|
2019-07-27 03:26:37 +03:00
|
|
|
|
|
|
|
GdkCursor *grab_cursor;
|
|
|
|
GdkCursor *grabbing_cursor;
|
|
|
|
GdkCursor *move_cursor;
|
|
|
|
|
|
|
|
unsigned int canvas_tick;
|
|
|
|
struct wd_gl_data *gl_data;
|
|
|
|
struct wd_render_data render;
|
2019-07-06 05:51:52 +03:00
|
|
|
};
|
|
|
|
|
2019-07-27 03:26:37 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Creates the application state structure.
|
|
|
|
*/
|
|
|
|
struct wd_state *wd_state_create(void);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Frees the application state structure.
|
|
|
|
*/
|
|
|
|
void wd_state_destroy(struct wd_state *state);
|
|
|
|
|
2019-07-06 05:51:52 +03:00
|
|
|
/*
|
|
|
|
* Displays an error message and then exits the program.
|
|
|
|
*/
|
|
|
|
void wd_fatal_error(int status, const char *message);
|
|
|
|
|
2019-07-27 03:26:37 +03:00
|
|
|
/*
|
|
|
|
* Add an output to the list of screen captured outputs.
|
|
|
|
*/
|
2019-08-13 01:38:46 +03:00
|
|
|
void wd_add_output(struct wd_state *state, struct wl_output *wl_output, struct wl_display *display);
|
2019-07-27 03:26:37 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Remove an output from the list of screen captured outputs.
|
|
|
|
*/
|
|
|
|
void wd_remove_output(struct wd_state *state, struct wl_output *wl_output, struct wl_display *display);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Finds the output associated with a given head. Can return NULL if the head's
|
|
|
|
* output is disabled.
|
|
|
|
*/
|
|
|
|
struct wd_output *wd_find_output(struct wd_state *state, struct wd_head *head);
|
2019-08-13 01:38:46 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Finds the head associated with a given output.
|
|
|
|
*/
|
|
|
|
struct wd_head *wd_find_head(struct wd_state *state, struct wd_output *output);
|
2019-07-06 05:51:52 +03:00
|
|
|
/*
|
|
|
|
* Starts listening for output management events from the compositor.
|
|
|
|
*/
|
|
|
|
void wd_add_output_management_listener(struct wd_state *state, struct wl_display *display);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Sends updated display configuration back to the compositor.
|
|
|
|
*/
|
2019-08-14 21:20:11 +03:00
|
|
|
void wd_apply_state(struct wd_state *state, struct wl_list *new_outputs, struct wl_display *display);
|
2019-07-06 05:51:52 +03:00
|
|
|
|
2019-07-27 03:26:37 +03:00
|
|
|
/*
|
|
|
|
* Queues capture of the next frame of all screens.
|
|
|
|
*/
|
|
|
|
void wd_capture_frame(struct wd_state *state);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Blocks until all captures are finished.
|
|
|
|
*/
|
|
|
|
void wd_capture_wait(struct wd_state *state, struct wl_display *display);
|
|
|
|
|
2019-07-06 05:51:52 +03:00
|
|
|
/*
|
|
|
|
* Updates the UI stack of all heads. Does not update individual head forms.
|
|
|
|
* Useful for when a display is plugged/unplugged and we want to add/remove
|
|
|
|
* a page, but we don't want to wipe out user's changes on the other pages.
|
|
|
|
*/
|
|
|
|
void wd_ui_reset_heads(struct wd_state *state);
|
|
|
|
|
|
|
|
/*
|
2019-07-27 03:26:37 +03:00
|
|
|
* Updates the UI form for a single head. Useful for when the compositor
|
|
|
|
* notifies us of updated configuration caused by another program.
|
2019-07-06 05:51:52 +03:00
|
|
|
*/
|
|
|
|
void wd_ui_reset_head(const struct wd_head *head, unsigned int fields);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Updates the stack and all forms to the last known server state.
|
|
|
|
*/
|
|
|
|
void wd_ui_reset_all(struct wd_state *state);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reactivates the GUI after the display configuration updates.
|
|
|
|
*/
|
|
|
|
void wd_ui_apply_done(struct wd_state *state, struct wl_list *outputs);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reactivates the GUI after the display configuration updates.
|
|
|
|
*/
|
|
|
|
void wd_ui_show_error(struct wd_state *state, const char *message);
|
|
|
|
|
2019-07-27 03:26:37 +03:00
|
|
|
/*
|
|
|
|
* Compiles the GL shaders.
|
|
|
|
*/
|
|
|
|
struct wd_gl_data *wd_gl_setup(void);
|
2019-08-13 01:38:46 +03:00
|
|
|
|
2019-07-27 03:26:37 +03:00
|
|
|
/*
|
|
|
|
* Renders the GL scene.
|
|
|
|
*/
|
|
|
|
void wd_gl_render(struct wd_gl_data *res, struct wd_render_data *info, uint64_t tick);
|
2019-08-13 01:38:46 +03:00
|
|
|
|
2019-07-27 03:26:37 +03:00
|
|
|
/*
|
|
|
|
* Destroys the GL shaders.
|
|
|
|
*/
|
|
|
|
void wd_gl_cleanup(struct wd_gl_data *res);
|
|
|
|
|
2019-08-13 01:38:46 +03:00
|
|
|
/*
|
|
|
|
* Create an overlay on the screen that contains a textual description of the
|
|
|
|
* output. This is to help the user identify the outputs visually.
|
|
|
|
*/
|
|
|
|
void wd_create_overlay(struct wd_output *output);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Forces redrawing of the screen overlay on the given output.
|
|
|
|
*/
|
|
|
|
void wd_redraw_overlay(struct wd_output *output);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Destroys the screen overlay on the given output.
|
|
|
|
*/
|
|
|
|
void wd_destroy_overlay(struct wd_output *output);
|
|
|
|
|
2019-07-06 05:51:52 +03:00
|
|
|
#endif
|