1 /*
2  * This file is part of brisk-menu.
3  *
4  * Copyright © 2017-2020 Brisk Menu Developers
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  */
11 
12 #define _GNU_SOURCE
13 
14 #include "util.h"
15 
16 BRISK_BEGIN_PEDANTIC
17 #include "backend.h"
18 BRISK_END_PEDANTIC
19 
20 /**
21  * IDs for our signals
22  */
23 enum { BACKEND_SIGNAL_ITEM_ADDED = 0,
24        BACKEND_SIGNAL_ITEM_REMOVED,
25        BACKEND_SIGNAL_SECTION_ADDED,
26        BACKEND_SIGNAL_SECTION_REMOVED,
27        BACKEND_SIGNAL_INVALIDATE_FILTER,
28        BACKEND_SIGNAL_HIDE_MENU,
29        BACKEND_SIGNAL_RESET,
30        N_SIGNALS };
31 
32 static guint backend_signals[N_SIGNALS] = { 0 };
33 
G_DEFINE_TYPE(BriskBackend,brisk_backend,G_TYPE_OBJECT)34 G_DEFINE_TYPE(BriskBackend, brisk_backend, G_TYPE_OBJECT)
35 
36 /**
37  * brisk_backend_dispose:
38  *
39  * Clean up a BriskBackend instance
40  */
41 static void brisk_backend_dispose(GObject *obj)
42 {
43         G_OBJECT_CLASS(brisk_backend_parent_class)->dispose(obj);
44 }
45 
46 /**
47  * brisk_backend_class_init:
48  *
49  * Handle class initialisation
50  */
brisk_backend_class_init(BriskBackendClass * klazz)51 static void brisk_backend_class_init(BriskBackendClass *klazz)
52 {
53         GObjectClass *obj_class = G_OBJECT_CLASS(klazz);
54 
55         /* gobject vtable hookup */
56         obj_class->dispose = brisk_backend_dispose;
57 
58         /**
59          * BriskBackend::item-added
60          * @backend: The backend that created the item
61          * @item: The newly available item
62          *
63          * Used to notify the frontend that a new item is available for consumption
64          */
65         backend_signals[BACKEND_SIGNAL_ITEM_ADDED] =
66             g_signal_new("item-added",
67                          BRISK_TYPE_BACKEND,
68                          G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
69                          G_STRUCT_OFFSET(BriskBackendClass, item_added),
70                          NULL,
71                          NULL,
72                          NULL,
73                          G_TYPE_NONE,
74                          1,
75                          BRISK_TYPE_ITEM);
76 
77         /**
78          * BriskBackend::item-removed
79          * @backend: The backend that removed the item
80          * @id: The item's ID that is being removed
81          *
82          * Used to notify the frontend that an item is being removed
83          */
84         backend_signals[BACKEND_SIGNAL_ITEM_REMOVED] =
85             g_signal_new("item-removed",
86                          BRISK_TYPE_BACKEND,
87                          G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
88                          G_STRUCT_OFFSET(BriskBackendClass, item_removed),
89                          NULL,
90                          NULL,
91                          NULL,
92                          G_TYPE_NONE,
93                          1,
94                          G_TYPE_STRING);
95 
96         /**
97          * BriskBackend::section-added
98          * @backend: The backend that created the section
99          * @item: The newly available section
100          *
101          * Used to notify the frontend that a new section is available for consumption
102          */
103         backend_signals[BACKEND_SIGNAL_SECTION_ADDED] =
104             g_signal_new("section-added",
105                          BRISK_TYPE_BACKEND,
106                          G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
107                          G_STRUCT_OFFSET(BriskBackendClass, section_added),
108                          NULL,
109                          NULL,
110                          NULL,
111                          G_TYPE_NONE,
112                          1,
113                          BRISK_TYPE_SECTION);
114 
115         /**
116          * BriskBackend::section-removed
117          * @backend: The backend that removed the section
118          * @id: The section's ID that is being removed
119          *
120          * Used to notify the frontend that an section is being removed
121          */
122         backend_signals[BACKEND_SIGNAL_SECTION_REMOVED] =
123             g_signal_new("section-removed",
124                          BRISK_TYPE_BACKEND,
125                          G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
126                          G_STRUCT_OFFSET(BriskBackendClass, section_removed),
127                          NULL,
128                          NULL,
129                          NULL,
130                          G_TYPE_NONE,
131                          1,
132                          G_TYPE_STRING);
133 
134         /**
135          * BriskBackend::invalidate-filter
136          * @backend: The backend that requested the invalidation
137          *
138          * Used to notify the frontend that the app list filter should be invalidated
139          */
140         backend_signals[BACKEND_SIGNAL_INVALIDATE_FILTER] =
141             g_signal_new("invalidate-filter",
142                          BRISK_TYPE_BACKEND,
143                          G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
144                          G_STRUCT_OFFSET(BriskBackendClass, invalidate_filter),
145                          NULL,
146                          NULL,
147                          NULL,
148                          G_TYPE_NONE,
149                          0);
150 
151         /**
152          * BriskBackend::hide-menu
153          * @backend: The backend that requested the hiding
154          *
155          * Used to notify the frontend that the menu window should be hidden
156          */
157         backend_signals[BACKEND_SIGNAL_HIDE_MENU] =
158             g_signal_new("hide-menu",
159                          BRISK_TYPE_BACKEND,
160                          G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
161                          G_STRUCT_OFFSET(BriskBackendClass, invalidate_filter),
162                          NULL,
163                          NULL,
164                          NULL,
165                          G_TYPE_NONE,
166                          0);
167 
168         /**
169          * BriskBackend::reset
170          * @backend: The backend that was reset
171          *
172          * Used to notify the frontend that all Item's should be destroyed
173          */
174         backend_signals[BACKEND_SIGNAL_RESET] =
175             g_signal_new("reset",
176                          BRISK_TYPE_BACKEND,
177                          G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
178                          G_STRUCT_OFFSET(BriskBackendClass, reset),
179                          NULL,
180                          NULL,
181                          NULL,
182                          G_TYPE_NONE,
183                          0);
184 }
185 
186 /**
187  * brisk_backend_init:
188  *
189  * Handle construction of the BriskBackend
190  */
brisk_backend_init(__brisk_unused__ BriskBackend * self)191 static void brisk_backend_init(__brisk_unused__ BriskBackend *self)
192 {
193 }
194 
195 /**
196  * brisk_backend_item_added:
197  *
198  * Implementations may use this method to emit the signal item-added
199  */
brisk_backend_item_added(BriskBackend * self,BriskItem * item)200 void brisk_backend_item_added(BriskBackend *self, BriskItem *item)
201 {
202         g_assert(self != NULL);
203         g_signal_emit(self, backend_signals[BACKEND_SIGNAL_ITEM_ADDED], 0, item);
204 }
205 
206 /**
207  * brisk_backend_item_removed:
208  *
209  * Implementations may use this method to emit the signal item-removed
210  */
brisk_backend_item_removed(BriskBackend * self,const gchar * id)211 void brisk_backend_item_removed(BriskBackend *self, const gchar *id)
212 {
213         g_assert(self != NULL);
214         g_signal_emit(self, backend_signals[BACKEND_SIGNAL_ITEM_REMOVED], 0, id);
215 }
216 
217 /**
218  * brisk_backend_section_added:
219  *
220  * Implementations may use this method to emit the signal section-added
221  */
brisk_backend_section_added(BriskBackend * self,BriskSection * section)222 void brisk_backend_section_added(BriskBackend *self, BriskSection *section)
223 {
224         g_assert(self != NULL);
225         g_signal_emit(self, backend_signals[BACKEND_SIGNAL_SECTION_ADDED], 0, section);
226 }
227 
228 /**
229  * brisk_backend_section_removed:
230  *
231  * Implementations may use this method to emit the signal section-removed
232  */
brisk_backend_section_removed(BriskBackend * self,const gchar * id)233 void brisk_backend_section_removed(BriskBackend *self, const gchar *id)
234 {
235         g_assert(self != NULL);
236         g_signal_emit(self, backend_signals[BACKEND_SIGNAL_SECTION_REMOVED], 0, id);
237 }
238 
239 /**
240  * brisk_backend_invalidate_filter:
241  *
242  * Implementations may use this method to emit the signal invalidate-filter
243  */
brisk_backend_invalidate_filter(BriskBackend * self)244 void brisk_backend_invalidate_filter(BriskBackend *self)
245 {
246         g_assert(self != NULL);
247         g_signal_emit(self, backend_signals[BACKEND_SIGNAL_INVALIDATE_FILTER], 0);
248 }
249 
250 /**
251  * brisk_backend_hide_menu:
252  *
253  * Implementations may use this method to emit the signal hide-menu
254  */
brisk_backend_hide_menu(BriskBackend * self)255 void brisk_backend_hide_menu(BriskBackend *self)
256 {
257         g_assert(self != NULL);
258         g_signal_emit(self, backend_signals[BACKEND_SIGNAL_HIDE_MENU], 0);
259 }
260 
261 /**
262  * brisk_backend_reset:
263  *
264  * Implementations may use this method to emit the signal reset
265  */
brisk_backend_reset(BriskBackend * self)266 void brisk_backend_reset(BriskBackend *self)
267 {
268         g_assert(self != NULL);
269         g_signal_emit(self, backend_signals[BACKEND_SIGNAL_RESET], 0);
270 }
271 
272 /**
273  * brisk_backend_get_flags:
274  *
275  * Return the supported flags for the backend
276  */
brisk_backend_get_flags(BriskBackend * backend)277 unsigned int brisk_backend_get_flags(BriskBackend *backend)
278 {
279         g_assert(backend != NULL);
280         BriskBackendClass *klazz = BRISK_BACKEND_GET_CLASS(backend);
281         g_assert(klazz->get_flags != NULL);
282         return klazz->get_flags(backend);
283 }
284 
285 /**
286  * brisk_backend_get_id:
287  *
288  * Return the unique ID for the backend
289  * @note This string is owned by the backend and must not be freed
290  */
brisk_backend_get_id(BriskBackend * backend)291 const gchar *brisk_backend_get_id(BriskBackend *backend)
292 {
293         g_assert(backend != NULL);
294         BriskBackendClass *klazz = BRISK_BACKEND_GET_CLASS(backend);
295         g_assert(klazz->get_id != NULL);
296         return klazz->get_id(backend);
297 }
298 
299 /**
300  * brisk_backend_get_display_name:
301  *
302  * Return the display name for the backend
303  * @note This string is owned by the backend and must not be freed
304  */
brisk_backend_get_display_name(BriskBackend * backend)305 const gchar *brisk_backend_get_display_name(BriskBackend *backend)
306 {
307         g_assert(backend != NULL);
308         BriskBackendClass *klazz = BRISK_BACKEND_GET_CLASS(backend);
309         g_assert(klazz->get_display_name != NULL);
310         return klazz->get_display_name(backend);
311 }
312 
brisk_backend_get_item_actions(BriskBackend * backend,BriskItem * item,GActionGroup * group)313 GMenu *brisk_backend_get_item_actions(BriskBackend *backend, BriskItem *item, GActionGroup *group)
314 {
315         g_assert(backend != NULL);
316         g_assert(item != NULL);
317         BriskBackendClass *klazz = BRISK_BACKEND_GET_CLASS(backend);
318         if (!klazz->get_item_actions) {
319                 return NULL;
320         }
321         return klazz->get_item_actions(backend, item, group);
322 }
323 
324 /**
325  * brisk_backend_load:
326  *
327  * Attempt to load the backend for the first time
328  */
brisk_backend_load(BriskBackend * backend)329 gboolean brisk_backend_load(BriskBackend *backend)
330 {
331         g_assert(backend != NULL);
332         BriskBackendClass *klazz = BRISK_BACKEND_GET_CLASS(backend);
333 
334         g_return_val_if_fail(klazz->load != NULL, FALSE);
335         return klazz->load(backend);
336 }
337 
338 /*
339  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
340  *
341  * Local variables:
342  * c-basic-offset: 8
343  * tab-width: 8
344  * indent-tabs-mode: nil
345  * End:
346  *
347  * vi: set shiftwidth=8 tabstop=8 expandtab:
348  * :indentSize=8:tabSize=8:noTabs=true:
349  */
350