1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
|
<!-- Automatically generated by emacsconf-publish-after-page -->
<a name="dbus-mainVideo-transcript"></a>
# Transcript
[[!template new="1" text="""Welcome to my EmacsConf 2022 talk, The Wheels on D-Bus.""" start="00:00:00.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""In this talk, we'll cover what D-Bus is,""" start="00:00:04.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""why you might want to use it, and how to use it with Emacs.""" start="00:00:07.440" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""D-Bus is fundamentally based on passing messages""" start="00:00:10.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""in between processes, using the bus as a mediator.""" start="00:00:13.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""On top of this is built an RPC system with method invocation""" start="00:00:17.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that has argument lists and return values,""" start="00:00:20.600" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""like you might find in any programming language.""" start="00:00:22.800" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""These are commonly used for verb-type actions""" start="00:00:25.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""like "restart my computer."""" start="00:00:27.840" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""You can also associate a collection of attributes""" start="00:00:30.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""with objects on the bus, and these are called properties.""" start="00:00:32.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""The properties can be read-only, write-only, or read-write.""" start="00:00:35.840" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Signals are a way of notifying participants on the bus""" start="00:00:39.840" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""of updated state, and are the basis""" start="00:00:43.160" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""for building dynamic user interfaces""" start="00:00:46.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that react to changes in the system.""" start="00:00:47.800" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""It has a static and strong type system,""" start="00:00:50.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""so if you send a message with the wrong type signature,""" start="00:00:52.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""it simply gets rejected instead of going through""" start="00:00:55.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""to the remote service.""" start="00:00:57.840" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""It also manages service life cycles,""" start="00:00:59.600" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""so you're not running services at all times.""" start="00:01:02.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""They can be started and stopped by D-Bus on demand.""" start="00:01:04.400" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""D-Bus has two major use cases.""" start="00:01:07.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""The first is acting as a lower-level substrate""" start="00:01:10.520" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""for higher-level programs,""" start="00:01:13.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""like a graphical desktop environment.""" start="00:01:14.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""For example, if you want to manage your network connectivity""" start="00:01:16.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""from your graphical environment,""" start="00:01:19.600" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""instead of having to build all of that from the ground up,""" start="00:01:21.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""you can rely on the D-Bus service to do that""" start="00:01:23.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and only build the graphical component of it.""" start="00:01:26.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""This gives you consistency between desktop environments""" start="00:01:28.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and reduces code duplication.""" start="00:01:31.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Another application is automating desktop programs.""" start="00:01:33.800" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""If your program offers a D-Bus service,""" start="00:01:37.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""then it can be remote-controlled,""" start="00:01:39.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and if all of your programs offer D-Bus,""" start="00:01:40.960" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""you can control your entire desktop.""" start="00:01:42.760" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""Let's look at the abstractions that D-Bus provides.""" start="00:01:45.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""The top level object is called a bus,""" start="00:01:48.560" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and it's like a partition""" start="00:01:51.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that messages get exchanged inside of.""" start="00:01:52.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Messages don't cross buses.""" start="00:01:54.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Inside of a bus are services.""" start="00:01:57.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Services are normally identified in reverse FQDN order,""" start="00:01:59.560" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""so org.foobar.FooService.""" start="00:02:03.160" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Each service provides some set of features""" start="00:02:06.160" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""related to a particular area of functionality.""" start="00:02:08.600" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Inside of each service are objects.""" start="00:02:11.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Objects use a path notation,""" start="00:02:14.440" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and usually follow the same reverse FQDN format""" start="00:02:16.600" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""as the service identifier.""" start="00:02:19.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Each object has one or more interfaces.""" start="00:02:21.960" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""An interface is like a facet that you can use""" start="00:02:24.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""to interact with an object,""" start="00:02:27.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and inside of the interface are properties, methods,""" start="00:02:29.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and signals, which we covered before.""" start="00:02:32.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Properties are attributes that can be read or written.""" start="00:02:34.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Methods are verbs that you can call to invoke an action,""" start="00:02:37.040" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and a signal is something that's used to move state""" start="00:02:40.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""in between a service and another participant on the bus.""" start="00:02:43.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""There can be any number of interfaces on an object,""" start="00:02:47.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""any number of objects in a service,""" start="00:02:49.600" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and any number of services on a bus,""" start="00:02:51.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and any number of buses on a system.""" start="00:02:53.440" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""There are two well-known busses,""" start="00:02:55.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and these roughly map to those two use cases""" start="00:03:00.040" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""I mentioned before.""" start="00:03:02.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""The system bus is for interfacing with hardware""" start="00:03:03.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and operating-system-level concerns""" start="00:03:06.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""like disks, networks, and so forth.""" start="00:03:08.440" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""The session bus is tied to a user login,""" start="00:03:11.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and is more in the desktop automation use case.""" start="00:03:14.320" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""There are some common interfaces you'll find""" start="00:03:20.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""if you go exploring D-Bus.""" start="00:03:21.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""The Introspectable interface is the basis""" start="00:03:23.960" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""of a lot of the reflection features.""" start="00:03:26.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""It has a single method called introspect""" start="00:03:27.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that returns the XML interface description""" start="00:03:30.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""of whatever you call it on.""" start="00:03:32.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Peer is used for lower level connectivity,""" start="00:03:33.400" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""for example, pinging a service to see if it's running.""" start="00:03:36.560" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And the Properties interface is the basis""" start="00:03:39.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""of the read-write properties,""" start="00:03:41.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""which are secretly method calls under the cover.""" start="00:03:43.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Just about every object you interact with on D-Bus""" start="00:03:45.800" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""will support all three of these interfaces.""" start="00:03:48.520" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Additionally, ObjectManager is used for services""" start="00:03:51.400" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that manage collections of objects.""" start="00:03:54.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""For example, the disk service has an object""" start="00:03:56.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""for each disk that's attached,""" start="00:03:59.840" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and the object manager allows you""" start="00:04:01.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""to enumerate all of those.""" start="00:04:02.800" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""Emacs supports D-Bus natively since version 23.1.""" start="00:04:06.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""It's a combination of native bindings""" start="00:04:10.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""with a C library and dbus.el.""" start="00:04:12.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""While there are some ports of D-Bus""" start="00:04:14.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""to non-Linux operating systems,""" start="00:04:17.560" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""it's probably only available on Linux""" start="00:04:19.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and almost certainly only usable on Linux.""" start="00:04:22.040" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""If you want to interact with D-Bus from Emacs,""" start="00:04:24.440" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""it's fairly straightforward.""" start="00:04:28.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""There's a collection of functions like `dbus-get-property'""" start="00:04:30.080" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""or `dbus-call-method', et cetera,""" start="00:04:33.200" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and they almost all take this same set""" start="00:04:35.040" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""of four arguments at the beginning:""" start="00:04:37.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""bus, service, path, and interface.""" start="00:04:39.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""In this case, it takes a single additional property,""" start="00:04:42.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""which is the one to read.""" start="00:04:45.440" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And what we're calling is the hostname1 service,""" start="00:04:46.600" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""which gives you just a little bit of information""" start="00:04:49.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""about the system, like its hostname or its chassis.""" start="00:04:51.520" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And in this case, you can see I'm running""" start="00:04:54.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""this presentation off my laptop.""" start="00:04:56.200" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""The problem with this and what I don't like about it""" start="00:04:57.720" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""is that all of these identifiers are very verbose""" start="00:05:00.960" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and very repetitive.""" start="00:05:04.600" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And if you end up calling these a lot,""" start="00:05:05.720" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""it gets old really quickly.""" start="00:05:07.680" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""So I wrote a wrapper called Debase,""" start="00:05:09.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""which is convenience on top of the built-in functions.""" start="00:05:13.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Most of the stock functions have Debase versions""" start="00:05:15.840" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""just by replacing "dbus" with "debase".""" start="00:05:18.840" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And let's look how that works.""" start="00:05:21.520" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""The fundamental idea of Debase is that you can bind together""" start="00:05:23.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""all of those arguments into a single object""" start="00:05:28.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that represents the endpoint.""" start="00:05:30.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""This is an EIEIO class, and it takes keyword arguments,""" start="00:05:31.560" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""so there's never any chance""" start="00:05:35.600" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""of mixing up which thing is what.""" start="00:05:36.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""So this sets the endpoint to that object,""" start="00:05:38.560" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""calls `debase-get-property' on it,""" start="00:05:41.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and you can see it works exactly the same.""" start="00:05:43.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""The thing that's really nice about this, though,""" start="00:05:45.040" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""is it knows that so many of these arguments""" start="00:05:47.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""are very similar that it can compute most of them""" start="00:05:50.200" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""if you don't provide them all.""" start="00:05:52.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""So if you just say service, it will assume""" start="00:05:54.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that you want the same object that matches""" start="00:05:57.160" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and the same interface that matches,""" start="00:05:59.160" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and it works just the same.""" start="00:06:00.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""I find this very, very convenient.""" start="00:06:02.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""You can also reuse the object""" start="00:06:04.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""instead of having to repeat every argument""" start="00:06:07.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""with every function call,""" start="00:06:09.160" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""which is a really great improvement in ergonomics.""" start="00:06:10.400" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""Because so many objects have multiple interfaces,""" start="00:06:13.440" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""you often find yourself needing to look""" start="00:06:18.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""at a different aspect of that object.""" start="00:06:20.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""This is supported with the built-in EIEIO `clone' method,""" start="00:06:22.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""which takes an object""" start="00:06:26.600" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and a set of keyword arguments to replace.""" start="00:06:28.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""So in this case, we can see we're calling""" start="00:06:30.440" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""the Properties method,""" start="00:06:32.600" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""but everything else on that endpoint is the same.""" start="00:06:33.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And then we're gonna call the method GetAll""" start="00:06:35.800" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""on that Properties interface,""" start="00:06:38.080" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and it's going to return all the properties""" start="00:06:39.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""of the org.freedesktop.hostname1 interface""" start="00:06:41.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""inside of that object.""" start="00:06:43.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And if we run that, we can see there's the hostname""" start="00:06:45.200" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and some other information about the laptop""" start="00:06:48.200" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that I'm running this on.""" start="00:06:50.160" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""Debase also supports object binding.""" start="00:06:51.080" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""This creates a lexical context in which the Debase object""" start="00:06:54.400" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""is the implicit target of any D-Bus function.""" start="00:06:58.560" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""This is really convenient if you need""" start="00:07:01.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""to fetch multiple properties or otherwise interact""" start="00:07:03.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""with the same endpoint in multiple different ways.""" start="00:07:06.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And you can see I'm still on a laptop""" start="00:07:09.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and it's still named meson.""" start="00:07:11.360" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""You can also, if you don't want to use the object,""" start="00:07:12.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""you can provide the raw argument list.""" start="00:07:16.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Under the covers, this is basically an `flet'""" start="00:07:18.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""where you're currying all of these functions""" start="00:07:20.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""so they start with those argument lists.""" start="00:07:23.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And you can see I'm running on a Linux machine,""" start="00:07:25.440" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""which should not be surprising.""" start="00:07:27.800" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""Debase also has an experimental code generation feature.""" start="00:07:29.400" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""It outputs EIEIO code with one class per D-Bus interface.""" start="00:07:34.080" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""This includes accessors for all of its properties""" start="00:07:38.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""with an in-process cache, so if you read one property,""" start="00:07:41.080" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""you don't have to go back to the bus to read it again.""" start="00:07:44.160" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""It also outputs generic functions and method implementations""" start="00:07:46.400" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""for the D-Bus interface methods.""" start="00:07:50.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""It includes name-mangling options,""" start="00:07:52.200" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""so you can control how everything is named.""" start="00:07:54.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And you can generate the code either""" start="00:07:56.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""via introspecting a live system""" start="00:07:58.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""or providing an XML interface description,""" start="00:08:00.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""which is handy if you want to use it""" start="00:08:02.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""as part of a non-interactive build.""" start="00:08:04.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""I think this has a lot of promise,""" start="00:08:05.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""but it doesn't feel quite right yet,""" start="00:08:08.160" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""so any feedback or contributions are very welcome.""" start="00:08:09.680" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""Let's generate some Elisp code""" start="00:08:14.200" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""for that hostname1 service we were interacting with before.""" start="00:08:16.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""`debase-gen-class' is the generation class,""" start="00:08:19.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and it says to create a class that matches this interface,""" start="00:08:23.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""named "hostname1", and then the rest of these arguments""" start="00:08:26.080" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""are the same ones to target the endpoint,""" start="00:08:29.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""just like with `debase-object',""" start="00:08:31.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""because it extends `debase-object'.""" start="00:08:32.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""`debase-gen-code' is a generic function""" start="00:08:34.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that takes any `debase-gen' class.""" start="00:08:37.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""There are different classes for functions,""" start="00:08:40.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""properties, et cetera,""" start="00:08:42.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and it creates all of the code for it.""" start="00:08:43.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""If we evaluate it, we can see the results""" start="00:08:45.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""look about like we would expect:""" start="00:08:48.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""creates a defclass named "hostname1",""" start="00:08:49.960" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""which extends `debase-object',""" start="00:08:52.160" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""has all of the slots and accessors defined,""" start="00:08:53.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and then methods that define everything""" start="00:08:56.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that you might want to do with it, including documentation.""" start="00:08:59.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""This is based on introspecting a running system,""" start="00:09:01.840" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""but as I mentioned,""" start="00:09:04.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""you can provide an XML interface description instead,""" start="00:09:05.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""if you like.""" start="00:09:08.040" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""Debase also comes with `debase-objectmanager',""" start="00:09:08.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""which is convenience for the D-Bus ObjectManager interface.""" start="00:09:12.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""This is used in a lot of places in D-Bus,""" start="00:09:15.400" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""where an object manages other objects.""" start="00:09:18.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""For example, the NetworkManager object""" start="00:09:20.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""manages network hardware objects,""" start="00:09:22.720" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and using the ObjectManager interface,""" start="00:09:25.160" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""you can enumerate all of the network hardware,""" start="00:09:26.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and by subscribing to the signals,""" start="00:09:28.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""you can be notified when they change.""" start="00:09:31.040" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""`debase-objectmanager' keeps a local cache,""" start="00:09:33.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and will fire a callback on any change.""" start="00:09:36.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""So it's the building block for that dynamic user interface,""" start="00:09:38.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""like you would see in a desktop system,""" start="00:09:41.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""but inside of Emacs.""" start="00:09:43.120" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""Let's do some demos.""" start="00:09:44.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Discomfort is an interface I wrote for UDisks2,""" start="00:09:47.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""which is what manages all of the block device hardware.""" start="00:09:51.040" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And again, it has that dynamic desktop-like interactivity,""" start="00:09:53.720" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and mostly will just do what you mean.""" start="00:09:57.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""This is definitely alpha state.""" start="00:10:00.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""It doesn't have all the features,""" start="00:10:03.520" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""but it's good enough that I use it daily.""" start="00:10:04.840" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""So here's Discomfort,""" start="00:10:06.560" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and you can see it has a list of all your hardware,""" start="00:10:08.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""what type it is, and where it's mounted.""" start="00:10:11.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""I have a little USB extension cable here,""" start="00:10:13.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and I'm gonna plug in a disc,""" start="00:10:16.200" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""just to show you how this works.""" start="00:10:17.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""You can see when I plug it in,""" start="00:10:19.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""just a moment later,""" start="00:10:21.080" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""it shows up in that list, automatically.""" start="00:10:22.400" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""I don't have to press any key,""" start="00:10:24.440" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""I don't have to refresh it, it's just there.""" start="00:10:25.720" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""If I unplug it, it's gone.""" start="00:10:27.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Plug it back in,""" start="00:10:29.520" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and there it is.""" start="00:10:30.720" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And you can see it's an encrypted volume.""" start="00:10:33.400" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""So in order to do anything with this,""" start="00:10:35.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""I'm going to have to supply a password.""" start="00:10:37.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Just pressing Enter goes into the "do what I mean" mode,""" start="00:10:38.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and it asks for the password.""" start="00:10:41.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""In this case, I've chosen the very secure password""" start="00:10:43.520" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""of "password".""" start="00:10:46.600" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""I hit Enter, and it unlocks it, and it mounts it,""" start="00:10:47.560" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and it opens `dired' looking at it.""" start="00:10:51.200" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And here's a little README.""" start="00:10:53.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Let's see what it says.""" start="00:10:54.440" video="mainVideo-dbus" id="subtitle"]]
[[!template text=""""Hello, EmacsConf."""" start="00:10:55.560" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""So that's my demo of discomfort.""" start="00:10:58.560" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""In addition to acting as a client for D-Bus,""" start="00:11:01.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Emacs can also offer services to other D-Bus clients.""" start="00:11:05.840" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""This is a really interesting opportunity""" start="00:11:09.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""because it allows many different programs""" start="00:11:11.960" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""to integrate with Emacs""" start="00:11:14.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""in ways that were previously very difficult.""" start="00:11:15.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""You can use this as an alternative to Emacs.""" start="00:11:17.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""The difference is D-Bus provides a full API,""" start="00:11:20.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""so instead of emacsclient being""" start="00:11:23.200" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""a sort of fire-and-forget system,""" start="00:11:25.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""you can actually get results back from the remote operation.""" start="00:11:26.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""So here's some code.""" start="00:11:30.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Here's a `dbus-eval' function, which takes a string,""" start="00:11:32.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""reads it, and evaluates it,""" start="00:11:35.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and returns whatever that value is.""" start="00:11:37.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Then we have a `debase-bind' block""" start="00:11:39.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that sets up an object on the session bus.""" start="00:11:41.840" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Again, that's my user login bus.""" start="00:11:44.800" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""It offers this D-Bus service Emacs.""" start="00:11:46.840" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""This is a constant inside of the dbus.el package.""" start="00:11:49.560" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And again, the path is a constant in there.""" start="00:11:53.400" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And we're gonna create this interface,""" start="00:11:55.440" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""org.gnu.Emacs.Eval, and then register a method called Eval""" start="00:11:57.160" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that calls that `dbus-eval' function.""" start="00:12:02.520" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Pretty straightforward, only a handful of lines of code.""" start="00:12:04.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""To test this out, we're going to use the dbus-send utility.""" start="00:12:08.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""This is a command line program that interacts with D-Bus.""" start="00:12:12.400" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""We're going to tell it to wait for and print the reply,""" start="00:12:15.400" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that the message should be sent to the session bus,""" start="00:12:18.080" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that we're going to talk""" start="00:12:21.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""to the org.gnu.Emacs service on that bus,""" start="00:12:22.600" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and the /org/gnu/Emacs object inside that service.""" start="00:12:25.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""On that object, we're gonna interact""" start="00:12:30.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""with the org.gnu.Emacs.Eval interface""" start="00:12:33.040" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and call its Eval method.""" start="00:12:36.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""We're gonna call that method with a single string argument,""" start="00:12:37.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""which is indicated by the string prefix,""" start="00:12:40.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and then a form to evaluate.""" start="00:12:42.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""I actually have to run this from a shell,""" start="00:12:45.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""because if I try using it in Org, it wedges.""" start="00:12:47.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""org-babel blocks waiting on completion,""" start="00:12:49.400" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""which blocks the D-Bus service from responding.""" start="00:12:51.960" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""I really wish Emacs was multi-threaded.""" start="00:12:54.520" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""But let's try it out.""" start="00:12:57.400" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""So if we run this, we can see that we get a return,""" start="00:12:59.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and that's an unsigned integer of 32 bits""" start="00:13:02.720" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""with a value of 3.""" start="00:13:05.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""So like I was saying, this is really a two-way API""" start="00:13:06.440" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""where you can communicate back and forth""" start="00:13:09.960" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""between Emacs and another program.""" start="00:13:11.720" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""It's not just fire-and-forget.""" start="00:13:13.400" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""I think that's really cool.""" start="00:13:14.960" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""Let's try another demo.""" start="00:13:16.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""What about a remote org-capture?""" start="00:13:18.520" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""What if you could trigger an org-capture""" start="00:13:20.600" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""from any program on your desktop?""" start="00:13:23.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""I think that would be pretty cool.""" start="00:13:24.680" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And we can see, there it is.""" start="00:13:26.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""All right, I think I've got that one covered.""" start="00:13:30.240" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""So I do want to say that remote eval is probably a bad idea""" start="00:13:38.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""from a security perspective,""" start="00:13:42.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""but the point of this is some quick and dirty demonstrations""" start="00:13:43.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""of what can happen and to get people's imaginations flowing,""" start="00:13:46.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""because I think this is something""" start="00:13:49.800" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that offers a lot of promise for Emacs.""" start="00:13:51.720" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""I think having a full-blown Emacs desktop environment""" start="00:13:54.080" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""where it can do all the things that a GNOME""" start="00:13:57.800" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""or a KDE environment can do is very exciting.""" start="00:13:59.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""And if you want to have a traditional GUI with Emacs""" start="00:14:02.760" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""as a more integrated participant of it,""" start="00:14:06.440" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""its service mechanism offers a lot of ability to do that.""" start="00:14:08.680" video="mainVideo-dbus" id="subtitle"]]
[[!template new="1" text="""In the micro sense, I think there's a lot of improvements""" start="00:14:11.880" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""that can be made to either dbus.el or to dbase.""" start="00:14:16.000" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""The main one is handling of the type system.""" start="00:14:19.280" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Lisp's dynamic type system doesn't mesh particularly well""" start="00:14:21.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""with the static strong type system that D-bus offers,""" start="00:14:25.840" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and having some convenience to assist that""" start="00:14:28.800" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""would be very helpful.""" start="00:14:31.360" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""There's also some weird interfaces.""" start="00:14:32.640" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""For example, some things return identifiers""" start="00:14:35.320" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""as an array of integer code points instead of a string,""" start="00:14:38.120" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and there should be a common way of handling that.""" start="00:14:40.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""I also think that the service support could be improved.""" start="00:14:43.720" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Even though I gave the demo service,""" start="00:14:46.160" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""it's not really a great D-bus citizen""" start="00:14:48.040" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""because it doesn't offer that introspection mechanism,""" start="00:14:50.480" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""and so the actual methods are pretty much invisible""" start="00:14:53.080" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""to other participants,""" start="00:14:55.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""unless they already know that you're using Emacs.""" start="00:14:56.920" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""That's my talk.""" start="00:15:00.080" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""Thank you.""" start="00:15:01.800" video="mainVideo-dbus" id="subtitle"]]
[[!template text="""You can find me on mastodon.social or on libera.chat.""" start="00:15:02.560" video="mainVideo-dbus" id="subtitle"]]
Captioner: sachac
Questions or comments? Please e-mail [emacsconf-org-private@gnu.org](mailto:emacsconf-org-private@gnu.org?subject=Comment%20for%20EmacsConf%202022%20dbus%3A%20The%20Wheels%20on%20D-Bus)
<!-- End of emacsconf-publish-after-page -->
|