// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#define _XOPEN_SOURCE 700

#ifndef WAYLANDCLIPBOARDPROTOCOL_H
#define WAYLANDCLIPBOARDPROTOCOL_H

#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>
#include "wayland-wlr-data-control-unstable-v1-client-protocol.h"
#ifdef __cplusplus
extern "C"
{
#endif
/* No source should be offering more than 25 types hopefully */
#define MAX_MIME_TYPES 25

/* We accept max 50MB of data */
#define MAX_DATA_SIZE 52428800
#define MAX_FILE_DATA_SIZE 4294967296

/* Read 64 KiB the capacity of pipes() buffer */
#define READ_SIZE 4096

#define WIRTE_SIZE 4096

/* By default wait 100ms for the client to start writing data
 for images and other types that may take longer we wait a second
 If we succesfully received data we can safetly wait for a while */
#define WAIT_TIME_SHORT 500
#define WAIT_TIME_LONG 2000
#define WAIT_TIME_LONGEST 8000
#define FILIE_PATH 100

// listener
typedef int (*WaylandClipDataChangedListenerPtr)(void *);

typedef enum {
    UNSET_BUFFER,
    SELECTION,
    PRIMARY
} clipboard_buffer;

/* Mime type and where its data is located */
typedef struct {
    char *type;
    char filepath[FILIE_PATH];
    uint16_t pos;
} mime_type;

/* Buffer not managed by us */
typedef struct {
    void *data[MAX_MIME_TYPES];
    mime_type types[MAX_MIME_TYPES];
    uint32_t len[MAX_MIME_TYPES];
    bool invalid_data[MAX_MIME_TYPES];
    uint32_t num_types;
    struct zwlr_data_control_offer_v1 *offer;
    clipboard_buffer buf;
} offer_buffer;

/* Buffer managed by us */
typedef struct {
    void *data[MAX_MIME_TYPES];
    mime_type types[MAX_MIME_TYPES];
    uint32_t len[MAX_MIME_TYPES];
    bool expired;
    uint32_t num_types;
    struct zwlr_data_control_source_v1 *source;
} source_buffer;

typedef struct {
    pthread_mutex_t cond_lock;
    pthread_t dispatch;
    bool lock;
    char *clipDatapath;
    void *xwl;
    bool clearflag;
    source_buffer *selection_s;
    offer_buffer *selection_o;
    struct wl_display *display;
    struct wl_seat *seat;
    struct zwlr_data_control_manager_v1 *cmng;
    struct zwlr_data_control_device_v1 *dmng;
    WaylandClipDataChangedListenerPtr datachange;
} WaylandClipboardProtocol;

WaylandClipboardProtocol *WaylandClip_Init(void);
void WaylandClip_Destroy(WaylandClipboardProtocol *clip);
void WaylandClip_ForkDestroy(WaylandClipboardProtocol *clip);
void WaylandClip_Watch(WaylandClipboardProtocol *clip);
void WaylandClip_Get_Selection(WaylandClipboardProtocol *clip);
void WaylandClip_Set_Selection(WaylandClipboardProtocol *clip);
void WaylandClip_Sync_Buffers(WaylandClipboardProtocol *clip);
void wayland_clip_clear_selection(WaylandClipboardProtocol *clip);
offer_buffer *Offer_Init(void);
void Offer_Clear(offer_buffer *ofr);
void Offer_Destroy(offer_buffer *ofr);
source_buffer *Source_Init(void);
void Source_Clear(source_buffer *src);
void Source_Destroy(source_buffer *src);

void *Xmalloc(size_t size);
void *Xrealloc(void *ptr, size_t size);
char *Xstrdup(const char *s);
#ifdef __cplusplus
}
#endif
#endif // COPYCLIENT_H
