Start work on the graphics manager

This commit is contained in:
Kovid Goyal 2017-09-27 07:57:18 +05:30
parent e52818d54c
commit 8418cc04c1
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 128 additions and 4 deletions

View File

@ -8,8 +8,88 @@
#include "graphics.h"
#include "state.h"
#define REPORT_ERROR(fmt, ...) { fprintf(stderr, fmt, __VA_ARGS__); fprintf(stderr, "\n"); }
GraphicsManager*
grman_realloc(GraphicsManager *old, index_type lines, index_type columns) {
GraphicsManager *self = (GraphicsManager *)GraphicsManager_Type.tp_alloc(&GraphicsManager_Type, 0);
self->lines = lines; self->columns = columns;
if (old == NULL) {
self->images_capacity = 64;
self->images = calloc(self->images_capacity, sizeof(Image));
if (self->images == NULL) {
Py_CLEAR(self); return NULL;
}
} else {
self->images_capacity = old->images_capacity; self->images = old->images; self->image_count = old->image_count;
old->images = NULL;
grman_free(old);
}
return self;
}
GraphicsManager*
grman_free(GraphicsManager* self) {
free(self->images);
Py_TYPE(self)->tp_free((PyObject*)self);
return NULL;
}
/* static size_t internal_id_counter = 1; */
static void
handle_add_command(GraphicsManager UNUSED *self, const GraphicsCommand UNUSED *g, const uint8_t UNUSED *payload) {
}
void
grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_t *payload) {
switch(g->action) {
case 't':
handle_add_command(self, g, payload);
break;
default:
REPORT_ERROR("Unknown graphics command action: %c", g->action);
break;
}
}
void
grman_clear(GraphicsManager UNUSED *self) {
// TODO: Implement this
}
// Boilerplate {{{
static PyObject *
new(PyTypeObject UNUSED *type, PyObject *args, PyObject UNUSED *kwds) {
unsigned int lines, columns;
if (!PyArg_ParseTuple(args, "II", &lines, &columns)) return NULL;
PyObject *ans = (PyObject*)grman_realloc(NULL, lines, columns);
if (ans == NULL) PyErr_NoMemory();
return ans;
}
static void
dealloc(GraphicsManager* self) {
grman_free(self);
}
PyTypeObject GraphicsManager_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "fast_data_types.GraphicsManager",
.tp_basicsize = sizeof(GraphicsManager),
.tp_dealloc = (destructor)dealloc,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = "GraphicsManager",
.tp_new = new,
};
bool
init_graphics(PyObject UNUSED *m) {
init_graphics(PyObject *module) {
if (PyType_Ready(&GraphicsManager_Type) < 0) return false;
if (PyModule_AddObject(module, "GraphicsManager", (PyObject *)&GraphicsManager_Type) != 0) return false;
Py_INCREF(&GraphicsManager_Type);
return true;
}
// }}}

View File

@ -5,8 +5,7 @@
*/
#pragma once
#include <stdint.h>
#include <stddef.h>
#include "data-types.h"
typedef struct {
unsigned char action, transmission_type;
@ -15,3 +14,25 @@ typedef struct {
int32_t z_index;
size_t payload_sz;
} GraphicsCommand;
typedef struct {
uint32_t gl_id, client_id, width, height;
size_t internal_id, refcnt;
} Image;
typedef struct {
PyObject_HEAD
index_type lines, columns;
size_t image_count, images_capacity;
Image *images;
} GraphicsManager;
PyTypeObject GraphicsManager_Type;
GraphicsManager* grman_realloc(GraphicsManager *, index_type lines, index_type columns);
void grman_clear(GraphicsManager*);
GraphicsManager* grman_free(GraphicsManager*);
void grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_t *payload);

View File

@ -677,6 +677,7 @@ parse_graphics_code(Screen *screen, PyObject UNUSED *dump_callback) {
#undef U
#undef A
#undef I
screen_handle_graphics_command(screen, &g, payload);
}
static inline void

View File

@ -81,8 +81,10 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
self->main_linebuf = alloc_linebuf(lines, columns); self->alt_linebuf = alloc_linebuf(lines, columns);
self->linebuf = self->main_linebuf;
self->historybuf = alloc_historybuf(MAX(scrollback, lines), columns);
self->main_grman = grman_realloc(NULL, lines, columns); self->alt_grman = grman_realloc(NULL, lines, columns);
self->grman = self->main_grman;
self->main_tabstops = PyMem_Calloc(2 * self->columns, sizeof(bool));
if (self->cursor == NULL || self->main_linebuf == NULL || self->alt_linebuf == NULL || self->main_tabstops == NULL || self->historybuf == NULL || self->color_profile == NULL) {
if (self->cursor == NULL || self->main_linebuf == NULL || self->alt_linebuf == NULL || self->main_tabstops == NULL || self->historybuf == NULL || self->main_grman == NULL || self->alt_grman == NULL || self->color_profile == NULL) {
Py_CLEAR(self); return NULL;
}
self->alt_tabstops = self->main_tabstops + self->columns * sizeof(bool);
@ -97,6 +99,7 @@ void
screen_reset(Screen *self) {
if (self->linebuf == self->alt_linebuf) screen_toggle_screen_buffer(self);
linebuf_clear(self->linebuf, BLANK_CHAR);
grman_clear(self->grman);
self->modes = empty_modes;
#define RC(name) self->color_profile->overridden.name = 0
RC(default_fg); RC(default_bg); RC(cursor_color); RC(highlight_fg); RC(highlight_bg);
@ -137,6 +140,8 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
bool is_main = self->linebuf == self->main_linebuf;
index_type num_content_lines_before, num_content_lines_after;
index_type num_content_lines;
// Resize main linebuf
HistoryBuf *nh = realloc_hb(self->historybuf, self->historybuf->ynum, columns);
if (nh == NULL) return false;
Py_CLEAR(self->historybuf); self->historybuf = nh;
@ -147,8 +152,17 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
n = realloc_lb(self->alt_linebuf, lines, columns, &num_content_lines_before, &num_content_lines_after, NULL);
if (n == NULL) return false;
Py_CLEAR(self->alt_linebuf); self->alt_linebuf = n;
GraphicsManager *g = grman_realloc(self->main_grman, lines, columns);
if (g == NULL) return false;
self->main_grman = g;
// Resize alt linebuf
g = grman_realloc(self->alt_grman, lines, columns);
if (g == NULL) return false;
self->alt_grman = g;
if (!is_main) num_content_lines = num_content_lines_after;
self->linebuf = is_main ? self->main_linebuf : self->alt_linebuf;
self->grman = is_main ? self->main_grman : self->alt_grman;
self->lines = lines; self->columns = columns;
self->margin_top = 0; self->margin_bottom = self->lines - 1;
@ -199,6 +213,8 @@ static void
dealloc(Screen* self) {
pthread_mutex_destroy(&self->read_buf_lock);
pthread_mutex_destroy(&self->write_buf_lock);
if (self->main_grman) { self->main_grman = grman_free(self->main_grman); }
if (self->alt_grman) { self->alt_grman = grman_free(self->alt_grman); }
PyMem_RawFree(self->write_buf);
Py_CLEAR(self->callbacks);
Py_CLEAR(self->test_child);
@ -393,6 +409,10 @@ END_ALLOW_CASE_RANGE
}
}
void
screen_handle_graphics_command(Screen *self, const GraphicsCommand *cmd, const uint8_t *payload) {
grman_handle_command(self->grman, cmd, payload);
}
// }}}
// Modes {{{

View File

@ -39,6 +39,7 @@ typedef struct {
SavepointBuffer main_savepoints, alt_savepoints;
PyObject *callbacks, *test_child;
LineBuf *linebuf, *main_linebuf, *alt_linebuf;
GraphicsManager *grman, *main_grman, *alt_grman;
HistoryBuf *historybuf;
unsigned int history_line_added_count;
bool *tabstops, *main_tabstops, *alt_tabstops;
@ -127,6 +128,7 @@ Line* screen_visual_line(Screen *self, index_type y);
unsigned long screen_current_char_width(Screen *self);
void screen_url_range(Screen *self, uint32_t *);
void screen_mark_url(Screen *self, index_type start_x, index_type start_y, index_type end_x, index_type end_y);
void screen_handle_graphics_command(Screen *self, const GraphicsCommand *cmd, const uint8_t *payload);
#define DECLARE_CH_SCREEN_HANDLER(name) void screen_##name(Screen *screen);
DECLARE_CH_SCREEN_HANDLER(bell)
DECLARE_CH_SCREEN_HANDLER(backspace)