From d3be9427ce35b9967b0be63e009f739334c79901 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 23 Oct 2013 18:53:24 +0200 Subject: [PATCH 01/16] screen: implement trivial ageing To fully support the new ageing API, we now implement trivial ageing. On each modification, we simply increase the screen-age (which overwrites any line or cell age). This basically invalidates the whole screen on each change, but at least makes the ageing API work. Note that for cursor movements we actually age only both changed cells. Same for flag-changes. But these are the only non-trivial ageing implementations so far. Signed-off-by: David Herrmann --- src/tsm_screen.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 226 insertions(+), 31 deletions(-) diff --git a/src/tsm_screen.c b/src/tsm_screen.c index 18d877e..5a48b78 100644 --- a/src/tsm_screen.c +++ b/src/tsm_screen.c @@ -138,6 +138,46 @@ struct tsm_screen { struct selection_pos sel_end; }; +static void inc_age(struct tsm_screen *con) +{ + if (!++con->age_cnt) { + con->age_reset = 1; + ++con->age_cnt; + } +} + +static struct cell *get_cursor_cell(struct tsm_screen *con) +{ + unsigned int cur_x, cur_y; + + cur_x = con->cursor_x; + if (cur_x >= con->size_x) + cur_x = con->size_x - 1; + + cur_y = con->cursor_y; + if (cur_y >= con->size_y) + cur_y = con->size_y - 1; + + return &con->lines[cur_y]->cells[cur_x]; +} + +static void move_cursor(struct tsm_screen *con, unsigned int x, unsigned int y) +{ + struct cell *c; + + if (con->cursor_x == x && con->cursor_y == y) + return; + + c = get_cursor_cell(con); + c->age = con->age_cnt; + + con->cursor_x = x; + con->cursor_y = y; + + c = get_cursor_cell(con); + c->age = con->age_cnt; +} + static void cell_init(struct tsm_screen *con, struct cell *cell) { cell->ch = 0; @@ -211,6 +251,9 @@ static void link_to_scrollback(struct tsm_screen *con, struct line *line) { struct line *tmp; + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + if (con->sb_max == 0) { if (con->sel_active) { if (con->sel_start.line == line) { @@ -288,6 +331,9 @@ static void screen_scroll_up(struct tsm_screen *con, unsigned int num) if (!num) return; + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + max = con->margin_bottom + 1 - con->margin_top; if (num > max) num = max; @@ -357,6 +403,9 @@ static void screen_scroll_down(struct tsm_screen *con, unsigned int num) if (!num) return; + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + max = con->margin_bottom + 1 - con->margin_top; if (num > max) num = max; @@ -406,6 +455,9 @@ static void screen_write(struct tsm_screen *con, unsigned int x, return; } + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + line = con->lines[y]; if ((con->flags & TSM_SCREEN_INSERT_MODE) && @@ -431,6 +483,9 @@ static void screen_erase_region(struct tsm_screen *con, unsigned int to; struct line *line; + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + if (y_to >= con->size_y) y_to = con->size_y - 1; if (x_to >= con->size_x) @@ -676,6 +731,10 @@ int tsm_screen_resize(struct tsm_screen *con, unsigned int x, } } + inc_age(con); + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + /* clear expansion/padding area */ for (j = 0; j < con->line_num; ++j) { i = 0; @@ -773,6 +832,10 @@ void tsm_screen_set_max_sb(struct tsm_screen *con, if (!con) return; + inc_age(con); + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + while (con->sb_count > max) { line = con->sb_first; con->sb_first = line->next; @@ -812,6 +875,10 @@ void tsm_screen_clear_sb(struct tsm_screen *con) if (!con) return; + inc_age(con); + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + for (iter = con->sb_first; iter; ) { tmp = iter; iter = iter->next; @@ -841,6 +908,10 @@ void tsm_screen_sb_up(struct tsm_screen *con, unsigned int num) if (!con || !num) return; + inc_age(con); + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + while (num--) { if (con->sb_pos) { if (!con->sb_pos->prev) @@ -861,6 +932,10 @@ void tsm_screen_sb_down(struct tsm_screen *con, unsigned int num) if (!con || !num) return; + inc_age(con); + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + while (num--) { if (con->sb_pos) con->sb_pos = con->sb_pos->next; @@ -875,6 +950,7 @@ void tsm_screen_sb_page_up(struct tsm_screen *con, unsigned int num) if (!con || !num) return; + inc_age(con); tsm_screen_sb_up(con, num * con->size_y); } @@ -884,6 +960,7 @@ void tsm_screen_sb_page_down(struct tsm_screen *con, unsigned int num) if (!con || !num) return; + inc_age(con); tsm_screen_sb_down(con, num * con->size_y); } @@ -893,6 +970,10 @@ void tsm_screen_sb_reset(struct tsm_screen *con) if (!con) return; + inc_age(con); + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + con->sb_pos = NULL; } @@ -914,6 +995,9 @@ void tsm_screen_reset(struct tsm_screen *con) if (!con) return; + inc_age(con); + con->age = con->age_cnt; + con->flags = 0; con->margin_top = 0; con->margin_bottom = con->size_y - 1; @@ -931,30 +1015,58 @@ SHL_EXPORT void tsm_screen_set_flags(struct tsm_screen *con, unsigned int flags) { unsigned int old; + struct cell *c; if (!con || !flags) return; + inc_age(con); + old = con->flags; con->flags |= flags; - if (!(old & TSM_SCREEN_ALTERNATE) && (flags & TSM_SCREEN_ALTERNATE)) + if (!(old & TSM_SCREEN_ALTERNATE) && (flags & TSM_SCREEN_ALTERNATE)) { + con->age = con->age_cnt; con->lines = con->alt_lines; + } + + if (!(old & TSM_SCREEN_HIDE_CURSOR) && + (flags & TSM_SCREEN_HIDE_CURSOR)) { + c = get_cursor_cell(con); + c->age = con->age_cnt; + } + + if (!(old & TSM_SCREEN_INVERSE) && (flags & TSM_SCREEN_INVERSE)) + con->age = con->age_cnt; } SHL_EXPORT void tsm_screen_reset_flags(struct tsm_screen *con, unsigned int flags) { unsigned int old; + struct cell *c; if (!con || !flags) return; + inc_age(con); + old = con->flags; con->flags &= ~flags; - if ((old & TSM_SCREEN_ALTERNATE) && (flags & TSM_SCREEN_ALTERNATE)) + if ((old & TSM_SCREEN_ALTERNATE) && (flags & TSM_SCREEN_ALTERNATE)) { + con->age = con->age_cnt; con->lines = con->main_lines; + } + + if ((old & TSM_SCREEN_HIDE_CURSOR) && + (flags & TSM_SCREEN_HIDE_CURSOR)) { + c = get_cursor_cell(con); + c->age = con->age_cnt; + } + + if ((old & TSM_SCREEN_INVERSE) && (flags & TSM_SCREEN_INVERSE)) + con->age = con->age_cnt; } SHL_EXPORT @@ -1027,6 +1139,10 @@ void tsm_screen_write(struct tsm_screen *con, tsm_symbol_t ch, if (!len) return; + inc_age(con); + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + if (con->cursor_y <= con->margin_bottom || con->cursor_y >= con->size_y) last = con->margin_bottom; @@ -1057,6 +1173,8 @@ void tsm_screen_newline(struct tsm_screen *con) if (!con) return; + inc_age(con); + tsm_screen_move_down(con, 1, true); tsm_screen_move_line_home(con); } @@ -1067,6 +1185,8 @@ void tsm_screen_scroll_up(struct tsm_screen *con, unsigned int num) if (!con || !num) return; + inc_age(con); + screen_scroll_up(con, num); } @@ -1076,6 +1196,8 @@ void tsm_screen_scroll_down(struct tsm_screen *con, unsigned int num) if (!con || !num) return; + inc_age(con); + screen_scroll_down(con, num); } @@ -1088,18 +1210,22 @@ void tsm_screen_move_to(struct tsm_screen *con, unsigned int x, if (!con) return; + inc_age(con); + if (con->flags & TSM_SCREEN_REL_ORIGIN) last = con->margin_bottom; else last = con->size_y - 1; - con->cursor_x = to_abs_x(con, x); - if (con->cursor_x >= con->size_x) - con->cursor_x = con->size_x - 1; + x = to_abs_x(con, x); + if (x >= con->size_x) + x = con->size_x - 1; - con->cursor_y = to_abs_y(con, y); - if (con->cursor_y > last) - con->cursor_y = last; + y = to_abs_y(con, y); + if (y > last) + y = last; + + move_cursor(con, x, y); } SHL_EXPORT @@ -1111,6 +1237,8 @@ void tsm_screen_move_up(struct tsm_screen *con, unsigned int num, if (!con || !num) return; + inc_age(con); + if (con->cursor_y >= con->margin_top) size = con->margin_top; else @@ -1121,9 +1249,9 @@ void tsm_screen_move_up(struct tsm_screen *con, unsigned int num, num -= diff; if (scroll) screen_scroll_down(con, num); - con->cursor_y = size; + move_cursor(con, con->cursor_x, size); } else { - con->cursor_y -= num; + move_cursor(con, con->cursor_x, con->cursor_y - num); } } @@ -1136,6 +1264,8 @@ void tsm_screen_move_down(struct tsm_screen *con, unsigned int num, if (!con || !num) return; + inc_age(con); + if (con->cursor_y <= con->margin_bottom) size = con->margin_bottom + 1; else @@ -1146,28 +1276,33 @@ void tsm_screen_move_down(struct tsm_screen *con, unsigned int num, num -= diff; if (scroll) screen_scroll_up(con, num); - con->cursor_y = size - 1; + move_cursor(con, con->cursor_x, size - 1); } else { - con->cursor_y += num; + move_cursor(con, con->cursor_x, con->cursor_y + num); } } SHL_EXPORT void tsm_screen_move_left(struct tsm_screen *con, unsigned int num) { + unsigned int x; + if (!con || !num) return; + inc_age(con); + if (num > con->size_x) num = con->size_x; - if (con->cursor_x >= con->size_x) - con->cursor_x = con->size_x - 1; + x = con->cursor_x; + if (x >= con->size_x) + x = con->size_x - 1; - if (num > con->cursor_x) - con->cursor_x = 0; + if (num > x) + move_cursor(con, 0, con->cursor_y); else - con->cursor_x -= num; + move_cursor(con, x - num, con->cursor_y); } SHL_EXPORT @@ -1176,13 +1311,15 @@ void tsm_screen_move_right(struct tsm_screen *con, unsigned int num) if (!con || !num) return; + inc_age(con); + if (num > con->size_x) num = con->size_x; if (num + con->cursor_x >= con->size_x) - con->cursor_x = con->size_x - 1; + move_cursor(con, con->size_x - 1, con->cursor_y); else - con->cursor_x += num; + move_cursor(con, con->cursor_x + num, con->cursor_y); } SHL_EXPORT @@ -1191,7 +1328,9 @@ void tsm_screen_move_line_end(struct tsm_screen *con) if (!con) return; - con->cursor_x = con->size_x - 1; + inc_age(con); + + move_cursor(con, con->size_x - 1, con->cursor_y); } SHL_EXPORT @@ -1200,54 +1339,66 @@ void tsm_screen_move_line_home(struct tsm_screen *con) if (!con) return; - con->cursor_x = 0; + inc_age(con); + + move_cursor(con, 0, con->cursor_y); } SHL_EXPORT void tsm_screen_tab_right(struct tsm_screen *con, unsigned int num) { - unsigned int i, j; + unsigned int i, j, x; if (!con || !num) return; + inc_age(con); + + x = con->cursor_x; for (i = 0; i < num; ++i) { - for (j = con->cursor_x + 1; j < con->size_x; ++j) { + for (j = x + 1; j < con->size_x; ++j) { if (con->tab_ruler[j]) break; } - con->cursor_x = j; - if (con->cursor_x + 1 >= con->size_x) + x = j; + if (x + 1 >= con->size_x) break; } /* tabs never cause pending new-lines */ - if (con->cursor_x >= con->size_x) - con->cursor_x = con->size_x - 1; + if (x >= con->size_x) + x = con->size_x - 1; + + move_cursor(con, x, con->cursor_y); } SHL_EXPORT void tsm_screen_tab_left(struct tsm_screen *con, unsigned int num) { - unsigned int i; + unsigned int i, x; int j; if (!con || !num) return; + inc_age(con); + + x = con->cursor_x; for (i = 0; i < num; ++i) { - for (j = con->cursor_x - 1; j > 0; --j) { + for (j = x - 1; j > 0; --j) { if (con->tab_ruler[j]) break; } if (j <= 0) { - con->cursor_x = 0; + x = 0; break; } - con->cursor_x = j; + x = j; } + + move_cursor(con, x, con->cursor_y); } SHL_EXPORT @@ -1262,6 +1413,10 @@ void tsm_screen_insert_lines(struct tsm_screen *con, unsigned int num) con->cursor_y > con->margin_bottom) return; + inc_age(con); + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + max = con->margin_bottom - con->cursor_y + 1; if (num > max) num = max; @@ -1298,6 +1453,10 @@ void tsm_screen_delete_lines(struct tsm_screen *con, unsigned int num) con->cursor_y > con->margin_bottom) return; + inc_age(con); + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + max = con->margin_bottom - con->cursor_y + 1; if (num > max) num = max; @@ -1331,6 +1490,10 @@ void tsm_screen_insert_chars(struct tsm_screen *con, unsigned int num) if (!con || !num || !con->size_y || !con->size_x) return; + inc_age(con); + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + if (con->cursor_x >= con->size_x) con->cursor_x = con->size_x - 1; if (con->cursor_y >= con->size_y) @@ -1360,6 +1523,10 @@ void tsm_screen_delete_chars(struct tsm_screen *con, unsigned int num) if (!con || !num || !con->size_y || !con->size_x) return; + inc_age(con); + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + if (con->cursor_x >= con->size_x) con->cursor_x = con->size_x - 1; if (con->cursor_y >= con->size_y) @@ -1388,6 +1555,8 @@ void tsm_screen_erase_cursor(struct tsm_screen *con) if (!con) return; + inc_age(con); + if (con->cursor_x >= con->size_x) x = con->size_x - 1; else @@ -1404,6 +1573,8 @@ void tsm_screen_erase_chars(struct tsm_screen *con, unsigned int num) if (!con || !num) return; + inc_age(con); + if (con->cursor_x >= con->size_x) x = con->size_x - 1; else @@ -1422,6 +1593,8 @@ void tsm_screen_erase_cursor_to_end(struct tsm_screen *con, if (!con) return; + inc_age(con); + if (con->cursor_x >= con->size_x) x = con->size_x - 1; else @@ -1438,6 +1611,8 @@ void tsm_screen_erase_home_to_cursor(struct tsm_screen *con, if (!con) return; + inc_age(con); + screen_erase_region(con, 0, con->cursor_y, con->cursor_x, con->cursor_y, protect); } @@ -1449,6 +1624,8 @@ void tsm_screen_erase_current_line(struct tsm_screen *con, if (!con) return; + inc_age(con); + screen_erase_region(con, 0, con->cursor_y, con->size_x - 1, con->cursor_y, protect); } @@ -1460,6 +1637,8 @@ void tsm_screen_erase_screen_to_cursor(struct tsm_screen *con, if (!con) return; + inc_age(con); + screen_erase_region(con, 0, 0, con->cursor_x, con->cursor_y, protect); } @@ -1472,6 +1651,8 @@ void tsm_screen_erase_cursor_to_screen(struct tsm_screen *con, if (!con) return; + inc_age(con); + if (con->cursor_x >= con->size_x) x = con->size_x - 1; else @@ -1487,6 +1668,8 @@ void tsm_screen_erase_screen(struct tsm_screen *con, bool protect) if (!con) return; + inc_age(con); + screen_erase_region(con, 0, 0, con->size_x - 1, con->size_y - 1, protect); } @@ -1544,6 +1727,10 @@ void tsm_screen_selection_reset(struct tsm_screen *con) if (!con) return; + inc_age(con); + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + con->sel_active = false; } @@ -1555,6 +1742,10 @@ void tsm_screen_selection_start(struct tsm_screen *con, if (!con) return; + inc_age(con); + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + con->sel_active = true; selection_set(con, &con->sel_start, posx, posy); memcpy(&con->sel_end, &con->sel_start, sizeof(con->sel_end)); @@ -1568,6 +1759,10 @@ void tsm_screen_selection_target(struct tsm_screen *con, if (!con || !con->sel_active) return; + inc_age(con); + /* TODO: more sophisticated ageing */ + con->age = con->age_cnt; + selection_set(con, &con->sel_end, posx, posy); } -- 2.7.4 From 0299cda7a9f4bfd54918fd2806626baba3de0c37 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 23 Oct 2013 19:07:17 +0200 Subject: [PATCH 02/16] screen: remove old cursor-drawing fallback We used to not guarantee that all cells are allocated. Hence, we had to correctly draw the cursor if they weren't. These days we have this guarantee, though. So remove the old fallbacks. Signed-off-by: David Herrmann --- src/tsm_screen.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/tsm_screen.c b/src/tsm_screen.c index 5a48b78..a23b28d 100644 --- a/src/tsm_screen.c +++ b/src/tsm_screen.c @@ -2005,7 +2005,6 @@ tsm_age_t tsm_screen_draw(struct tsm_screen *con, tsm_screen_draw_cb draw_cb, struct line *iter, *line = NULL; struct cell *cell; struct tsm_screen_attr attr; - bool cursor_done = false; int ret, warned = 0; const uint32_t *ch; size_t len; @@ -2085,12 +2084,9 @@ tsm_age_t tsm_screen_draw(struct tsm_screen *con, tsm_screen_draw_cb draw_cb, } } - if (k == cur_y + 1 && - j == cur_x) { - cursor_done = true; - if (!(con->flags & TSM_SCREEN_HIDE_CURSOR)) - attr.inverse = !attr.inverse; - } + if (k == cur_y + 1 && j == cur_x && + !(con->flags & TSM_SCREEN_HIDE_CURSOR)) + attr.inverse = !attr.inverse; /* TODO: do some more sophisticated inverse here. When * INVERSE mode is set, we should instead just select @@ -2128,16 +2124,6 @@ tsm_age_t tsm_screen_draw(struct tsm_screen *con, tsm_screen_draw_cb draw_cb, "suppressing further warnings during this rendering round"); } } - - if (k == cur_y + 1 && !cursor_done) { - cursor_done = true; - if (!(con->flags & TSM_SCREEN_HIDE_CURSOR)) { - if (!(con->flags & TSM_SCREEN_INVERSE)) - attr.inverse = !attr.inverse; - draw_cb(con, 0, NULL, 0, 1, - cur_x, i, &attr, 0, data); - } - } } if (con->age_reset) { -- 2.7.4 From 0761efaf48aa1ba9e9be58d2d50982438075d9c7 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 23 Oct 2013 20:02:22 +0200 Subject: [PATCH 03/16] screen: implement proper ageing for tsm_screen_write() tsm_screen_write() is fairly simple so we can easily implement proper ageing support. Signed-off-by: David Herrmann --- src/tsm_screen.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/tsm_screen.c b/src/tsm_screen.c index a23b28d..634e004 100644 --- a/src/tsm_screen.c +++ b/src/tsm_screen.c @@ -455,22 +455,24 @@ static void screen_write(struct tsm_screen *con, unsigned int x, return; } - /* TODO: more sophisticated ageing */ - con->age = con->age_cnt; - line = con->lines[y]; if ((con->flags & TSM_SCREEN_INSERT_MODE) && - (int)x < ((int)con->size_x - len)) + (int)x < ((int)con->size_x - len)) { + line->age = con->age_cnt; memmove(&line->cells[x + len], &line->cells[x], sizeof(struct cell) * (con->size_x - len - x)); + } + line->cells[x].age = con->age_cnt; line->cells[x].ch = ch; line->cells[x].width = len; memcpy(&line->cells[x].attr, attr, sizeof(*attr)); - for (i = 1; i < len && i + x < con->size_x; ++i) + for (i = 1; i < len && i + x < con->size_x; ++i) { + line->cells[x + i].age = con->age_cnt; line->cells[x + i].width = 0; + } } static void screen_erase_region(struct tsm_screen *con, @@ -1140,8 +1142,6 @@ void tsm_screen_write(struct tsm_screen *con, tsm_symbol_t ch, return; inc_age(con); - /* TODO: more sophisticated ageing */ - con->age = con->age_cnt; if (con->cursor_y <= con->margin_bottom || con->cursor_y >= con->size_y) @@ -1150,21 +1150,19 @@ void tsm_screen_write(struct tsm_screen *con, tsm_symbol_t ch, last = con->size_y - 1; if (con->cursor_x >= con->size_x) { - if (con->flags & TSM_SCREEN_AUTO_WRAP) { - con->cursor_x = 0; - ++con->cursor_y; - } else { - con->cursor_x = con->size_x - 1; - } + if (con->flags & TSM_SCREEN_AUTO_WRAP) + move_cursor(con, 0, con->cursor_y + 1); + else + move_cursor(con, con->size_x - 1, con->cursor_y); } if (con->cursor_y > last) { - con->cursor_y = last; + move_cursor(con, con->cursor_x, last); screen_scroll_up(con, 1); } screen_write(con, con->cursor_x, con->cursor_y, ch, len, attr); - con->cursor_x += len; + move_cursor(con, con->cursor_x + len, con->cursor_y); } SHL_EXPORT -- 2.7.4 From 90bc3a9669daa926986c851668a92cc779fa76a5 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 23 Oct 2013 20:07:45 +0200 Subject: [PATCH 04/16] screen: clear existing cells when shrinking Clear parts of the existing screen if it is about to get hidden. Otherwise, it might reach the scrollback later when it is no longer part of the line it was during resize. Signed-off-by: David Herrmann --- src/tsm_screen.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tsm_screen.c b/src/tsm_screen.c index 634e004..24ffb56 100644 --- a/src/tsm_screen.c +++ b/src/tsm_screen.c @@ -654,7 +654,7 @@ int tsm_screen_resize(struct tsm_screen *con, unsigned int x, unsigned int y) { struct line **cache; - unsigned int i, j, width, diff; + unsigned int i, j, width, diff, start; int ret; bool *tab_ruler; @@ -738,20 +738,23 @@ int tsm_screen_resize(struct tsm_screen *con, unsigned int x, con->age = con->age_cnt; /* clear expansion/padding area */ + start = x; + if (x > con->size_x) + start = con->size_x; for (j = 0; j < con->line_num; ++j) { + /* main-lines may go into SB, so clear all cells */ i = 0; if (j < con->size_y) - i = con->size_x; + i = start; - /* main-lines may go into SB, so clear all cells */ for ( ; i < con->main_lines[j]->size; ++i) cell_init(con, &con->main_lines[j]->cells[i]); + /* alt-lines never go into SB, only clear visible cells */ i = 0; if (j < con->size_y) i = con->size_x; - /* alt-lines never go into SB, only clear visible cells */ for ( ; i < x; ++i) cell_init(con, &con->alt_lines[j]->cells[i]); } -- 2.7.4 From e6e0f6a4ca4df7cd5d6c5d4f3f87416c4af90a8d Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 23 Oct 2013 20:20:16 +0200 Subject: [PATCH 05/16] screen: implement proper ageing on screen resize Screen-resize doesn't actually move any cells so it's fairly easy to age new cells. No need to redraw the whole buffer. Signed-off-by: David Herrmann --- src/tsm_screen.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/tsm_screen.c b/src/tsm_screen.c index 24ffb56..f8e2b69 100644 --- a/src/tsm_screen.c +++ b/src/tsm_screen.c @@ -734,8 +734,6 @@ int tsm_screen_resize(struct tsm_screen *con, unsigned int x, } inc_age(con); - /* TODO: more sophisticated ageing */ - con->age = con->age_cnt; /* clear expansion/padding area */ start = x; @@ -779,22 +777,22 @@ int tsm_screen_resize(struct tsm_screen *con, unsigned int x, con->size_x = x; if (con->cursor_x >= con->size_x) - con->cursor_x = con->size_x - 1; + move_cursor(con, con->size_x - 1, con->cursor_y); /* scroll buffer if screen height shrinks */ if (y < con->size_y) { diff = con->size_y - y; screen_scroll_up(con, diff); if (con->cursor_y > diff) - con->cursor_y -= diff; + move_cursor(con, con->cursor_x, con->cursor_y - diff); else - con->cursor_y = 0; + move_cursor(con, con->cursor_x, 0); } con->size_y = y; con->margin_bottom = con->size_y - 1; if (con->cursor_y >= con->size_y) - con->cursor_y = con->size_y - 1; + move_cursor(con, con->cursor_x, con->size_y - 1); return 0; } -- 2.7.4 From bd52696633247055ecd8e7aedb99394d84433d29 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 23 Oct 2013 20:24:42 +0200 Subject: [PATCH 06/16] screen: skip ageing on cursor move if hidden If the cursor is hidden we don't need to increase the age. We already do this whenever the HIDE_CURSOR flag is changed. Signed-off-by: David Herrmann --- src/tsm_screen.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/tsm_screen.c b/src/tsm_screen.c index f8e2b69..fd61d37 100644 --- a/src/tsm_screen.c +++ b/src/tsm_screen.c @@ -165,6 +165,17 @@ static void move_cursor(struct tsm_screen *con, unsigned int x, unsigned int y) { struct cell *c; + /* if cursor is hidden, just move it */ + if (con->flags & TSM_SCREEN_HIDE_CURSOR) { + con->cursor_x = x; + con->cursor_y = y; + return; + } + + /* If cursor is visible, we have to mark the current and the new cell + * as changed by resetting their age. We skip it if the cursor-position + * didn't actually change. */ + if (con->cursor_x == x && con->cursor_y == y) return; -- 2.7.4 From 6a1faab3e333b948a266a42d6b725ebd5a59ebb7 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 29 Oct 2013 07:50:05 +0100 Subject: [PATCH 07/16] build: make autogen.sh comply to gnome-build rules Fix some minor autogen.sh features so we comply to common build-chain rules. Signed-off-by: David Herrmann --- autogen.sh | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/autogen.sh b/autogen.sh index ccd3d9c..65a6fe1 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,8 +1,17 @@ #!/bin/sh set -e + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +origdir=`pwd` +cd $srcdir + mkdir -p m4 -autoreconf -is +autoreconf -is --force + +cd $origdir -if test ! "x$NOCONFIGURE" = "x1" ; then - exec ./configure "$@" +if test -z "$NOCONFIGURE" ; then + exec $srcdir/configure "$@" fi -- 2.7.4 From 7df6e8616a9e7122399300a3c002767b51411718 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 29 Oct 2013 07:56:53 +0100 Subject: [PATCH 08/16] build: minor style cleanups in configure.ac Some minor modifications, typo-fixes and comment additions for configure.ac. Signed-off-by: David Herrmann --- configure.ac | 33 ++++++++++++++++++++------------- docs/libtsm.pc.in | 2 +- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac index ad11deb..c559c39 100644 --- a/configure.ac +++ b/configure.ac @@ -21,6 +21,8 @@ AC_CANONICAL_HOST AM_INIT_AUTOMAKE([foreign 1.11 subdir-objects dist-xz no-dist-gzip tar-pax -Wall -Werror -Wno-portability]) AM_SILENT_RULES([yes]) +AC_SUBST(PACKAGE_DESCRIPTION, ["terminal-emulator state machine"]) + # # Don't add a default "-g -O2" if CFLAGS wasn't specified. For debugging it is # often more convenient to have "-g -O0". You can still override it by @@ -43,14 +45,8 @@ LT_PREREQ(2.2) LT_INIT # -# pkg-config dependencies -# This unconditionally checks for all dependencies even if they are disabled. We -# later look whether all required depedencies are met and finish the -# configuration. We group similar packages into one logical group here to avoid -# having variables for each single library. -# This, however, makes ./configure output very unintuitive error messages if a -# package is not found so we must make sure we print more verbose messages -# ourself. +# We need xkbcommon for keysym definitions. If it's not found, we use our own +# private copy of xkbcommon-keysyms.h. # PKG_CHECK_MODULES([XKBCOMMON], [xkbcommon], @@ -61,6 +57,11 @@ if test "x$have_xkbcommon" = "xyes" ; then fi AM_CONDITIONAL([BUILD_HAVE_XKBCOMMON], [test "x$have_xkbcommon" = "xyes"]) +# +# Test for "check" which we use for our test-suite. If not found, we disable +# all tests. +# + PKG_CHECK_MODULES([CHECK], [check], [have_check=yes], [have_check=no]) AC_SUBST(CHECK_CFLAGS) @@ -68,12 +69,12 @@ AC_SUBST(CHECK_LIBS) AM_CONDITIONAL([BUILD_HAVE_CHECK], [test "x$have_check" = "xyes"]) # -# Parse arguments -# This parses all arguments that are given via "--enable-XY" or "--with-XY" and -# saves the results in local variables. +# debug mode +# If --enable-debug is given, we enable several non-standard debug options. We +# enable a lot of debug options by default, so this option is really only for +# extended developer debug modes. # -# debug AC_MSG_CHECKING([whether to build with debugging on]) AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], @@ -82,6 +83,7 @@ if test "x$enable_debug" = "x" ; then enable_debug="yes (default)" fi AC_MSG_RESULT([$enable_debug]) + if test "x${enable_debug% *}" = "xyes" ; then enable_debug="yes" AC_DEFINE([BUILD_ENABLE_DEBUG], [1], [Enable debug mode]) @@ -92,7 +94,11 @@ fi AM_CONDITIONAL([BUILD_ENABLE_DEBUG], [test "x$enable_debug" = "xyes"]) -# optimizations +# +# Enable gcc compiler optimizations. We enable them by default but allow +# disabling them for better backtraces during debugging. +# + AC_MSG_CHECKING([whether to enable code optimizations]) AC_ARG_ENABLE([optimizations], [AS_HELP_STRING([--disable-optimizations], @@ -101,6 +107,7 @@ if test "x$enable_optimizations" = "x" ; then enable_optimizations="yes (default)" fi AC_MSG_RESULT([$enable_optimizations]) + if test "x${enable_optimizations% *}" = "xyes" ; then enable_optimizations="yes" else diff --git a/docs/libtsm.pc.in b/docs/libtsm.pc.in index 210e27b..cc1aa6f 100644 --- a/docs/libtsm.pc.in +++ b/docs/libtsm.pc.in @@ -4,7 +4,7 @@ libdir=@libdir@ includedir=@includedir@ Name: libtsm -Description: Terminal-emulator State Machine +Description: @PACKAGE_DESCRIPTION@ URL: @PACKAGE_URL@ Version: @PACKAGE_VERSION@ Libs: -L${libdir} -ltsm -- 2.7.4 From 21d333022e53be08a0659753bf0f2b3e1f19291f Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 29 Oct 2013 08:21:56 +0100 Subject: [PATCH 09/16] Remove old compatibility headers We don't need tsm_*.h as installed headers. Remove them. Signed-off-by: David Herrmann --- Makefile.am | 9 +-------- src/tsm_screen.h | 33 --------------------------------- src/tsm_unicode.h | 33 --------------------------------- src/tsm_vte.h | 33 --------------------------------- 4 files changed, 1 insertion(+), 107 deletions(-) delete mode 100644 src/tsm_screen.h delete mode 100644 src/tsm_unicode.h delete mode 100644 src/tsm_vte.h diff --git a/Makefile.am b/Makefile.am index 3fb5efb..bda7dfd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -108,21 +108,14 @@ libshl_la_LIBADD = $(AM_LIBADD) # lib_LTLIBRARIES += libtsm.la -include_HEADERS += \ - src/tsm_screen.h \ - src/tsm_unicode.h \ - src/tsm_vte.h \ - src/libtsm.h +include_HEADERS += src/libtsm.h pkgconfig_DATA += docs/libtsm.pc libtsm_la_SOURCES = \ src/libtsm.h \ src/libtsm_int.h \ - src/tsm_unicode.h \ src/tsm_unicode.c \ - src/tsm_screen.h \ src/tsm_screen.c \ - src/tsm_vte.h \ src/tsm_vte.c \ src/tsm_vte_charsets.c \ external/wcwidth.h \ diff --git a/src/tsm_screen.h b/src/tsm_screen.h deleted file mode 100644 index 257935c..0000000 --- a/src/tsm_screen.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * libtsm - Screen Management - * - * Copyright (c) 2011-2013 David Herrmann - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef TSM_SCREEN_H -#define TSM_SCREEN_H - -#warning "Please include libtsm.h directly instead of any sub-headers." - -#include - -#endif /* TSM_SCREEN_H */ diff --git a/src/tsm_unicode.h b/src/tsm_unicode.h deleted file mode 100644 index 9d61356..0000000 --- a/src/tsm_unicode.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * libtsm - Unicode Handling - * - * Copyright (c) 2011-2013 David Herrmann - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef TSM_UNICODE_H -#define TSM_UNICODE_H - -#warning "Please include libtsm.h directly instead of any sub-headers." - -#include - -#endif /* TSM_UNICODE_H */ diff --git a/src/tsm_vte.h b/src/tsm_vte.h deleted file mode 100644 index 3c36aae..0000000 --- a/src/tsm_vte.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * libtsm - VT Emulator - * - * Copyright (c) 2011-2013 David Herrmann - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef TSM_VTE_H -#define TSM_VTE_H - -#warning "Please include libtsm.h directly instead of any sub-headers." - -#include - -#endif /* TSM_VTE_H */ -- 2.7.4 From ee1e6f0225f64056563b0fe97f42085a52c98924 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 29 Oct 2013 08:22:25 +0100 Subject: [PATCH 10/16] gitignore: add config.h.in~ Add temp config.h.in files. Signed-off-by: David Herrmann --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 00fe76c..ed1bfa3 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ autom4te.cache/ build-aux/ config.h config.h.in +config.h.in~ config.log config.status configure -- 2.7.4 From 673b48ef2fb3a8488faf9fe78d150a57fe42ee23 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 29 Oct 2013 08:28:25 +0100 Subject: [PATCH 11/16] build: add LICENSE_htable to EXTRA_DIST We need to ship the additional license file with tarballs. Signed-off-by: David Herrmann --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index bda7dfd..549cc37 100644 --- a/Makefile.am +++ b/Makefile.am @@ -30,6 +30,7 @@ include_HEADERS = EXTRA_DIST = \ README \ COPYING \ + LICENSE_htable \ NEWS \ docs/libtsm.pc.in \ docs/libtsm.sym -- 2.7.4 From 314c5d77edcb6fb902aa1ddd27e2a3cb28d7b4ff Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 29 Oct 2013 08:28:46 +0100 Subject: [PATCH 12/16] build: remove -fstack-protector -fstack-protector should be set by the build-environment, not by each project. It may fail in subtle ways if the toolchain doesn't support it. Signed-off-by: David Herrmann --- Makefile.am | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 549cc37..898caca 100644 --- a/Makefile.am +++ b/Makefile.am @@ -65,8 +65,7 @@ AM_CFLAGS = \ -fno-strict-aliasing \ -fvisibility=hidden \ -ffunction-sections \ - -fdata-sections \ - -fstack-protector + -fdata-sections AM_CPPFLAGS = \ -include $(top_builddir)/config.h \ -I $(srcdir)/src -- 2.7.4 From 2ed1832b49dbf41c317ee821734cfb66bb34ed9d Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 29 Oct 2013 08:30:14 +0100 Subject: [PATCH 13/16] build: increase version to 3 We used to provide libtsm as part of kmscon. To avoid any compatibility problems, increase the library version to 3 (same for symbol versions). This way, old libtsm libraries will not be linked to by new programs. Signed-off-by: David Herrmann --- Makefile.am | 2 +- docs/libtsm.sym | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index 898caca..2c5388b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,7 +7,7 @@ # Library Version Numbers # -LIBTSM_CURRENT = 1 +LIBTSM_CURRENT = 3 LIBTSM_REVISION = 0 LIBTSM_AGE = 0 diff --git a/docs/libtsm.sym b/docs/libtsm.sym index 63d2cda..3593646 100644 --- a/docs/libtsm.sym +++ b/docs/libtsm.sym @@ -26,9 +26,18 @@ LIBTSM_1 { global: tsm_ucs4_get_width; +local: + *; +}; + +LIBTSM_2 { +global: tsm_ucs4_to_utf8; tsm_ucs4_to_utf8_alloc; +} LIBTSM_1; +LIBTSM_3 { +global: tsm_screen_new; tsm_screen_ref; tsm_screen_unref; @@ -102,6 +111,4 @@ global: tsm_vte_hard_reset; tsm_vte_input; tsm_vte_handle_keyboard; -local: - *; -}; +} LIBTSM_2; -- 2.7.4 From 4434379dff2fafe9ddab9c47763dc4d5b135aa23 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 29 Oct 2013 08:34:10 +0100 Subject: [PATCH 14/16] README: fix links Fix links to point to the fdo wiki and dirs. Signed-off-by: David Herrmann --- README | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/README b/README index 87b2765..eadb139 100644 --- a/README +++ b/README @@ -18,7 +18,7 @@ as possible. This is why the TERM variable can be set to xterm-color256 with any TSM based terminal emulator. Website: - http://dvdhrm.github.io/libtsm + http://www.freedesktop.org/wiki/Software/kmscon/libtsm == Requirements == @@ -30,7 +30,7 @@ Website: == Download == Released tarballs can be found at: - http://dvdhrm.github.io/libtsm + http://www.freedesktop.org/software/kmscon/releases == Install == @@ -44,17 +44,15 @@ Released tarballs can be found at: == Documentation == - TODO + There is currently no API documentation available. You can have a look at the + example terminal-emulator "wlterm" available at: + http://www.freedesktop.org/wiki/Software/kmscon/wlterm == License == This software is licensed under the terms of an MIT-like license. Please see ./COPYING for further information. -== FAQ == - - Please see: http://dvdhrm.github.io/libtsm - == Contact == This software is maintained by: -- 2.7.4 From e998bb280049ccd477b50a35718abdb46ab6a9fc Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 29 Oct 2013 08:37:22 +0100 Subject: [PATCH 15/16] build: increase package version to 3 Same as for library/symbol version, we set the package version to 3 to avoid any conflicts with earlier embedded libtsm releases. Signed-off-by: David Herrmann --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index c559c39..f57ffb3 100644 --- a/configure.ac +++ b/configure.ac @@ -6,7 +6,7 @@ AC_PREREQ(2.68) AC_INIT([libtsm], - [1], + [3], [https://github.com/dvdhrm/libtsm/issues], [libtsm], [http://dvdhrm.github.io/libtsm]) -- 2.7.4 From c35608a710c62306eb0fe44c29e600808907c463 Mon Sep 17 00:00:00 2001 From: Quanxian Wang Date: Fri, 6 Jun 2014 11:42:06 +0800 Subject: [PATCH 16/16] Add packaging Change-Id: Ic3f706d8ffc8834b710c3340b3cc6fc8ea1836d1 Signed-off-by: Quanxian Wang --- packaging/libtsm.manifest | 5 ++++ packaging/libtsm.spec | 69 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 packaging/libtsm.manifest create mode 100644 packaging/libtsm.spec diff --git a/packaging/libtsm.manifest b/packaging/libtsm.manifest new file mode 100644 index 0000000..017d22d --- /dev/null +++ b/packaging/libtsm.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/libtsm.spec b/packaging/libtsm.spec new file mode 100644 index 0000000..63318eb --- /dev/null +++ b/packaging/libtsm.spec @@ -0,0 +1,69 @@ +Name: libtsm +Version: 3.0 +Release: 0 +Summary: State machine for terminal emulators +License: MIT +Group: Graphics & UI Framework/Wayland Window System +Url: http://www.freedesktop.org/wiki/Software/libtsm + +#Git-Clone: git://people.freedesktop.org/~dvdhrm/libtsm +#Git-Web: http://cgit.freedesktop.org/~dvdhrm/libtsm +Source0: %name-%version.tar.xz +Source1001: libtsm.manifest +BuildRequires: autoconf >= 2.64, automake >= 1.11 +BuildRequires: expat-devel +BuildRequires: libjpeg-devel +BuildRequires: libtool >= 2.2 +BuildRequires: libvpx-devel +BuildRequires: pam-devel +BuildRequires: pkgconfig +BuildRequires: xz +BuildRequires: pkgconfig(xkbcommon) >= 0.3.0 + +%description +TSM-Terminal Emulator State Machine +TSM is a state machine for DEC VT100-VT520 compatible terminal +emulators. It tries to support all common standards while keeping +compatibility to existing emulators like xterm, gnome-terminal, +konsole,.. +TSM itself does not provide any rendering nor window management. +It is a simple plain state machine without any external dependencies. +It can be used to implement terminal emulators, but also to implement +other applications that need to interpret terminal escape sequences. + +%package devel +Summary: Development files for package %{name} +Group: Graphics & UI Framework/Development +Requires: libtsm + +%description devel +This package provides header files and other developer releated files +for package %{name}. + +%prep +%setup -q +cp %{SOURCE1001} . + +%build +%autogen +make + +%install +%make_install + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license COPYING +%_libdir/%{name}.so* + +%files devel +%manifest %{name}.manifest +%_includedir/%{name}.h +%_libdir/pkgconfig/%{name}.pc + +%changelog -- 2.7.4