File: X11Display.h

package info (click to toggle)
lsp-plugins 1.2.5-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 91,856 kB
  • sloc: cpp: 427,831; xml: 57,779; makefile: 9,961; php: 1,005; sh: 18
file content (387 lines) | stat: -rw-r--r-- 18,261 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
/*
 * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
 *           (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
 *
 * This file is part of lsp-ws-lib
 * Created on: 10 окт. 2016 г.
 *
 * lsp-ws-lib is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * lsp-ws-lib 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with lsp-ws-lib. If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef UI_X11_X11DISPLAY_H_
#define UI_X11_X11DISPLAY_H_

#include <lsp-plug.in/ws/version.h>

#ifdef USE_LIBX11

#include <lsp-plug.in/common/atomic.h>
#include <lsp-plug.in/common/status.h>
#include <lsp-plug.in/lltl/parray.h>
#include <lsp-plug.in/lltl/darray.h>
#include <lsp-plug.in/lltl/pphash.h>
#include <lsp-plug.in/ws/IDisplay.h>

#include <private/x11/X11Atoms.h>
#include <private/x11/X11Window.h>

#include <time.h>
#include <X11/Xlib.h>

// Freetype headers
#ifdef USE_LIBFREETYPE
    #include <ft2build.h>
    #include FT_SFNT_NAMES_H
    #include FT_FREETYPE_H
    #include FT_GLYPH_H
    #include FT_OUTLINE_H
    #include FT_BBOX_H
    #include FT_TYPE1_TABLES_H
#endif /* USE_LIBFREETYPE */

// Cairo headers
#ifdef USE_LIBCAIRO
    #include <cairo/cairo.h>
#endif /* USE_LIBCAIRO */

namespace lsp
{
    namespace ws
    {
        namespace x11
        {
            class X11Window;

        #ifdef USE_LIBCAIRO
            class X11CairoSurface;
        #endif /* USE_LIBCAIRO */

            class LSP_HIDDEN_MODIFIER X11Display: public IDisplay
            {
                friend class X11Window;

            #ifdef USE_LIBCAIRO
                friend class X11CairoSurface;
            #endif /* USE_LIBCAIRO */

                protected:
                    enum x11_async_types
                    {
                        X11ASYNC_CB_RECV,
                        X11ASYNC_CB_SEND,
                        X11ASYNC_DND_RECV,
                        X11ASYNC_DND_PROXY
                    };

                    enum x11_cb_recv_states
                    {
                        CB_RECV_CTYPE,
                        CB_RECV_SIMPLE,
                        CB_RECV_INCR
                    };

                    enum x11_dnd_recv_states
                    {
                        DND_RECV_PENDING,
                        DND_RECV_POSITION,
                        DND_RECV_ACCEPT,
                        DND_RECV_REJECT,
                        DND_RECV_SIMPLE,
                        DND_RECV_INCR
                    };

                    typedef struct wnd_lock_t
                    {
                        X11Window      *pOwner;
                        X11Window      *pWaiter;
                        ssize_t         nCounter;
                    } wnd_lock_t;

                    struct x11_async_t;

                    typedef struct cb_common_t
                    {
                        bool                bComplete;
                        Atom                hProperty;
                    } cb_common_t;

                    typedef struct cb_recv_t: public cb_common_t
                    {
                        Atom                hSelection;
                        Atom                hType;
                        x11_cb_recv_states  enState;
                        IDataSink          *pSink;
                    } cb_recv_t;

                    typedef struct cb_send_t: public cb_common_t
                    {
                        Atom                hSelection;
                        Atom                hType;
                        Window              hRequestor;
                        IDataSource        *pSource;
                        io::IInStream      *pStream;
                    } cb_send_t;

                    typedef struct dnd_recv_t: public cb_common_t
                    {
                        Window              hTarget;
                        Window              hSource;
                        Atom                hSelection;
                        Atom                hType;
                        x11_dnd_recv_states enState;
                        IDataSink          *pSink;
                        Atom                hAction;
                        Window              hProxy;
                    } dnd_recv_t;

                    typedef struct xtranslate_t
                    {
                        Window              hSrcW;          // Source Window
                        Window              hDstW;          // Destination window
                        bool                bSuccess;       // Success flag
                    } xtranslate_t;

                    typedef struct dnd_proxy_t: public cb_common_t
                    {
                        Window              hTarget;        // The target window which has XDndProxy attribute
                        Window              hSource;        // The source window
                        Window              hCurrent;       // The current window that receives proxy events
                        long                enter[4];       // XDndEnter headers
                    } dnd_proxy_t;

                    typedef struct x11_async_t
                    {
                        x11_async_types     type;
                        status_t            result;
                        union
                        {
                            cb_common_t         cb_common;
                            cb_recv_t           cb_recv;
                            cb_send_t           cb_send;
                            dnd_recv_t          dnd_recv;
                            dnd_proxy_t         dnd_proxy;
                        };
                    } x11_async_t;

                    typedef struct x11_screen_t
                    {
                        size_t              id;
                        size_t              grabs;          // Number of grab owners
                        size_t              width;          // Width of display
                        size_t              height;         // Height of display
                        size_t              mm_width;       // Width of display in mm
                        size_t              mm_height;      // Height of display in mm
                    } x11_screen_t;

                public:
                    typedef struct font_t
                    {
                        char               *name;           // Name of the font
                        char               *alias;          // Font alias (the symbolic name of the font)
                        void               *data;           // Font data (font file contents loaded to memory)
                        ssize_t             refs;           // Number of references
                        FT_Face             ft_face;        // Font face handle for freetype

                    #ifdef USE_LIBCAIRO
                        cairo_font_face_t  *cr_face[4];     // Font faces for cairo
                    #endif /* USE_LIBCAIRO */
                    } font_t;

                private:
                    static volatile atomic_t    hLock;
                    static X11Display          *pHandlers;
                    X11Display                 *pNextHandler;

                    static int                  x11_error_handler(Display *dpy, XErrorEvent *ev);

                protected:
                    volatile bool               bExit;
                    Display                    *pDisplay;
                    Window                      hRootWnd;           // Root window of the display
                    Window                      hClipWnd;           // Unmapped clipboard window
                    X11Window                  *pFocusWindow;       // Focus window after show
                    Atom                        nWakeupMessage;     // Wakeup message type
                    int                         nBlackColor;
                    int                         nWhiteColor;
                    x11_atoms_t                 sAtoms;
                    Cursor                      vCursors[__MP_COUNT];
                    size_t                      nIOBufSize;
                    uint8_t                    *pIOBuf;
                    FT_Library                  hFtLibrary;
                    IDataSource                *pCbOwner[_CBUF_TOTAL];
                #ifdef USE_LIBCAIRO
                    cairo_user_data_key_t       sCairoUserDataKey;
                #endif /* USE_LIBCAIRO */

                    lltl::darray<x11_screen_t>  vScreens;
                    lltl::parray<X11Window>     vWindows;
                    lltl::parray<X11Window>     vGrab[__GRAB_TOTAL];
                    lltl::parray<X11Window>     sTargets;
                    lltl::darray<wnd_lock_t>    sLocks;
                    lltl::darray<x11_async_t>   sAsync;
                    lltl::parray<char>          vDndMimeTypes;
                    lltl::pphash<char, font_t>  vCustomFonts;
                    xtranslate_t                sTranslateReq;

                    lltl::darray<MonitorInfo>   vMonitors;

                    ISurface                   *pEstimation;        // Estimation surface

                protected:
                    void            decode_event(event_t *ue, XEvent *ev);
                    void            handle_event(XEvent *ev);
                    bool            handle_clipboard_event(XEvent *ev);
                    bool            handle_drag_event(XEvent *ev);
                    static void     destroy_font_object(font_t *font);
                    static void     unload_font_object(font_t *font);
                    static font_t  *alloc_font_object(const char *name);

                    status_t        do_main_iteration(timestamp_t ts);
                    void            do_destroy();
                    void            drop_custom_fonts();
                    X11Window      *get_locked(X11Window *wnd);
                    X11Window      *get_redirect(X11Window *wnd);
                    static void     compress_long_data(void *data, size_t nitems);
                    Atom            gen_selection_id();
                    X11Window      *find_window(Window wnd);
                    status_t        bufid_to_atom(size_t bufid, Atom *atom);
                    status_t        atom_to_bufid(Atom x, size_t *bufid);

                    status_t        read_property(Window wnd, Atom property, Atom ptype, uint8_t **data, size_t *size, Atom *type);
                    status_t        decode_mime_types(lltl::parray<char> *ctype, const uint8_t *data, size_t size);
                    void            drop_mime_types(lltl::parray<char> *ctype);
                    static status_t sink_data_source(IDataSink *dst, IDataSource *src);

                    void            handle_property_notify(XPropertyEvent *ev);
                    status_t        handle_property_notify(cb_recv_t *task, XPropertyEvent *ev);
                    status_t        handle_property_notify(cb_send_t *task, XPropertyEvent *ev);
                    status_t        handle_property_notify(dnd_recv_t *task, XPropertyEvent *ev);

                    void            handle_selection_notify(XSelectionEvent *ev);
                    status_t        handle_selection_notify(cb_recv_t *task, XSelectionEvent *ev);
                    status_t        handle_selection_notify(dnd_recv_t *task, XSelectionEvent *ev);

                    void            handle_selection_request(XSelectionRequestEvent *ev);
                    status_t        handle_selection_request(cb_send_t *task, XSelectionRequestEvent *ev);

                    void            handle_selection_clear(XSelectionClearEvent *ev);

                    status_t        handle_drag_enter(XClientMessageEvent *ev);
                    status_t        handle_drag_leave(dnd_recv_t *task, XClientMessageEvent *ev);
                    status_t        handle_drag_position(dnd_recv_t *task, XClientMessageEvent *ev);
                    status_t        handle_drag_drop(dnd_recv_t *task, XClientMessageEvent *ev);
                    void            complete_dnd_transfer(dnd_recv_t *task, bool success);
                    void            reject_dnd_transfer(dnd_recv_t *task);

                    void            send_immediate(Window wnd, Bool propagate, long event_mask, XEvent *event);

                    x11_async_t    *find_dnd_proxy_task(Window wnd);
                    status_t        proxy_drag_leave(dnd_proxy_t *task, XClientMessageEvent *ev);
                    status_t        proxy_drag_position(dnd_proxy_t *task, XClientMessageEvent *ev);
                    status_t        proxy_drag_drop(dnd_proxy_t *task, XClientMessageEvent *ev);

                    x11_async_t    *lookup_dnd_proxy_task();

                    dnd_recv_t     *current_drag_task();
                    void            complete_async_tasks();

                    status_t        init_freetype_library();

                    bool            translate_coordinates(Window src_w, Window dest_w, int src_x, int src_y, int *dest_x, int *dest_y, Window *child_return);

                    static void                 drop_monitors(lltl::darray<MonitorInfo> *list);

                protected:
                    virtual bool                r3d_backend_supported(const r3d::backend_metadata_t *meta) override;
                    virtual void                task_queue_changed() override;

                public:
                    explicit X11Display();
                    virtual ~X11Display();

                    virtual status_t            init(int argc, const char **argv) override;
                    virtual void                destroy() override;

                public:
                    virtual IWindow            *create_window() override;
                    virtual IWindow            *create_window(size_t screen) override;
                    virtual IWindow            *create_window(void *handle) override;
                    virtual IWindow            *wrap_window(void *handle) override;
                    virtual ISurface           *create_surface(size_t width, size_t height) override;

                    virtual status_t            main() override;
                    virtual status_t            main_iteration() override;
                    virtual void                quit_main() override;
                    virtual status_t            wait_events(wssize_t millis) override;

                    virtual size_t              screens() override;
                    virtual size_t              default_screen() override;
                    virtual status_t            screen_size(size_t screen, ssize_t *w, ssize_t *h) override;
                    virtual status_t            work_area_geometry(ws::rectangle_t *r) override;

                    virtual status_t            set_clipboard(size_t id, IDataSource *ds) override;
                    virtual status_t            get_clipboard(size_t id, IDataSink *dst) override;
                    virtual const char * const *get_drag_ctypes() override;

                    virtual status_t            reject_drag() override;
                    virtual status_t            accept_drag(IDataSink *sink, drag_t action, const rectangle_t *r = NULL) override;

                    virtual status_t            get_pointer_location(size_t *screen, ssize_t *left, ssize_t *top) override;

                    virtual status_t            add_font(const char *name, io::IInStream *is) override;
                    virtual status_t            add_font_alias(const char *name, const char *alias) override;
                    virtual status_t            remove_font(const char *name) override;
                    virtual void                remove_all_fonts() override;

                    virtual bool                get_font_parameters(const Font &f, font_parameters_t *fp) override;
                    virtual bool                get_text_parameters(const Font &f, text_parameters_t *tp, const char *text) override;
                    virtual bool                get_text_parameters(const Font &f, text_parameters_t *tp, const LSPString *text, ssize_t first, ssize_t last) override;

                    virtual const MonitorInfo  *enum_monitors(size_t *count) override;

                    virtual void                sync() override;

                public:
                    void                        handle_error(XErrorEvent *ev);

                    bool                        add_window(X11Window *wnd);
                    bool                        remove_window(X11Window *wnd);

                    inline Display             *x11display() const  { return pDisplay; }
                    inline Window               x11root() const     { return hRootWnd; }
                    inline const x11_atoms_t   &atoms() const       { return sAtoms; }
                    Cursor                      get_cursor(mouse_pointer_t pointer);

                    size_t                      get_screen(Window root);

                    status_t                    grab_events(X11Window *wnd, grab_t group);
                    status_t                    ungrab_events(X11Window *wnd);

                    status_t                    lock_events(X11Window *wnd, X11Window *lock);
                    status_t                    unlock_events(X11Window *wnd);

                    font_t                     *get_font(const char *name);

                    void                        flush();

                public:
                    static const char          *event_name(int xev_code);
            };
        } /* namespace x11 */
    } /* namespace ws */
} /* namespace lsp */

#endif /* USE_LIBX11 */

#endif /* UI_X11_X11DISPLAY_H_ */