Anklang 0.3.0-460-gc4ef46ba
ASE — Anklang Sound Engine (C++)

« « « Anklang Documentation
Loading...
Searching...
No Matches
dbus.cc
Go to the documentation of this file.
1 // This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
2#include "dbus.hh"
3#include "strings.hh"
4
5#if !__has_include(<dbus/dbus.h>)
6#error "Missing <dbus/dbus.h> from libdbus-dev, please set CXXFLAGS and LDFLAGS"
7#endif
8#include <dbus/dbus.h>
9
10namespace Ase::DBus {
11
12static DBusConnection*
13get_system_dbus()
14{
15 static DBusConnection *bcon = [] () {
16 DBusError error;
17 dbus_error_init (&error);
18 DBusConnection *bcon = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error);
19 if (bcon)
20 dbus_connection_set_exit_on_disconnect (bcon, false);
21 dbus_error_free (&error);
22 return bcon;
23 } ();
24 return bcon;
25}
26
28rtkit_make_high_priority (pid_t thread, int nice_level)
29{
30 const String realtimekit1 = "org.freedesktop.RealtimeKit1";
31 const char *const DISABLE_RTKIT = getenv ("DISABLE_RTKIT");
32 if (DISABLE_RTKIT && DISABLE_RTKIT[0])
33 return string_format ("%s: %s", realtimekit1, strerror (ENOTSUP));
34 DBusConnection *bcon = get_system_dbus();
35 if (!bcon)
36 return string_format ("%s: %s", realtimekit1, strerror (ECONNREFUSED));
37
38 DBusMessage *m = dbus_message_new_method_call (realtimekit1.c_str(), // service name
39 "/org/freedesktop/RealtimeKit1", // object path
40 "org.freedesktop.RealtimeKit1", // object interface
41 "MakeThreadHighPriority"); // method
42 if (m)
43 {
44 dbus_uint64_t tid = thread;
45 dbus_int32_t prio = nice_level;
46 if (!dbus_message_append_args (m, DBUS_TYPE_UINT64, &tid, DBUS_TYPE_INT32, &prio, DBUS_TYPE_INVALID)) {
47 dbus_message_unref (m);
48 m = nullptr;
49 }
50 }
51 if (!m)
52 return string_format ("%s: %s", realtimekit1, strerror (ENOMEM));
53
54 DBusError error;
55 dbus_error_init (&error);
56 DBusMessage *r = dbus_connection_send_with_reply_and_block (bcon, m, -1, &error);
57 dbus_message_unref (m);
58 String emsg = "";
59 if (r)
60 {
61 if (dbus_set_error_from_message (&error, r))
62 emsg = error.name;
63 dbus_message_unref (r);
64 }
65 else
66 emsg = error.name;
67 dbus_error_free (&error);
68 return emsg.empty() ? "" : string_format ("%s: %s", realtimekit1, emsg);
69}
70
71int
72rtkit_get_min_nice_level ()
73{
74 const char *const DISABLE_RTKIT = getenv ("DISABLE_RTKIT");
75 if (DISABLE_RTKIT && DISABLE_RTKIT[0])
76 return 0;
77 DBusConnection *bcon = get_system_dbus();
78 if (!bcon)
79 return 0;
80
81 DBusMessage *m = dbus_message_new_method_call ("org.freedesktop.RealtimeKit1", // service name
82 "/org/freedesktop/RealtimeKit1", // object path
83 "org.freedesktop.DBus.Properties", // object interface
84 "Get"); // method
85 if (m)
86 {
87 const char *rtkinterface = "org.freedesktop.RealtimeKit1";
88 const char *proeprty = "MinNiceLevel";
89 if (!dbus_message_append_args (m, DBUS_TYPE_STRING, &rtkinterface, DBUS_TYPE_STRING, &proeprty, DBUS_TYPE_INVALID)) {
90 dbus_message_unref (m);
91 m = nullptr;
92 }
93 }
94 if (!m)
95 return 0;
96
97 DBusError error;
98 dbus_error_init (&error);
99 DBusMessage *r = dbus_connection_send_with_reply_and_block (bcon, m, -1, &error);
100 dbus_message_unref (m);
101 int nice_level = 0;
102 if (r)
103 {
104 if (!dbus_set_error_from_message (&error, r))
105 {
106 DBusMessageIter mit;
107 dbus_message_iter_init (r, &mit);
108 for (int mtype; mtype = dbus_message_iter_get_arg_type (&mit), mtype != DBUS_TYPE_INVALID; dbus_message_iter_next (&mit))
109 if (mtype == DBUS_TYPE_VARIANT)
110 {
111 DBusMessageIter rit;
112 dbus_message_iter_recurse (&mit, &rit);
113 for (int rtype; rtype = dbus_message_iter_get_arg_type (&rit), rtype != DBUS_TYPE_INVALID; dbus_message_iter_next (&rit))
114 {
115 DBusBasicValue u = {};
116 dbus_message_iter_get_basic (&rit, &u);
117 if (rtype == DBUS_TYPE_INT32)
118 nice_level = u.i32;
119 if (rtype == DBUS_TYPE_INT64)
120 nice_level = u.i64;
121 }
122 }
123 }
124 dbus_message_unref (r);
125 }
126 dbus_error_free (&error);
127 return nice_level;
128}
129
130} // Ase::DBus
getenv
std::string string_format(const char *format, const Args &...args) __attribute__((__format__(__printf__
Format a string similar to sprintf(3) with support for std::string and std::ostringstream convertible...
std::string String
Convenience alias for std::string.
Definition cxxaux.hh:35