aboutsummaryrefslogtreecommitdiff
path: root/android/protocol/fb-updates-impl.c
diff options
context:
space:
mode:
Diffstat (limited to 'android/protocol/fb-updates-impl.c')
-rw-r--r--android/protocol/fb-updates-impl.c271
1 files changed, 0 insertions, 271 deletions
diff --git a/android/protocol/fb-updates-impl.c b/android/protocol/fb-updates-impl.c
deleted file mode 100644
index e36c4bfe18..0000000000
--- a/android/protocol/fb-updates-impl.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/* Copyright (C) 2010 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-/*
- * Contains UI-side framebuffer client that receives framebuffer updates
- * from the core.
- */
-
-#include "android/utils/system.h"
-#include "android/utils/debug.h"
-#include "android/utils/eintr_wrapper.h"
-#include "android/utils/panic.h"
-#include "android/sync-utils.h"
-#include "android/protocol/core-connection.h"
-#include "android/protocol/fb-updates.h"
-#include "android/protocol/fb-updates-impl.h"
-
-/*Enumerates states for the client framebuffer update reader. */
-typedef enum FbImplState {
- /* The reader is waiting on update header. */
- EXPECTS_HEADER,
-
- /* The reader is waiting on pixels. */
- EXPECTS_PIXELS,
-} FbImplState;
-
-/* Descriptor for the UI-side implementation of the "framebufer" service.
- */
-typedef struct FrameBufferImpl {
- /* Framebuffer for this client. */
- QFrameBuffer* fb;
-
- /* Core connection instance for the framebuffer client. */
- CoreConnection* core_connection;
-
- /* Current update header. */
- FBUpdateMessage update_header;
-
- /* Reader's buffer. */
- uint8_t* reader_buffer;
-
- /* Offset in the reader's buffer where to read next chunk of data. */
- size_t reader_offset;
-
- /* Total number of bytes the reader expects to read. */
- size_t reader_bytes;
-
- /* Current state of the update reader. */
- FbImplState fb_state;
-
- /* Socket descriptor for the framebuffer client. */
- int sock;
-
- /* Custom i/o handler */
- LoopIo io[1];
-
- /* Number of bits used to encode single pixel. */
- int bits_per_pixel;
-} FrameBufferImpl;
-
-/* One and the only FrameBufferImpl instance. */
-static FrameBufferImpl _fbImpl;
-
-/*
- * 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()
- */
-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)
-{
- 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);
-}
-
-/*
- * Asynchronous I/O callback launched when framebuffer notifications are ready
- * to be read.
- * Param:
- * opaque - FrameBufferImpl instance.
- */
-static void
-_fbUpdatesImpl_io_callback(void* opaque, int fd, unsigned events)
-{
- FrameBufferImpl* fbi = opaque;
- int ret;
-
- // Read updates while they are immediately available.
- for (;;) {
- // Read next chunk of data.
- ret = HANDLE_EINTR(
- socket_recv(fbi->sock,
- fbi->reader_buffer + fbi->reader_offset,
- fbi->reader_bytes - fbi->reader_offset));
- if (ret < 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
- // Chunk is not avalable at this point. Come back later.
- return;
- }
- if (ret <= 0) {
- /* disconnection ! */
- derror("Unable to receive framebuffer data: %s\n",
- ret < 0 ? strerror(errno), "unexpected disconnection");
- fbUpdatesImpl_destroy();
- return;
- }
-
- fbi->reader_offset += ret;
- if (fbi->reader_offset != fbi->reader_bytes) {
- // There are still some data left in the pipe.
- continue;
- }
-
- // All expected data has been read. Time to change the state.
- if (fbi->fb_state == EXPECTS_HEADER) {
- // Update header has been read. Prepare for the pixels.
- fbi->fb_state = EXPECTS_PIXELS;
- fbi->reader_offset = 0;
- fbi->reader_bytes = fbi->update_header.w *
- fbi->update_header.h *
- (fbi->bits_per_pixel / 8);
- fbi->reader_buffer = malloc(fbi->reader_bytes);
- if (fbi->reader_buffer == NULL) {
- APANIC("Unable to allocate memory for framebuffer update\n");
- }
- } else {
- // Pixels have been read. Prepare for the header.
- uint8_t* pixels = fbi->reader_buffer;
-
- fbi->fb_state = EXPECTS_HEADER;
- fbi->reader_offset = 0;
- fbi->reader_bytes = sizeof(FBUpdateMessage);
- fbi->reader_buffer = (uint8_t*)&fbi->update_header;
-
- // Perform the update. Note that pixels buffer must be freed there.
- _update_rect(fbi->fb, fbi->update_header.x,
- fbi->update_header.y, fbi->update_header.w,
- fbi->update_header.h, fbi->bits_per_pixel,
- pixels);
- }
- }
-}
-
-int
-fbUpdatesImpl_create(SockAddress* console_socket,
- const char* protocol,
- QFrameBuffer* fb,
- Looper* looper)
-{
- FrameBufferImpl* fbi = &_fbImpl;
- char* handshake = NULL;
- char switch_cmd[256];
-
- // Initialize descriptor.
- fbi->fb = fb;
- fbi->reader_buffer = (uint8_t*)&fbi->update_header;
- fbi->reader_offset = 0;
- fbi->reader_bytes = sizeof(FBUpdateMessage);
-
- // Connect to the framebuffer service.
- snprintf(switch_cmd, sizeof(switch_cmd), "framebuffer %s", protocol);
- fbi->core_connection =
- core_connection_create_and_switch(console_socket, switch_cmd, &handshake);
- if (fbi->core_connection == NULL) {
- derror("Unable to connect to the framebuffer service: %s\n",
- errno_str);
- return -1;
- }
-
- // We expect core framebuffer to return us bits per pixel property in
- // the handshake message.
- fbi->bits_per_pixel = 0;
- if (handshake != NULL) {
- char* bpp = strstr(handshake, "bitsperpixel=");
- if (bpp != NULL) {
- char* end;
- bpp += strlen("bitsperpixel=");
- end = strchr(bpp, ' ');
- if (end == NULL) {
- end = bpp + strlen(bpp);
- }
- fbi->bits_per_pixel = strtol(bpp, &end, 0);
- }
- }
- if (!fbi->bits_per_pixel) {
- derror("Unexpected core framebuffer reply: %s\n"
- "Bits per pixel property is not there, or is invalid\n",
- handshake);
- fbUpdatesImpl_destroy();
- return -1;
- }
-
- fbi->sock = core_connection_get_socket(fbi->core_connection);
-
- // At last setup read callback, and start receiving the updates.
- loopIo_init(fbi->io, looper, fbi->sock,
- _fbUpdatesImpl_io_callback, &_fbImpl);
- loopIo_wantRead(fbi->io);
- {
- // Force the core to send us entire framebuffer now, when we're prepared
- // to receive it.
- FBRequestHeader hd;
- SyncSocket* sk = syncsocket_init(fbi->sock);
-
- hd.request_type = AFB_REQUEST_REFRESH;
- syncsocket_start_write(sk);
- syncsocket_write(sk, &hd, sizeof(hd), 5000);
- syncsocket_stop_write(sk);
- syncsocket_free(sk);
- }
-
- fprintf(stdout, "framebuffer is now connected to the core at %s.",
- sock_address_to_string(console_socket));
- if (handshake != NULL) {
- if (handshake[0] != '\0') {
- fprintf(stdout, " Handshake: %s", handshake);
- }
- free(handshake);
- }
- fprintf(stdout, "\n");
-
- return 0;
-}
-
-void
-fbUpdatesImpl_destroy(void)
-{
- FrameBufferImpl* fbi = &_fbImpl;
-
- if (fbi->core_connection != NULL) {
- // Disable the reader callback.
- loopIo_done(fbi->io);
-
- // Close framebuffer connection.
- core_connection_close(fbi->core_connection);
- core_connection_free(fbi->core_connection);
- fbi->core_connection = NULL;
- }
-
- fbi->fb = NULL;
- if (fbi->reader_buffer != NULL &&
- fbi->reader_buffer != (uint8_t*)&fbi->update_header) {
- free(fbi->reader_buffer);
- fbi->reader_buffer = (uint8_t*)&fbi->update_header;
- }
-}