quakeforge/ruamoko/qwaq/qwaq-curses.c

1276 lines
31 KiB
C
Raw Normal View History

/*
#FILENAME#
#DESCRIPTION#
Copyright (C) 2001 #AUTHOR#
Author: #AUTHOR#
Date: #DATE#
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <curses.h>
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
#include <panel.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "QF/dstring.h"
#include "QF/progs.h"
#include "QF/sys.h"
#include "qwaq.h"
#include "event.h"
#define always_inline inline __attribute__((__always_inline__))
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
#define QUEUE_SIZE 16
#define MOUSE_MOVES_ON "\033[?1003h"// Make the terminal report mouse movements
#define MOUSE_MOVES_OFF "\033[?1003l"// Make the terminal report mouse movements
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
#define STRING_ID_QUEUE_SIZE 8 // must be > 1
#define COMMAND_QUEUE_SIZE 1280
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
#define CMD_SIZE(x) sizeof(x)/sizeof(x[0])
typedef enum qwaq_commands_e {
qwaq_cmd_newwin,
qwaq_cmd_delwin,
qwaq_cmd_getwrect,
qwaq_cmd_new_panel,
qwaq_cmd_del_panel,
qwaq_cmd_hide_panel,
qwaq_cmd_show_panel,
qwaq_cmd_top_panel,
qwaq_cmd_bottom_panel,
qwaq_cmd_move_panel,
qwaq_cmd_panel_window,
qwaq_cmd_update_panels,
qwaq_cmd_doupdate,
qwaq_cmd_mvwaddstr,
qwaq_cmd_waddstr,
2020-03-02 09:24:45 +00:00
qwaq_cmd_mvwaddch,
qwaq_cmd_wrefresh,
2020-02-29 05:48:18 +00:00
qwaq_cmd_init_pair,
qwaq_cmd_wbkgd,
qwaq_cmd_scrollok,
qwaq_cmd_move,
qwaq_cmd_curs_set,
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
} qwaq_commands;
const char *qwaq_command_names[]= {
"newwin",
"delwin",
"getwrect",
"new_panel",
"del_panel",
"hide_panel",
"show_panel",
"top_panel",
"bottom_panel",
"move_panel",
"panel_window",
"update_panels",
"doupdate",
"mvwaddstr",
"waddstr",
"mvwaddch",
"wrefresh",
"init_pair",
"wbkgd",
"scrollok",
"move",
"curs_set",
#define RING_BUFFER(type, size) \
struct { \
type buffer[size]; \
unsigned head; \
unsigned tail; \
}
#define RB_buffer_size(ring_buffer) \
({ __auto_type rb = (ring_buffer); \
sizeof (rb->buffer) / sizeof (rb->buffer[0]); \
})
#define RB_SPACE_AVAILABLE(ring_buffer) \
({ __auto_type rb = &(ring_buffer); \
(rb->tail + RB_buffer_size(rb) - rb->head - 1) % RB_buffer_size(rb);\
})
#define RB_DATA_AVAILABLE(ring_buffer) \
({ __auto_type rb = &(ring_buffer); \
(rb->head + RB_buffer_size (rb) - rb->tail) % RB_buffer_size (rb); \
})
#define RB_WRITE_DATA(ring_buffer, data, count) \
({ __auto_type rb = &(ring_buffer); \
const typeof (rb->buffer[0]) *d = (data); \
unsigned c = (count); \
unsigned h = rb->head; \
rb->head = (h + c) % RB_buffer_size (rb); \
if (c > RB_buffer_size (rb) - h) { \
memcpy (rb->buffer + h, d, \
(RB_buffer_size (rb) - h) * sizeof (rb->buffer[0])); \
c -= RB_buffer_size (rb) - h; \
d += RB_buffer_size (rb) - h; \
h = 0; \
} \
memcpy (rb->buffer + h, d, c * sizeof (rb->buffer[0])); \
})
#define RB_READ_DATA(ring_buffer, data, count) \
({ __auto_type rb = &(ring_buffer); \
typeof (&rb->buffer[0]) d = (data); \
unsigned c = (count); \
unsigned oc = c; \
unsigned t = rb->tail; \
if (c > RB_buffer_size (rb) - t) { \
memcpy (d, rb->buffer + t, \
(RB_buffer_size (rb) - t) * sizeof (rb->buffer[0])); \
c -= RB_buffer_size (rb) - t; \
d += RB_buffer_size (rb) - t; \
t = 0; \
} \
memcpy (d, rb->buffer + t, c * sizeof (rb->buffer[0])); \
rb->tail = (t + oc) % RB_buffer_size (rb); \
})
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
#define RB_DROP_DATA(ring_buffer, count) \
({ __auto_type rb = &(ring_buffer); \
unsigned c = (count); \
unsigned t = rb->tail; \
rb->tail = (t + c) % RB_buffer_size (rb); \
})
#define RB_PEEK_DATA(ring_buffer, ahead) \
({ __auto_type rb = &(ring_buffer); \
rb->buffer[(rb->tail + ahead) % RB_buffer_size (rb)]; \
})
#define RB_POKE_DATA(ring_buffer, ahead, data) \
({ __auto_type rb = &(ring_buffer); \
rb->buffer[(rb->tail + ahead) % RB_buffer_size (rb)] = (data); \
})
typedef struct window_s {
WINDOW *win;
} window_t;
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
typedef struct panel_s {
PANEL *panel;
int window_id;
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
} panel_t;
typedef struct qwaq_resources_s {
progs_t *pr;
int initialized;
2020-02-29 05:38:54 +00:00
window_t stdscr;
PR_RESMAP (window_t) window_map;
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
PR_RESMAP (panel_t) panel_map;
RING_BUFFER (qwaq_event_t, QUEUE_SIZE) event_queue;
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
RING_BUFFER (int, COMMAND_QUEUE_SIZE) command_queue;
RING_BUFFER (int, COMMAND_QUEUE_SIZE) results;
RING_BUFFER (int, STRING_ID_QUEUE_SIZE) string_ids;
dstring_t strings[STRING_ID_QUEUE_SIZE - 1];
} qwaq_resources_t;
static window_t *
window_new (qwaq_resources_t *res)
{
PR_RESNEW (window_t, res->window_map);
}
static void
window_free (qwaq_resources_t *res, window_t *win)
{
PR_RESFREE (window_t, res->window_map, win);
}
static void
window_reset (qwaq_resources_t *res)
{
PR_RESRESET (window_t, res->window_map);
}
static inline window_t *
window_get (qwaq_resources_t *res, unsigned index)
{
PR_RESGET(res->window_map, index);
}
static inline int
window_index (qwaq_resources_t *res, window_t *win)
{
PR_RESINDEX (res->window_map, win);
}
static always_inline window_t * __attribute__((pure))
get_window (qwaq_resources_t *res, const char *name, int handle)
{
2020-02-29 05:38:54 +00:00
if (handle == 1) {
return &res->stdscr;
}
window_t *window = window_get (res, handle);
if (!window || !window->win) {
PR_RunError (res->pr, "invalid window passed to %s", name + 3);
}
return window;
}
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
static panel_t *
panel_new (qwaq_resources_t *res)
{
PR_RESNEW (panel_t, res->panel_map);
}
static void
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
panel_free (qwaq_resources_t *res, panel_t *win)
{
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
PR_RESFREE (panel_t, res->panel_map, win);
}
static void
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
panel_reset (qwaq_resources_t *res)
{
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
PR_RESRESET (panel_t, res->panel_map);
}
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
static inline panel_t *
panel_get (qwaq_resources_t *res, unsigned index)
{
PR_RESGET(res->panel_map, index);
}
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
static inline int
panel_index (qwaq_resources_t *res, panel_t *win)
{
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
PR_RESINDEX (res->panel_map, win);
}
static always_inline panel_t * __attribute__((pure))
get_panel (qwaq_resources_t *res, const char *name, int handle)
{
panel_t *panel = panel_get (res, handle);
if (!panel || !panel->panel) {
PR_RunError (res->pr, "invalid panel passed to %s", name + 3);
}
return panel;
}
static int
acquire_string (qwaq_resources_t *res)
{
int string_id = -1;
// XXX add locking and loop for available
if (RB_DATA_AVAILABLE (res->string_ids)) {
RB_READ_DATA (res->string_ids, &string_id, 1);
}
// XXX unlock and end of loop
return string_id;
}
static void
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
release_string (qwaq_resources_t *res, int string_id)
{
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
// locking shouldn't be necessary as there should be only one writer
// but if it becomes such that there is more than one writer, locks as per
// acquire
if (RB_SPACE_AVAILABLE (res->string_ids)) {
RB_WRITE_DATA (res->string_ids, &string_id, 1);
}
}
static void
qwaq_submit_command (qwaq_resources_t *res, const int *cmd)
{
unsigned len = cmd[1];
if (RB_SPACE_AVAILABLE (res->command_queue) >= len) {
RB_WRITE_DATA (res->command_queue, cmd, len);
} else {
PR_RunError (res->pr, "command buffer full");
}
}
static void
qwaq_submit_result (qwaq_resources_t *res, const int *result, unsigned len)
{
// loop
if (RB_SPACE_AVAILABLE (res->results) >= len) {
RB_WRITE_DATA (res->results, result, len);
} else {
PR_RunError (res->pr, "result buffer full");
}
}
//XXX goes away with threads
static void process_commands (qwaq_resources_t *);
static void process_input (qwaq_resources_t *);
static void
qwaq_wait_result (qwaq_resources_t *res, int *result, int cmd, unsigned len)
{
// XXX should just wait on the mutex
process_commands (res);
process_input (res);
// locking and loop until id is correct
if (RB_DATA_AVAILABLE (res->results) >= len
&& RB_PEEK_DATA (res->results, 0) == cmd) {
RB_READ_DATA (res->results, result, len);
}
}
static void
cmd_newwin (qwaq_resources_t *res)
{
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
int xpos = RB_PEEK_DATA (res->command_queue, 2);
int ypos = RB_PEEK_DATA (res->command_queue, 3);
int xlen = RB_PEEK_DATA (res->command_queue, 4);
int ylen = RB_PEEK_DATA (res->command_queue, 5);
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
window_t *window = window_new (res);
window->win = newwin (ylen, xlen, ypos, xpos);
keypad (window->win, TRUE);
int window_id = window_index (res, window);
int cmd_result[] = { qwaq_cmd_newwin, window_id };
qwaq_submit_result (res, cmd_result, CMD_SIZE (cmd_result));
}
static void
cmd_delwin (qwaq_resources_t *res)
{
int window_id = RB_PEEK_DATA (res->command_queue, 2);
window_t *window = get_window (res, __FUNCTION__, window_id);
delwin (window->win);
window_free (res, window);
}
static void
cmd_getwrect (qwaq_resources_t *res)
{
int window_id = RB_PEEK_DATA (res->command_queue, 2);
int xpos, ypos;
int xlen, ylen;
window_t *window = get_window (res, __FUNCTION__, window_id);
getparyx (window->win, ypos, xpos);
if (xpos == -1 && ypos ==-1) {
getbegyx (window->win, ypos, xpos);
}
getmaxyx (window->win, ylen, xlen);
int cmd_result[] = { qwaq_cmd_getwrect, xpos, ypos, xlen, ylen };
qwaq_submit_result (res, cmd_result, CMD_SIZE (cmd_result));
}
static void
cmd_new_panel (qwaq_resources_t *res)
{
int window_id = RB_PEEK_DATA (res->command_queue, 2);
window_t *window = get_window (res, __FUNCTION__, window_id);
panel_t *panel = panel_new (res);
panel->panel = new_panel (window->win);
panel->window_id = window_id;
int panel_id = panel_index (res, panel);
int cmd_result[] = { qwaq_cmd_new_panel, panel_id };
qwaq_submit_result (res, cmd_result, CMD_SIZE (cmd_result));
}
static void
cmd_del_panel (qwaq_resources_t *res)
{
int panel_id = RB_PEEK_DATA (res->command_queue, 2);
panel_t *panel = get_panel (res, __FUNCTION__, panel_id);
del_panel (panel->panel);
panel_free (res, panel);
}
static void
cmd_hide_panel (qwaq_resources_t *res)
{
int panel_id = RB_PEEK_DATA (res->command_queue, 2);
panel_t *panel = get_panel (res, __FUNCTION__, panel_id);
hide_panel (panel->panel);
panel_free (res, panel);
}
static void
cmd_show_panel (qwaq_resources_t *res)
{
int panel_id = RB_PEEK_DATA (res->command_queue, 2);
panel_t *panel = get_panel (res, __FUNCTION__, panel_id);
show_panel (panel->panel);
panel_free (res, panel);
}
static void
cmd_top_panel (qwaq_resources_t *res)
{
int panel_id = RB_PEEK_DATA (res->command_queue, 2);
panel_t *panel = get_panel (res, __FUNCTION__, panel_id);
top_panel (panel->panel);
panel_free (res, panel);
}
static void
cmd_bottom_panel (qwaq_resources_t *res)
{
int panel_id = RB_PEEK_DATA (res->command_queue, 2);
panel_t *panel = get_panel (res, __FUNCTION__, panel_id);
bottom_panel (panel->panel);
panel_free (res, panel);
}
static void
cmd_move_panel (qwaq_resources_t *res)
{
int panel_id = RB_PEEK_DATA (res->command_queue, 2);
int x = RB_PEEK_DATA (res->command_queue, 3);
int y = RB_PEEK_DATA (res->command_queue, 4);
panel_t *panel = get_panel (res, __FUNCTION__, panel_id);
move_panel (panel->panel, y, x);
panel_free (res, panel);
}
static void
cmd_panel_window (qwaq_resources_t *res)
{
int panel_id = RB_PEEK_DATA (res->command_queue, 2);
panel_t *panel = get_panel (res, __FUNCTION__, panel_id);
int window_id = panel->window_id;
int cmd_result[] = { qwaq_cmd_panel_window, window_id, };
qwaq_submit_result (res, cmd_result, CMD_SIZE (cmd_result));
}
static void
cmd_update_panels (qwaq_resources_t *res)
{
update_panels ();
}
static void
cmd_doupdate (qwaq_resources_t *res)
{
doupdate ();
}
static void
cmd_mvwaddstr (qwaq_resources_t *res)
{
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
int window_id = RB_PEEK_DATA (res->command_queue, 2);
int x = RB_PEEK_DATA (res->command_queue, 3);
int y = RB_PEEK_DATA (res->command_queue, 4);
int string_id = RB_PEEK_DATA (res->command_queue, 5);
window_t *window = get_window (res, __FUNCTION__, window_id);
mvwaddstr (window->win, y, x, res->strings[string_id].str);
release_string (res, string_id);
}
static void
cmd_waddstr (qwaq_resources_t *res)
{
int window_id = RB_PEEK_DATA (res->command_queue, 2);
int string_id = RB_PEEK_DATA (res->command_queue, 3);
window_t *window = get_window (res, __FUNCTION__, window_id);
waddstr (window->win, res->strings[string_id].str);
release_string (res, string_id);
}
2020-03-02 09:24:45 +00:00
static void
cmd_mvwaddch (qwaq_resources_t *res)
{
int window_id = RB_PEEK_DATA (res->command_queue, 2);
int x = RB_PEEK_DATA (res->command_queue, 3);
int y = RB_PEEK_DATA (res->command_queue, 4);
int ch = RB_PEEK_DATA (res->command_queue, 5);
window_t *window = get_window (res, __FUNCTION__, window_id);
mvwaddch (window->win, y, x, ch);
}
static void
cmd_wrefresh (qwaq_resources_t *res)
{
int window_id = RB_PEEK_DATA (res->command_queue, 2);
window_t *window = get_window (res, __FUNCTION__, window_id);
wrefresh (window->win);
}
2020-02-29 05:48:18 +00:00
static void
cmd_init_pair (qwaq_resources_t *res)
{
int pair = RB_PEEK_DATA (res->command_queue, 2);
int f = RB_PEEK_DATA (res->command_queue, 3);
int b = RB_PEEK_DATA (res->command_queue, 4);
init_pair (pair, f, b);
}
static void
cmd_wbkgd (qwaq_resources_t *res)
{
int window_id = RB_PEEK_DATA (res->command_queue, 2);
int ch = RB_PEEK_DATA (res->command_queue, 3);
window_t *window = get_window (res, __FUNCTION__, window_id);
wbkgd (window->win, ch);
}
static void
cmd_scrollok (qwaq_resources_t *res)
{
int window_id = RB_PEEK_DATA (res->command_queue, 2);
int flag = RB_PEEK_DATA (res->command_queue, 3);
window_t *window = get_window (res, __FUNCTION__, window_id);
scrollok (window->win, flag);
}
static void
cmd_move (qwaq_resources_t *res)
{
int x = RB_PEEK_DATA (res->command_queue, 2);
int y = RB_PEEK_DATA (res->command_queue, 3);
move (y, x);
}
static void
cmd_curs_set (qwaq_resources_t *res)
{
int visibility = RB_PEEK_DATA (res->command_queue, 2);
curs_set (visibility);
}
static void
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
process_commands (qwaq_resources_t *res)
{
while (RB_DATA_AVAILABLE (res->command_queue) >= 2) {
qwaq_commands cmd = RB_PEEK_DATA (res->command_queue, 0);
int len = RB_PEEK_DATA (res->command_queue, 1);
Sys_Printf ("%s[%d]", qwaq_command_names[cmd], len);
for (int i = 2; i < len; i++) {
Sys_Printf (" %d", RB_PEEK_DATA (res->command_queue, i));
}
Sys_Printf ("\n");
switch (cmd) {
case qwaq_cmd_newwin:
cmd_newwin (res);
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
break;
case qwaq_cmd_delwin:
cmd_delwin (res);
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
break;
case qwaq_cmd_getwrect:
cmd_getwrect (res);
break;
case qwaq_cmd_new_panel:
cmd_new_panel (res);
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
break;
case qwaq_cmd_del_panel:
cmd_del_panel (res);
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
break;
case qwaq_cmd_hide_panel:
cmd_hide_panel (res);
break;
case qwaq_cmd_show_panel:
cmd_show_panel (res);
break;
case qwaq_cmd_top_panel:
cmd_top_panel (res);
break;
case qwaq_cmd_bottom_panel:
cmd_bottom_panel (res);
break;
case qwaq_cmd_move_panel:
cmd_move_panel (res);
break;
case qwaq_cmd_panel_window:
cmd_panel_window (res);
break;
case qwaq_cmd_update_panels:
cmd_update_panels (res);
break;
case qwaq_cmd_doupdate:
cmd_doupdate (res);
break;
case qwaq_cmd_mvwaddstr:
cmd_mvwaddstr (res);
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
break;
case qwaq_cmd_waddstr:
cmd_waddstr (res);
break;
2020-03-02 09:24:45 +00:00
case qwaq_cmd_mvwaddch:
cmd_mvwaddch (res);
break;
case qwaq_cmd_wrefresh:
cmd_wrefresh (res);
break;
2020-02-29 05:48:18 +00:00
case qwaq_cmd_init_pair:
cmd_init_pair (res);
break;
case qwaq_cmd_wbkgd:
cmd_wbkgd (res);
break;
case qwaq_cmd_scrollok:
cmd_scrollok (res);
break;
case qwaq_cmd_move:
cmd_move (res);
break;
case qwaq_cmd_curs_set:
cmd_curs_set (res);
break;
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
}
RB_DROP_DATA (res->command_queue, RB_PEEK_DATA (res->command_queue, 1));
}
}
static void
add_event (qwaq_resources_t *res, qwaq_event_t *event)
{
// lock
// {
// merge motion events
unsigned last = RB_DATA_AVAILABLE (res->event_queue);
if (event->what == qe_mousemove && last > 1
&& RB_PEEK_DATA(res->event_queue, last - 1).what == qe_mousemove) {
RB_POKE_DATA(res->event_queue, last - 1, *event);
return; // unlock
}
// }
if (RB_SPACE_AVAILABLE (res->event_queue) >= 1) {
RB_WRITE_DATA (res->event_queue, event, 1);
}
}
static int
get_event (qwaq_resources_t *res, qwaq_event_t *event)
{
if (RB_DATA_AVAILABLE (res->event_queue) >= 1) {
if (event) {
RB_READ_DATA (res->event_queue, event, 1);
}
return 1;
}
return 0;
}
#define M_MOVE REPORT_MOUSE_POSITION
#define M_PRESS ( BUTTON1_PRESSED \
| BUTTON2_PRESSED \
| BUTTON3_PRESSED \
| BUTTON4_PRESSED \
| BUTTON5_PRESSED)
#define M_RELEASE ( BUTTON1_RELEASED \
| BUTTON2_RELEASED \
| BUTTON3_RELEASED \
| BUTTON4_RELEASED \
| BUTTON5_RELEASED)
#define M_CLICK ( BUTTON1_CLICKED \
| BUTTON2_CLICKED \
| BUTTON3_CLICKED \
| BUTTON4_CLICKED \
| BUTTON5_CLICKED)
#define M_DCLICK ( BUTTON1_DOUBLE_CLICKED \
| BUTTON2_DOUBLE_CLICKED \
| BUTTON3_DOUBLE_CLICKED \
| BUTTON4_DOUBLE_CLICKED \
| BUTTON5_DOUBLE_CLICKED)
#define M_TCLICK ( BUTTON1_TRIPLE_CLICKED \
| BUTTON2_TRIPLE_CLICKED \
| BUTTON3_TRIPLE_CLICKED \
| BUTTON4_TRIPLE_CLICKED \
| BUTTON5_TRIPLE_CLICKED)
static void
mouse_event (qwaq_resources_t *res, const MEVENT *mevent)
{
int mask = mevent->bstate;
qwaq_event_t event = {};
event.mouse.x = mevent->x;
event.mouse.y = mevent->y;
event.mouse.buttons = mevent->bstate;
if (mask & M_MOVE) {
event.what = qe_mousemove;
mask &= ~M_MOVE;
}
if (mask & M_PRESS) {
event.what = qe_mousedown;
mask &= ~M_PRESS;
}
if (mask & M_RELEASE) {
event.what = qe_mouseup;
mask &= ~M_RELEASE;
}
if (mask & M_CLICK) {
event.what = qe_mouseclick;
mask &= ~M_CLICK;
event.mouse.click = 1;
}
if (mask & M_DCLICK) {
event.what = qe_mouseclick;
mask &= ~M_DCLICK;
event.mouse.click = 2;
}
if (mask & M_TCLICK) {
event.what = qe_mouseclick;
mask &= ~M_TCLICK;
event.mouse.click = 3;
}
add_event (res, &event);
}
static void
key_event (qwaq_resources_t *res, int key)
{
qwaq_event_t event = {};
event.what = qe_keydown;
event.key = key;
add_event (res, &event);
}
static void
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
process_input (qwaq_resources_t *res)
{
if (Sys_CheckInput (1, -1)) {
int ch;
while ((ch = getch ()) != ERR && ch) {
fflush (stderr);
if (ch == KEY_MOUSE) {
MEVENT mevent;
getmouse (&mevent);
mouse_event (res, &mevent);
} else {
key_event (res, ch);
}
}
}
}
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
static int need_endwin;
static void
bi_shutdown (void)
{
if (need_endwin) {
write(1, MOUSE_MOVES_OFF, sizeof (MOUSE_MOVES_OFF) - 1);
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
endwin ();
}
}
static void
bi_newwin (progs_t *pr)
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int xpos = P_INT (pr, 0);
int ypos = P_INT (pr, 1);
int xlen = P_INT (pr, 2);
int ylen = P_INT (pr, 3);
int command[] = {
qwaq_cmd_newwin, 0,
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
xpos, ypos, xlen, ylen,
};
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
int cmd_result[2];
qwaq_wait_result (res, cmd_result, qwaq_cmd_newwin, CMD_SIZE (cmd_result));
R_INT (pr) = cmd_result[1];
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
}
static void
bi_delwin (progs_t *pr)
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int window_id = P_INT (pr, 0);
if (get_window (res, __FUNCTION__, window_id)) {
int command[] = { qwaq_cmd_delwin, 0, window_id, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
}
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
}
static void
bi_getwrect (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int window_id = P_INT (pr, 0);
if (get_window (res, __FUNCTION__, window_id)) {
int command[] = { qwaq_cmd_getwrect, 0, window_id, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
int cmd_result[5];
qwaq_wait_result (res, cmd_result, qwaq_cmd_getwrect,
CMD_SIZE (cmd_result));
// return xpos, ypos, xlen, ylen
(&R_INT (pr))[0] = cmd_result[1];
(&R_INT (pr))[1] = cmd_result[2];
(&R_INT (pr))[2] = cmd_result[3];
(&R_INT (pr))[3] = cmd_result[4];
}
}
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
static void
bi_new_panel (progs_t *pr)
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int window_id = P_INT (pr, 0);
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
if (get_window (res, __FUNCTION__, window_id)) {
int command[] = { qwaq_cmd_new_panel, 0, window_id, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
int cmd_result[2];
qwaq_wait_result (res, cmd_result, qwaq_cmd_new_panel,
CMD_SIZE (cmd_result));
R_INT (pr) = cmd_result[1];
}
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
}
static void
panel_command (progs_t *pr, qwaq_commands cmd)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int panel_id = P_INT (pr, 0);
if (get_panel (res, __FUNCTION__, panel_id)) {
int command[] = { cmd, 0, panel_id, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
}
}
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
static void
bi_del_panel (progs_t *pr)
{
panel_command (pr, qwaq_cmd_del_panel);
}
static void
bi_hide_panel (progs_t *pr)
{
panel_command (pr, qwaq_cmd_hide_panel);
}
static void
bi_show_panel (progs_t *pr)
{
panel_command (pr, qwaq_cmd_show_panel);
}
static void
bi_top_panel (progs_t *pr)
{
panel_command (pr, qwaq_cmd_top_panel);
}
static void
bi_bottom_panel (progs_t *pr)
{
panel_command (pr, qwaq_cmd_bottom_panel);
}
static void
bi_move_panel (progs_t *pr)
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int panel_id = P_INT (pr, 0);
int x = P_INT (pr, 1);
int y = P_INT (pr, 2);
if (get_panel (res, __FUNCTION__, panel_id)) {
int command[] = { qwaq_cmd_move_panel, 0, panel_id, x, y, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
}
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
}
static void
bi_panel_window (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int panel_id = P_INT (pr, 0);
if (get_panel (res, __FUNCTION__, panel_id)) {
int command[] = { qwaq_cmd_panel_window, 0, panel_id, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
int cmd_result[2];
qwaq_wait_result (res, cmd_result, qwaq_cmd_panel_window,
CMD_SIZE (cmd_result));
(&R_INT (pr))[0] = cmd_result[1];
}
}
static void
bi_update_panels (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int command[] = { qwaq_cmd_update_panels, 0, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
}
static void
bi_doupdate (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int command[] = { qwaq_cmd_doupdate, 0, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
}
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
static void
bi_mvwprintf (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int window_id = P_INT (pr, 0);
int x = P_INT (pr, 1);
int y = P_INT (pr, 2);
const char *fmt = P_GSTRING (pr, 3);
int count = pr->pr_argc - 4;
pr_type_t **args = pr->pr_params + 4;
if (get_window (res, __FUNCTION__, window_id)) {
int string_id = acquire_string (res);
dstring_t *print_buffer = res->strings + string_id;
int command[] = {
qwaq_cmd_mvwaddstr, 0,
window_id, x, y, string_id
};
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
command[1] = CMD_SIZE(command);
dstring_clearstr (print_buffer);
PR_Sprintf (pr, print_buffer, "mvwaddstr", fmt, count, args);
qwaq_submit_command (res, command);
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
}
}
static void
bi_wprintf (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int window_id = P_INT (pr, 0);
const char *fmt = P_GSTRING (pr, 1);
int count = pr->pr_argc - 2;
pr_type_t **args = pr->pr_params + 2;
if (get_window (res, __FUNCTION__, window_id)) {
int string_id = acquire_string (res);
dstring_t *print_buffer = res->strings + string_id;
int command[] = {
qwaq_cmd_waddstr, 0,
window_id, string_id
};
command[1] = CMD_SIZE(command);
dstring_clearstr (print_buffer);
PR_Sprintf (pr, print_buffer, "waddstr", fmt, count, args);
qwaq_submit_command (res, command);
}
}
static void
bi_wvprintf (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int window_id = P_INT (pr, 0);
const char *fmt = P_GSTRING (pr, 1);
__auto_type args = (pr_va_list_t *) &P_POINTER (pr, 2);
pr_type_t *list_start = PR_GetPointer (pr, args->list);
pr_type_t **list = alloca (args->count * sizeof (*list));
for (int i = 0; i < args->count; i++) {
list[i] = list_start + i * pr->pr_param_size;
}
if (get_window (res, __FUNCTION__, window_id)) {
int string_id = acquire_string (res);
dstring_t *print_buffer = res->strings + string_id;
int command[] = {
qwaq_cmd_waddstr, 0,
window_id, string_id
};
command[1] = CMD_SIZE(command);
dstring_clearstr (print_buffer);
PR_Sprintf (pr, print_buffer, "waddstr", fmt, args->count, list);
qwaq_submit_command (res, command);
}
}
2020-03-02 09:24:45 +00:00
static void
bi_mvwaddch (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int window_id = P_INT (pr, 0);
int x = P_INT (pr, 1);
int y = P_INT (pr, 2);
int ch = P_INT (pr, 3);
if (get_window (res, __FUNCTION__, window_id)) {
int command[] = {
qwaq_cmd_mvwaddch, 0,
window_id, x, y, ch
};
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
}
}
static void
bi_wrefresh (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int window_id = P_INT (pr, 0);
if (get_window (res, __FUNCTION__, window_id)) {
int command[] = { qwaq_cmd_wrefresh, 0, window_id, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
}
}
static void
bi_get_event (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
qwaq_event_t *event = &G_STRUCT (pr, qwaq_event_t, P_INT (pr, 0));
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
process_commands (res);
process_input (res);
R_INT (pr) = get_event (res, event);
}
2020-02-29 05:48:18 +00:00
static void
bi_max_colors (progs_t *pr)
{
R_INT (pr) = COLORS;
}
static void
bi_max_color_pairs (progs_t *pr)
{
R_INT (pr) = COLOR_PAIRS;
}
static void
bi_init_pair (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int pair = P_INT (pr, 0);
int f = P_INT (pr, 1);
int b = P_INT (pr, 2);
int command[] = { qwaq_cmd_init_pair, 0, pair, f, b, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
2020-02-29 05:48:18 +00:00
}
static void
bi_wbkgd (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int window_id = P_INT (pr, 0);
int ch = P_INT (pr, 1);
if (get_window (res, __FUNCTION__, window_id)) {
int command[] = { qwaq_cmd_wbkgd, 0, window_id, ch, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
2020-03-02 09:24:45 +00:00
}
}
2020-02-29 05:48:18 +00:00
static void
bi_scrollok (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int window_id = P_INT (pr, 0);
int flag = P_INT (pr, 1);
if (get_window (res, __FUNCTION__, window_id)) {
int command[] = { qwaq_cmd_scrollok, 0, window_id, flag, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
}
}
2020-03-02 09:24:45 +00:00
static const char qwaq_acs_char_map[] = "lmkjtuvwqxnos`afg~,+.-hi0pryz{|}";
static void
bi_acs_char (progs_t *pr)
{
unsigned acs = P_INT (pr, 0);
if (acs < 256) {
R_INT (pr) = NCURSES_ACS(acs);
} else if (acs - 256 < sizeof (qwaq_acs_char_map)) {
R_INT (pr) = NCURSES_ACS(qwaq_acs_char_map[acs - 256]);
} else {
R_INT (pr) = 0;
2020-02-29 05:48:18 +00:00
}
}
static void
bi_move (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int x = P_INT (pr, 0);
int y = P_INT (pr, 1);
int command[] = { qwaq_cmd_move, 0, x, y, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
}
static void
bi_curs_set (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int visibility = P_INT (pr, 0);
int command[] = { qwaq_cmd_curs_set, 0, visibility, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
}
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
static void
bi_initialize (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
initscr ();
need_endwin = 1;
res->initialized = 1;
2020-02-29 05:48:18 +00:00
start_color ();
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
raw ();
keypad (stdscr, TRUE);
noecho ();
nonl ();
nodelay (stdscr, TRUE);
mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL);
write(1, MOUSE_MOVES_ON, sizeof (MOUSE_MOVES_ON) - 1);
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
refresh();
2020-02-29 05:38:54 +00:00
res->stdscr.win = stdscr;
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
}
static void
bi_qwaq_clear (progs_t *pr, void *data)
{
__auto_type res = (qwaq_resources_t *) data;
if (res->initialized) {
write(1, MOUSE_MOVES_OFF, sizeof (MOUSE_MOVES_OFF) - 1);
endwin ();
}
need_endwin = 0;
window_reset (res);
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
panel_reset (res);
}
static builtin_t builtins[] = {
{"initialize", bi_initialize, -1},
{"create_window", bi_newwin, -1},
{"destroy_window", bi_delwin, -1},
{"getwrect", bi_getwrect, -1},
{"create_panel", bi_new_panel, -1},
{"destroy_panel", bi_del_panel, -1},
{"hide_panel", bi_hide_panel, -1},
{"show_panel", bi_show_panel, -1},
{"top_panel", bi_top_panel, -1},
{"bottom_panel", bi_bottom_panel, -1},
{"move_panel", bi_move_panel, -1},
{"panel_window", bi_panel_window, -1},
{"update_panels", bi_update_panels, -1},
{"doupdate", bi_doupdate, -1},
{"mvwprintf", bi_mvwprintf, -1},
{"wprintf", bi_wprintf, -1},
{"wvprintf", bi_wvprintf, -1},
2020-03-02 09:24:45 +00:00
{"mvwaddch", bi_mvwaddch, -1},
{"wrefresh", bi_wrefresh, -1},
{"get_event", bi_get_event, -1},
2020-02-29 05:48:18 +00:00
{"max_colors", bi_max_colors, -1},
{"max_color_pairs", bi_max_color_pairs, -1},
{"init_pair", bi_init_pair, -1},
{"wbkgd", bi_wbkgd, -1},
{"scrollok", bi_scrollok, -1},
2020-03-02 09:24:45 +00:00
{"acs_char", bi_acs_char, -1},
{"move", bi_move, -1},
{"curs_set", bi_curs_set, -1},
{0}
};
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
static __attribute__((format(printf, 1, 0))) void
qwaq_print (const char *fmt, va_list args)
{
vfprintf (stderr, fmt, args);
fflush (stderr);
}
void
BI_Init (progs_t *pr)
{
qwaq_resources_t *res = calloc (sizeof (*res), 1);
res->pr = pr;
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
for (int i = 0; i < STRING_ID_QUEUE_SIZE - 1; i++) {
RB_WRITE_DATA (res->string_ids, &i, 1);
res->strings[i].mem = &dstring_default_mem;
}
PR_Resources_Register (pr, "qwaq", res, bi_qwaq_clear);
PR_RegisterBuiltins (pr, builtins);
Sys_RegisterShutdown (bi_shutdown);
[qwaq] Prepare for threading So far, no threading has been set up, and only window creation and printing have been updated, but the basics of the design seem to be sound. The builtin functions now no longer call ncurses directly: the build commands and write them to a command buffer. Commands that have return values (eg, window creation) write their results to a results buffer that the originating builtin function reads. Builtin functions that expect a result "poll" the results buffer for the correct result (marked by the same command). In a single UI-thread environment, the results should always be in the same order as the commands, and in a multi-UI-thread environment, things should (fingers crossed) sort themselves out as ONE of the threads will be the originator of the next available result. Strings in commands (eg, for printing) are handled by acquiring a string id (index into an array of dstring_t) and including the string id in the written command. The string id is released upon completion of the command. Builtin functions write commands, acquire string ids, and read results. The command processor reads commands, releases string ids, and writes results. Since commands, string ids, and results are all in ring buffers, and assuming there is only one thread running the builtin functions and only one thread processing commands (there can be only one because ncurses is not thread-safe), then there should never be any contention on the buffers. Of course, if there are multiple threads running the builtin functions, then locking will be required on the builtin function side.
2020-02-28 16:45:33 +00:00
Sys_SetStdPrintf (qwaq_print);
}