aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_render.c
blob: f36b4d2489443d19d40e30e2e9532887deed0ed7 (plain)
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
#include "ecore_xcb_private.h"
#include <ctype.h> // for isupper/tolower
#ifdef ECORE_XCB_RENDER
# include <xcb/render.h>
# include <xcb/xcb_renderutil.h>
#endif

/* local function prototypes */
static Eina_Bool _ecore_xcb_render_parse_boolean(char *v);

/* local variables */
static Eina_Bool _render_avail = EINA_FALSE;
static Eina_Bool _render_argb = EINA_FALSE;
static Eina_Bool _render_anim = EINA_FALSE;

void
_ecore_xcb_render_init(void)
{
   LOGFN(__FILE__, __LINE__, __FUNCTION__);

#ifdef ECORE_XCB_RENDER
   xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_render_id);
#endif
}

void
_ecore_xcb_render_finalize(void)
{
#ifdef ECORE_XCB_RENDER
   const xcb_query_extension_reply_t *ext_reply;
#endif

   LOGFN(__FILE__, __LINE__, __FUNCTION__);

#ifdef ECORE_XCB_RENDER
   ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_render_id);
   if ((ext_reply) && (ext_reply->present))
     {
        xcb_render_query_version_cookie_t cookie;
        xcb_render_query_version_reply_t *reply;

        cookie =
          xcb_render_query_version_unchecked(_ecore_xcb_conn,
                                             XCB_RENDER_MAJOR_VERSION,
                                             XCB_RENDER_MINOR_VERSION);
        reply = xcb_render_query_version_reply(_ecore_xcb_conn, cookie, NULL);
        if (reply)
          {
//        if ((reply->major_version >= XCB_RENDER_MAJOR_VERSION) &&
               if (reply->minor_version >= XCB_RENDER_MINOR_VERSION)
                 {
                    char *v = NULL;

                    _render_avail = EINA_TRUE;
                    _ecore_xcb_xdefaults_init();
                    if ((reply->major_version > 0) || (reply->minor_version >= 5))
                      {
                         _render_argb = EINA_TRUE;
                         v = getenv("XCURSOR_CORE");
                         if (!v)
                           v = _ecore_xcb_xdefaults_string_get("Xcursor", "core");
                         if ((v) && (_ecore_xcb_render_parse_boolean(v)))
                           _render_argb = EINA_FALSE;
                      }
                    if ((_render_argb) &&
                        ((reply->major_version > 0) || (reply->minor_version >= 8)))
                      {
                         _render_anim = EINA_TRUE;
                         v = getenv("XCURSOR_ANIM");
                         if (!v)
                           v = _ecore_xcb_xdefaults_string_get("Xcursor", "anim");
                         if ((v) && (_ecore_xcb_render_parse_boolean(v)))
                           _render_anim = EINA_FALSE;
                      }
                    _ecore_xcb_xdefaults_shutdown();
                 }
          }
        free(reply);
     }
#endif
}

Eina_Bool
_ecore_xcb_render_avail_get(void)
{
   return _render_avail;
}

Eina_Bool
_ecore_xcb_render_argb_get(void)
{
   return _render_argb;
}

Eina_Bool
_ecore_xcb_render_anim_get(void)
{
   return _render_anim;
}

Eina_Bool
_ecore_xcb_render_visual_supports_alpha(Ecore_X_Visual visual)
{
   Eina_Bool ret = EINA_FALSE;
#ifdef ECORE_XCB_RENDER
   const xcb_render_query_pict_formats_reply_t *reply;
   xcb_render_pictvisual_t *vis;
#endif

   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   CHECK_XCB_CONN;

   if (!visual) return EINA_FALSE;
   if (!_render_avail) return EINA_FALSE;

#ifdef ECORE_XCB_RENDER
   reply = xcb_render_util_query_formats(_ecore_xcb_conn);
   if (!reply) return EINA_FALSE;

   vis =
     xcb_render_util_find_visual_format(reply,
                                        ((xcb_visualtype_t *)visual)->visual_id);
   if (vis)
     {
        xcb_render_pictforminfo_t temp;
        xcb_render_pictforminfo_t *format;

        temp.id = vis->format;
        format =
          xcb_render_util_find_format(reply, XCB_PICT_FORMAT_ID, &temp, 0);

        if ((format->type == XCB_RENDER_PICT_TYPE_DIRECT) &&
            (format->direct.alpha_mask))
          ret = EINA_TRUE;
     }

#endif

   return ret;
}

uint32_t
_ecore_xcb_render_find_visual_id(int       type,
                                 Eina_Bool check_alpha)
{
#ifdef ECORE_XCB_RENDER
   const xcb_render_query_pict_formats_reply_t *reply;
   xcb_render_pictvisual_t *visual = NULL;
   xcb_render_pictscreen_iterator_t screens;
   xcb_render_pictdepth_iterator_t depths;
   xcb_render_pictvisual_iterator_t visuals;
#endif

   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   CHECK_XCB_CONN;

   if (!_render_avail) return 0;

#ifdef ECORE_XCB_RENDER
   reply = xcb_render_util_query_formats(_ecore_xcb_conn);
   if (!reply) return 0;

   for (screens = xcb_render_query_pict_formats_screens_iterator(reply);
        screens.rem; xcb_render_pictscreen_next(&screens))
     {
        for (depths = xcb_render_pictscreen_depths_iterator(screens.data);
             depths.rem; xcb_render_pictdepth_next(&depths))
          {
             for (visuals = xcb_render_pictdepth_visuals_iterator(depths.data);
                  visuals.rem; xcb_render_pictvisual_next(&visuals))
               {
                  xcb_render_pictforminfo_t temp;
                  xcb_render_pictforminfo_t *format;

                  visual = visuals.data;
                  temp.id = visual->format;

                  format =
                    xcb_render_util_find_format(reply, XCB_PICT_FORMAT_ID,
                                                &temp, 0);
                  if (!format) continue;
                  if (format->type == type)
                    {
                       if (check_alpha)
                         {
                            if (format->direct.alpha_mask)
                              return visual->visual;
                         }
                       else
                         return visual->visual;
                    }
               }
          }
     }
#endif

   return 0;
}

/* local function prototypes */
static Eina_Bool
_ecore_xcb_render_parse_boolean(char *v)
{
   char c;

   c = *v;
   if (isupper((int)c))
     c = tolower(c);
   if ((c == 't') || (c == 'y') || (c == '1'))
     return EINA_TRUE;
   if ((c == 'f') || (c == 'n') || (c == '0'))
     return EINA_FALSE;
   if (c == 'o')
     {
        char d;

        d = v[1];
        if (isupper((int)d))
          d = tolower(d);
        if (d == 'n') return EINA_TRUE;
        if (d == 'f') return EINA_FALSE;
     }
   return EINA_FALSE;
}