[elm_navigationbar]: check added if the button being added is same then dont delete it.
[framework/uifw/elementary.git] / src / lib / elm_cbhm_helper.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 #include <X11/Xlib.h>
5 #include <X11/Xatom.h>
6
7
8 /**
9  * @defgroup CBHM_helper CBHM_helper
10  * @ingroup Elementary
11  *
12  * retrieving date from Clipboard History Manager
13  * CBHM_helper supports to get CBHM's contents
14  */
15
16 #define ATOM_CLIPBOARD_NAME "CLIPBOARD"
17 #define ATOM_CLIPBOARD_MANGER_NAME "CLIPBOARD_MANAGER"
18 #define CLIPBOARD_MANAGER_WINDOW_TITLE_STRING "X11_CLIPBOARD_HISTORY_MANAGER"
19 #define ATOM_CBHM_WINDOW_NAME "CBHM_XWIN"
20
21 static Ecore_X_Display *cbhm_disp = NULL;
22 static Ecore_X_Window cbhm_win = None;
23 static Ecore_X_Window self_win = None;
24 static Eina_Bool init_flag = EINA_FALSE;
25
26 void _get_clipboard_window();
27 unsigned int _get_cbhm_serial_number();
28 void _search_clipboard_window(Ecore_X_Window w);
29 int _send_clipboard_events(char *cmd);
30 int _get_clipboard_data(Atom datom, char **datomptr);
31
32 void _get_clipboard_window()
33 {
34         Atom actual_type;
35         int actual_format;
36         unsigned long nitems, bytes_after;
37         unsigned char *prop_return = NULL;
38         Atom atomCbhmWin = XInternAtom(cbhm_disp, ATOM_CBHM_WINDOW_NAME, False);
39         if(Success == 
40            XGetWindowProperty(cbhm_disp, DefaultRootWindow(cbhm_disp), atomCbhmWin, 
41                                                   0, sizeof(Ecore_X_Window), False, XA_WINDOW, 
42                                                   &actual_type, &actual_format, &nitems, &bytes_after, &prop_return) && 
43            prop_return)
44         {
45                 cbhm_win = *(Ecore_X_Window*)prop_return;
46                 XFree(prop_return);
47                 fprintf(stderr, "## find clipboard history manager at root\n");
48         }
49 }
50
51 unsigned int _get_cbhm_serial_number()
52 {
53         Atom actual_type;
54         int actual_format;
55         unsigned long nitems, bytes_after;
56         unsigned char *prop_return = NULL;
57         unsigned int senum = 0;
58         Atom atomCbhmSN = XInternAtom(cbhm_disp, "CBHM_SERIAL_NUMBER", False);
59
60         // FIXME : is it really needed?
61         XSync(cbhm_disp, EINA_FALSE);
62
63         if(Success == 
64            XGetWindowProperty(cbhm_disp, cbhm_win, atomCbhmSN, 
65                                                   0, sizeof(Ecore_X_Window), False, XA_INTEGER, 
66                                                   &actual_type, &actual_format, &nitems, &bytes_after, &prop_return) && 
67            prop_return)
68         {
69                 senum = *(unsigned int*)prop_return;
70                 XFree(prop_return);
71         }
72         fprintf(stderr, "## chbm_serial = %d\n", senum);
73         return senum;
74 }
75
76 void _search_clipboard_window(Ecore_X_Window w)
77 {
78     // Get the PID for the current Window.
79         Atom atomWMName = XInternAtom(cbhm_disp, "_NET_WM_NAME", False);
80         Atom atomUTF8String = XInternAtom(cbhm_disp, "UTF8_STRING", False);
81         Atom type;
82         int format;
83         unsigned long nitems;
84         unsigned long bytes_after;
85         unsigned long nsize;
86         unsigned char *propName = 0;
87         if(Success == 
88            XGetWindowProperty(cbhm_disp, w, atomWMName, 0, (long)nsize, False,
89                                                   atomUTF8String, &type, &format, &nitems, &bytes_after, &propName))
90
91         {
92                 if(propName != 0)
93                 {
94                         if (strcmp(CLIPBOARD_MANAGER_WINDOW_TITLE_STRING, propName) == 0)
95                                 cbhm_win = w;
96                         XFree(propName);
97                 }
98         }
99
100     // Recurse into child windows.
101         Window wroot;
102         Window wparent;
103         Window *wchild;
104         unsigned nchildren;
105         int i;
106         if(0 != XQueryTree(cbhm_disp, w, &wroot, &wparent, &wchild, &nchildren))
107         {
108                 for(i = 0; i < nchildren; i++)
109                         _search_clipboard_window(wchild[i]);
110         }
111 }
112
113 int _send_clipboard_events(char *cmd)
114 {
115         if (cmd == NULL)
116                 return -1;
117
118         Atom atomCBHM_MSG = XInternAtom(cbhm_disp, "CBHM_MSG", False);
119
120         XClientMessageEvent m;
121         memset(&m, sizeof(m), 0);
122         m.type = ClientMessage;
123         m.display = cbhm_disp;
124         m.window = self_win;
125         m.message_type = atomCBHM_MSG;
126         m.format = 8;
127         sprintf(m.data.b, "%s", cmd);
128
129         XSendEvent(cbhm_disp, cbhm_win, False, NoEventMask, (XEvent*)&m);
130
131         return 0;
132 }
133
134 int _get_clipboard_data(Atom datom, char **datomptr)
135 {
136         Atom atomUTF8String = XInternAtom(cbhm_disp, "UTF8_STRING", False);
137         Atom type;
138         int format;
139         unsigned long nitems;
140         unsigned long nsize;
141         unsigned char *propname = NULL;
142
143         // FIXME : is it really needed?
144         XSync(cbhm_disp, EINA_FALSE);
145
146         if (Success == 
147                 XGetWindowProperty(cbhm_disp, self_win, datom, 0, 0, False,
148                                                    AnyPropertyType, &type, &format, &nitems, &nsize, &propname))
149                 XFree(propname);
150         else
151                 return -1;
152
153         fprintf(stderr, "## format = %d\n", format);
154         fprintf(stderr, "## nsize = %d\n", nsize);
155
156         if (format != 8)
157                 return -1;
158
159         if (Success == 
160                 XGetWindowProperty(cbhm_disp, self_win, datom, 0, (long)nsize, False,
161                                                    AnyPropertyType, &type, &format, &nitems, &nsize, &propname))
162         {
163                 if (nsize != 0)
164                         XGetWindowProperty(cbhm_disp, self_win, datom, 0, (long)nsize, False,
165                                                            AnyPropertyType, &type, &format, &nitems, &nsize, &propname);
166
167                 if(propname != NULL)
168                 {
169                         fprintf(stderr, "## get data(0x%x) : %s\n", propname, propname);
170                         fprintf(stderr, "## after nsize = %d\n", nsize);
171                         *datomptr = propname;
172 //                      XFree(propName);
173                 }
174
175                 XDeleteProperty(cbhm_disp, self_win, datom);
176                 XFlush(cbhm_disp);
177         }
178
179         if (propname != NULL)
180                 return 0;
181
182         *datomptr = NULL;
183         return -1;
184 }
185
186
187 void free_clipboard_data(char *dptr)
188 {
189         return XFree(dptr);
190 }
191
192
193 /**
194  * initalizing CBHM_helper
195  *
196  * @param self The self window object which receive events
197  * @return return TRUE or FALSE if it cannot be created
198  *
199  * @ingroup CBHM_helper
200  */
201 EAPI Eina_Bool 
202 elm_cbhm_helper_init(Evas_Object *self)
203 {
204         init_flag = EINA_FALSE;
205
206         cbhm_disp = ecore_x_display_get();
207         if (cbhm_disp == NULL)
208                 return init_flag;
209         if (cbhm_win == None)
210                 _get_clipboard_window();
211         if (cbhm_win == None)
212                 _search_clipboard_window(DefaultRootWindow(cbhm_disp));
213         if (self_win == None)
214                 self_win = ecore_evas_software_x11_window_get(ecore_evas_ecore_evas_get(evas_object_evas_get(self)));
215    
216         if (cbhm_disp && cbhm_win && self_win)
217                 init_flag = EINA_TRUE;
218
219         return init_flag;
220 }
221
222 /**
223  * getting serial number of CBHM
224  *
225  * @return return serial number of clipboard history manager
226  *
227  * @ingroup CBHM_helper
228  */
229 EAPI unsigned int 
230 elm_cbhm_get_serial_number()
231 {
232         if (init_flag == EINA_FALSE)
233                 return 0;
234
235         unsigned int num = 0;
236         num = _get_cbhm_serial_number();
237         return num;
238 }
239
240 /**
241  * getting count of CBHM's contents
242  *
243  * @return return count of history contents
244  *
245  * @ingroup CBHM_helper
246  */
247 EAPI int 
248 elm_cbhm_get_count()
249 {
250         if (init_flag == EINA_FALSE)
251                 return -1;
252
253         char *retptr = NULL;
254         int count = 0;
255
256         _send_clipboard_events("get count");
257
258         Atom atomCBHM_cCOUNT = XInternAtom(cbhm_disp, "CBHM_cCOUNT", False);
259
260         _get_clipboard_data(atomCBHM_cCOUNT, &retptr);
261
262         if (retptr != NULL)
263         {
264                 fprintf(stderr, "## c get retptr : %s\n", retptr);
265                 count = atoi(retptr);
266
267                 free_clipboard_data(retptr);
268                 retptr = NULL;
269         }
270
271         return count;
272 }
273
274 /**
275  * getting raw data of CBHM's contents
276  *
277  * @return return raw data of history contents
278  *
279  * @ingroup CBHM_helper
280  */
281 EAPI int 
282 elm_cbhm_get_raw_data()
283 {
284         if (init_flag == EINA_FALSE)
285                 return -1;
286
287         char *retptr = NULL;
288
289         _send_clipboard_events("get raw");
290
291         Atom atomCBHM_cRAW = XInternAtom(cbhm_disp, "CBHM_cRAW", False);
292
293         _get_clipboard_data(atomCBHM_cRAW, &retptr);
294
295         if (retptr != NULL)
296         {
297                 free_clipboard_data(retptr);
298                 retptr = NULL;
299         }
300
301         return 0;
302 }
303
304 /**
305  * sending raw command to CBHM
306  *
307  * @return void
308  *
309  * @ingroup CBHM_helper
310  */
311 EAPI void
312 elm_cbhm_send_raw_data(char *cmd)
313 {
314         if (init_flag == EINA_FALSE)
315                 return;
316
317         if (cmd == NULL)
318                 return;
319
320         _send_clipboard_events(cmd);
321         fprintf(stderr, "## cbhm - send raw cmd = %s\n", cmd);
322
323         return;
324 }
325
326 /**
327  * getting data by history position of CBHM's contents
328  * 0 is current content.
329  *
330  * @return return data pointer of position of history contents
331  *
332  * @ingroup CBHM_helper
333  */
334 EAPI int
335 elm_cbhm_get_data_by_position(int pos, char **dataptr)
336 {
337         if (init_flag == EINA_FALSE)
338                 return -1;
339
340         char reqbuf[16];
341         int ret = 0;
342         sprintf(reqbuf, "get #%d", pos);
343
344         _send_clipboard_events(reqbuf);
345
346         sprintf(reqbuf, "CBHM_c%d", pos);
347
348         Atom atomCBHM_cPOS = XInternAtom(cbhm_disp, reqbuf, False);
349
350         ret = _get_clipboard_data(atomCBHM_cPOS, dataptr);
351
352         if (ret >= 0 && *dataptr != NULL)
353         {
354                 fprintf(stderr, "## d get retptr : %s\n", *dataptr);
355                 fprintf(stderr, "## dptr = 0x%x\n", *dataptr);
356
357                 return 0;
358         }
359
360         return -1;
361 }
362
363 /**
364  * free data by history position of CBHM's contents
365  *
366  * @return None
367  *
368  * @ingroup CBHM_helper
369  */
370 EAPI void
371 elm_cbhm_free_data(char *dptr)
372 {
373         if (dptr != NULL)
374                 free_clipboard_data(dptr);
375 }