]> git.proxmox.com Git - spiceterm.git/commitdiff
implement scroll
authorDietmar Maurer <dietmar@proxmox.com>
Wed, 21 Aug 2013 12:30:16 +0000 (14:30 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Wed, 21 Aug 2013 12:30:16 +0000 (14:30 +0200)
spiceterm.c
test_display_base.c
test_display_base.h

index f45bccdd4e0bc195b471c87f0267102369a557ac..0104cc7b2b510ebcbf72b351aed5a46bae5f9276 100644 (file)
@@ -205,102 +205,84 @@ vncterm_refresh (vncTerm *vt)
 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
index 128149ac58213fc45de79053c80bb9226e91e6b6..e6c91fe866b1255c0891a3d60a722e1643ed2dfa 100644 (file)
@@ -85,6 +85,29 @@ static void simple_set_release_info(QXLReleaseInfo *info, intptr_t ptr)
     //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,
@@ -196,6 +219,73 @@ static SimpleSpiceUpdate *test_draw_char(Test *test, int x, int y, int c, int fg
     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)
 {
@@ -271,30 +361,6 @@ static void get_init_info(QXLInstance *qin, QXLDevInitInfo *info)
     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)
 {
index 6b3c4ca409385d929ce11850bf625facede09c75..a4f8ab12ac540a530edc1777eb9f2b62559abb79 100644 (file)
@@ -139,6 +139,9 @@ void test_add_keyboard_interface(Test *test);
 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);