f722fb461fe9d5ee66f0508540fef2e054d735b1
[platform/upstream/efl.git] / src / lib / ecore_x / xcb / ecore_xcb_present.c
1 #include "ecore_xcb_private.h"
2 # ifdef ECORE_XCB_XPRESENT
3 #  include <xcb/present.h>
4 # endif
5
6 /* local variables */
7 static Eina_Bool _xpresent_avail = EINA_FALSE;
8
9 /* external variables */
10 int _ecore_xcb_event_xpresent = -1;
11
12 void
13 _ecore_xcb_xpresent_init(void)
14 {
15    LOGFN(__FILE__, __LINE__, __FUNCTION__);
16
17 #ifdef ECORE_XCB_XPRESENT
18    xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_present_id);
19 #endif
20 }
21
22 void
23 _ecore_xcb_xpresent_finalize(void)
24 {
25 #ifdef ECORE_XCB_XPRESENT
26    const xcb_query_extension_reply_t *ext_reply;
27 #endif
28
29    LOGFN(__FILE__, __LINE__, __FUNCTION__);
30
31 #ifdef ECORE_XCB_XPRESENT
32    ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_present_id);
33    if ((ext_reply) && (ext_reply->present))
34      {
35         xcb_present_query_version_cookie_t cookie;
36         xcb_present_query_version_reply_t *reply;
37
38         cookie =
39           xcb_present_query_version_unchecked(_ecore_xcb_conn,
40                                              XCB_PRESENT_MAJOR_VERSION,
41                                              XCB_PRESENT_MINOR_VERSION);
42         reply = xcb_present_query_version_reply(_ecore_xcb_conn, cookie, NULL);
43         if (reply)
44           {
45                 _xpresent_avail = EINA_TRUE;
46                 free(reply);
47           }
48
49         if (_xpresent_avail)
50           _ecore_xcb_event_xpresent = ext_reply->first_event;
51      }
52 #endif
53 }
54
55 #ifdef ECORE_XCB_XPRESENT
56 #define SET(X) e->X = ev->X
57
58 static void
59 _present_configure(xcb_present_configure_notify_event_t *ev)
60 {
61    Ecore_X_Event_Present_Configure *e;
62
63    e = calloc(1, sizeof(Ecore_X_Event_Present_Configure));
64    if (!e) return;
65
66    e->win = ev->window;
67    SET(x), SET(y);
68    SET(width), SET(height);
69    SET(off_x), SET(off_y);
70    SET(pixmap_width), SET(pixmap_height);
71    SET(pixmap_flags);
72
73    ecore_event_add(ECORE_X_EVENT_PRESENT_CONFIGURE, e, NULL, NULL);
74 }
75
76 static void
77 _present_complete(xcb_present_complete_notify_event_t *ev)
78 {
79    unsigned int mode[] =
80    {
81     [XCB_PRESENT_COMPLETE_MODE_COPY] = ECORE_X_PRESENT_COMPLETE_MODE_COPY,
82     [XCB_PRESENT_COMPLETE_MODE_FLIP] = ECORE_X_PRESENT_COMPLETE_MODE_FLIP,
83     [XCB_PRESENT_COMPLETE_MODE_SKIP] = ECORE_X_PRESENT_COMPLETE_MODE_SKIP,
84    };
85    Ecore_X_Event_Present_Complete *e;
86
87    e = calloc(1, sizeof(Ecore_X_Event_Present_Complete));
88    if (!e) return;
89
90    e->win = ev->window;
91    SET(serial);
92    SET(ust), SET(msc);
93    e->kind = (ev->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC);
94    e->mode = mode[ev->mode];
95    ecore_event_add(ECORE_X_EVENT_PRESENT_COMPLETE, e, NULL, NULL);
96 }
97
98 static void
99 _present_idle(xcb_present_idle_notify_event_t *ev)
100 {
101    Ecore_X_Event_Present_Idle *e;
102
103    e = calloc(1, sizeof(Ecore_X_Event_Present_Idle));
104    if (!e) return;
105
106    e->win = ev->window;
107    SET(serial);
108    SET(pixmap);
109    SET(idle_fence);
110    ecore_event_add(ECORE_X_EVENT_PRESENT_IDLE, e, NULL, NULL);
111 }
112 #undef SET
113
114 void
115 _ecore_xcb_event_handle_present_event(xcb_ge_event_t *ev)
116 {
117    switch (ev->event_type)
118      {
119       case XCB_PRESENT_EVENT_CONFIGURE_NOTIFY:
120         _present_configure((xcb_present_configure_notify_event_t*)(long)ev->pad1);
121         break;
122       case XCB_PRESENT_EVENT_COMPLETE_NOTIFY:
123         _present_complete((xcb_present_complete_notify_event_t*)(long)ev->pad1);
124         break;
125       case XCB_PRESENT_EVENT_IDLE_NOTIFY:
126         _present_idle((xcb_present_idle_notify_event_t*)(long)ev->pad1);
127         break;
128       default: break;
129      }
130 }
131 #endif
132
133
134 EAPI void
135 ecore_x_present_select_events(Ecore_X_Window win, unsigned int events)
136 {
137    LOGFN(__FILE__, __LINE__, __FUNCTION__);
138 #ifdef ECORE_XCB_XPRESENT
139    CHECK_XCB_CONN;
140    xcb_present_select_input(_ecore_xcb_conn, _ecore_xcb_event_xpresent, win, events);
141 #else
142    (void)win;
143    (void)events;
144 #endif
145 }
146
147 EAPI void
148 ecore_x_present_notify_msc(Ecore_X_Window win, unsigned int serial, unsigned long long target_msc, unsigned long long divisor, unsigned long long remainder)
149 {
150    LOGFN(__FILE__, __LINE__, __FUNCTION__);
151 #ifdef ECORE_XCB_XPRESENT
152    CHECK_XCB_CONN;
153    xcb_present_notify_msc(_ecore_xcb_conn, win, serial, target_msc, divisor, remainder);
154 #else
155    (void)win;
156    (void)serial;
157    (void)target_msc;
158    (void)divisor;
159    (void)remainder;
160 #endif
161 }
162
163 EAPI void
164 ecore_x_present_pixmap(Ecore_X_Window win, Ecore_X_Pixmap pixmap, unsigned int serial, Ecore_X_Region valid,
165                        Ecore_X_Region update, int x_off, int y_off, Ecore_X_Randr_Crtc target_crtc,
166                        Ecore_X_Sync_Fence wait_fence, Ecore_X_Sync_Fence idle_fence, unsigned int options,
167                        unsigned long long target_msc, unsigned long long divisor, unsigned long long remainder,
168                        Ecore_X_Present *notifies, int num_notifies)
169 {
170    LOGFN(__FILE__, __LINE__, __FUNCTION__);
171 #ifdef ECORE_XCB_XPRESENT
172    CHECK_XCB_CONN;
173    xcb_present_pixmap(_ecore_xcb_conn, win, pixmap, serial, valid, update,
174                   x_off, y_off, target_crtc, wait_fence, idle_fence, options, target_msc,
175                   divisor, remainder, num_notifies, (xcb_present_notify_t*)notifies);
176 #else
177    (void)win;
178    (void)pixmap;
179    (void)serial;
180    (void)valid;
181    (void)update;
182    (void)x_off;
183    (void)y_off;
184    (void)target_crtc;
185    (void)wait_fence;
186    (void)idle_fence;
187    (void)options;
188    (void)target_msc;
189    (void)divisor;
190    (void)remainder;
191    (void)notifies;
192    (void)num_notifies;
193 #endif
194 }
195
196 EAPI Eina_Bool
197 ecore_x_present_exists(void)
198 {
199    return _xpresent_avail;
200 }