/*
 * (C) Copyright Johannes Brodwall <johannes@brodwall.com>, 2006
 *
 * Version 1.0.1
 *
 * History:
 * * 2006/02/20: Version 1.0: Colors and brightnesses with range checking.
 * * 05/11/2006: Tweaked by David Pritchard to add touchpad configuration.
 *
 * This work is licensed under the Creative Commons Attribution2.5 License.
 * To view a copy of this license, visit 
 * http://creativecommons.org/licenses/by/2.5/ 
 * or send a letter to 
 * Creative Commons, 543 Howard Street, 5th Floor, 
 * San Francisco, California, 94105, USA.
 */


#include <windows.h>

#define BUFF_SIZE 0x2c


BOOL setXpsColors(char side_color, char front_color, char top_color, char brightness, char touchpad_light) {
  //printf("setXpsColors(side_color = %d, front_color = %d, top_color = %d, brightness = %d, touchpad_light = %d)\n",
  //     side_color, front_color, top_color, brightness, touchpad_light);

  HANDLE hHandle = CreateFileA("\\\\.\\APPDRV", 
    GENERIC_READ|GENERIC_WRITE, 0, NULL,
    OPEN_EXISTING, 0x80, NULL);
  if (hHandle == INVALID_HANDLE_VALUE) {
    printf("CreateFileA(\\\\.\\APPDRV) failed: 0x%x\n", GetLastError());
    return FALSE;
  }
  
  char buffer[BUFF_SIZE];
  memset(buffer, 0, BUFF_SIZE);
  buffer[0] = 0x04;
  buffer[1] = 0x00;
  buffer[2] = 0x06;
  buffer[3] = 0x00;
  
  buffer[4] = side_color;
  buffer[5] = front_color;
  buffer[6] = top_color;
  buffer[7] = brightness;
  buffer[8] = 0x1;

  buffer[12] = touchpad_light;

  DWORD bytesReturned;
  BOOL result = DeviceIoControl(hHandle, 0x22209C, 
    buffer, BUFF_SIZE, buffer, BUFF_SIZE,
    &bytesReturned, NULL);
  if (!result) {
    printf("DeviceIoControl failed: 0x%x\n", GetLastError());
  }
  

  CloseHandle(hHandle);

  return result;  
}

void usage(char* program_name) {
  printf("usage: %s [-all color] [-front color] [-top color] "
         "[-side color] [-bright value] [-touchpad 0|1]\n", program_name);
  printf("   Where color is a number from 0-16\n");
  printf("   and brightness value is a number from 0-7\n");
  printf("\n");
  printf("(C) Copyright Johannes Brodwall <johannes@brodwall.com>, 2006\n");
  printf(" Some rights reserved: http://creativecommons.org/licenses/by/2.5/\n");
        
}

void check_range(char* program_name, char* parameter_name, int value, int low, int high) {
  if (value < low || high < value) {
    printf("Invalid value for '%s' (was %d)\n", parameter_name, value);
    usage(program_name);
    exit(-2);
  } else {
    //printf("%s = %d\n", parameter_name, value);
  }
}

int main(int argc, char** argv) {
        
  unsigned int side_color = 0;
  unsigned int front_color = 0;
  unsigned int top_color = 0;
  unsigned int brightness = 7;
  unsigned int touchpad_light = 0;
  int i = 1;
  
  if (argc<2) {
    usage(argv[0]);
    exit(0);
  }
  
  for (i=1; i<argc-1; i+=2) {
    if (strcmp(argv[i], "-front") == 0) {
        front_color = atoi(argv[i+1]);
        check_range(argv[0], "-front", front_color, 0, 16);
    } else if (strcmp(argv[i], "-top") == 0) {
        top_color = atoi(argv[i+1]);
        check_range(argv[0], "-top", top_color, 0, 16);
    } else if (strcmp(argv[i], "-side") == 0) {
        side_color = atoi(argv[i+1]);
        check_range(argv[0], "-side", side_color, 0, 16);
    } else if (strcmp(argv[i], "-bright") == 0) {
        brightness = atoi(argv[i+1]);
        check_range(argv[0], "-bright", brightness, 0, 7);
    } else if (strcmp(argv[i], "-touchpad") == 0) {
        touchpad_light = atoi(argv[i+1]);
        check_range(argv[0], "-touchpad", touchpad_light, 0, 1);
    } else if (strcmp(argv[i], "-all") == 0) {
        side_color = top_color = front_color = atoi(argv[i+1]);
        check_range(argv[0], "-all", side_color, 0, 16);
    } else {
        usage(argv[0]);
        exit(-1);
    }
  }
  if (i<argc) {
    // extra parameters
    usage(argv[0]);
    exit(-3);
  }


  setXpsColors((char)side_color, (char)front_color, 
          (char)top_color, (char)brightness, (char)touchpad_light);
  
  return 0;
}
