mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
Implemented UWAC clipboard handling.
This commit is contained in:
@@ -27,9 +27,9 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#if __GNUC__ >= 4
|
||||
#define UWAC_API __attribute__ ((visibility("default")))
|
||||
#define UWAC_API __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define UWAC_API
|
||||
#define UWAC_API
|
||||
#endif
|
||||
|
||||
typedef struct uwac_size UwacSize;
|
||||
@@ -41,7 +41,8 @@ typedef uint32_t UwacSeatId;
|
||||
|
||||
|
||||
/** @brief error codes */
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
UWAC_SUCCESS = 0,
|
||||
UWAC_ERROR_NOMEMORY,
|
||||
UWAC_ERROR_UNABLE_TO_CONNECT,
|
||||
@@ -56,21 +57,24 @@ typedef enum {
|
||||
} UwacReturnCode;
|
||||
|
||||
/** @brief input modifiers */
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
UWAC_MOD_SHIFT_MASK = 0x01,
|
||||
UWAC_MOD_ALT_MASK = 0x02,
|
||||
UWAC_MOD_CONTROL_MASK = 0x04,
|
||||
};
|
||||
|
||||
/** @brief a rectangle size measure */
|
||||
struct uwac_size {
|
||||
struct uwac_size
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
|
||||
/** @brief event types */
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
UWAC_EVENT_NEW_SEAT = 0,
|
||||
UWAC_EVENT_REMOVED_SEAT,
|
||||
UWAC_EVENT_NEW_OUTPUT,
|
||||
@@ -90,91 +94,105 @@ enum {
|
||||
UWAC_EVENT_TOUCH_FRAME_END,
|
||||
UWAC_EVENT_FRAME_DONE,
|
||||
UWAC_EVENT_CLOSE,
|
||||
UWAC_EVENT_CLIPBOARD_AVAILABLE,
|
||||
UWAC_EVENT_CLIPBOARD_SELECT,
|
||||
UWAC_EVENT_CLIPBOARD_OFFER,
|
||||
};
|
||||
|
||||
/** @brief window states */
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
UWAC_WINDOW_MAXIMIZED = 0x1,
|
||||
UWAC_WINDOW_RESIZING = 0x2,
|
||||
UWAC_WINDOW_FULLSCREEN = 0x4,
|
||||
UWAC_WINDOW_ACTIVATED = 0x8,
|
||||
};
|
||||
|
||||
struct uwac_new_output_event {
|
||||
struct uwac_new_output_event
|
||||
{
|
||||
int type;
|
||||
UwacOutput *output;
|
||||
UwacOutput* output;
|
||||
};
|
||||
typedef struct uwac_new_output_event UwacOutputNewEvent;
|
||||
|
||||
struct uwac_new_seat_event {
|
||||
struct uwac_new_seat_event
|
||||
{
|
||||
int type;
|
||||
UwacSeat *seat;
|
||||
UwacSeat* seat;
|
||||
};
|
||||
typedef struct uwac_new_seat_event UwacSeatNewEvent;
|
||||
|
||||
|
||||
struct uwac_removed_seat_event {
|
||||
struct uwac_removed_seat_event
|
||||
{
|
||||
int type;
|
||||
UwacSeatId id;
|
||||
};
|
||||
typedef struct uwac_removed_seat_event UwacSeatRemovedEvent;
|
||||
|
||||
struct uwac_keyboard_enter_event {
|
||||
struct uwac_keyboard_enter_event
|
||||
{
|
||||
int type;
|
||||
UwacWindow *window;
|
||||
UwacSeat *seat;
|
||||
UwacWindow* window;
|
||||
UwacSeat* seat;
|
||||
};
|
||||
typedef struct uwac_keyboard_enter_event UwacKeyboardEnterLeaveEvent;
|
||||
|
||||
struct uwac_pointer_enter_event {
|
||||
struct uwac_pointer_enter_event
|
||||
{
|
||||
int type;
|
||||
UwacWindow *window;
|
||||
UwacSeat *seat;
|
||||
UwacWindow* window;
|
||||
UwacSeat* seat;
|
||||
uint32_t x, y;
|
||||
};
|
||||
typedef struct uwac_pointer_enter_event UwacPointerEnterLeaveEvent;
|
||||
|
||||
struct uwac_pointer_motion_event {
|
||||
struct uwac_pointer_motion_event
|
||||
{
|
||||
int type;
|
||||
UwacWindow *window;
|
||||
UwacSeat *seat;
|
||||
UwacWindow* window;
|
||||
UwacSeat* seat;
|
||||
uint32_t x, y;
|
||||
};
|
||||
typedef struct uwac_pointer_motion_event UwacPointerMotionEvent;
|
||||
|
||||
struct uwac_pointer_button_event {
|
||||
struct uwac_pointer_button_event
|
||||
{
|
||||
int type;
|
||||
UwacWindow *window;
|
||||
UwacSeat *seat;
|
||||
UwacWindow* window;
|
||||
UwacSeat* seat;
|
||||
uint32_t x, y;
|
||||
uint32_t button;
|
||||
enum wl_pointer_button_state state;
|
||||
};
|
||||
typedef struct uwac_pointer_button_event UwacPointerButtonEvent;
|
||||
|
||||
struct uwac_pointer_axis_event {
|
||||
struct uwac_pointer_axis_event
|
||||
{
|
||||
int type;
|
||||
UwacWindow *window;
|
||||
UwacSeat *seat;
|
||||
UwacWindow* window;
|
||||
UwacSeat* seat;
|
||||
uint32_t x, y;
|
||||
uint32_t axis;
|
||||
wl_fixed_t value;
|
||||
};
|
||||
typedef struct uwac_pointer_axis_event UwacPointerAxisEvent;
|
||||
|
||||
struct uwac_touch_frame_event {
|
||||
struct uwac_touch_frame_event
|
||||
{
|
||||
int type;
|
||||
UwacWindow *window;
|
||||
UwacSeat *seat;
|
||||
UwacWindow* window;
|
||||
UwacSeat* seat;
|
||||
};
|
||||
typedef struct uwac_touch_frame_event UwacTouchFrameBegin;
|
||||
typedef struct uwac_touch_frame_event UwacTouchFrameEnd;
|
||||
typedef struct uwac_touch_frame_event UwacTouchCancel;
|
||||
|
||||
struct uwac_touch_data {
|
||||
struct uwac_touch_data
|
||||
{
|
||||
int type;
|
||||
UwacWindow *window;
|
||||
UwacSeat *seat;
|
||||
UwacWindow* window;
|
||||
UwacSeat* seat;
|
||||
int32_t id;
|
||||
wl_fixed_t x;
|
||||
wl_fixed_t y;
|
||||
@@ -183,39 +201,51 @@ typedef struct uwac_touch_data UwacTouchUp;
|
||||
typedef struct uwac_touch_data UwacTouchDown;
|
||||
typedef struct uwac_touch_data UwacTouchMotion;
|
||||
|
||||
struct uwac_frame_done_event {
|
||||
struct uwac_frame_done_event
|
||||
{
|
||||
int type;
|
||||
UwacWindow *window;
|
||||
UwacWindow* window;
|
||||
};
|
||||
typedef struct uwac_frame_done_event UwacFrameDoneEvent;
|
||||
|
||||
struct uwac_configure_event {
|
||||
struct uwac_configure_event
|
||||
{
|
||||
int type;
|
||||
UwacWindow *window;
|
||||
UwacWindow* window;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
int states;
|
||||
};
|
||||
typedef struct uwac_configure_event UwacConfigureEvent;
|
||||
|
||||
struct uwac_key_event {
|
||||
struct uwac_key_event
|
||||
{
|
||||
int type;
|
||||
UwacWindow *window;
|
||||
UwacWindow* window;
|
||||
uint32_t raw_key;
|
||||
uint32_t sym;
|
||||
bool pressed;
|
||||
};
|
||||
typedef struct uwac_key_event UwacKeyEvent;
|
||||
|
||||
struct uwac_close_event {
|
||||
struct uwac_close_event
|
||||
{
|
||||
int type;
|
||||
UwacWindow *window;
|
||||
UwacWindow* window;
|
||||
};
|
||||
typedef struct uwac_close_event UwacCloseEvent;
|
||||
|
||||
struct uwac_clipboard_event
|
||||
{
|
||||
int type;
|
||||
UwacSeat* seat;
|
||||
char mime[64];
|
||||
};
|
||||
typedef struct uwac_clipboard_event UwacClipboardEvent;
|
||||
|
||||
/** @brief */
|
||||
union uwac_event {
|
||||
union uwac_event
|
||||
{
|
||||
int type;
|
||||
UwacOutputNewEvent output_new;
|
||||
UwacSeatNewEvent seat_new;
|
||||
@@ -225,6 +255,7 @@ union uwac_event {
|
||||
UwacPointerButtonEvent mouse_button;
|
||||
UwacPointerAxisEvent mouse_axis;
|
||||
UwacKeyboardEnterLeaveEvent keyboard_enter_leave;
|
||||
UwacClipboardEvent clipboard;
|
||||
UwacKeyEvent key;
|
||||
UwacTouchFrameBegin touchFrameBegin;
|
||||
UwacTouchUp touchUp;
|
||||
@@ -238,7 +269,9 @@ union uwac_event {
|
||||
};
|
||||
typedef union uwac_event UwacEvent;
|
||||
|
||||
typedef bool (*UwacErrorHandler)(UwacDisplay *d, UwacReturnCode code, const char *msg, ...);
|
||||
typedef bool (*UwacErrorHandler)(UwacDisplay* d, UwacReturnCode code, const char* msg, ...);
|
||||
typedef void (*UwacDataTransferHandler)(UwacSeat* seat, void* context, const char* mime, int fd);
|
||||
typedef void (*UwacCancelDataTransferHandler)(UwacSeat* seat, void* context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -261,7 +294,7 @@ UWAC_API void UwacInstallErrorHandler(UwacErrorHandler handler);
|
||||
* @param name the name of the display to open
|
||||
* @return the created UwacDisplay object
|
||||
*/
|
||||
UWAC_API UwacDisplay *UwacOpenDisplay(const char *name, UwacReturnCode *err);
|
||||
UWAC_API UwacDisplay* UwacOpenDisplay(const char* name, UwacReturnCode* err);
|
||||
|
||||
/**
|
||||
* closes the corresponding UwacDisplay
|
||||
@@ -269,7 +302,7 @@ UWAC_API UwacDisplay *UwacOpenDisplay(const char *name, UwacReturnCode *err);
|
||||
* @param pdisplay a pointer on the display to close
|
||||
* @return UWAC_SUCCESS if the operation was successful, the corresponding error otherwise
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacCloseDisplay(UwacDisplay **pdisplay);
|
||||
UWAC_API UwacReturnCode UwacCloseDisplay(UwacDisplay** pdisplay);
|
||||
|
||||
/**
|
||||
* Returns the file descriptor associated with the UwacDisplay, this is useful when
|
||||
@@ -278,7 +311,7 @@ UWAC_API UwacReturnCode UwacCloseDisplay(UwacDisplay **pdisplay);
|
||||
* @param display an opened UwacDisplay
|
||||
* @return the corresponding descriptor
|
||||
*/
|
||||
UWAC_API int UwacDisplayGetFd(UwacDisplay *display);
|
||||
UWAC_API int UwacDisplayGetFd(UwacDisplay* display);
|
||||
|
||||
/**
|
||||
* Returns a human readable form of a Uwac error code
|
||||
@@ -286,7 +319,7 @@ UWAC_API int UwacDisplayGetFd(UwacDisplay *display);
|
||||
* @param error the error number
|
||||
* @return the associated string
|
||||
*/
|
||||
UWAC_API const char *UwacErrorString(UwacReturnCode error);
|
||||
UWAC_API const char* UwacErrorString(UwacReturnCode error);
|
||||
|
||||
/**
|
||||
* returns the last error that occurred on a display
|
||||
@@ -294,7 +327,7 @@ UWAC_API const char *UwacErrorString(UwacReturnCode error);
|
||||
* @param display the display
|
||||
* @return the last error that have been set for this display
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacDisplayGetLastError(const UwacDisplay *display);
|
||||
UWAC_API UwacReturnCode UwacDisplayGetLastError(const UwacDisplay* display);
|
||||
|
||||
/**
|
||||
* retrieves the version of a given interface
|
||||
@@ -304,7 +337,8 @@ UWAC_API UwacReturnCode UwacDisplayGetLastError(const UwacDisplay *display);
|
||||
* @param version the output variable for the version
|
||||
* @return UWAC_SUCCESS if the interface was found, UWAC_NOT_FOUND otherwise
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacDisplayQueryInterfaceVersion(const UwacDisplay *display, const char *name, uint32_t *version);
|
||||
UWAC_API UwacReturnCode UwacDisplayQueryInterfaceVersion(const UwacDisplay* display,
|
||||
const char* name, uint32_t* version);
|
||||
|
||||
/**
|
||||
* returns the number SHM formats that have been reported by the compositor
|
||||
@@ -312,7 +346,7 @@ UWAC_API UwacReturnCode UwacDisplayQueryInterfaceVersion(const UwacDisplay *disp
|
||||
* @param display a connected UwacDisplay
|
||||
* @return the number of SHM formats supported
|
||||
*/
|
||||
UWAC_API uint32_t UwacDisplayQueryGetNbShmFormats(UwacDisplay *display);
|
||||
UWAC_API uint32_t UwacDisplayQueryGetNbShmFormats(UwacDisplay* display);
|
||||
|
||||
/**
|
||||
* returns the supported ShmFormats
|
||||
@@ -323,7 +357,8 @@ UWAC_API uint32_t UwacDisplayQueryGetNbShmFormats(UwacDisplay *display);
|
||||
* @param filled the number of filled entries in the formats array
|
||||
* @return UWAC_SUCCESS on success, an error otherwise
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacDisplayQueryShmFormats(const UwacDisplay *display, enum wl_shm_format *formats, int formats_size, int *filled);
|
||||
UWAC_API UwacReturnCode UwacDisplayQueryShmFormats(const UwacDisplay* display,
|
||||
enum wl_shm_format* formats, int formats_size, int* filled);
|
||||
|
||||
/**
|
||||
* returns the number of registered outputs
|
||||
@@ -331,7 +366,7 @@ UWAC_API UwacReturnCode UwacDisplayQueryShmFormats(const UwacDisplay *display, e
|
||||
* @param display the display to query
|
||||
* @return the number of outputs
|
||||
*/
|
||||
UWAC_API uint32_t UwacDisplayGetNbOutputs(UwacDisplay *display);
|
||||
UWAC_API uint32_t UwacDisplayGetNbOutputs(UwacDisplay* display);
|
||||
|
||||
/**
|
||||
* retrieve a particular UwacOutput object
|
||||
@@ -340,7 +375,7 @@ UWAC_API uint32_t UwacDisplayGetNbOutputs(UwacDisplay *display);
|
||||
* @param index index of the output
|
||||
* @return the given UwacOutput, NULL if something failed (so you should query UwacDisplayGetLastError() to have the reason)
|
||||
*/
|
||||
UWAC_API UwacOutput *UwacDisplayGetOutput(UwacDisplay *display, int index);
|
||||
UWAC_API UwacOutput* UwacDisplayGetOutput(UwacDisplay* display, int index);
|
||||
|
||||
/**
|
||||
* retrieve the resolution of a given UwacOutput
|
||||
@@ -349,7 +384,7 @@ UWAC_API UwacOutput *UwacDisplayGetOutput(UwacDisplay *display, int index);
|
||||
* @param resolution a pointer on the
|
||||
* @return UWAC_SUCCESS on success
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacOutputGetResolution(UwacOutput *output, UwacSize *resolution);
|
||||
UWAC_API UwacReturnCode UwacOutputGetResolution(UwacOutput* output, UwacSize* resolution);
|
||||
|
||||
|
||||
/**
|
||||
@@ -361,7 +396,8 @@ UWAC_API UwacReturnCode UwacOutputGetResolution(UwacOutput *output, UwacSize *re
|
||||
* @param format format to use for the SHM surface
|
||||
* @return the created UwacWindow, NULL if something failed (use UwacDisplayGetLastError() to know more about this)
|
||||
*/
|
||||
UWAC_API UwacWindow *UwacCreateWindowShm(UwacDisplay *display, uint32_t width, uint32_t height, enum wl_shm_format format);
|
||||
UWAC_API UwacWindow* UwacCreateWindowShm(UwacDisplay* display, uint32_t width, uint32_t height,
|
||||
enum wl_shm_format format);
|
||||
|
||||
/**
|
||||
* destroys the corresponding UwacWindow
|
||||
@@ -369,7 +405,7 @@ UWAC_API UwacWindow *UwacCreateWindowShm(UwacDisplay *display, uint32_t width, u
|
||||
* @param window a pointer on the UwacWindow to destroy
|
||||
* @return if the operation completed successfully
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacDestroyWindow(UwacWindow **window);
|
||||
UWAC_API UwacReturnCode UwacDestroyWindow(UwacWindow** window);
|
||||
|
||||
/**
|
||||
* Sets the region that should be considered opaque to the compositor.
|
||||
@@ -381,7 +417,8 @@ UWAC_API UwacReturnCode UwacDestroyWindow(UwacWindow **window);
|
||||
* @param height
|
||||
* @return UWAC_SUCCESS on success, an error otherwise
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacWindowSetOpaqueRegion(UwacWindow *window, uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||
UWAC_API UwacReturnCode UwacWindowSetOpaqueRegion(UwacWindow* window, uint32_t x, uint32_t y,
|
||||
uint32_t width, uint32_t height);
|
||||
|
||||
/**
|
||||
* Sets the region of the window that can trigger input events
|
||||
@@ -393,14 +430,15 @@ UWAC_API UwacReturnCode UwacWindowSetOpaqueRegion(UwacWindow *window, uint32_t x
|
||||
* @param height
|
||||
* @return
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacWindowSetInputRegion(UwacWindow *window, uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||
UWAC_API UwacReturnCode UwacWindowSetInputRegion(UwacWindow* window, uint32_t x, uint32_t y,
|
||||
uint32_t width, uint32_t height);
|
||||
|
||||
/**
|
||||
* retrieves a pointer on the current window content to draw a frame
|
||||
* @param window the UwacWindow
|
||||
* @return a pointer on the current window content
|
||||
*/
|
||||
UWAC_API void *UwacWindowGetDrawingBuffer(UwacWindow *window);
|
||||
UWAC_API void* UwacWindowGetDrawingBuffer(UwacWindow* window);
|
||||
|
||||
/**
|
||||
* sets a rectangle as dirty for the next frame of a window
|
||||
@@ -412,7 +450,8 @@ UWAC_API void *UwacWindowGetDrawingBuffer(UwacWindow *window);
|
||||
* @param height the height of the dirty rectangle
|
||||
* @return UWAC_SUCCESS on success, an Uwac error otherwise
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacWindowAddDamage(UwacWindow *window, uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||
UWAC_API UwacReturnCode UwacWindowAddDamage(UwacWindow* window, uint32_t x, uint32_t y,
|
||||
uint32_t width, uint32_t height);
|
||||
|
||||
/**
|
||||
* Sends a frame to the compositor with the content of the drawing buffer
|
||||
@@ -421,7 +460,7 @@ UWAC_API UwacReturnCode UwacWindowAddDamage(UwacWindow *window, uint32_t x, uint
|
||||
* @param copyContentForNextFrame if true the content to display is copied in the next drawing buffer
|
||||
* @return UWAC_SUCCESS if the operation was successful
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacWindowSubmitBuffer(UwacWindow *window, bool copyContentForNextFrame);
|
||||
UWAC_API UwacReturnCode UwacWindowSubmitBuffer(UwacWindow* window, bool copyContentForNextFrame);
|
||||
|
||||
/**
|
||||
* returns the geometry of the given UwacWindows
|
||||
@@ -430,7 +469,7 @@ UWAC_API UwacReturnCode UwacWindowSubmitBuffer(UwacWindow *window, bool copyCont
|
||||
* @param geometry the geometry to fill
|
||||
* @return UWAC_SUCCESS on success, an Uwac error otherwise
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacWindowGetGeometry(UwacWindow *window, UwacSize *geometry);
|
||||
UWAC_API UwacReturnCode UwacWindowGetGeometry(UwacWindow* window, UwacSize* geometry);
|
||||
|
||||
/**
|
||||
* Sets or unset the fact that the window is set fullscreen. After this call the
|
||||
@@ -442,7 +481,8 @@ UWAC_API UwacReturnCode UwacWindowGetGeometry(UwacWindow *window, UwacSize *geom
|
||||
* @param isFullscreen set or unset fullscreen
|
||||
* @return UWAC_SUCCESS if the operation was a success
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacWindowSetFullscreenState(UwacWindow *window, UwacOutput *output, bool isFullscreen);
|
||||
UWAC_API UwacReturnCode UwacWindowSetFullscreenState(UwacWindow* window, UwacOutput* output,
|
||||
bool isFullscreen);
|
||||
|
||||
/**
|
||||
* When possible (depending on the shell) sets the title of the UwacWindow
|
||||
@@ -450,7 +490,7 @@ UWAC_API UwacReturnCode UwacWindowSetFullscreenState(UwacWindow *window, UwacOut
|
||||
* @param window the UwacWindow
|
||||
* @param name title
|
||||
*/
|
||||
UWAC_API void UwacWindowSetTitle(UwacWindow *window, const char *name);
|
||||
UWAC_API void UwacWindowSetTitle(UwacWindow* window, const char* name);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -458,7 +498,7 @@ UWAC_API void UwacWindowSetTitle(UwacWindow *window, const char *name);
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
UWAC_API int UwacDisplayDispatch(UwacDisplay *display, int timeout);
|
||||
UWAC_API int UwacDisplayDispatch(UwacDisplay* display, int timeout);
|
||||
|
||||
/**
|
||||
* Returns if you have some pending events, and you can UwacNextEvent() without blocking
|
||||
@@ -466,7 +506,7 @@ UWAC_API int UwacDisplayDispatch(UwacDisplay *display, int timeout);
|
||||
* @param display the UwacDisplay
|
||||
* @return if there's some pending events
|
||||
*/
|
||||
UWAC_API bool UwacHasEvent(UwacDisplay *display);
|
||||
UWAC_API bool UwacHasEvent(UwacDisplay* display);
|
||||
|
||||
/** Waits until an event occurs, and when it's there copy the event from the queue to
|
||||
* event.
|
||||
@@ -475,8 +515,7 @@ UWAC_API bool UwacHasEvent(UwacDisplay *display);
|
||||
* @param event the event to fill
|
||||
* @return if the operation completed successfully
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacNextEvent(UwacDisplay *display, UwacEvent *event);
|
||||
|
||||
UWAC_API UwacReturnCode UwacNextEvent(UwacDisplay* display, UwacEvent* event);
|
||||
|
||||
/**
|
||||
* returns the name of the given UwacSeat
|
||||
@@ -484,7 +523,7 @@ UWAC_API UwacReturnCode UwacNextEvent(UwacDisplay *display, UwacEvent *event);
|
||||
* @param seat the UwacSeat
|
||||
* @return the name of the seat
|
||||
*/
|
||||
UWAC_API const char *UwacSeatGetName(const UwacSeat *seat);
|
||||
UWAC_API const char* UwacSeatGetName(const UwacSeat* seat);
|
||||
|
||||
/**
|
||||
* returns the id of the given UwacSeat
|
||||
@@ -492,7 +531,18 @@ UWAC_API const char *UwacSeatGetName(const UwacSeat *seat);
|
||||
* @param seat the UwacSeat
|
||||
* @return the id of the seat
|
||||
*/
|
||||
UWAC_API UwacSeatId UwacSeatGetId(const UwacSeat *seat);
|
||||
UWAC_API UwacSeatId UwacSeatGetId(const UwacSeat* seat);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UWAC_API UwacReturnCode UwacClipboardOfferDestroy(UwacSeat* seat);
|
||||
UWAC_API UwacReturnCode UwacClipboardOfferCreate(UwacSeat* seat, const char* mime);
|
||||
UWAC_API UwacReturnCode UwacClipboardOfferAnnounce(UwacSeat* seat,
|
||||
void* context,
|
||||
UwacDataTransferHandler transfer,
|
||||
UwacCancelDataTransferHandler cancel);
|
||||
UWAC_API void* UwacClipboardDataGet(UwacSeat* seat, const char* mime, size_t* size);
|
||||
|
||||
/**
|
||||
* Inhibits or restores keyboard shortcuts.
|
||||
|
||||
@@ -58,6 +58,7 @@ set(${MODULE_PREFIX}_SRCS
|
||||
${GENERATED_SOURCES}
|
||||
uwac-display.c
|
||||
uwac-input.c
|
||||
uwac-clipboard.c
|
||||
uwac-os.c
|
||||
uwac-os.h
|
||||
uwac-output.c
|
||||
|
||||
288
uwac/libuwac/uwac-clipboard.c
Normal file
288
uwac/libuwac/uwac-clipboard.c
Normal file
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Copyright © 2018 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright © 2018 Thincast Technologies GmbH
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "uwac-priv.h"
|
||||
#include "uwac-utils.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
/* paste */
|
||||
static void data_offer_offer(void* data, struct wl_data_offer* data_offer,
|
||||
const char* offered_mime_type)
|
||||
{
|
||||
UwacSeat* seat = (UwacSeat*)data;
|
||||
|
||||
if (seat && !seat->ignore_announcement)
|
||||
{
|
||||
UwacClipboardEvent* event = (UwacClipboardEvent*)UwacDisplayNewEvent(seat->display,
|
||||
UWAC_EVENT_CLIPBOARD_OFFER);
|
||||
|
||||
if (!event)
|
||||
{
|
||||
assert(uwacErrorHandler(seat->display, UWAC_ERROR_INTERNAL,
|
||||
"failed to allocate a close event\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
event->seat = seat;
|
||||
sprintf_s(event->mime, sizeof(event->mime), "%s", offered_mime_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_data_offer_listener data_offer_listener =
|
||||
{
|
||||
.offer = data_offer_offer
|
||||
};
|
||||
|
||||
static void data_device_data_offer(void* data, struct wl_data_device* data_device,
|
||||
struct wl_data_offer* data_offer)
|
||||
{
|
||||
UwacSeat* seat = (UwacSeat*)data;
|
||||
|
||||
if (seat && !seat->ignore_announcement)
|
||||
{
|
||||
UwacClipboardEvent* event = (UwacClipboardEvent*)UwacDisplayNewEvent(seat->display,
|
||||
UWAC_EVENT_CLIPBOARD_SELECT);
|
||||
|
||||
if (!event)
|
||||
{
|
||||
assert(uwacErrorHandler(seat->display, UWAC_ERROR_INTERNAL,
|
||||
"failed to allocate a close event\n"));
|
||||
}
|
||||
else
|
||||
event->seat = seat;
|
||||
|
||||
wl_data_offer_add_listener(data_offer, &data_offer_listener, data);
|
||||
seat->offer = data_offer;
|
||||
}
|
||||
else if (seat)
|
||||
seat->offer = NULL;
|
||||
}
|
||||
|
||||
static void data_device_selection(void* data, struct wl_data_device* data_device,
|
||||
struct wl_data_offer* data_offer)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_data_device_listener data_device_listener =
|
||||
{
|
||||
.data_offer = data_device_data_offer,
|
||||
.selection = data_device_selection
|
||||
};
|
||||
|
||||
/* copy */
|
||||
static void data_source_target_handler(void* data, struct wl_data_source* data_source,
|
||||
const char* mime_type)
|
||||
{
|
||||
}
|
||||
|
||||
static void data_source_send_handler(void* data, struct wl_data_source* data_source,
|
||||
const char* mime_type, int fd)
|
||||
{
|
||||
UwacSeat* seat = (UwacSeat*)data;
|
||||
seat->transfer_data(seat, seat->data_context, mime_type, fd);
|
||||
}
|
||||
|
||||
static void data_source_cancelled_handler(void* data, struct wl_data_source* data_source)
|
||||
{
|
||||
UwacSeat* seat = (UwacSeat*)data;
|
||||
seat->cancel_data(seat, seat->data_context);
|
||||
}
|
||||
|
||||
static const struct wl_data_source_listener data_source_listener =
|
||||
{
|
||||
.target = data_source_target_handler,
|
||||
.send = data_source_send_handler,
|
||||
.cancelled = data_source_cancelled_handler
|
||||
};
|
||||
|
||||
static UwacReturnCode UwacRegisterDeviceListener(UwacSeat* s)
|
||||
{
|
||||
if (!s)
|
||||
return UWAC_ERROR_INTERNAL;
|
||||
|
||||
wl_data_device_add_listener(s->data_device, &data_device_listener, s);
|
||||
return UWAC_SUCCESS;
|
||||
}
|
||||
|
||||
UwacReturnCode UwacCreateDataSource(UwacSeat* s)
|
||||
{
|
||||
if (!s)
|
||||
return UWAC_ERROR_INTERNAL;
|
||||
|
||||
s->data_source = wl_data_device_manager_create_data_source(s->display->data_device_manager);
|
||||
wl_data_source_add_listener(s->data_source, &data_source_listener, s);
|
||||
return UWAC_SUCCESS;
|
||||
}
|
||||
|
||||
UwacReturnCode UwacSeatRegisterClipboard(UwacSeat* s)
|
||||
{
|
||||
UwacReturnCode rc;
|
||||
UwacClipboardEvent* event;
|
||||
|
||||
if (!s)
|
||||
return UWAC_ERROR_INTERNAL;
|
||||
|
||||
rc = UwacRegisterDeviceListener(s);
|
||||
|
||||
if (rc != UWAC_SUCCESS)
|
||||
return rc;
|
||||
|
||||
rc = UwacCreateDataSource(s);
|
||||
|
||||
if (rc != UWAC_SUCCESS)
|
||||
return rc;
|
||||
|
||||
event = (UwacClipboardEvent*)UwacDisplayNewEvent(s->display, UWAC_EVENT_CLIPBOARD_AVAILABLE);
|
||||
|
||||
if (!event)
|
||||
{
|
||||
assert(uwacErrorHandler(s->display, UWAC_ERROR_INTERNAL,
|
||||
"failed to allocate a close event\n"));
|
||||
return UWAC_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
event->seat = s;
|
||||
}
|
||||
|
||||
UwacReturnCode UwacClipboardOfferDestroy(UwacSeat* seat)
|
||||
{
|
||||
if (!seat)
|
||||
return UWAC_ERROR_INTERNAL;
|
||||
|
||||
if (seat->data_source)
|
||||
wl_data_source_destroy(seat->data_source);
|
||||
|
||||
return UwacCreateDataSource(seat);
|
||||
}
|
||||
|
||||
UwacReturnCode UwacClipboardOfferCreate(UwacSeat* seat, const char* mime)
|
||||
{
|
||||
if (!seat || !mime)
|
||||
return UWAC_ERROR_INTERNAL;
|
||||
|
||||
wl_data_source_offer(seat->data_source, mime);
|
||||
return UWAC_SUCCESS;
|
||||
}
|
||||
|
||||
static void callback_done(void* data, struct wl_callback* callback, uint32_t serial)
|
||||
{
|
||||
*(uint32_t*)data = serial;
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener callback_listener =
|
||||
{
|
||||
.done = callback_done
|
||||
};
|
||||
|
||||
uint32_t get_serial(UwacSeat* s)
|
||||
{
|
||||
struct wl_callback* callback;
|
||||
uint32_t serial = 0;
|
||||
callback = wl_display_sync(s->display->display);
|
||||
wl_callback_add_listener(callback, &callback_listener, &serial);
|
||||
|
||||
while (serial == 0)
|
||||
{
|
||||
wl_display_dispatch(s->display->display);
|
||||
}
|
||||
|
||||
return serial;
|
||||
}
|
||||
|
||||
UwacReturnCode UwacClipboardOfferAnnounce(UwacSeat* seat,
|
||||
void* context,
|
||||
UwacDataTransferHandler transfer,
|
||||
UwacCancelDataTransferHandler cancel)
|
||||
{
|
||||
if (!seat)
|
||||
return UWAC_ERROR_INTERNAL;
|
||||
|
||||
seat->data_context = context;
|
||||
seat->transfer_data = transfer;
|
||||
seat->cancel_data = cancel;
|
||||
seat->ignore_announcement = true;
|
||||
wl_data_device_set_selection(seat->data_device, seat->data_source, get_serial(seat));
|
||||
wl_display_roundtrip(seat->display->display);
|
||||
seat->ignore_announcement = false;
|
||||
return UWAC_SUCCESS;
|
||||
}
|
||||
|
||||
void* UwacClipboardDataGet(UwacSeat* seat, const char* mime, size_t* size)
|
||||
{
|
||||
ssize_t r = 0;
|
||||
size_t alloc = 0;
|
||||
size_t pos = 0;
|
||||
char* data = NULL;
|
||||
int pipefd[2];
|
||||
|
||||
if (!seat || !mime || !size || !seat->offer)
|
||||
return NULL;
|
||||
|
||||
if (pipe(pipefd) != 0)
|
||||
return NULL;
|
||||
|
||||
wl_data_offer_receive(seat->offer, mime, pipefd[1]);
|
||||
close(pipefd[1]);
|
||||
wl_display_roundtrip(seat->display->display);
|
||||
wl_display_flush(seat->display->display);
|
||||
|
||||
do
|
||||
{
|
||||
void* tmp;
|
||||
alloc += 1024;
|
||||
tmp = realloc(data, alloc);
|
||||
if (!tmp)
|
||||
{
|
||||
free(data);
|
||||
close(pipefd[0]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = tmp;
|
||||
r = read(pipefd[0], &data[pos], alloc - pos);
|
||||
if (r > 0)
|
||||
pos += r;
|
||||
if (r < 0)
|
||||
{
|
||||
free(data);
|
||||
close(pipefd[0]);
|
||||
return NULL;
|
||||
}
|
||||
} while(r > 0);
|
||||
|
||||
close(pipefd[0]);
|
||||
close(pipefd[1]);
|
||||
|
||||
*size = pos + 1;
|
||||
return data;
|
||||
}
|
||||
@@ -191,6 +191,7 @@ static void registry_handle_global(void* data, struct wl_registry* registry, uin
|
||||
return;
|
||||
}
|
||||
|
||||
UwacSeatRegisterClipboard(seat);
|
||||
ev = (UwacSeatNewEvent*)UwacDisplayNewEvent(d, UWAC_EVENT_NEW_SEAT);
|
||||
|
||||
if (!ev)
|
||||
@@ -276,7 +277,6 @@ static void registry_handle_global_remove(void* data, struct wl_registry* regist
|
||||
if (strcmp(global->interface, "wl_seat") == 0)
|
||||
{
|
||||
UwacSeatRemovedEvent* ev;
|
||||
|
||||
display_destroy_seat(d, name);
|
||||
ev = (UwacSeatRemovedEvent*)UwacDisplayNewEvent(d, UWAC_EVENT_REMOVED_SEAT);
|
||||
|
||||
@@ -727,7 +727,6 @@ bool UwacHasEvent(UwacDisplay* display)
|
||||
return display->pop_queue != NULL;
|
||||
}
|
||||
|
||||
|
||||
UwacReturnCode UwacNextEvent(UwacDisplay* display, UwacEvent* event)
|
||||
{
|
||||
UwacEventListItem* prevItem;
|
||||
|
||||
@@ -807,6 +807,7 @@ UwacSeat *UwacSeatNew(UwacDisplay *d, uint32_t id, uint32_t version) {
|
||||
goto error_watch_timerfd;
|
||||
}
|
||||
|
||||
ret->data_device = wl_data_device_manager_get_data_device(d->data_device_manager, ret->seat);
|
||||
wl_list_insert(d->seats.prev, &ret->link);
|
||||
return ret;
|
||||
|
||||
@@ -864,6 +865,12 @@ void UwacSeatDestroy(UwacSeat *s) {
|
||||
wl_keyboard_destroy(s->keyboard);
|
||||
}
|
||||
|
||||
if (s->data_device)
|
||||
wl_data_device_destroy(s->data_device);
|
||||
|
||||
if (s->data_source)
|
||||
wl_data_source_destroy(s->data_source);
|
||||
|
||||
wl_list_remove(&s->link);
|
||||
free(s);
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ struct uwac_display {
|
||||
struct wl_shell *shell;
|
||||
struct xdg_toplevel *xdg_toplevel;
|
||||
struct xdg_wm_base *xdg_base;
|
||||
struct wl_data_device_manager* devicemanager;
|
||||
struct zwp_keyboard_shortcuts_inhibit_manager_v1 *keyboard_inhibit_manager;
|
||||
struct zxdg_decoration_manager_v1 *deco_manager;
|
||||
struct org_kde_kwin_server_decoration_manager *kde_deco_manager;
|
||||
@@ -154,9 +155,12 @@ struct uwac_seat {
|
||||
struct wl_seat *seat;
|
||||
uint32_t seat_id;
|
||||
uint32_t seat_version;
|
||||
struct wl_data_device* data_device;
|
||||
struct wl_data_source* data_source;
|
||||
struct wl_pointer *pointer;
|
||||
struct wl_keyboard *keyboard;
|
||||
struct wl_touch *touch;
|
||||
struct wl_data_offer* offer;
|
||||
struct xkb_context *xkb_context;
|
||||
struct zwp_keyboard_shortcuts_inhibitor_v1 *keyboard_inhibitor;
|
||||
|
||||
@@ -185,6 +189,11 @@ struct uwac_seat {
|
||||
UwacTask repeat_task;
|
||||
float sx, sy;
|
||||
struct wl_list link;
|
||||
|
||||
void* data_context;
|
||||
UwacDataTransferHandler transfer_data;
|
||||
UwacCancelDataTransferHandler cancel_data;
|
||||
bool ignore_announcement;
|
||||
};
|
||||
|
||||
|
||||
@@ -246,4 +255,6 @@ void UwacSeatDestroy(UwacSeat *s);
|
||||
UwacOutput *UwacCreateOutput(UwacDisplay *d, uint32_t id, uint32_t version);
|
||||
int UwacDestroyOutput(UwacOutput *output);
|
||||
|
||||
UwacReturnCode UwacSeatRegisterClipboard(UwacSeat* s);
|
||||
|
||||
#endif /* UWAC_PRIV_H_ */
|
||||
|
||||
Reference in New Issue
Block a user