svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore_x / xlib / ecore_x_randr.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #ifdef HAVE_CONFIG_H
6 # include <config.h>
7 #endif
8
9 #include <stdlib.h>
10
11 #include "ecore_x_private.h"
12
13 static int _randr_available = 0;
14 #ifdef ECORE_XRANDR
15 static int _randr_major, _randr_minor, _randr_version;
16 #define RANDR_1_2 ((1 << 16) | 2)
17 #define RANDR_1_3 ((1 << 16) | 3)
18 #endif
19
20 void
21 _ecore_x_randr_init(void)
22 {
23 #ifdef ECORE_XRANDR
24    _randr_major = 1;
25    _randr_minor = 3;
26    _randr_version = 0;
27
28    if (XRRQueryVersion(_ecore_x_disp, &_randr_major, &_randr_minor))
29      {
30         _randr_version = (_randr_major << 16) | _randr_minor;
31         _randr_available = 1;
32      }
33    else
34      _randr_available = 0;
35 #else
36    _randr_available = 0;
37 #endif
38 }
39
40 EAPI int
41 ecore_x_randr_query(void)
42 {
43    LOGFN(__FILE__, __LINE__, __FUNCTION__);
44    return _randr_available;
45 }
46
47 EAPI int
48 ecore_x_randr_events_select(Ecore_X_Window win, int on)
49 {
50 #ifdef ECORE_XRANDR
51    int mask;
52
53    LOGFN(__FILE__, __LINE__, __FUNCTION__);
54    if (!on)
55      mask = 0;
56    else
57      {
58         mask = RRScreenChangeNotifyMask;
59         if (_randr_version >= RANDR_1_2)
60           mask |= (RRCrtcChangeNotifyMask |
61                    RROutputChangeNotifyMask |
62                    RROutputPropertyNotifyMask);
63      }
64
65    XRRSelectInput(_ecore_x_disp, win, mask);
66
67    return 1;
68 #else
69    return 0;
70 #endif
71 }
72
73 EAPI Ecore_X_Randr_Rotation
74 ecore_x_randr_screen_rotations_get(Ecore_X_Window root)
75 {
76 #ifdef ECORE_XRANDR
77    Rotation rot, crot;
78    
79    LOGFN(__FILE__, __LINE__, __FUNCTION__);
80    rot = XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &crot);
81    return rot;
82 #else
83    return 0;
84 #endif   
85 }
86
87 EAPI Ecore_X_Randr_Rotation
88 ecore_x_randr_screen_rotation_get(Ecore_X_Window root)
89 {
90 #ifdef ECORE_XRANDR
91    Rotation crot = 0;
92    
93    LOGFN(__FILE__, __LINE__, __FUNCTION__);
94    XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &crot);
95    return crot;
96 #else
97    return 0;
98 #endif   
99 }
100
101 EAPI void
102 ecore_x_randr_screen_rotation_set(Ecore_X_Window root, Ecore_X_Randr_Rotation rot)
103 {
104 #ifdef ECORE_XRANDR
105    XRRScreenConfiguration *xrrcfg;
106    SizeID sizeid;
107    Rotation crot;
108    
109    LOGFN(__FILE__, __LINE__, __FUNCTION__);
110    xrrcfg = XRRGetScreenInfo(_ecore_x_disp, root);
111    if (!xrrcfg) return;
112    sizeid = XRRConfigCurrentConfiguration(xrrcfg, &crot);
113    XRRSetScreenConfig(_ecore_x_disp, xrrcfg, root, sizeid, rot, CurrentTime);
114    XRRFreeScreenConfigInfo(xrrcfg);
115 #endif   
116 }
117
118 EAPI Ecore_X_Screen_Size *
119 ecore_x_randr_screen_sizes_get(Ecore_X_Window root, int *num)
120 {
121 #ifdef ECORE_XRANDR
122    Ecore_X_Screen_Size *ret;
123    XRRScreenSize *sizes;
124    int i, n;
125
126    LOGFN(__FILE__, __LINE__, __FUNCTION__);
127    if (num) *num = 0;
128
129    /* we don't have to free sizes, no idea why not */
130    sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
131    ret = calloc(n, sizeof(Ecore_X_Screen_Size));
132    if (!ret) return NULL;
133
134    if (num) *num = n;
135    for (i = 0; i < n; i++)
136      {
137         ret[i].width = sizes[i].width;
138         ret[i].height = sizes[i].height;
139      }
140    return ret;
141 #else
142    if (num) *num = 0;
143    return NULL;
144 #endif
145 }
146
147 EAPI Ecore_X_Screen_Size
148 ecore_x_randr_current_screen_size_get(Ecore_X_Window root)
149 {
150    Ecore_X_Screen_Size ret = { -1, -1 };
151 #ifdef ECORE_XRANDR
152    XRRScreenSize *sizes;
153    XRRScreenConfiguration *sc;
154    SizeID size_index;
155    Rotation rotation;
156    int n;
157
158    LOGFN(__FILE__, __LINE__, __FUNCTION__);
159    sc = XRRGetScreenInfo(_ecore_x_disp, root);
160    if (!sc)
161      {
162         ERR("Couldn't get screen information for %d", root);
163         return ret;
164      }
165    size_index = XRRConfigCurrentConfiguration(sc, &rotation);
166
167    sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
168    if (size_index < n)
169      {
170         ret.width = sizes[size_index].width;
171         ret.height = sizes[size_index].height;
172      }
173    XRRFreeScreenConfigInfo(sc);
174 #endif
175    return ret;
176 }
177
178 EAPI int
179 ecore_x_randr_screen_size_set(Ecore_X_Window root, Ecore_X_Screen_Size size)
180 {
181 #ifdef ECORE_XRANDR
182    XRRScreenConfiguration *sc;
183    XRRScreenSize *sizes;
184    int i, n, size_index = -1;
185
186    LOGFN(__FILE__, __LINE__, __FUNCTION__);
187    sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
188    for (i = 0; i < n; i++)
189      {
190         if ((sizes[i].width == size.width) && (sizes[i].height == size.height))
191           {
192              size_index = i;
193              break;
194           }
195      }
196    if (size_index == -1) return 0;
197    
198    sc = XRRGetScreenInfo(_ecore_x_disp, root);
199    if (XRRSetScreenConfig(_ecore_x_disp, sc,
200                           root, size_index,
201                           RR_Rotate_0, CurrentTime))
202      {
203         ERR("Can't set new screen size!");
204         XRRFreeScreenConfigInfo(sc);
205         return 0;
206      }
207    XRRFreeScreenConfigInfo(sc);
208    return 1;
209 #else
210    return 0;
211 #endif
212 }
213
214 EAPI Ecore_X_Screen_Refresh_Rate
215 ecore_x_randr_current_screen_refresh_rate_get(Ecore_X_Window root)
216 {
217    Ecore_X_Screen_Refresh_Rate ret = { -1 };
218 #ifdef ECORE_XRANDR
219    XRRScreenConfiguration *sc;
220
221    LOGFN(__FILE__, __LINE__, __FUNCTION__);
222    sc = XRRGetScreenInfo(_ecore_x_disp, root);
223    if (!sc)
224      {
225         ERR("Couldn't get screen information for %d", root);
226         return ret;
227      }
228    ret.rate = XRRConfigCurrentRate(sc);
229    XRRFreeScreenConfigInfo(sc);   
230 #endif
231    return ret;
232 }
233
234 EAPI Ecore_X_Screen_Refresh_Rate *
235 ecore_x_randr_screen_refresh_rates_get(Ecore_X_Window root, int size_id, int *num)
236 {
237 #ifdef ECORE_XRANDR
238    Ecore_X_Screen_Refresh_Rate *ret = NULL;
239    XRRScreenConfiguration *sc;   
240    short *rates;
241    int i, n;
242
243    LOGFN(__FILE__, __LINE__, __FUNCTION__);
244    if (num) *num = 0;
245
246    sc = XRRGetScreenInfo(_ecore_x_disp, root);
247    if (!sc)
248      {
249         ERR("Couldn't get screen information for %d", root);
250         return ret;
251      }
252    
253    rates = XRRRates(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), size_id, &n);
254    ret = calloc(n, sizeof(Ecore_X_Screen_Refresh_Rate));
255    if (!ret) 
256      { 
257         XRRFreeScreenConfigInfo(sc);
258         return NULL;
259      }
260    
261    if (num) *num = n;
262    for (i = 0; i < n; i++)
263      {
264         ret[i].rate = rates[i];
265      }
266    XRRFreeScreenConfigInfo(sc);   
267    return ret;
268 #else
269    if (num) *num = 0;   
270    return NULL;
271 #endif
272 }
273
274 EAPI int
275 ecore_x_randr_screen_refresh_rate_set(Ecore_X_Window root, Ecore_X_Screen_Size size, Ecore_X_Screen_Refresh_Rate rate)
276 {
277 #ifdef ECORE_XRANDR
278    XRRScreenConfiguration *sc;
279    XRRScreenSize *sizes;
280    int i, n, size_index = -1;
281
282    LOGFN(__FILE__, __LINE__, __FUNCTION__);
283    sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
284    for (i = 0; i < n; i++)
285      {
286         if ((sizes[i].width == size.width) && (sizes[i].height == size.height))
287           {
288              size_index = i;
289              break;
290           }
291      }
292    if (size_index == -1) return 0;
293    
294    sc = XRRGetScreenInfo(_ecore_x_disp, root);
295    if (XRRSetScreenConfigAndRate(_ecore_x_disp, sc,
296                                  root, size_index,
297                                  RR_Rotate_0, rate.rate, CurrentTime))
298      {
299         ERR("Can't set new screen size and refresh rate!");
300         XRRFreeScreenConfigInfo(sc);
301         return 0;
302      }
303    XRRFreeScreenConfigInfo(sc);
304    return 1;
305 #else
306    return 1;
307 #endif
308 }