1 /* copyright 2013 Sascha Kruse and contributors (see LICENSE for licensing information) */
2 #ifndef DUNST_NOTIFICATION_H
3 #define DUNST_NOTIFICATION_H
4 
5 #include <gdk-pixbuf/gdk-pixbuf.h>
6 #include <glib.h>
7 #include <stdbool.h>
8 
9 #include "markup.h"
10 
11 #define DUNST_NOTIF_MAX_CHARS 50000
12 
13 enum behavior_fullscreen {
14         FS_NULL,      //!< Invalid value
15         FS_DELAY,     //!< Delay the notification until leaving fullscreen mode
16         FS_PUSHBACK,  //!< When entering fullscreen mode, push the notification back to waiting
17         FS_SHOW,      //!< Show the message when in fullscreen mode
18 };
19 
20 /// Representing the urgencies according to the notification spec
21 enum urgency {
22         URG_NONE = -1, /**< Urgency not set (invalid) */
23         URG_MIN = 0,   /**< Minimum value, useful for boundary checking */
24         URG_LOW = 0,   /**< Low urgency */
25         URG_NORM = 1,  /**< Normal urgency */
26         URG_CRIT = 2,  /**< Critical urgency */
27         URG_MAX = 2,   /**< Maximum value, useful for boundary checking */
28 };
29 
30 typedef struct _notification_private NotificationPrivate;
31 
32 struct notification_colors {
33         char *frame;
34         char *bg;
35         char *fg;
36         char *highlight;
37 };
38 
39 struct notification {
40         NotificationPrivate *priv;
41         int id;
42         char *dbus_client;
43         bool dbus_valid;
44 
45         char *appname;
46         char *summary;
47         char *body;
48         char *category;
49         char *desktop_entry;     /**< The desktop entry hint sent via every GApplication */
50         enum urgency urgency;
51 
52         GdkPixbuf *icon;         /**< The raw cached icon data used to draw */
53         char *icon_id;           /**< plain icon information, which acts as the pixbuf's id, which is saved in .icon
54                                       May be a hash for a raw icon or a name/path for a regular app icon. */
55         char *iconname;          /**< plain icon information (may be a path or just a name)
56                                       Use this to compare the icon name with rules.*/
57 
58         gint64 start;      /**< begin of current display (in milliseconds) */
59         gint64 timestamp;  /**< arrival time (in milliseconds) */
60         gint64 timeout;    /**< time to display (in milliseconds) */
61         int locked;     /**< If non-zero the notification is locked **/
62 
63         GHashTable *actions;
64 
65         enum markup_mode markup;
66         const char *format;
67         const char **scripts;
68         int script_count;
69         struct notification_colors colors;
70 
71         char *stack_tag;    /**< stack notifications by tag */
72 
73         /* Hints */
74         bool transient;     /**< timeout albeit user is idle */
75         int progress;       /**< percentage (-1: undefined) */
76         int history_ignore; /**< push to history or free directly */
77         int skip_display;   /**< insert notification into history, skipping initial waiting and display */
78 
79         /* internal */
80         bool redisplayed;       /**< has been displayed before? */
81         bool first_render;      /**< markup has been rendered before? */
82         int dup_count;          /**< amount of duplicate notifications stacked onto this */
83         int displayed_height;
84         enum behavior_fullscreen fullscreen; //!< The instruction what to do with it, when desktop enters fullscreen
85         bool script_run;        /**< Has the script been executed already? */
86         guint8 marked_for_closure;
87 
88         /* derived fields */
89         char *msg;            /**< formatted message */
90         char *text_to_render; /**< formatted message (with age and action indicators) */
91         char *urls;           /**< urllist delimited by '\\n' */
92 };
93 
94 /**
95  * Create notification struct and initialise all fields with either
96  *  - the default (if it's not needed to be freed later)
97  *  - its undefined representation (NULL, -1)
98  *
99  * The reference counter is set to 1.
100  *
101  * This function is guaranteed to return a valid pointer.
102  * @returns The generated notification
103  */
104 struct notification *notification_create(void);
105 
106 /**
107  * Retrieve the current reference count of the notification
108  */
109 gint notification_refcount_get(struct notification *n);
110 
111 /**
112  * Increase the reference counter of the notification.
113  */
114 void notification_ref(struct notification *n);
115 
116 /**
117  * Sanitize values of notification, apply all matching rules
118  * and generate derived fields.
119  *
120  * @param n: the notification to sanitize
121  */
122 void notification_init(struct notification *n);
123 
124 /**
125  * Decrease the reference counter of the notification.
126  *
127  * If the reference count drops to 0, the object gets freed.
128  */
129 void notification_unref(struct notification *n);
130 
131 /**
132  * Helper function to compare two given notifications.
133  */
134 int notification_cmp(const struct notification *a, const struct notification *b);
135 
136 /**
137  * Wrapper for notification_cmp to match glib's
138  * compare functions signature.
139  */
140 int notification_cmp_data(const void *va, const void *vb, void *data);
141 
142 bool notification_is_duplicate(const struct notification *a, const struct notification *b);
143 
144 bool notification_is_locked(struct notification *n);
145 
146 struct notification *notification_lock(struct notification *n);
147 
148 struct notification *notification_unlock(struct notification *n);
149 
150 /**Replace the current notification's icon with the icon specified by path.
151  *
152  * Removes the reference for the previous icon automatically and will also free the
153  * iconname field. So passing n->iconname as new_icon is invalid.
154  *
155  * @param n the notification to replace the icon
156  * @param new_icon The path of the new icon. May be an absolute path or an icon name.
157  */
158 void notification_icon_replace_path(struct notification *n, const char *new_icon);
159 
160 /**Replace the current notification's icon with the raw icon given in the GVariant.
161  *
162  * Removes the reference for the previous icon automatically.
163  *
164  * @param n the notification to replace the icon
165  * @param new_icon The icon's data. Has to be in the format of the notification spec.
166  */
167 void notification_icon_replace_data(struct notification *n, GVariant *new_icon);
168 
169 /**
170  * Run the script associated with the
171  * given notification.
172  *
173  * If the script of the notification has been executed already and
174  * settings.always_run_script is not set, do nothing.
175  */
176 void notification_run_script(struct notification *n);
177 /**
178  * print a human readable representation
179  * of the given notification to stdout.
180  */
181 void notification_print(const struct notification *n);
182 
183 /**
184  * Replace the two chars where **needle points
185  * with a quoted "replacement", according to the markup settings.
186  *
187  * The needle is a double pointer and gets updated upon return
188  * to point to the first char, which occurs after replacement.
189  */
190 void notification_replace_single_field(char **haystack,
191                                        char **needle,
192                                        const char *replacement,
193                                        enum markup_mode markup_mode);
194 
195 void notification_update_text_to_render(struct notification *n);
196 
197 /**
198  * If the notification has exactly one action, or one is marked as default,
199  * invoke it. If there are multiple and no default, open the context menu. If
200  * there are no actions, proceed similarly with urls.
201  */
202 void notification_do_action(const struct notification *n);
203 
204 /**
205  * Remove all client action data from the notification.
206  *
207  * This should be called after a notification is closed to avoid showing
208  * actions that will not work anymore since the client has stopped listening
209  * for them.
210  */
211 void notification_invalidate_actions(struct notification *n);
212 
213 const char *notification_urgency_to_string(const enum urgency urgency);
214 
215 /**
216  * Return the string representation for fullscreen behavior
217  *
218  * @param in the #behavior_fullscreen enum value to represent
219  * @return the string representation for `in`
220  */
221 const char *enum_to_string_fullscreen(enum behavior_fullscreen in);
222 
223 #endif
224 /* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
225