/* ply-gamma.c - plymouth gamma setup via KMS
 *
 * Copyright (C) 2011, The Chromium OS Authors.
 *
 * 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.
 *
 */

#include "ply-gamma.h"
#include "ply-kms.h"

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <xf86drm.h>
#include <xf86drmMode.h>

static const int kInternalPanel = 1;

typedef struct {
  uint16_t *red;
  uint16_t *green;
  uint16_t *blue;
} GammaRamp;

static GammaRamp* load_gamma_ramp(const char* file) {
  const int kGammaSize = 256;
  int i, r = 0;

  FILE* f = fopen(file, "rb");
  if (!f)
    return NULL;

  unsigned char red[kGammaSize], green[kGammaSize], blue[kGammaSize];

  r += fread(red, sizeof(red), 1, f);
  r += fread(green, sizeof(green), 1, f);
  r += fread(blue, sizeof(blue), 1, f);
  fclose(f);

  if (r != 3)
    return NULL;

  GammaRamp* ramp = (GammaRamp*)malloc(sizeof(GammaRamp));
  ramp->red = (uint16_t*)malloc(sizeof(uint16_t) * kGammaSize);
  ramp->green = (uint16_t*)malloc(sizeof(uint16_t) * kGammaSize);
  ramp->blue = (uint16_t*)malloc(sizeof(uint16_t) * kGammaSize);

  for(i = 0; i < kGammaSize; ++i) {
    ramp->red[i]   = (uint16_t)red[i] * 257;
    ramp->green[i] = (uint16_t)green[i] * 257;
    ramp->blue[i]  = (uint16_t)blue[i] * 257;
  }

  return ramp;
}

static void free_gamma_ramp(GammaRamp* ramp) {
  free(ramp->red);
  free(ramp->green);
  free(ramp->blue);
  free(ramp);
}

bool ply_gamma_set(const char* file) {
  int r;
  int crtc;
  drmModeCrtcPtr mode;
  GammaRamp* ramp;

  ramp = load_gamma_ramp(file);

  if (!ramp) {
    fprintf(stderr, "Unable to load gamma ramp\n");
    return false;
  }

  int fd = ply_kms_open();
  if (fd < 0) {
    fprintf(stderr, "Unable to open a KMS module\n");
    return false;
  }

  drmModeRes *resources = drmModeGetResources(fd);
  if (!resources) {
    fprintf(stderr, "Unable to get mode resources\n");
    drmClose(fd);
    return false;
  }

  crtc = (kInternalPanel < resources->count_crtcs) ? kInternalPanel : 0;
  mode = drmModeGetCrtc(fd, resources->crtcs[crtc]);
  r = drmModeCrtcSetGamma(fd,
                           mode->crtc_id,
                           mode->gamma_size,
                           ramp->red,
                           ramp->green,
                           ramp->blue);

  drmModeFreeResources(resources);
  drmClose(fd);
  free_gamma_ramp(ramp);
  return r >= 0;
}
