@@ -127,6 +127,9 @@ void msg_queue_push(msg_queue_t *queue, const char *msg,
127127 new_elem -> prio = prio ;
128128 new_elem -> duration = duration ;
129129 new_elem -> msg = msg ? strdup (msg ) : NULL ;
130+ new_elem -> title = title ? strdup (title ) : NULL ;
131+ new_elem -> icon = icon ;
132+ new_elem -> category = category ;
130133
131134 queue -> elems [queue -> ptr ] = new_elem ;
132135
@@ -165,6 +168,7 @@ void msg_queue_clear(msg_queue_t *queue)
165168 if (queue -> elems [i ])
166169 {
167170 free (queue -> elems [i ]-> msg );
171+ free (queue -> elems [i ]-> title );
168172 free (queue -> elems [i ]);
169173 queue -> elems [i ] = NULL ;
170174 }
@@ -203,9 +207,9 @@ const char *msg_queue_pull(msg_queue_t *queue)
203207 queue -> tmp_msg = front -> msg ;
204208 front -> msg = NULL ;
205209
206- front = (struct queue_elem * )queue -> elems [1 ];
207210 last = (struct queue_elem * )queue -> elems [-- queue -> ptr ];
208211 queue -> elems [1 ] = last ;
212+ free (front -> title );
209213 free (front );
210214
211215 for (;;)
@@ -243,3 +247,100 @@ const char *msg_queue_pull(msg_queue_t *queue)
243247
244248 return queue -> tmp_msg ;
245249}
250+
251+ /**
252+ * msg_queue_extract:
253+ * @queue : pointer to queue object
254+ * @queue_entry : pointer to external queue entry struct
255+ *
256+ * Removes highest priority message from queue, copying
257+ * contents into queue_entry struct.
258+ *
259+ * Returns: false if no messages in queue, otherwise true
260+ **/
261+ bool msg_queue_extract (msg_queue_t * queue , msg_queue_entry_t * queue_entry )
262+ {
263+ struct queue_elem * front = NULL , * last = NULL ;
264+ size_t tmp_ptr = 1 ;
265+
266+ (void )tmp_ptr ;
267+
268+ /* Ensure arguments are valid and queue is not
269+ * empty */
270+ if (!queue || queue -> ptr == 1 || !queue_entry )
271+ return false;
272+
273+ front = (struct queue_elem * )queue -> elems [1 ];
274+ last = (struct queue_elem * )queue -> elems [-- queue -> ptr ];
275+ queue -> elems [1 ] = last ;
276+
277+ /* Copy element parameters */
278+ queue_entry -> duration = front -> duration ;
279+ queue_entry -> prio = front -> prio ;
280+ queue_entry -> icon = front -> icon ;
281+ queue_entry -> category = front -> category ;
282+ queue_entry -> msg [0 ] = '\0' ;
283+ queue_entry -> title [0 ] = '\0' ;
284+
285+ if (front -> msg )
286+ strlcpy (queue_entry -> msg , front -> msg , sizeof (queue_entry -> msg ));
287+
288+ if (front -> title )
289+ strlcpy (queue_entry -> title , front -> title , sizeof (queue_entry -> title ));
290+
291+ /* Delete element */
292+ free (front -> msg );
293+ free (front -> title );
294+ free (front );
295+
296+ for (;;)
297+ {
298+ struct queue_elem * parent = NULL ;
299+ struct queue_elem * child = NULL ;
300+ size_t switch_index = tmp_ptr ;
301+ bool left = (tmp_ptr * 2 <= queue -> ptr )
302+ && (queue -> elems [tmp_ptr ] < queue -> elems [tmp_ptr * 2 ]);
303+ bool right = (tmp_ptr * 2 + 1 <= queue -> ptr )
304+ && (queue -> elems [tmp_ptr ] < queue -> elems [tmp_ptr * 2 + 1 ]);
305+
306+ if (!left && !right )
307+ break ;
308+
309+ if (left && !right )
310+ switch_index <<= 1 ;
311+ else if (right && !left )
312+ switch_index += switch_index + 1 ;
313+ else
314+ {
315+ if (queue -> elems [tmp_ptr * 2 ]
316+ >= queue -> elems [tmp_ptr * 2 + 1 ])
317+ switch_index <<= 1 ;
318+ else
319+ switch_index += switch_index + 1 ;
320+ }
321+
322+ parent = (struct queue_elem * )queue -> elems [tmp_ptr ];
323+ child = (struct queue_elem * )queue -> elems [switch_index ];
324+ queue -> elems [tmp_ptr ] = child ;
325+ queue -> elems [switch_index ] = parent ;
326+ tmp_ptr = switch_index ;
327+ }
328+
329+ return true;
330+ }
331+
332+ /**
333+ * msg_queue_size:
334+ * @queue : pointer to queue object
335+ *
336+ * Fetches number of messages in queue.
337+ *
338+ * Returns: Number of messages in queue.
339+ **/
340+ size_t msg_queue_size (msg_queue_t * queue )
341+ {
342+ if (!queue || queue -> ptr <= 1 )
343+ return 0 ;
344+
345+ return queue -> ptr - 1 ;
346+ }
0 commit comments