#include <stdio.h>
#include <X11/Xlib.h>
#define KEY_MISCELLANY
#include <X11/keysymdef.h>
#include <unistd.h>
#include <stdlib.h>

#define KEY_VOLUME_ADD	176
#define KEY_VOLUME_SUB	174
#define KEY_MUTE	160
#define KEY_PLAY_PAUSE	162
#define KEY_STOP	164
#define KEY_REWIND	144
#define KEY_FASTFORWARD	153
#define KEY_WLAN	136
#define KEY_BATTERY	135
#define KEY_EJECT	137

#define  ALSA

Display *dpy;
static int keylist[] = {
	KEY_VOLUME_ADD,
	KEY_VOLUME_SUB,
	KEY_MUTE,
	KEY_PLAY_PAUSE,
	KEY_STOP,
	KEY_REWIND,
	KEY_FASTFORWARD,
	KEY_WLAN,
	KEY_BATTERY,
	KEY_EJECT,
  	0
};

void
GrabKeyAll(unsigned int keycode, unsigned int modi)
{
  int i;

  for(i = ScreenCount(dpy) - 1; i >= 0; i--)
    {
      XGrabKey(dpy, keycode, modi, RootWindow(dpy, i),
	  False, GrabModeAsync, GrabModeAsync);
#ifdef DEBUG
      printf("grab keycode %d, modi %d, Root %d, a %d, b %d\n", 
		  keycode, modi, RootWindow(dpy, i), a, b);
      XSync(dpy, False);
#endif
    }
}

void
UngrabKeyAll(unsigned int keycode, unsigned int modi)
{
  int i;

  for(i = ScreenCount(dpy) - 1; i >= 0; i--)
    XUngrabKey(dpy, keycode, modi, RootWindow(dpy, i));
}

void
SetVolume(int volume)
{
  char buf[64];

#ifdef ALSA
  int mvol = volume*31/100;
  static int oldvol = 50;

  const char *str = oldvol==0 ? "unmute" : (mvol == 0 ? "mute" : "");
  sprintf(buf, "amixer -q set PCM %d %s", mvol, str);
  system(buf);
  sprintf(buf, "amixer -q set CD  %d %s", mvol, str);
  system(buf);
  sprintf(buf, "amixer -q set Master %d", mvol);
  system(buf);
#else
  sprintf(buf, "aumix -W %d -w %d", volume, volume);
  system(buf);
#endif
  oldvol = volume;
}

int
main(int ac, char *av[])
{
  int i, muted = 0, volume = 50;
  XEvent e;

  dpy = XOpenDisplay(0);
  if(!dpy)
    {
      printf("Cannot open the display\n");
      exit(1);
    }

  if(fork())
    return 0;

  for(i = 0; keylist[i]; i++)
    GrabKeyAll(keylist[i], AnyModifier);

  for(;;)
    {
      XNextEvent(dpy, &e);
      XAllowEvents(dpy, AsyncKeyboard, CurrentTime);
      XFlush(dpy);

      if(e.type != KeyPress)
	continue;

      switch(e.xkey.keycode)
        {
	  case KEY_VOLUME_ADD:
	    volume += 5;
	    if(volume > 100)
	      volume = 100;
	    SetVolume(volume);
	    break;

	  case KEY_VOLUME_SUB:
	    volume -= 5;
	    if(volume < 0)
	      volume = 0;
	    SetVolume(volume);
	    break;

	  case KEY_MUTE:
	    volume = muted ? 50 : 0;
	    SetVolume(volume);
	    muted = 1-muted;
	    break;

	  case KEY_PLAY_PAUSE:
	    system("xmms -n 0 -t");
	    break;

	  case KEY_STOP:
//	    for(i = 0; keylist[i]; i++)
//	      UngrabKeyAll(keylist[i], AnyModifier);
//	    exit(0);
	    system("xmms -n 0 -s");
	    break;

	  case KEY_REWIND:
	    system("xmms -n 0 -r");
	    break;

	  case KEY_FASTFORWARD:
	    system("xmms -n 0 -f");
	    break;

	  case KEY_WLAN:
	    break;

	  case KEY_BATTERY:
	    break;

	  case KEY_EJECT:
	    system("eject /dev/cdrom");
	    break;
	}
    }
  return 0;
}
