aboutsummaryrefslogtreecommitdiffstats
path: root/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_damage.c
blob: 84870a8689dcc6cbfc366227e73ffd3bc665364a (plain) (blame)
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
#include "ecore_xcb_private.h"
# ifdef ECORE_XCB_DAMAGE
#  include <xcb/damage.h>
# endif

/* local variables */
static Eina_Bool _damage_avail = EINA_FALSE;

/* external variables */
int _ecore_xcb_event_damage = -1;

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

#ifdef ECORE_XCB_DAMAGE
   xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_damage_id);
#endif
}

void 
_ecore_xcb_damage_finalize(void) 
{
#ifdef ECORE_XCB_DAMAGE
   const xcb_query_extension_reply_t *ext_reply;
#endif

   LOGFN(__FILE__, __LINE__, __FUNCTION__);

#ifdef ECORE_XCB_DAMAGE
   ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_damage_id);
   if ((ext_reply) && (ext_reply->present)) 
     {
        xcb_damage_query_version_cookie_t cookie;
        xcb_damage_query_version_reply_t *reply;

        cookie = 
          xcb_damage_query_version_unchecked(_ecore_xcb_conn, 
                                             XCB_DAMAGE_MAJOR_VERSION, 
                                             XCB_DAMAGE_MINOR_VERSION);
        reply = xcb_damage_query_version_reply(_ecore_xcb_conn, cookie, NULL);
        if (reply)
          {
             _damage_avail = EINA_TRUE;
             free(reply);
          }

        if (_damage_avail)
          _ecore_xcb_event_damage = ext_reply->first_event;
     }
#endif
}

/**
 * @defgroup Ecore_X_Damage_Group X Damage Extension Functions
 * 
 * Functions related to the X Damage Extension.
 */

EAPI Eina_Bool 
ecore_x_damage_query(void) 
{
   return _damage_avail;
}

/**
 * Create a damage object
 * 
 * @param drawable The drawable to monitor
 * @param level The level of the damage report
 * @return The damage object
 * 
 * Creates a damage object to monitor changes to @p drawable, 
 * with the level @p level.
 * 
 * @ingroup Ecore_X_Damage_Group
 */
EAPI Ecore_X_Damage 
ecore_x_damage_new(Ecore_X_Drawable drawable, Ecore_X_Damage_Report_Level level) 
{
   Ecore_X_Damage damage = 0;

   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   CHECK_XCB_CONN;

   if (!_damage_avail) return 0;

#ifdef ECORE_XCB_DAMAGE
   damage = xcb_generate_id(_ecore_xcb_conn);
   xcb_damage_create(_ecore_xcb_conn, damage, drawable, level);
//   ecore_x_flush();
#endif

   return damage;
}

/**
 * Destroy a damage object
 * 
 * @param The damage object to destroy
 * 
 * Destroys the damage object @p damage
 * 
 * @ingroup Ecore_X_Damage_Group
 */
EAPI void 
ecore_x_damage_free(Ecore_X_Damage damage) 
{
   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   CHECK_XCB_CONN;

   if (!_damage_avail) return;

#ifdef ECORE_XCB_DAMAGE
   xcb_damage_destroy(_ecore_xcb_conn, damage);
//   ecore_x_flush();
#endif
}

/**
 * Synchronously modifies the region
 * 
 * @param damage The damage object to destroy
 * @param repair The repair region
 * @param parts The parts region
 *
 * Synchronously modifies the regions in the following manner:
 * If @p repair is @c XCB_NONE:
 *   1) parts = damage
 *   2) damage = <empty>
 * Otherwise:
 *   1) parts = damage INTERSECT repair
 *   2) damage = damage - parts
 *   3) Generate DamageNotify for remaining damage areas
 * 
 * @ingroup Ecore_X_Damage_Group
 */
EAPI void 
ecore_x_damage_subtract(Ecore_X_Damage damage, Ecore_X_Region repair, Ecore_X_Region parts) 
{
   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   CHECK_XCB_CONN;

   if (!_damage_avail) return;

#ifdef ECORE_XCB_DAMAGE
   xcb_damage_subtract(_ecore_xcb_conn, damage, repair, parts);
//   ecore_x_flush();
#endif
}