Implement reverse video and DECSCNM

This commit is contained in:
Kovid Goyal 2016-11-30 11:12:34 +05:30
parent f0b1af964b
commit f71e266764
5 changed files with 16 additions and 49 deletions

View File

@ -307,7 +307,7 @@ void cursor_reset(Cursor*);
Cursor* cursor_copy(Cursor*);
void cursor_copy_to(Cursor *src, Cursor *dest);
void cursor_reset_display_attrs(Cursor*);
bool update_cell_range_data(SpriteMap *, Line *, unsigned int, unsigned int, ColorProfile *, const uint32_t, const uint32_t, unsigned int *);
bool update_cell_range_data(ScreenModes *modes, SpriteMap *, Line *, unsigned int, unsigned int, ColorProfile *, const uint32_t, const uint32_t, unsigned int *);
uint32_t to_color(ColorProfile *, uint32_t, uint32_t);
PyObject* line_text_at(char_type, combining_type);

View File

@ -331,12 +331,11 @@ set_mode_from_const(Screen *self, unsigned int mode, bool val) {
}
break;
case DECSCNM:
// Mark all displayed characters as reverse.
self->modes.mDECSCNM = val;
linebuf_set_attribute(self->linebuf, REVERSE_SHIFT, 0);
tracker_update_screen(self->change_tracker);
self->cursor->reverse = val;
tracker_cursor_changed(self->change_tracker);
// Render screen in reverse video
if (self->modes.mDECSCNM != val) {
self->modes.mDECSCNM = val;
tracker_update_screen(self->change_tracker);
}
break;
case DECOM:
self->modes.mDECOM = val;
@ -965,7 +964,7 @@ screen_update_cell_data(Screen *self, PyObject *args) {
PyObject *cursor_changed = self->change_tracker->cursor_changed ? Py_True : Py_False;
unsigned int history_line_added_count = self->change_tracker->history_line_added_count;
if (!tracker_update_cell_data(self->change_tracker, self->linebuf, spm, color_profile, data, default_fg, default_bg, (bool)force_screen_refresh)) return NULL;
if (!tracker_update_cell_data(&(self->modes), self->change_tracker, self->linebuf, spm, color_profile, data, default_fg, default_bg, (bool)force_screen_refresh)) return NULL;
return Py_BuildValue("OI", cursor_changed, history_line_added_count);
}
@ -985,7 +984,7 @@ set_scroll_cell_data(Screen *self, PyObject *args) {
for (index_type y = 0; y < MIN(self->lines, scrolled_by); y++) {
historybuf_init_line(self->historybuf, scrolled_by - y, self->historybuf->line);
self->historybuf->line->ynum = y;
if (!update_cell_range_data(spm, self->historybuf->line, 0, self->columns - 1, color_profile, default_bg, default_fg, data)) return NULL;
if (!update_cell_range_data(&(self->modes), spm, self->historybuf->line, 0, self->columns - 1, color_profile, default_bg, default_fg, data)) return NULL;
}
if (scrolled_by < self->lines) {
// Less than a full screen has been scrolled, copy some lines from the screen buffer to the scroll buffer

View File

@ -140,11 +140,12 @@ position_for(SpriteMap *self, PyObject *args) {
}
bool
update_cell_range_data(SpriteMap *self, Line *line, unsigned int xstart, unsigned int xmax, ColorProfile *color_profile, const uint32_t default_bg, const uint32_t default_fg, unsigned int *data) {
update_cell_range_data(ScreenModes *modes, SpriteMap *self, Line *line, unsigned int xstart, unsigned int xmax, ColorProfile *color_profile, const uint32_t default_bg, const uint32_t default_fg, unsigned int *data) {
SpritePosition *sp;
char_type previous_ch=0, ch;
uint8_t previous_width = 0;
int err = 0;
const bool screen_reversed = modes->mDECSCNM;
size_t base = line->ynum * line->xnum * DATA_CELL_SIZE;
for (size_t i = xstart, offset = base + xstart * DATA_CELL_SIZE; i <= xmax; i++, offset += DATA_CELL_SIZE) {
@ -155,11 +156,12 @@ update_cell_range_data(SpriteMap *self, Line *line, unsigned int xstart, unsigne
char_type attrs = ch >> ATTRS_SHIFT;
unsigned int decoration = (attrs >> DECORATION_SHIFT) & DECORATION_MASK;
unsigned int strikethrough = ((attrs >> STRIKE_SHIFT) & 1) ? 3 : 0;
bool reverse = ((attrs >> REVERSE_SHIFT) & 1) ^ screen_reversed;
data[offset] = sp->x;
data[offset+1] = sp->y;
data[offset+2] = sp->z;
data[offset+3] = to_color(color_profile, line->colors[i] & COL_MASK, default_fg);
data[offset+4] = to_color(color_profile, line->colors[i] >> COL_SHIFT, default_bg);
data[offset+(reverse ? 4 : 3)] = to_color(color_profile, line->colors[i] & COL_MASK, default_fg);
data[offset+(reverse ? 3 : 4)] = to_color(color_profile, line->colors[i] >> COL_SHIFT, default_bg);
unsigned int decoration_fg = decoration > 1 ? to_color(color_profile, line->decoration_fg[i] & COL_MASK, data[offset+3]) : data[offset+3];
data[offset+5] = (decoration_fg & COL_MASK) | (decoration << 24) | (strikethrough << 26);
previous_ch = ch; previous_width = (attrs) & WIDTH_MASK;
@ -167,20 +169,6 @@ update_cell_range_data(SpriteMap *self, Line *line, unsigned int xstart, unsigne
return true;
}
static PyObject*
update_cell_data(SpriteMap *self, PyObject *args) {
#define update_cell_data_doc "update_cell_data(line, xstart, xmax, color_profile, default_bg, default_fg, data_pointer) -> Update the range [xstart, xmax] in data_pointer with the data from line"
unsigned int xstart, xmax;
uint32_t default_fg, default_bg;
Line *line; ColorProfile *color_profile;
PyObject *data_pointer;
if (!PyArg_ParseTuple(args, "O!IIO!IIO!", &Line_Type, &line, &xstart, &xmax, &ColorProfile_Type, &color_profile, &default_bg, &default_fg, &PyLong_Type, &data_pointer)) return NULL;
unsigned int *dp = PyLong_AsVoidPtr(data_pointer);
if (!update_cell_range_data(self, line, xstart, xmax, color_profile, default_bg, default_fg, dp)) return NULL;
Py_RETURN_NONE;
}
static PyObject*
render_dirty_cells(SpriteMap *self, PyObject *args) {
#define render_dirty_cells_doc "Render all cells that are marked as dirty"
@ -230,7 +218,6 @@ static PyMethodDef methods[] = {
METHOD(layout, METH_VARARGS)
METHOD(position_for, METH_VARARGS)
METHOD(render_dirty_cells, METH_VARARGS)
METHOD(update_cell_data, METH_VARARGS)
METHOD(increment, METH_NOARGS)
{NULL} /* Sentinel */
};

View File

@ -97,7 +97,7 @@ update_cell_range(ChangeTracker *self, PyObject *args) {
Py_RETURN_NONE;
}
bool tracker_update_cell_data(ChangeTracker *self, LineBuf *lb, SpriteMap *spm, ColorProfile *color_profile, unsigned int *data, unsigned long default_fg, unsigned long default_bg, bool force_screen_refresh) {
bool tracker_update_cell_data(ScreenModes *modes, ChangeTracker *self, LineBuf *lb, SpriteMap *spm, ColorProfile *color_profile, unsigned int *data, unsigned long default_fg, unsigned long default_bg, bool force_screen_refresh) {
unsigned int y;
Py_ssize_t start;
default_fg &= COL_MASK;
@ -105,7 +105,7 @@ bool tracker_update_cell_data(ChangeTracker *self, LineBuf *lb, SpriteMap *spm,
#define UPDATE_RANGE(xstart, xmax) \
linebuf_init_line(lb, y); \
if (!update_cell_range_data(spm, lb->line, (xstart), (xmax), color_profile, default_bg, default_fg, data)) return false;
if (!update_cell_range_data(modes, spm, lb->line, (xstart), (xmax), color_profile, default_bg, default_fg, data)) return false;
if (self->screen_changed || force_screen_refresh) {
for (y = 0; y < self->ynum; y++) {
@ -140,24 +140,6 @@ bool tracker_update_cell_data(ChangeTracker *self, LineBuf *lb, SpriteMap *spm,
return true;
}
PyObject*
update_cell_data(ChangeTracker *self, PyObject *args) {
#define update_cell_data_doc "update_cell_data(line_buf, sprite_map, color_profile, data_ptr, default_fg, default_bg, force_screen_refresh)"
SpriteMap *spm;
LineBuf *lb;
ColorProfile *color_profile;
PyObject *dp;
unsigned int *data;
unsigned long default_bg, default_fg;
int force_screen_refresh;
if (!PyArg_ParseTuple(args, "O!O!O!O!kkp", &LineBuf_Type, &lb, &SpriteMap_Type, &spm, &ColorProfile_Type, &color_profile, &PyLong_Type, &dp, &default_fg, &default_bg, &force_screen_refresh)) return NULL;
data = PyLong_AsVoidPtr(dp);
PyObject *cursor_changed = self->cursor_changed ? Py_True : Py_False;
if (!tracker_update_cell_data(self, lb, spm, color_profile, data, default_fg, default_bg, (bool)force_screen_refresh)) return NULL;
Py_INCREF(cursor_changed);
return cursor_changed;
}
static inline PyObject*
get_ranges(bool *line, unsigned int xnum) {
PyObject *ans = PyList_New(0), *t;
@ -252,7 +234,6 @@ static PyGetSetDef getseters[] = {
static PyMethodDef methods[] = {
METHOD(resize, METH_VARARGS)
METHOD(update_cell_data, METH_VARARGS)
METHOD(reset, METH_NOARGS)
METHOD(cursor_changed, METH_NOARGS)
{"consolidate_changes", (PyCFunction)tracker_consolidate_changes, METH_NOARGS, ""},

View File

@ -52,4 +52,4 @@ static inline void tracker_reset(ChangeTracker *self) {
PyObject* tracker_consolidate_changes(ChangeTracker *self);
bool tracker_resize(ChangeTracker *self, unsigned int ynum, unsigned int xnum);
bool tracker_update_cell_data(ChangeTracker *, LineBuf *, SpriteMap *, ColorProfile *, unsigned int *, unsigned long, unsigned long, bool);
bool tracker_update_cell_data(ScreenModes*, ChangeTracker *, LineBuf *, SpriteMap *, ColorProfile *, unsigned int *, unsigned long, unsigned long, bool);