static void
vncterm_scroll_down (vncTerm *vt, int top, int bottom, int lines)
{
- if ((top + lines) >= bottom) {
- lines = bottom - top -1;
- }
-
- if (top < 0 || bottom > vt->height || top >= bottom || lines < 1) {
- return;
- }
-
- g_error("vncterm_scroll_down not implemented");
+ if ((top + lines) >= bottom) {
+ lines = bottom - top -1;
+ }
- /*
- int h = lines * 16;
- int y0 = top*16;
- int y1 = y0 + h;
- int y2 = bottom*16;
- int rowstride = vt->screen->paddedWidthInBytes;
- int rows = (bottom - top - lines)*16;
+ if (top < 0 || bottom > vt->height || top >= bottom || lines < 1) {
+ return;
+ }
- char *in = vt->screen->frameBuffer+y0*rowstride;
- char *out = vt->screen->frameBuffer+y1*rowstride;
- memmove(out,in, rowstride*rows);
+ int i;
+ for(i = bottom - top - lines - 1; i >= 0; i--) {
+ int src = ((vt->y_base + top + i) % vt->total_height)*vt->width;
+ int dst = ((vt->y_base + top + lines + i) % vt->total_height)*vt->width;
- memset(vt->screen->frameBuffer+y0*rowstride, 0, h*rowstride);
- rfbMarkRectAsModified (vt->screen, 0, y0, vt->screen->width, y2);
+ memmove(vt->cells + dst, vt->cells + src, vt->width*sizeof (TextCell));
+ }
- int i;
- for(i = bottom - top - lines - 1; i >= 0; i--) {
- int src = ((vt->y_base + top + i) % vt->total_height)*vt->width;
- int dst = ((vt->y_base + top + lines + i) % vt->total_height)*vt->width;
+ for (i = 0; i < lines; i++) {
+ int j;
+ TextCell *c = vt->cells + ((vt->y_base + top + i) % vt->total_height)*vt->width;
+ for(j = 0; j < vt->width; j++) {
+ c->attrib = vt->default_attrib;
+ c->ch = ' ';
+ c++;
+ }
+ }
- memmove(vt->cells + dst, vt->cells + src, vt->width*sizeof (TextCell));
- }
+ int h = lines * 16;
+ int y0 = top*16;
+ int y1 = y0 + h;
+ int y2 = bottom*16;
- for (i = 0; i < lines; i++) {
- int j;
- TextCell *c = vt->cells + ((vt->y_base + top + i) % vt->total_height)*vt->width;
- for(j = 0; j < vt->width; j++) {
- c->attrib = vt->default_attrib;
- c->ch = ' ';
- c++;
- }
- }
- */
+ test_spice_scroll(vt->screen, 0, y1, vt->screen->primary_width, y2, 0, y0);
+ test_spice_clear(vt->screen, 0, y0, vt->screen->primary_width, y1);
}
static void
vncterm_scroll_up (vncTerm *vt, int top, int bottom, int lines, int moveattr)
{
- if ((top + lines) >= bottom) {
- lines = bottom - top - 1;
- }
-
- if (top < 0 || bottom > vt->height || top >= bottom || lines < 1) {
- return;
- }
-
- g_error("vncterm_scroll_down not implemented");
-
- /*
- int h = lines * 16;
- int y0 = top*16;
- int y1 = (top + lines)*16;
- int y2 = bottom*16;
- int rowstride = vt->screen->paddedWidthInBytes;
- int rows = (bottom - top - lines)*16;
+ if ((top + lines) >= bottom) {
+ lines = bottom - top - 1;
+ }
- char *in = vt->screen->frameBuffer+y1*rowstride;
- char *out = vt->screen->frameBuffer+y0*rowstride;
- memmove(out,in, rowstride*rows);
+ if (top < 0 || bottom > vt->height || top >= bottom || lines < 1) {
+ return;
+ }
- memset(vt->screen->frameBuffer+(y2-h)*rowstride, 0, h*rowstride);
- rfbMarkRectAsModified (vt->screen, 0, y0, vt->screen->width, y2);
+ int h = lines * 16;
+ int y0 = top*16;
+ int y1 = (top + lines)*16;
+ int y2 = bottom*16;
- if (!moveattr) return;
+ test_spice_scroll(vt->screen, 0, y0, vt->screen->primary_width, y2 -h, 0, y1);
+ test_spice_clear(vt->screen, 0, y2 -h, vt->screen->primary_width, y2);
+
+ if (!moveattr) {
+ return;
+ }
- // move attributes
+ // move attributes
- int i;
- for(i = 0; i < (bottom - top - lines); i++) {
- int dst = ((vt->y_base + top + i) % vt->total_height)*vt->width;
- int src = ((vt->y_base + top + lines + i) % vt->total_height)*vt->width;
+ int i;
+ for(i = 0; i < (bottom - top - lines); i++) {
+ int dst = ((vt->y_base + top + i) % vt->total_height)*vt->width;
+ int src = ((vt->y_base + top + lines + i) % vt->total_height)*vt->width;
- memmove(vt->cells + dst, vt->cells + src, vt->width*sizeof (TextCell));
- }
+ memmove(vt->cells + dst, vt->cells + src, vt->width*sizeof (TextCell));
+ }
- for (i = 1; i <= lines; i++) {
- int j;
- TextCell *c = vt->cells + ((vt->y_base + bottom - i) % vt->total_height)*vt->width;
- for(j = 0; j < vt->width; j++) {
- c->attrib = vt->default_attrib;
- c->ch = ' ';
- c++;
+ for (i = 1; i <= lines; i++) {
+ int j;
+ TextCell *c = vt->cells + ((vt->y_base + bottom - i) % vt->total_height)*vt->width;
+ for(j = 0; j < vt->width; j++) {
+ c->attrib = vt->default_attrib;
+ c->ch = ' ';
+ c++;
+ }
}
- }
- */
}
static void
//info->group_id = MEM_SLOT_GROUP_ID;
}
+// We shall now have a ring of commands, so that we can update
+// it from a separate thread - since get_command is called from
+// the worker thread, and we need to sometimes do an update_area,
+// which cannot be done from red_worker context (not via dispatcher,
+// since you get a deadlock, and it isn't designed to be done
+// any other way, so no point testing that).
+
+
+static void push_command(Test *test, QXLCommandExt *ext)
+{
+ g_mutex_lock(test->command_mutex);
+
+ while (test->commands_end - test->commands_start >= COMMANDS_SIZE) {
+ g_cond_wait(test->command_cond, test->command_mutex);
+ }
+ g_assert(test->commands_end - test->commands_start < COMMANDS_SIZE);
+ test->commands[test->commands_end % COMMANDS_SIZE] = ext;
+ test->commands_end++;
+ g_mutex_unlock(test->command_mutex);
+
+ test->qxl_worker->wakeup(test->qxl_worker);
+}
+
/* bitmap are freed, so they must be allocated with g_malloc */
SimpleSpiceUpdate *test_spice_create_update_from_bitmap(uint32_t surface_id,
QXLRect bbox,
return test_spice_create_update_from_bitmap(0, bbox, bitmap);
}
+void test_spice_scroll(Test *test, int x1, int y1, int x2, int y2, int src_x, int src_y)
+{
+ SimpleSpiceUpdate *update;
+ QXLDrawable *drawable;
+ QXLRect bbox;
+
+ int surface_id = 0; // fixme
+
+ update = g_new0(SimpleSpiceUpdate, 1);
+ drawable = &update->drawable;
+
+ bbox.left = x1;
+ bbox.top = y1;
+ bbox.right = x2;
+ bbox.bottom = y2;
+
+ drawable->surface_id = surface_id;
+
+ drawable->bbox = bbox;
+ drawable->clip.type = SPICE_CLIP_TYPE_NONE;
+ drawable->effect = QXL_EFFECT_OPAQUE;
+ simple_set_release_info(&drawable->release_info, (intptr_t)update);
+ drawable->type = QXL_COPY_BITS;
+ drawable->surfaces_dest[0] = -1;
+ drawable->surfaces_dest[1] = -1;
+ drawable->surfaces_dest[2] = -1;
+
+ drawable->u.copy_bits.src_pos.x = src_x;
+ drawable->u.copy_bits.src_pos.y = src_y;
+
+ set_cmd(&update->ext, QXL_CMD_DRAW, (intptr_t)drawable);
+
+ push_command(test, &update->ext);
+}
+
+void test_spice_clear(Test *test, int x1, int y1, int x2, int y2)
+{
+ SimpleSpiceUpdate *update;
+ QXLDrawable *drawable;
+ QXLRect bbox;
+
+ int surface_id = 0; // fixme
+
+ update = g_new0(SimpleSpiceUpdate, 1);
+ drawable = &update->drawable;
+
+ bbox.left = x1;
+ bbox.top = y1;
+ bbox.right = x2;
+ bbox.bottom = y2;
+
+ drawable->surface_id = surface_id;
+
+ drawable->bbox = bbox;
+ drawable->clip.type = SPICE_CLIP_TYPE_NONE;
+ drawable->effect = QXL_EFFECT_OPAQUE;
+ simple_set_release_info(&drawable->release_info, (intptr_t)update);
+ drawable->type = QXL_DRAW_BLACKNESS;
+ drawable->surfaces_dest[0] = -1;
+ drawable->surfaces_dest[1] = -1;
+ drawable->surfaces_dest[2] = -1;
+
+ set_cmd(&update->ext, QXL_CMD_DRAW, (intptr_t)drawable);
+
+ push_command(test, &update->ext);
+}
+
static void create_primary_surface(Test *test, uint32_t width,
uint32_t height)
{
info->n_surfaces = 1;
}
-
-// We shall now have a ring of commands, so that we can update
-// it from a separate thread - since get_command is called from
-// the worker thread, and we need to sometimes do an update_area,
-// which cannot be done from red_worker context (not via dispatcher,
-// since you get a deadlock, and it isn't designed to be done
-// any other way, so no point testing that).
-
-
-static void push_command(Test *test, QXLCommandExt *ext)
-{
- g_mutex_lock(test->command_mutex);
-
- while (test->commands_end - test->commands_start >= COMMANDS_SIZE) {
- g_cond_wait(test->command_cond, test->command_mutex);
- }
- g_assert(test->commands_end - test->commands_start < COMMANDS_SIZE);
- test->commands[test->commands_end % COMMANDS_SIZE] = ext;
- test->commands_end++;
- g_mutex_unlock(test->command_mutex);
-
- test->qxl_worker->wakeup(test->qxl_worker);
-}
-
// called from spice_server thread (i.e. red_worker thread)
static int get_command(QXLInstance *qin, struct QXLCommandExt *ext)
{
Test* test_new(SpiceCoreInterface* core);
void test_draw_update_char(Test *test, int x, int y, int c, TextAttributes attrib);
+void test_spice_scroll(Test *test, int x1, int y1, int x2, int y2, int src_x, int src_y);
+void test_spice_clear(Test *test, int x1, int y1, int x2, int y2);
+
uint32_t test_get_width(void);
uint32_t test_get_height(void);