Prevent improper display of (old style) OSD text when widgets are enabled

This commit is contained in:
jdgleaver 2020-03-05 12:23:14 +00:00
parent b5c87aaef8
commit 35977efe43
4 changed files with 194 additions and 10 deletions

View File

@ -752,10 +752,14 @@ bool disk_control_verify_initial_index(disk_control_interface_t *disk_control)
RARCH_LOG("%s\n", msg);
/* Note: Do not flush message queue here, since
* it is likely other notifications will be
* generated before setting the disk index, and
* we do not want to 'overwrite' them */
runloop_msg_queue_push(
msg,
0, msg_duration,
true, NULL,
false, NULL,
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
}

View File

@ -44,6 +44,16 @@ enum message_queue_category
typedef struct msg_queue msg_queue_t;
typedef struct
{
char msg[1024];
char title[1024];
unsigned duration;
unsigned prio;
enum message_queue_icon icon;
enum message_queue_category category;
} msg_queue_entry_t;
/**
* msg_queue_new:
* @size : maximum size of message
@ -82,6 +92,28 @@ void msg_queue_push(msg_queue_t *queue, const char *msg,
**/
const char *msg_queue_pull(msg_queue_t *queue);
/**
* msg_queue_extract:
* @queue : pointer to queue object
* @queue_entry : pointer to external queue entry struct
*
* Removes highest priority message from queue, copying
* contents into queue_entry struct.
*
* Returns: false if no messages in queue, otherwise true
**/
bool msg_queue_extract(msg_queue_t *queue, msg_queue_entry_t *queue_entry);
/**
* msg_queue_size:
* @queue : pointer to queue object
*
* Fetches number of messages in queue.
*
* Returns: Number of messages in queue.
**/
size_t msg_queue_size(msg_queue_t *queue);
/**
* msg_queue_clear:
* @queue : pointer to queue object

View File

@ -127,6 +127,9 @@ void msg_queue_push(msg_queue_t *queue, const char *msg,
new_elem->prio = prio;
new_elem->duration = duration;
new_elem->msg = msg ? strdup(msg) : NULL;
new_elem->title = title ? strdup(title) : NULL;
new_elem->icon = icon;
new_elem->category = category;
queue->elems[queue->ptr] = new_elem;
@ -165,6 +168,7 @@ void msg_queue_clear(msg_queue_t *queue)
if (queue->elems[i])
{
free(queue->elems[i]->msg);
free(queue->elems[i]->title);
free(queue->elems[i]);
queue->elems[i] = NULL;
}
@ -203,9 +207,9 @@ const char *msg_queue_pull(msg_queue_t *queue)
queue->tmp_msg = front->msg;
front->msg = NULL;
front = (struct queue_elem*)queue->elems[1];
last = (struct queue_elem*)queue->elems[--queue->ptr];
queue->elems[1] = last;
free(front->title);
free(front);
for (;;)
@ -243,3 +247,100 @@ const char *msg_queue_pull(msg_queue_t *queue)
return queue->tmp_msg;
}
/**
* msg_queue_extract:
* @queue : pointer to queue object
* @queue_entry : pointer to external queue entry struct
*
* Removes highest priority message from queue, copying
* contents into queue_entry struct.
*
* Returns: false if no messages in queue, otherwise true
**/
bool msg_queue_extract(msg_queue_t *queue, msg_queue_entry_t *queue_entry)
{
struct queue_elem *front = NULL, *last = NULL;
size_t tmp_ptr = 1;
(void)tmp_ptr;
/* Ensure arguments are valid and queue is not
* empty */
if (!queue || queue->ptr == 1 || !queue_entry)
return false;
front = (struct queue_elem*)queue->elems[1];
last = (struct queue_elem*)queue->elems[--queue->ptr];
queue->elems[1] = last;
/* Copy element parameters */
queue_entry->duration = front->duration;
queue_entry->prio = front->prio;
queue_entry->icon = front->icon;
queue_entry->category = front->category;
queue_entry->msg[0] = '\0';
queue_entry->title[0] = '\0';
if (front->msg)
strlcpy(queue_entry->msg, front->msg, sizeof(queue_entry->msg));
if (front->title)
strlcpy(queue_entry->title, front->title, sizeof(queue_entry->title));
/* Delete element */
free(front->msg);
free(front->title);
free(front);
for (;;)
{
struct queue_elem *parent = NULL;
struct queue_elem *child = NULL;
size_t switch_index = tmp_ptr;
bool left = (tmp_ptr * 2 <= queue->ptr)
&& (queue->elems[tmp_ptr] < queue->elems[tmp_ptr * 2]);
bool right = (tmp_ptr * 2 + 1 <= queue->ptr)
&& (queue->elems[tmp_ptr] < queue->elems[tmp_ptr * 2 + 1]);
if (!left && !right)
break;
if (left && !right)
switch_index <<= 1;
else if (right && !left)
switch_index += switch_index + 1;
else
{
if (queue->elems[tmp_ptr * 2]
>= queue->elems[tmp_ptr * 2 + 1])
switch_index <<= 1;
else
switch_index += switch_index + 1;
}
parent = (struct queue_elem*)queue->elems[tmp_ptr];
child = (struct queue_elem*)queue->elems[switch_index];
queue->elems[tmp_ptr] = child;
queue->elems[switch_index] = parent;
tmp_ptr = switch_index;
}
return true;
}
/**
* msg_queue_size:
* @queue : pointer to queue object
*
* Fetches number of messages in queue.
*
* Returns: Number of messages in queue.
**/
size_t msg_queue_size(msg_queue_t *queue)
{
if (!queue || queue->ptr <= 1)
return 0;
return queue->ptr - 1;
}

View File

@ -1087,6 +1087,7 @@ static retro_keyboard_event_t runloop_key_event = NULL;
static retro_keyboard_event_t runloop_frontend_key_event = NULL;
static core_option_manager_t *runloop_core_options = NULL;
static msg_queue_t *runloop_msg_queue = NULL;
static size_t runloop_msg_queue_size = 0;
static unsigned runloop_pending_windowed_scale = 0;
static unsigned runloop_max_frames = 0;
@ -3741,7 +3742,8 @@ static void retroarch_msg_queue_deinit(void)
_runloop_msg_queue_lock = NULL;
#endif
runloop_msg_queue = NULL;
runloop_msg_queue = NULL;
runloop_msg_queue_size = 0;
}
static void retroarch_msg_queue_init(void)
@ -23597,14 +23599,57 @@ static void video_driver_frame(const void *data, unsigned width,
video_driver_msg[0] = '\0';
if (video_info.font_enable)
if (runloop_msg_queue_size > 0)
{
const char *msg = NULL;
runloop_msg_queue_lock();
msg = msg_queue_pull(runloop_msg_queue);
if (msg)
strlcpy(video_driver_msg, msg, sizeof(video_driver_msg));
runloop_msg_queue_unlock();
/* If widgets are currently enabled, then
* messages were pushed to the queue before
* widgets were initialised - in this case, the
* first item in the message queue should be
* extracted and pushed to the widget message
* queue instead */
#if defined(HAVE_GFX_WIDGETS)
if (gfx_widgets_inited)
{
bool msg_found = false;
msg_queue_entry_t msg_entry;
runloop_msg_queue_lock();
msg_found = msg_queue_extract(runloop_msg_queue, &msg_entry);
runloop_msg_queue_size = msg_queue_size(runloop_msg_queue);
runloop_msg_queue_unlock();
if (msg_found)
gfx_widgets_msg_queue_push(
NULL,
msg_entry.msg,
roundf((float)msg_entry.duration / 60.0f * 1000.0f),
msg_entry.title,
msg_entry.icon,
msg_entry.category,
msg_entry.prio,
false,
#ifdef HAVE_MENU
menu_driver_alive
#else
false
#endif
);
}
/* ...otherwise, just output message via
* regular OSD notification text (if enabled) */
else if (video_info.font_enable)
#else
if (video_info.font_enable)
#endif
{
const char *msg = NULL;
runloop_msg_queue_lock();
msg = msg_queue_pull(runloop_msg_queue);
runloop_msg_queue_size = msg_queue_size(runloop_msg_queue);
if (msg)
strlcpy(video_driver_msg, msg, sizeof(video_driver_msg));
runloop_msg_queue_unlock();
}
}
if (video_info.statistics_show)
@ -28570,6 +28615,8 @@ void runloop_msg_queue_push(const char *msg,
msg_queue_push(runloop_msg_queue, msg,
prio, duration,
title, icon, category);
runloop_msg_queue_size = msg_queue_size(runloop_msg_queue);
}
ui_companion_driver_msg_queue_push(msg,