Hook up framebuffer changes with UI window

Change-Id: Ib2dff72c808614cd6ded096d62717afc1c41e667
diff --git a/android/framebuffer-core.c b/android/framebuffer-core.c
index 62e979a..f4f53a7 100644
--- a/android/framebuffer-core.c
+++ b/android/framebuffer-core.c
@@ -225,9 +225,6 @@
     AsyncStatus status;
     FBUpdateNotify* descr = fbupdatenotify_create(core_fb, fb, x, y, w, h);
 
-    printf("Update framebuffer (%u bytes): %d:%d - %d:%d         ",
-           descr->message_size, x, y, w, h);
-
     // Lets see if we should list it behind other pending updates.
     if (core_fb->fb_update_tail != NULL) {
         core_fb->fb_update_tail->next_fb_update = descr;
diff --git a/android/framebuffer-ui.c b/android/framebuffer-ui.c
index 47c0d8a..5202381 100644
--- a/android/framebuffer-ui.c
+++ b/android/framebuffer-ui.c
@@ -39,6 +39,9 @@
  * Descriptor for the framebuffer client.
  */
 struct ClientFramebuffer {
+    /* Framebuffer for this client. */
+    QFrameBuffer*   fb;
+
     /* Core connection instance for the framebuffer client. */
     CoreConnection* core_connection;
 
@@ -68,20 +71,30 @@
 static ClientFramebuffer _client_fb;
 
 /*
- * Updates a desplay rectangle.
+ * Updates a display rectangle.
  * Param
+ *  fb - Framebuffer where to update the rectangle.
  *  x, y, w, and h define rectangle to update.
  *  bits_per_pixel define number of bits used to encode a single pixel.
  *  pixels contains pixels for the rectangle. Buffer addressed by this parameter
  *      must be eventually freed with free()
  */
-void
-update_rect(uint16_t x, uint16_t y, uint16_t w, uint16_t h,
+static void
+update_rect(QFrameBuffer* fb, uint16_t x, uint16_t y, uint16_t w, uint16_t h,
             uint8_t bits_per_pixel, uint8_t* pixels)
 {
-    // TODO: Do the actual update!
-    printf("Update rectangle (%d bytes): %d:%d %d:%d\n",
-           w * h * (bits_per_pixel / 8), x, y, w, h);
+    if (fb != NULL) {
+        uint16_t n;
+        const uint8_t* src = pixels;
+        const uint16_t src_line_size = w * ((bits_per_pixel + 7) / 8);
+        uint8_t* dst  = (uint8_t*)fb->pixels + y * fb->pitch + x * fb->bytes_per_pixel;
+        for (n = 0; n < h; n++) {
+            memcpy(dst, src, src_line_size);
+            src += src_line_size;
+            dst += fb->pitch;
+        }
+        qframebuffer_update(fb, x, y, w, h);
+    }
     free(pixels);
 }
 
@@ -145,15 +158,18 @@
             fb_client->reader_buffer = (uint8_t*)&fb_client->update_header;
 
             // Perform the update. Note that pixels buffer must be freed there.
-            update_rect(fb_client->update_header.x, fb_client->update_header.y,
-                        fb_client->update_header.w, fb_client->update_header.h,
-                        fb_client->bits_per_pixel, pixels);
+            update_rect(fb_client->fb, fb_client->update_header.x,
+                        fb_client->update_header.y, fb_client->update_header.w,
+                        fb_client->update_header.h, fb_client->bits_per_pixel,
+                        pixels);
         }
     }
 }
 
 ClientFramebuffer*
-clientfb_create(SockAddress* console_socket, const char* protocol)
+clientfb_create(SockAddress* console_socket,
+                const char* protocol,
+                QFrameBuffer* fb)
 {
     char* connect_message = NULL;
     char switch_cmd[256];
@@ -212,6 +228,7 @@
     }
 
     // Now that we're connected lets initialize the descriptor.
+    _client_fb.fb = fb;
     _client_fb.sock = core_connection_get_socket(_client_fb.core_connection);
     _client_fb.fb_state = WAIT_HEADER;
     _client_fb.reader_buffer = (uint8_t*)&_client_fb.update_header;
diff --git a/android/framebuffer-ui.h b/android/framebuffer-ui.h
index 188a3c1..158f137 100644
--- a/android/framebuffer-ui.h
+++ b/android/framebuffer-ui.h
@@ -19,6 +19,7 @@
 #define _ANDROID_FRAMEBUFFER_UI_H
 
 #include "console.h"
+#include "framebuffer.h"
 #include "android/looper.h"
 #include "android/async-utils.h"
 #include "android/core-connection.h"
@@ -33,11 +34,13 @@
  *  protocol Protocol to use for the updates:
  *      -raw Stream pixels over socket
  *      -shared Use shared memory for pixels.
+ * fb - Framebuffer associated with this FB client.
  * Return:
  *  Descriptor for the framebuffer client on success, or NULL on failure.
  */
 ClientFramebuffer* clientfb_create(SockAddress* console_socket,
-                                   const char* protocol);
+                                   const char* protocol,
+                                   QFrameBuffer* fb);
 
 /*
  * Disconnects and destroys framebuffer client.
diff --git a/android/main-ui.c b/android/main-ui.c
index 688c529..8cf3de7 100644
--- a/android/main-ui.c
+++ b/android/main-ui.c
@@ -862,6 +862,7 @@
     int iter;
     SockAddress console_socket;
     SockAddress** sockaddr_list;
+    QEmulator* emulator;
 
     // Parse attach_core param extracting the host name, and the port name.
     char* console_address = strdup(opts->attach_core);
@@ -943,7 +944,9 @@
         return -1;
     }
 
-    fb_client = clientfb_create(&console_socket, "-raw");
+    emulator = qemulator_get();
+    fb_client = clientfb_create(&console_socket, "-raw",
+                                qemulator_get_first_framebuffer(emulator));
     if (fb_client == NULL) {
         return -1;
     }
@@ -1044,14 +1047,6 @@
         exit(0);
     }
 
-    // Lets see if we're attaching to a running core process here.
-    if (opts->attach_core) {
-        /* TODO: This is just for the testing and debugging purposes. Later,
-         * when code develops, there will be more meat on that bone. */
-        if (attach_to_core(opts)) {
-            return -1;
-        }
-    }
 
     if (android_charmap_setup(opts->charmap)) {
         exit(1);
@@ -1375,6 +1370,15 @@
     emulator_config_init();
     init_skinned_ui(opts->skindir, opts->skin, opts);
 
+    // Lets see if we're attaching to a running core process here.
+    if (opts->attach_core) {
+        /* TODO: This is just for the testing and debugging purposes. Later,
+         * when code develops, there will be more meat on that bone. */
+        if (attach_to_core(opts)) {
+            return -1;
+        }
+    }
+
     if (!opts->netspeed) {
         if (skin_network_speed)
             D("skin network speed: '%s'", skin_network_speed);
diff --git a/android/qemulator.c b/android/qemulator.c
index 32983be..3f427b8 100644
--- a/android/qemulator.c
+++ b/android/qemulator.c
@@ -194,6 +194,19 @@
     return emulator->layout;
 }
 
+QFrameBuffer*
+qemulator_get_first_framebuffer(QEmulator* emulator)
+{
+    /* register as a framebuffer clients for all displays defined in the skin file */
+    SKIN_FILE_LOOP_PARTS( emulator->layout_file, part )
+        SkinDisplay*  disp = part->display;
+        if (disp->valid) {
+            return disp->qfbuff;
+        }
+    SKIN_FILE_LOOP_END_PARTS
+    return NULL;
+}
+
 void
 qemulator_set_title(QEmulator* emulator)
 {
diff --git a/android/qemulator.h b/android/qemulator.h
index d9728cd..189cc53 100644
--- a/android/qemulator.h
+++ b/android/qemulator.h
@@ -62,6 +62,10 @@
 SkinLayout*
 qemulator_get_layout( QEmulator* emulator );
 
+/* Gets framebuffer for the first display. */
+QFrameBuffer*
+qemulator_get_first_framebuffer(QEmulator* emulator);
+
 /* A helper routine for getting device DPI. */
 int
 get_device_dpi( AndroidOptions*  opts );