svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_sync.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #include "ecore_xcb_private.h"
6
7
8 /**
9  * @defgroup Ecore_X_Sync_Group X Sync Extension Functions
10  *
11  * Functions related to the X Sync extension.
12  */
13
14
15 #ifdef ECORE_XCB_SYNC
16 static int _sync_available = 0;
17 static xcb_sync_initialize_cookie_t _ecore_xcb_sync_init_cookie;
18 #endif /* ECORE_XCB_SYNC */
19
20
21 /* To avoid round trips, the initialization is separated in 2
22    functions: _ecore_xcb_sync_init and
23    _ecore_xcb_sync_init_finalize. The first one gets the cookies and
24    the second one gets the replies and set the atoms. */
25
26 void
27 _ecore_x_sync_init(const xcb_query_extension_reply_t *reply)
28 {
29 #ifdef ECORE_XCB_SYNC
30    if (reply && (reply->present))
31      _ecore_xcb_sync_init_cookie = xcb_sync_initialize_unchecked(_ecore_xcb_conn,
32                                                                  XCB_SYNC_MAJOR_VERSION,
33                                                                  XCB_SYNC_MINOR_VERSION);
34 #endif /* ECORE_XCB_SYNC */
35 }
36
37 void
38 _ecore_x_sync_init_finalize(void)
39 {
40 #ifdef ECORE_XCB_SYNC
41    xcb_sync_initialize_reply_t *reply;
42
43    reply = xcb_sync_initialize_reply(_ecore_xcb_conn,
44                                      _ecore_xcb_sync_init_cookie, NULL);
45
46    if (reply)
47      {
48        if (reply->major_version >= 3)
49         _sync_available = 1;
50         free(reply);
51      }
52 #endif /* ECORE_XCB_SYNC */
53 }
54
55
56 /**
57  * Return whether the X server supports the Sync Extension.
58  * @return 1 if the X Sync Extension is available, 0 otherwise.
59  *
60  * Return 1 if the X server supports the Sync Extension version 3.0,
61  * 0 otherwise.
62  * @ingroup Ecore_X_Sync_Group
63  */
64 EAPI int
65 ecore_x_sync_query(void)
66 {
67 #ifdef ECORE_XCB_SYNC
68    return _sync_available;
69 #else
70    return 0;
71 #endif /* ECORE_XCB_SYNC */
72 }
73
74
75 /**
76  * Create a new alarm.
77  * @param counter A counter.
78  * @return        A newly created alarm.
79  *
80  * Create a new alarm.
81  * @ingroup Ecore_X_Sync_Group
82  */
83 EAPI Ecore_X_Sync_Alarm
84 ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter)
85 {
86 #ifdef ECORE_XCB_SYNC
87    uint32_t           value_list[6];
88    xcb_sync_int64_t   init;
89    Ecore_X_Sync_Alarm alarm;
90    uint32_t           value_mask;
91
92    init.lo = 0;
93    init.hi = 0;
94    xcb_sync_set_counter(_ecore_xcb_conn, counter, init);
95
96    value_mask =
97      XCB_SYNC_CA_COUNTER | XCB_SYNC_CA_VALUE_TYPE |
98      XCB_SYNC_CA_VALUE   | XCB_SYNC_CA_TEST_TYPE  |
99      XCB_SYNC_CA_DELTA   | XCB_SYNC_CA_EVENTS;
100    value_list[0] = counter;
101    value_list[1] = XCB_SYNC_VALUETYPE_ABSOLUTE;
102    value_list[2] = 1;
103    value_list[3] = XCB_SYNC_TESTTYPE_POSITIVE_COMPARISON;
104    value_list[4] = 1;
105    value_list[5] = 1;
106    alarm = xcb_generate_id(_ecore_xcb_conn);
107    xcb_sync_create_alarm(_ecore_xcb_conn,
108                          alarm,
109                          value_mask,
110                          (const uint32_t *)value_list);
111
112    ecore_x_sync();
113    return alarm;
114 #else
115    return 0;
116 #endif /* ECORE_XCB_SYNC */
117 }
118
119
120 /**
121  * Delete an alarm.
122  * @param alarm The alarm to delete.
123  * @return      1 on success, 0 otherwise.
124  *
125  * Delete the @p alarm. Returns 1 on success, 0 otherwise.
126  * @ingroup Ecore_X_Sync_Group
127  */
128 EAPI int
129 ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm)
130 {
131 #ifdef ECORE_XCB_SYNC
132    xcb_sync_destroy_alarm(_ecore_xcb_conn, alarm);
133    return 1;
134 #else
135    return 0;
136 #endif /* ECORE_XCB_SYNC */
137 }
138
139 /* FIXME: round trip */
140
141 EAPI int
142 ecore_x_sync_counter_query(Ecore_X_Sync_Counter counter, unsigned int *val)
143 {
144 #ifdef ECORE_XCB_SYNC
145   xcb_sync_query_counter_cookie_t cookie;
146   xcb_sync_query_counter_reply_t *reply;
147
148   cookie = xcb_sync_query_counter_unchecked(_ecore_xcb_conn, counter);
149   reply = xcb_sync_query_counter_reply(_ecore_xcb_conn, cookie, NULL);
150   if (reply)
151     {
152        *val = (unsigned int)reply->counter_value.lo;
153        free(reply);
154        return 1;
155     }
156 #endif /* ECORE_XCB_SYNC */
157
158   return 0;
159 }