blob: 1f138d0ac5907b2948f2c5b83f22ef05dd5d923e [file] [log] [blame]
/* 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;
}