Blender V4.3
GHOST_TaskbarX11.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2018-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9/* NOTE(@ideasman42): 2023-04-07, see: !106608.
10 * Even though Ubuntu's Unity (desktop-environment)
11 * is no longer in widespread use, DBUS API's defined by: `libunity.so`
12 * are still supported by some KDE/GNOME docks (as close as it gets to a standard it seems).
13 * So when `libunity.so` is available, it can still be used to update a progress bar.
14 *
15 * Over time `libunity.so` has become less common on the Linux Desktop.
16 * (it's no longer installed by default on most distributions, or even easily available).
17 * So long term Blender should be updated to talk to DBUS directly,
18 * perhaps as a dynamically loaded library which is used when available.
19 *
20 * This would allow X11/WAYLAND to share their task-bar implementation too. */
21
22#include "GHOST_TaskbarX11.hh"
23
24#include <cassert>
25#include <cstdio>
26#include <cstdlib>
27#include <dlfcn.h>
28
29using unity_get_entry_t = void *(*)(const char *);
30using unity_set_progress_t = void (*)(void *, double);
31using unity_set_progress_visible_t = void (*)(void *, int);
32using unity_event_loop_t = int (*)(void *, int);
33
38
39static bool libunity_initialized = false;
40static bool libunity_available = false;
41static void *libunity_handle = nullptr;
42
44{
45 if (libunity_handle) {
46 dlclose(libunity_handle);
47 libunity_handle = nullptr;
48 }
49}
50
52{
54 return libunity_available;
55 }
56
58
59 const char *libunity_names[] = {
60 "libunity.so.4", "libunity.so.6", "libunity.so.9", "libunity.so", nullptr};
61 for (int i = 0; libunity_names[i]; i++) {
62 libunity_handle = dlopen(libunity_names[i], RTLD_LAZY);
63 if (libunity_handle) {
64 break;
65 }
66 }
67
68 if (!libunity_handle) {
69 return false;
70 }
71
73 "unity_launcher_entry_get_for_desktop_id");
74 if (!unity_get_entry) {
75 fprintf(stderr, "failed to load libunity: %s\n", dlerror());
76 return false;
77 }
79 "unity_launcher_entry_set_progress");
80 if (!unity_set_progress) {
81 fprintf(stderr, "failed to load libunity: %s\n", dlerror());
82 return false;
83 }
85 libunity_handle, "unity_launcher_entry_set_progress_visible");
87 fprintf(stderr, "failed to load libunity: %s\n", dlerror());
88 return false;
89 }
90 unity_event_loop = (unity_event_loop_t)dlsym(libunity_handle, "g_main_context_iteration");
91 if (!unity_event_loop) {
92 fprintf(stderr, "failed to load libunity: %s\n", dlerror());
93 return false;
94 }
95
97
98 libunity_available = true;
99 return true;
100}
101
103{
105 handle = unity_get_entry(name);
106 }
107 else {
108 handle = nullptr;
109 }
110}
111
113{
114 return (handle != nullptr);
115}
116
118{
119 assert(is_valid());
120 unity_set_progress(handle, progress);
121}
122
124{
125 assert(is_valid());
126 unity_set_progress_visible(handle, enabled ? 1 : 0);
127 unity_event_loop(nullptr, 0);
128}
typedef double(DMatrix)[4][4]
static unity_event_loop_t unity_event_loop
void(*)(void *, double) unity_set_progress_t
static bool libunity_available
int(*)(void *, int) unity_event_loop_t
void(*)(void *, int) unity_set_progress_visible_t
static unity_set_progress_visible_t unity_set_progress_visible
static bool libunity_initialized
void *(*)(const char *) unity_get_entry_t
static unity_set_progress_t unity_set_progress
static unity_get_entry_t unity_get_entry
static void * libunity_handle
GHOST_TaskBarX11(const char *name)
void set_progress(double progress)
void set_progress_enabled(bool enabled)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int