/* 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;
  buffer->drm_device_fd = -1;

  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;
  ply_monitor_close(buffer);
}

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)) {
    int line;

    if (buffer->bytes_per_pixel == 2) {
      uint16_t *src_16 = 0, *src_16_end;

      /* 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 (buffer->bytes_per_pixel == 3) {
      uint8_t *src_8 = (uint8_t *) malloc(width * sizeof(uint8_t) * 3);

      if (!src_8)
        return false;

      for (line = 0; line < lines; line++) {
        int col;
        uint8_t *s = src_8;
        for (col = 0; col < width; col++) {
          *s++ = (uint8_t)(src[col] & 0xFF); // blue
          *s++ = (uint8_t)((src[col] >> 8) & 0xFF); // green
          *s++ = (uint8_t)((src[col] >> 16) & 0xFF); // red
        }

        memcpy(dst, src_8, width * buffer->bytes_per_pixel);

        dst += buffer->row_stride * buffer->bytes_per_pixel;
        src += area->width;
      }
      free(src_8);
    } else {
      return false;
    }
  } 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 3: {
      uint8_t* ptr = (uint8_t*) buffer->map_address;
      uint8_t* curr_ptr;
      uint8_t b0 = (uint8_t)(fb_clear_color & 0xFF);
      uint8_t b1 = (uint8_t)((fb_clear_color >> 8) & 0xFF);
      uint8_t b2 = (uint8_t)((fb_clear_color >> 16) & 0xFF);
      for (j = 0; j < fb_height; j++) {
        curr_ptr = ptr + j * fb_stride * 3;
        for (i = 0; i < fb_width; i++) {
          *curr_ptr++ = b0;
          *curr_ptr++ = b1;
          *curr_ptr++ = b2;
        }
      }
      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);
  }
}
