Atlas - SDL_progressbar.c
Home / ext / SDL / src / core / linux Lines: 1 | Size: 5548 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "SDL_progressbar.h" 22#include "SDL_internal.h" 23 24#include "SDL_dbus.h" 25 26#ifdef SDL_USE_LIBDBUS 27 28#include <unistd.h> 29 30#include "../unix/SDL_appid.h" 31 32#define UnityLauncherAPI_DBUS_INTERFACE "com.canonical.Unity.LauncherEntry" 33#define UnityLauncherAPI_DBUS_SIGNAL "Update" 34 35static char *GetDBUSObjectPath(void) 36{ 37 char *app_id = SDL_strdup(SDL_GetAppID()); 38 39 if (!app_id) { 40 return NULL; 41 } 42 43 // Sanitize exe_name to make it a legal D-Bus path element 44 for (char *p = app_id; *p; ++p) { 45 if (!SDL_isalnum(*p)) { 46 *p = '_'; 47 } 48 } 49 50 // Ensure it starts with a letter or underscore 51 if (!SDL_isalpha(app_id[0]) && app_id[0] != '_') { 52 app_id = SDL_realloc(app_id, SDL_strlen(app_id) + 2); 53 if (!app_id) { 54 return NULL; 55 } 56 SDL_memmove(app_id + 1, app_id, SDL_strlen(app_id) + 1); 57 app_id[0] = '_'; 58 } 59 60 // Create full path 61 char *path; 62 if (SDL_asprintf(&path, "/org/libsdl/%s_%d", app_id, getpid()) < 0) { 63 path = NULL; 64 } 65 66 SDL_free(app_id); 67 68 return path; 69} 70 71static char *GetAppDesktopPath(void) 72{ 73 const char *desktop_suffix = ".desktop"; 74 const char *app_id = SDL_GetAppID(); 75 const size_t desktop_path_total_length = SDL_strlen(app_id) + SDL_strlen(desktop_suffix) + 1; 76 char *desktop_path = (char *)SDL_malloc(desktop_path_total_length); 77 if (!desktop_path) { 78 return NULL; 79 } 80 *desktop_path = '\0'; 81 SDL_strlcat(desktop_path, app_id, desktop_path_total_length); 82 SDL_strlcat(desktop_path, desktop_suffix, desktop_path_total_length); 83 84 return desktop_path; 85} 86 87static int ShouldShowProgress(SDL_ProgressState progressState) 88{ 89 if (progressState == SDL_PROGRESS_STATE_INVALID || 90 progressState == SDL_PROGRESS_STATE_NONE) { 91 return 0; 92 } 93 94 // Unity LauncherAPI only supports "normal" display of progress 95 return 1; 96} 97 98bool DBUS_ApplyWindowProgress(SDL_VideoDevice *_this, SDL_Window *window) 99{ 100 // Signal signature: 101 // signal com.canonical.Unity.LauncherEntry.Update (in s app_uri, in a{sv} properties) 102 103 SDL_DBusContext *dbus = SDL_DBus_GetContext(); 104 105 if (!dbus || !dbus->session_conn) { 106 return false; 107 } 108 109 char *objectPath = GetDBUSObjectPath(); 110 if (!objectPath) { 111 return false; 112 } 113 114 DBusMessage *msg = dbus->message_new_signal(objectPath, UnityLauncherAPI_DBUS_INTERFACE, UnityLauncherAPI_DBUS_SIGNAL); 115 if (!msg) { 116 SDL_free(objectPath); 117 return false; 118 } 119 120 char *desktop_path = GetAppDesktopPath(); 121 if (!desktop_path) { 122 dbus->message_unref(msg); 123 SDL_free(objectPath); 124 return false; 125 } 126 127 const char *progress_visible_str = "progress-visible"; 128 const char *progress_str = "progress"; 129 130 const int progress_visible = ShouldShowProgress(window->progress_state); 131 double progress = (double)window->progress_value; 132 133 DBusMessageIter args, props; 134 dbus->message_iter_init_append(msg, &args); 135 dbus->message_iter_append_basic(&args, DBUS_TYPE_STRING, &desktop_path); // Setup app_uri paramter 136 dbus->message_iter_open_container(&args, DBUS_TYPE_ARRAY, "{sv}", &props); // Setup properties parameter 137 DBusMessageIter key_it, value_it; 138 // Set progress visible property 139 dbus->message_iter_open_container(&props, DBUS_TYPE_DICT_ENTRY, NULL, &key_it); 140 dbus->message_iter_append_basic(&key_it, DBUS_TYPE_STRING, &progress_visible_str); // Append progress-visible key data 141 dbus->message_iter_open_container(&key_it, DBUS_TYPE_VARIANT, "b", &value_it); 142 dbus->message_iter_append_basic(&value_it, DBUS_TYPE_BOOLEAN, &progress_visible); // Append progress-visible value data 143 dbus->message_iter_close_container(&key_it, &value_it); 144 dbus->message_iter_close_container(&props, &key_it); 145 // Set progress value property 146 dbus->message_iter_open_container(&props, DBUS_TYPE_DICT_ENTRY, NULL, &key_it); 147 dbus->message_iter_append_basic(&key_it, DBUS_TYPE_STRING, &progress_str); // Append progress key data 148 dbus->message_iter_open_container(&key_it, DBUS_TYPE_VARIANT, "d", &value_it); 149 dbus->message_iter_append_basic(&value_it, DBUS_TYPE_DOUBLE, &progress); // Append progress value data 150 dbus->message_iter_close_container(&key_it, &value_it); 151 dbus->message_iter_close_container(&props, &key_it); 152 dbus->message_iter_close_container(&args, &props); 153 154 dbus->connection_send(dbus->session_conn, msg, NULL); 155 156 SDL_free(desktop_path); 157 dbus->message_unref(msg); 158 SDL_free(objectPath); 159 160 return true; 161} 162 163#endif // SDL_USE_LIBDBUS 164[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.