diff --git a/src/posix_dbus.c b/src/posix_dbus.c index 2b79b959..53db1162 100644 --- a/src/posix_dbus.c +++ b/src/posix_dbus.c @@ -130,7 +130,6 @@ void _glfwInitDBusPOSIX(void) const pid_t pid = getpid(); sprintf(busName, "org.glfw.%s_%d", _glfw.dbus.executableName, pid); - printf("The object path is: %s\n", busName); const int res = dbus_bus_request_name(_glfw.dbus.connection, busName, DBUS_NAME_FLAG_REPLACE_EXISTING, &_glfw.dbus.error); _glfw_free(busName); @@ -260,6 +259,8 @@ void _glfwTerminateDBusPOSIX(void) void _glfwUpdateTaskbarProgressDBusPOSIX(dbus_bool_t progressVisible, double progressValue) { + struct DBusMessage* msg = NULL; + if(!_glfw.dbus.handle || !_glfw.dbus.connection || !_glfw.dbus.desktopFilePath || !_glfw.dbus.signalName) return; @@ -269,53 +270,151 @@ void _glfwUpdateTaskbarProgressDBusPOSIX(dbus_bool_t progressVisible, double pro struct DBusMessageIter args; memset(&args, 0, sizeof(args)); - DBusMessage* msg = dbus_message_new_signal(_glfw.dbus.signalName, "com.canonical.Unity.LauncherEntry", "Update"); - if(!msg) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to create new DBus message"); + if(!_glfwNewMessageSignalDBusPOSIX(_glfw.dbus.signalName, "com.canonical.Unity.LauncherEntry", "Update", &msg)) return; - } dbus_message_iter_init_append(msg, &args); //Setup app_uri parameter - dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &_glfw.dbus.desktopFilePath); + _glfwAppendDataDBusPOSIX(&args, DBUS_TYPE_STRING, &_glfw.dbus.desktopFilePath); //Set properties parameter - struct DBusMessageIter sub1, sub2, sub3; + struct DBusMessageIter sub1; memset(&sub1, 0, sizeof(sub1)); - memset(&sub2, 0, sizeof(sub2)); - memset(&sub3, 0, sizeof(sub3)); - dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "{sv}", &sub1); + _glfwOpenContainerDBusPOSIX(&args, DBUS_TYPE_ARRAY, "{sv}", &sub1); //Set progress visible property - dbus_message_iter_open_container(&sub1, DBUS_TYPE_DICT_ENTRY, NULL, &sub2); const char* progressVisibleStr = "progress-visible"; - dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &progressVisibleStr); - dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "b", &sub3); - dbus_message_iter_append_basic(&sub3, DBUS_TYPE_BOOLEAN, &progressVisible); - dbus_message_iter_close_container(&sub2, &sub3); - dbus_message_iter_close_container(&sub1, &sub2); + _glfwAppendDictDataDBusPOSIX(&sub1, DBUS_TYPE_STRING, &progressVisibleStr, DBUS_TYPE_BOOLEAN, &progressVisible); //Set progress value property - dbus_message_iter_open_container(&sub1, DBUS_TYPE_DICT_ENTRY, NULL, &sub2); - const char* progressValueStr = "progress"; - dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &progressValueStr); - dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "d", &sub3); - dbus_message_iter_append_basic(&sub3, DBUS_TYPE_DOUBLE, &progressValue); - dbus_message_iter_close_container(&sub2, &sub3); - dbus_message_iter_close_container(&sub1, &sub2); + const char* progressStr = "progress"; + _glfwAppendDictDataDBusPOSIX(&sub1, DBUS_TYPE_STRING, &progressStr, DBUS_TYPE_DOUBLE, &progressValue); - dbus_message_iter_close_container(&args, &sub1); + _glfwCloseContainerDBusPOSIX(&args, &sub1); - //Finally send the signal - unsigned int serial = 0; - if(!dbus_connection_send(_glfw.dbus.connection, msg, &serial)) - _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to send DBus message"); - else - dbus_connection_flush(_glfw.dbus.connection); + _glfwSendMessageDBusPOSIX(msg); //Free the message dbus_message_unref(msg); } + +dbus_bool_t _glfwNewMessageSignalDBusPOSIX(const char* objectPath, const char* interfaceName, const char* signalName, struct DBusMessage** outMessage) +{ + if(!outMessage) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to create new DBus message, output message pointer is NULL"); + return GLFW_FALSE; + } + + *outMessage = dbus_message_new_signal(objectPath, interfaceName, signalName); + if(!(*outMessage)) + { + *outMessage = NULL; + _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to create new DBus message"); + return GLFW_FALSE; + } + + return GLFW_TRUE; +} + +dbus_bool_t _glfwOpenContainerDBusPOSIX(struct DBusMessageIter* iterator, int DBusType, const char* signature, struct DBusMessageIter* subIterator) +{ + if(DBusType != DBUS_TYPE_ARRAY && DBusType != DBUS_TYPE_STRUCT_OPEN && + DBusType != DBUS_TYPE_STRUCT_CLOSE && DBusType != DBUS_TYPE_VARIANT && + DBusType != DBUS_TYPE_DICT_ENTRY) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Invalid DBUS container type provided"); + return GLFW_FALSE; + } + if(!iterator || !subIterator) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "DBus message iterator is NULL"); + return GLFW_FALSE; + } + + return dbus_message_iter_open_container(iterator, DBusType, signature, subIterator); +} + +dbus_bool_t _glfwCloseContainerDBusPOSIX(struct DBusMessageIter* iterator, struct DBusMessageIter* subIterator) +{ + if(!iterator || !subIterator) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "DBus message iterator is NULL"); + return GLFW_FALSE; + } + + return dbus_message_iter_close_container(iterator, subIterator); +} + +dbus_bool_t _glfwAppendDataDBusPOSIX(struct DBusMessageIter* iterator, int DBusType, const void* data) +{ + if(DBusType == DBUS_TYPE_ARRAY || DBusType == DBUS_TYPE_VARIANT || DBusType == DBUS_TYPE_DICT_ENTRY || DBusType == DBUS_TYPE_STRUCT_OPEN || DBusType == DBUS_TYPE_STRUCT_CLOSE) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Invalid DBus type provided"); + return GLFW_FALSE; + } + if(!iterator) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "DBus message iterator is NULL"); + return GLFW_FALSE; + } + if(!data) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "DBus data to append is NULL"); + return GLFW_FALSE; + } + + return dbus_message_iter_append_basic(iterator, DBusType, data); +} + +dbus_bool_t _glfwAppendDictDataDBusPOSIX(struct DBusMessageIter* iterator, int keyType, const void* keyData, int valueType, const void* valueData) +{ + struct DBusMessageIter keyIterator; + struct DBusMessageIter valueIterator; + memset(&keyIterator, 0, sizeof(keyIterator)); + memset(&valueIterator, 0, sizeof(valueIterator)); + + if(!_glfwOpenContainerDBusPOSIX(iterator, DBUS_TYPE_DICT_ENTRY, NULL, &keyIterator)) + return GLFW_FALSE; + + //Append key data + if(!_glfwAppendDataDBusPOSIX(&keyIterator, keyType, keyData)) + return GLFW_FALSE; + + if(!_glfwOpenContainerDBusPOSIX(&keyIterator, DBUS_TYPE_VARIANT, (const char*)&valueType, &valueIterator)) + return GLFW_FALSE; + + //Append value data + if(!_glfwAppendDataDBusPOSIX(&valueIterator, valueType, valueData)) + return GLFW_FALSE; + + if(!_glfwCloseContainerDBusPOSIX(&keyIterator, &valueIterator)) + return GLFW_FALSE; + + if(!_glfwCloseContainerDBusPOSIX(iterator, &keyIterator)) + return GLFW_FALSE; + + return GLFW_TRUE; +} + +dbus_bool_t _glfwSendMessageDBusPOSIX(struct DBusMessage* message) +{ + if(!message) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "DBus message is NULL"); + return GLFW_FALSE; + } + + unsigned int serial = 0; + if(!dbus_connection_send(_glfw.dbus.connection, message, &serial)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to send DBus message"); + return GLFW_FALSE; + } + + dbus_connection_flush(_glfw.dbus.connection); + + return GLFW_TRUE; +} \ No newline at end of file diff --git a/src/posix_dbus.h b/src/posix_dbus.h index 74e6e62b..39244b0b 100644 --- a/src/posix_dbus.h +++ b/src/posix_dbus.h @@ -68,6 +68,17 @@ struct DBusMessageIter #define DBUS_TYPE_VARIANT (unsigned int)'v' #define DBUS_TYPE_BOOLEAN (unsigned int)'b' #define DBUS_TYPE_DOUBLE (unsigned int)'d' +#define DBUS_TYPE_INT16 (unsigned int)'n' +#define DBUS_TYPE_UINT16 (unsigned int)'q' +#define DBUS_TYPE_INT32 (unsigned int)'i' +#define DBUS_TYPE_UINT32 (unsigned int)'u' +#define DBUS_TYPE_INT64 (unsigned int)'x' +#define DBUS_TYPE_UINT64 (unsigned int)'t' +#define DBUS_TYPE_STRUCT_OPEN (unsigned int)'(' +#define DBUS_TYPE_STRUCT_CLOSE (unsigned int)')' +#define DBUS_TYPE_BYTE (unsigned int)'y' +#define DBUS_TYPE_OBJECT_PATH (unsigned int)'o' +#define DBUS_TYPE_SIGNATURE (unsigned int)'g' typedef void (* PFN_dbus_error_init)(struct DBusError*); typedef dbus_bool_t (* PFN_dbus_error_is_set)(const struct DBusError*); @@ -136,3 +147,10 @@ void _glfwCacheExecutableNameDBusPOSIX(void); void _glfwCacheDesktopFilePathDBusPOSIX(void); void _glfwTerminateDBusPOSIX(void); void _glfwUpdateTaskbarProgressDBusPOSIX(dbus_bool_t progressVisible, double progressValue); + +dbus_bool_t _glfwNewMessageSignalDBusPOSIX(const char* objectPath, const char* interfaceName, const char* signalName, struct DBusMessage** outMessage); +dbus_bool_t _glfwOpenContainerDBusPOSIX(struct DBusMessageIter* iterator, int DBusType, const char* signature, struct DBusMessageIter* subIterator); +dbus_bool_t _glfwCloseContainerDBusPOSIX(struct DBusMessageIter* iterator, struct DBusMessageIter* subIterator); +dbus_bool_t _glfwAppendDataDBusPOSIX(struct DBusMessageIter* iterator, int DBusType, const void* data); +dbus_bool_t _glfwAppendDictDataDBusPOSIX(struct DBusMessageIter* iterator, int keyType, const void* keyData, int valueType, const void* valueData); +dbus_bool_t _glfwSendMessageDBusPOSIX(struct DBusMessage* message); \ No newline at end of file