Merge branch 'blender2.7'
[blender.git] / intern / ghost / intern / GHOST_TaskbarX11.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s):
19  *   Lukas Stockner
20  *
21  * ***** END GPL LICENSE BLOCK *****
22  */
23
24 /** \file ghost/intern/GHOST_TaskbarX11.cpp
25  *  \ingroup GHOST
26  */
27
28 #include "GHOST_TaskbarX11.h"
29
30 #include <dlfcn.h>
31 #include <cstdio>
32 #include <cassert>
33 #include <cstdlib>
34
35 typedef void*(*unity_get_entry_t)(const char*);
36 typedef void(*unity_set_progress_t)(void*, double);
37 typedef void(*unity_set_progress_visible_t)(void*, int);
38 typedef int(*unity_event_loop_t)(void*, int);
39
40 static unity_get_entry_t unity_get_entry;
41 static unity_set_progress_t unity_set_progress;
42 static unity_set_progress_visible_t unity_set_progress_visible;
43 static unity_event_loop_t unity_event_loop;
44
45 static bool libunity_initialized = false;
46 static bool libunity_available = false;
47 static void *libunity_handle = NULL;
48
49 void GHOST_TaskBarX11::free()
50 {
51         if(libunity_handle) {
52                 dlclose(libunity_handle);
53                 libunity_handle = NULL;
54         }
55 }
56
57 bool GHOST_TaskBarX11::init()
58 {
59         if(libunity_initialized) {
60                 return libunity_available;
61         }
62
63         libunity_initialized = true;
64
65         const char *libunity_names[] = {"libunity.so.4", "libunity.so.6", "libunity.so.9", "libunity.so", NULL};
66         for(int i = 0; libunity_names[i]; i++) {
67                 libunity_handle = dlopen(libunity_names[i], RTLD_LAZY);
68                 if(libunity_handle) {
69                         break;
70                 }
71         }
72
73         if(!libunity_handle) {
74                 return false;
75         }
76
77         unity_get_entry = (unity_get_entry_t) dlsym(libunity_handle, "unity_launcher_entry_get_for_desktop_id");
78         if(!unity_get_entry) {
79                 fprintf(stderr, "failed to load libunity: %s\n", dlerror());
80                 return false;
81         }
82         unity_set_progress = (unity_set_progress_t) dlsym(libunity_handle, "unity_launcher_entry_set_progress");
83         if(!unity_set_progress) {
84                 fprintf(stderr, "failed to load libunity: %s\n", dlerror());
85                 return false;
86         }
87         unity_set_progress_visible = (unity_set_progress_visible_t) dlsym(libunity_handle, "unity_launcher_entry_set_progress_visible");
88         if(!unity_set_progress_visible) {
89                 fprintf(stderr, "failed to load libunity: %s\n", dlerror());
90                 return false;
91         }
92         unity_event_loop = (unity_event_loop_t) dlsym(libunity_handle, "g_main_context_iteration");
93         if(!unity_event_loop) {
94                 fprintf(stderr, "failed to load libunity: %s\n", dlerror());
95                 return false;
96         }
97
98         atexit(GHOST_TaskBarX11::free);
99
100         libunity_available = true;
101         return true;
102 }
103
104 GHOST_TaskBarX11::GHOST_TaskBarX11(const char *name)
105 {
106         if(GHOST_TaskBarX11::init()) {
107                 handle = unity_get_entry(name);
108         }
109         else {
110                 handle = NULL;
111         }
112 }
113
114 bool GHOST_TaskBarX11::is_valid()
115 {
116         return (handle != NULL);
117 }
118
119 void GHOST_TaskBarX11::set_progress(double progress)
120 {
121         assert(is_valid());
122         unity_set_progress(handle, progress);
123 }
124
125 void GHOST_TaskBarX11::set_progress_enabled(bool enabled)
126 {
127         assert(is_valid());
128         unity_set_progress_visible(handle, enabled ? 1 : 0);
129         unity_event_loop(NULL, 0);
130 }