/* ply-frame-buffer.c - framebuffer abstraction
 *
 * Copyright (C) 2006, 2007, 2008 Red Hat, Inc.
 *               2008 Charlie Brej <cbrej@cs.man.ac.uk>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 *
 * Written by: Charlie Brej <cbrej@cs.man.ac.uk>
 *             Kristian Høgsberg <krh@redhat.com>
 *             Ray Strode <rstrode@redhat.com>
 */

#include "ply-frame-buffer.h"

#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <values.h>
#include <unistd.h>

#include <linux/fb.h>

#include "ply-list.h"
#include "ply-monitor.h"
#include "ply-utils.h"

#ifndef PLY_FRAME_BUFFER_DEFAULT_FB_DEVICE_NAME
#define PLY_FRAME_BUFFER_DEFAULT_FB_DEVICE_NAME "/dev/fb0"
#endif

static bool ply_frame_buffer_open_device(ply_frame_buffer_t  *buffer);
static void ply_frame_buffer_close_device(ply_frame_buffer_t *buffer);
static bool ply_frame_buffer_query_device(ply_frame_buffer_t *buffer);
static bool ply_frame_buffer_map_to_device(ply_frame_buffer_t *buffer);
static inline uint_fast32_t
  ply_frame_buffer_pixel_value_to_device_pixel_value(
    ply_frame_buffer_t *buffer,
    uint32_t            pixel_value);

static bool ply_frame_buffer_open_device(ply_frame_buffer_t *buffer) {
  assert(buffer != NULL);
  assert(buffer->device_name != NULL);

  buffer->device_fd = open(buffer->device_name, O_RDWR);

  if (buffer->device_fd < 0) {
    return false;
  }

  return true;
}

static void ply_frame_buffer_close_device(ply_frame_buffer_t *buffer) {
  assert(buffer != NULL);

  if (buffer->map_address != MAP_FAILED) {
    munmap(buffer->map_address, buffer->size);
    buffer->map_address = MAP_FAILED;
  }

  if (buffer->device_fd >= 0) {
    close(buffer->device_fd);
    buffer->device_fd = -1;
  }
}

static void flush_area_to_any_device(ply_frame_buffer_t      *buffer,
                                     ply_frame_buffer_area_t *area_to_flush) {
  unsigned long row, column;
  char *row_buffer;
  unsigned long x1, y1, x2, y2;

  x1 = area_to_flush->x;
  y1 = area_to_flush->y;
  x2 = x1 + area_to_flush->width;
  y2 = y1 + area_to_flush->height;

  row_buffer = malloc(buffer->row_stride * buffer->bytes_per_pixel);
  for (row = y1; row < y2; row++) {
    unsigned long offset;

    for (column = x1; column < x2; column++) {
      uint32_t pixel_value;
      uint_fast32_t device_pixel_value;

      pixel_value = buffer->shadow_buffer[row * buffer->area.width + column];

      device_pixel_value =
        ply_frame_buffer_pixel_value_to_device_pixel_value(buffer,
                                                           pixel_value);

      memcpy(row_buffer + column * buffer->bytes_per_pixel,
             &device_pixel_value,
             buffer->bytes_per_pixel);
    }

    offset = row * buffer->row_stride * buffer->bytes_per_pixel +
      x1 * buffer->bytes_per_pixel;
    memcpy(buffer->map_address + offset,
           row_buffer + x1 * buffer->bytes_per_pixel,
           area_to_flush->width * buffer->bytes_per_pixel);
  }
  free(row_buffer);
}

static void flush_area_to_xrgb32_device(
    ply_frame_buffer_t *buffer, ply_frame_buffer_area_t *area_to_flush) {
  unsigned long x1, y1, y2, y;
  char *dst, *src;

  x1 = area_to_flush->x;
  y1 = area_to_flush->y;
  y2 = y1 + area_to_flush->height;

  dst = &buffer->map_address[(y1 * buffer->row_stride + x1) * 4];
  src = (char *) &buffer->shadow_buffer[y1 * buffer->area.width + x1];

  if (area_to_flush->width == buffer->row_stride) {
    memcpy(dst, src, area_to_flush->width * area_to_flush->height * 4);
    return;
  }

  for (y = y1; y < y2; y++) {
    memcpy(dst, src, area_to_flush->width * 4);
    dst += buffer->row_stride * 4;
    src += buffer->area.width * 4;
  }
}


static bool ply_frame_buffer_query_device(ply_frame_buffer_t *buffer) {
  struct fb_var_screeninfo variable_screen_info;
  struct fb_fix_screeninfo fixed_screen_info;

  assert(buffer != NULL);
  assert(buffer->device_fd >= 0);

  if (ioctl(buffer->device_fd, FBIOGET_VSCREENINFO, &variable_screen_info) < 0)
    return false;

  if (ioctl(buffer->device_fd, FBIOGET_FSCREENINFO, &fixed_screen_info) < 0)
    return false;

  /* Normally the pixel is divided into channels between the color components.
   * Each channel directly maps to a color channel on the hardware.
   *
   * There are some odd ball modes that use an indexed palette instead.  In
   * those cases (pseudocolor, direct color, etc), the pixel value is just an
   * index into a lookup table of the real color values.
   *
   * We don't support that.
   */
  if (fixed_screen_info.visual != FB_VISUAL_TRUECOLOR) {
    int rc = -1;
    int i;
    int depths[] = {32, 24, 16, 0};

    // ply_trace("Visual was %s, trying to find usable mode.\n",
    // p_visual(fixed_screen_info.visual));

    for (i = 0; depths[i] != 0; i++) {
      variable_screen_info.bits_per_pixel = depths[i];
      variable_screen_info.activate |= FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;

      rc = ioctl(buffer->device_fd, FBIOPUT_VSCREENINFO,
                 &variable_screen_info);
      if (rc >= 0) {
        if (ioctl(buffer->device_fd, FBIOGET_FSCREENINFO,
                  &fixed_screen_info) < 0)
          return false;
        if (fixed_screen_info.visual == FB_VISUAL_TRUECOLOR)
          break;
      }
    }

    if (ioctl(buffer->device_fd, FBIOGET_VSCREENINFO,
              &variable_screen_info) < 0)
      return false;

    if (ioctl(buffer->device_fd, FBIOGET_FSCREENINFO,
              &fixed_screen_info) < 0)
      return false;
  }

  if (fixed_screen_info.visual != FB_VISUAL_TRUECOLOR ||
      variable_screen_info.bits_per_pixel < 16) {
    return false;
  }

  buffer->area.x = variable_screen_info.xoffset;
  buffer->area.y = variable_screen_info.yoffset;
  buffer->area.width = variable_screen_info.xres;
  buffer->area.height = variable_screen_info.yres;
  buffer->area.visible_width = variable_screen_info.xres;
  buffer->area.visible_height = variable_screen_info.yres;
  ply_monitor_setup(buffer);

  buffer->red_bit_position = variable_screen_info.red.offset;
  buffer->bits_for_red = variable_screen_info.red.length;

  buffer->green_bit_position = variable_screen_info.green.offset;
  buffer->bits_for_green = variable_screen_info.green.length;

  buffer->blue_bit_position = variable_screen_info.blue.offset;
  buffer->bits_for_blue = variable_screen_info.blue.length;

  buffer->alpha_bit_position = variable_screen_info.transp.offset;
  buffer->bits_for_alpha = variable_screen_info.transp.length;

  buffer->bytes_per_pixel = variable_screen_info.bits_per_pixel >> 3;
  buffer->row_stride = fixed_screen_info.line_length / buffer->bytes_per_pixel;
  buffer->size = buffer->area.visible_height * buffer->row_stride *
      buffer->bytes_per_pixel;
  
  buffer->dither_red = 0;
  buffer->dither_green = 0;
  buffer->dither_blue = 0;

  if (buffer->bytes_per_pixel == 4 &&
      buffer->red_bit_position == 16 && buffer->bits_for_red == 8 &&
      buffer->green_bit_position == 8 && buffer->bits_for_green == 8 &&
      buffer->blue_bit_position == 0 && buffer->bits_for_blue == 8)
    buffer->flush_area = flush_area_to_xrgb32_device;
  else
    buffer->flush_area = flush_area_to_any_device;

  return true;
}

static bool ply_frame_buffer_map_to_device(ply_frame_buffer_t *buffer) {
  assert(buffer != NULL);
  assert(buffer->device_fd >= 0);
  assert(buffer->size > 0);

  buffer->map_address = mmap(NULL, buffer->size, PROT_WRITE,
                             MAP_SHARED, buffer->device_fd, 0);

  return buffer->map_address != MAP_FAILED;
}

static inline uint_fast32_t 
    ply_frame_buffer_pixel_value_to_device_pixel_value(
      ply_frame_buffer_t *buffer, uint32_t pixel_value) {
  uint8_t r, g, b, a;
  int orig_r, orig_g, orig_b, orig_a;
  int i;
  
  orig_a = pixel_value >> 24; 
  a = orig_a >> (8 - buffer->bits_for_alpha);

  orig_r = ((pixel_value >> 16) & 0xff) - buffer->dither_red; 
  r = CLAMP(orig_r, 0, 255) >> (8 - buffer->bits_for_red);

  orig_g = ((pixel_value >> 8) & 0xff) - buffer->dither_green;
  g = CLAMP(orig_g, 0, 255) >> (8 - buffer->bits_for_green);

  orig_b = (pixel_value & 0xff) - buffer->dither_blue;
  b = CLAMP(orig_b, 0, 255) >> (8 - buffer->bits_for_blue);
  
  uint8_t new_r = r << (8 - buffer->bits_for_red);
  uint8_t new_g = g << (8 - buffer->bits_for_green);
  uint8_t new_b = b << (8 - buffer->bits_for_blue);
  for (i=buffer->bits_for_red;   i<8; i*=2) new_r |= new_r >> i;
  for (i=buffer->bits_for_green; i<8; i*=2) new_g |= new_g >> i;
  for (i=buffer->bits_for_blue;  i<8; i*=2) new_b |= new_b >> i;
  
  buffer->dither_red = new_r - orig_r;
  buffer->dither_green = new_g - orig_g;
  buffer->dither_blue = new_b - orig_b;
  

  return ((a << buffer->alpha_bit_position)
          | (r << buffer->red_bit_position)
          | (g << buffer->green_bit_position)
          | (b << buffer->blue_bit_position));
}


static inline void 
    ply_frame_buffer_place_value_at_pixel(ply_frame_buffer_t *buffer,
                                          int                 x,
                                          int                 y,
                                          uint32_t            pixel_value) {
  buffer->shadow_buffer[y * buffer->area.width + x] = pixel_value;
}


ply_frame_buffer_t *ply_frame_buffer_new(const char *device_name) {
  ply_frame_buffer_t *buffer;

  buffer = calloc(1, sizeof(ply_frame_buffer_t));

  if (device_name != NULL)
    buffer->device_name = strdup(device_name);
  else if (getenv("FRAMEBUFFER") != NULL)
    buffer->device_name = strdup(getenv("FRAMEBUFFER"));
  else
    buffer->device_name = 
      strdup(PLY_FRAME_BUFFER_DEFAULT_FB_DEVICE_NAME);

  buffer->map_address = MAP_FAILED;
  buffer->shadow_buffer = NULL;
  buffer->areas_to_flush = ply_list_new();

  buffer->pause_count = 0;

  return buffer;
}

static void free_flush_areas(ply_frame_buffer_t *buffer) {
  ply_list_node_t *node;

  node = ply_list_get_first_node(buffer->areas_to_flush);
  while (node != NULL) {
    ply_list_node_t *next_node;
    ply_frame_buffer_area_t *area_to_flush;

    area_to_flush = (ply_frame_buffer_area_t *) ply_list_node_get_data(node);

    next_node = ply_list_get_next_node(buffer->areas_to_flush, node);

    free(area_to_flush);
    ply_list_remove_node(buffer->areas_to_flush, node);

    node = next_node;
  }

  ply_list_free(buffer->areas_to_flush);
}

void ply_frame_buffer_free(ply_frame_buffer_t *buffer) {
  assert(buffer != NULL);

  if (ply_frame_buffer_device_is_open(buffer))
    ply_frame_buffer_close(buffer);

  free_flush_areas(buffer);

  free(buffer->device_name);
  free(buffer->shadow_buffer);
  free(buffer);
}

bool ply_frame_buffer_open(ply_frame_buffer_t *buffer) {
  bool is_open;

  assert(buffer != NULL);

  is_open = false;

  if (!ply_frame_buffer_open_device(buffer)) {
    goto out;
  }

  if (!ply_frame_buffer_query_device(buffer)) {
    goto out;
  }

  if (!ply_frame_buffer_map_to_device(buffer)) {
    goto out;
  }

  buffer->shadow_buffer =
    realloc(buffer->shadow_buffer,
            4 * buffer->area.width * buffer->area.height);
  is_open = true;

out:

  if (!is_open) {
    int saved_errno;

    saved_errno = errno;
    ply_frame_buffer_close_device(buffer);
    errno = saved_errno;
  }

  return is_open;
}


bool ply_frame_buffer_device_is_open(ply_frame_buffer_t *buffer) {
  assert(buffer != NULL);
  return buffer->device_fd >= 0 && buffer->map_address != MAP_FAILED;
}

char *ply_frame_buffer_get_device_name(ply_frame_buffer_t *buffer) {
  assert(buffer != NULL);
  assert(ply_frame_buffer_device_is_open(buffer));
  assert(buffer->device_name != NULL);

  return strdup(buffer->device_name);
}

void ply_frame_buffer_set_device_name(ply_frame_buffer_t *buffer,
                                      const char         *device_name) {
  assert(buffer != NULL);
  assert(!ply_frame_buffer_device_is_open(buffer));
  assert(device_name != NULL);
  assert(buffer->device_name != NULL);

  if (strcmp(buffer->device_name, device_name) != 0) {
    free(buffer->device_name);
    buffer->device_name = strdup(device_name);
  }
}

void ply_frame_buffer_close(ply_frame_buffer_t *buffer) {
  assert(buffer != NULL);

  assert(ply_frame_buffer_device_is_open(buffer));
  ply_frame_buffer_close_device(buffer);

  buffer->bytes_per_pixel = 0;
  buffer->area.x = 0;
  buffer->area.y = 0;
  buffer->area.width = 0;
  buffer->area.height = 0;
}

void ply_frame_buffer_get_size(ply_frame_buffer_t      *buffer,
                               ply_frame_buffer_area_t *size) {
  assert(buffer != NULL);
  assert(ply_frame_buffer_device_is_open(buffer));
  assert(size != NULL);

  *size = buffer->area;
}


/*
 * Fill the given frame buffer with the given image data.  The image
 * is to occupy an area of the frame buffer given by the area
 * pointer.  That image area will be clipped as necessary to fit the
 * frame buffer boundaries.
 *
 * Returns true if any part of the image was copied.  Returns false
 * if any condition (e.g. clipping) caused the entire image to be
 * skipped.
 */
bool ply_frame_buffer_fill(ply_frame_buffer_t *buffer,
                           ply_frame_buffer_area_t *area,
                           const uint32_t *data) {
  assert(buffer != NULL);
  assert(ply_frame_buffer_device_is_open(buffer));
  assert(area != NULL);
  assert(data != NULL);

  /*
   * Short-circuit if there's no intersection between the image
   * area and the frame buffer.
   */
  if (area->x + (long) area->width < 0 ||
      area->x >= (long) buffer->area.width ||
      area->y + (long) area->height < 0 ||
      area->y >= (long) buffer->area.height)
    return false;

  /*
   * There's at least some overlap; clip the image to fit.
   */
  const uint32_t *src = data;
  char *dst = buffer->map_address;
  size_t width = area->width;
  size_t lines = area->height;

  if (area->x < 0) {
    // clip image on the left
    src -= area->x;
    width += area->x;
  } else {
    dst += area->x * buffer->bytes_per_pixel;
  }

  if (area->x + area->width > buffer->area.width) {
    // clip image on the right
    width -= area->x + area->width - buffer->area.width;
  }

  if (area->y < 0) {
    // clip the top of the image
    src -= area->y * area->width;
    lines += area->y;
  } else {
    dst += area->y * buffer->row_stride * buffer->bytes_per_pixel;
  }

  if (area->y + area->height > buffer->area.height) {
    // clip the bottom of the image
    lines -= area->y + area->height - buffer->area.height;
  }

  /*
   * Copy the image to the frame buffer.  There are three cases:
   * 1) The frame buffer pixels are not RGB32; in this case we must
   *    convert each image line to match the target before copying.
   *    (N.B. The only supported alternative to RGB32 is RGB 565).
   * 2) The image width is unclipped and the width matches the frame
   *    buffer width.  In this case, a single copy can cover the
   *    entire image.
   * 3) In all other cases we copy line by line.
   */
  if (buffer->bytes_per_pixel != sizeof(*data)) {
    uint16_t *src_16 = 0, *src_16_end;
    int line;

    /* Handle the 16 bpp case (specifically RGB 565 case) */
    if (buffer->bytes_per_pixel != 2)
      return false;

    /* Allocate temporary row pixel data storage for 16 bpp displays */
    src_16 = (uint16_t *) malloc(width * sizeof(*src_16));

    if (!src_16)
      return false;

    src_16_end = src_16 + width;

    for (line = 0; line < lines; line++) {
      const uint32_t *src_32_temp;
      uint16_t *src_16_temp;

      for (src_32_temp = src, src_16_temp = src_16;
           src_16_temp != src_16_end;
           src_16_temp++) {
        uint32_t src_32_value = *src_32_temp++;
        *src_16_temp = (uint16_t)(
            ((src_32_value & 0x00F80000) >> 8) |
            ((src_32_value & 0x0000FC00) >> 5) |
            ((src_32_value & 0x000000F8) >> 3)
          );
      }
      memcpy(dst, src_16, width * buffer->bytes_per_pixel);

      dst += buffer->row_stride * buffer->bytes_per_pixel;
      src += area->width;
    }

    free(src_16);
  } else if (width == area->width && width == buffer->row_stride) {
    memcpy(dst, src, width * lines * sizeof(*data));
  } else {
    int line;

    for (line = 0; line < lines; line++) {
      memcpy(dst, src, width * sizeof(*data));
      dst += buffer->row_stride * sizeof(*data);
      src += area->width;
    }
  }

  return true;
}


const char *ply_frame_buffer_get_bytes(ply_frame_buffer_t *buffer) {
  return (char *) buffer->shadow_buffer;
}


void ply_frame_buffer_clear(ply_frame_buffer_t *buffer,
                            uint32_t clear_color) {
  int i, j;
  int fb_width = buffer->area.visible_width;
  int fb_height = buffer->area.visible_height;
  int fb_stride = buffer->row_stride;
  uint32_t fb_clear_color;
  assert(buffer != NULL);
  assert(ply_frame_buffer_device_is_open(buffer));

  fb_clear_color =
      ply_frame_buffer_pixel_value_to_device_pixel_value(buffer,
                                                         clear_color);

  switch (buffer->bytes_per_pixel) {
    case 4: {
      uint32_t* ptr = (uint32_t*) buffer->map_address;
      uint32_t* curr_ptr;
      for (j = 0; j < fb_height; j++) {
        curr_ptr = ptr + j * fb_stride;
        for (i = 0; i < fb_width; i++)
          *curr_ptr++ = fb_clear_color;
      }
      break;
    }
    case 2: {
      uint16_t* ptr = (uint16_t*) buffer->map_address;
      uint16_t* curr_ptr;
      for (j = 0; j < fb_height; j++) {
        curr_ptr = ptr + j * fb_stride;
        for (i = 0; i < fb_width; i++)
          *curr_ptr++ = fb_clear_color;
      }
      break;
    }
    default:
      assert(0);
  }
}
