Blob Blame Raw
#ifndef KEYBOARD_H
#define KEYBOARD_H


#include "graph.h"
#include "input.h"


// key flags
enum {
  KF_DOUBLE = 1 << 0,   // show two lables, insensitive for capslock
  KF_HOLD   = 1 << 1,   // key to switch layout
  KF_SHIFT  = 1 << 2,   // key to switch layout
  KF_CAPS   = 1 << 3,   // key to switch layout
  KF_LAYOUT = 1 << 4,   // key to switch layout
  KF_MOVE   = 1 << 5,   // handle to move the window
  KF_SIZE   = 1 << 6,   // key to resize the window
  KF_CLOSE  = 1 << 7 }; // key to close the window

// special layout indices
enum {
  LI_PREV   = -1,   // switch to previous layout in the list
  LI_NEXT   = -2,   // switch to next layout in the list
  LI_REVERT = -3 }; // switch to previously used layout

  
  
struct Key;
struct Layout;
struct Keyboard;
typedef struct Key Key;
typedef struct Layout Layout;
typedef struct Keyboard Keyboard;


struct Key {
  // keep these filds at the begining for easyest static initialization
  int x, y, w, h;
  unsigned int keySym;
  unsigned int keySym2;
  const char *label;
  const char *label2;
  unsigned int flags;
  int layoutIndex;
  
  // these fields will be set while initialization
  Layout *l;
  TextLayout tl;
  TextLayout tl2;
  
  // dynamic fields
  int down;
  int downKeycode;
  int mx, my; // mouse down position, relative to key origin
  Key *nextHeld, *prevHeld;
};


struct Layout {
  // keep these filds at the begining for easyest static initialization
  Key *keys;
  int keysCount;
  int w, h;
  
  // these fields will be set while initialization
  Keyboard *kbd;

  // dynamic fields
  Layout *prev; // previously used layout
  Key *downKey; // key that received the last mouse down event
};


struct Keyboard {
  // keep these filds at the begining for easyest static initialization
  Layout *layouts;
  int layoutsCount;
  int w, h;
  
  // these fields will be set while initialization
  App *app;
  
  // dynamic fields
  Layout *current;
  Key *firstHeld;
  int shiftsDown;
  int capslock;
};


int keyInit(Key *k, Layout *l);
void keyDeinit(Key *k);
void keyDraw(Key *k, int cx, int cy, int cw, int ch);
void keyDown(Key *k, int x, int y);
void keyMotion(Key *k, int x, int y);
void keyUp(Key *k, int force);

int layoutInit(Layout *l, Keyboard *kbd);
void layoutDeinit(Layout *l);
void layoutDraw(Layout *l, int cx, int cy, int cw, int ch);
void layoutMouseDown(Layout *l, int x, int y);
void layoutMouseMotion(Layout *l, int x, int y);
void layoutMouseUp(Layout *l);

int keyboardInit(Keyboard *kbd, App *app);
void keyboardDeinit(Keyboard *kbd);
void keyboardResize(Keyboard *kbd);
void keyboardDraw(Keyboard *kbd, int cx, int cy, int cw, int ch);
void keyboardMouseDown(Keyboard *kbd, int x, int y);
void keyboardMouseMotion(Keyboard *kbd, int x, int y);
void keyboardMouseUp(Keyboard *kbd);
void keyboardSwitchLayout(Keyboard *kbd, int index);
void keyboardRelaseHeld(Keyboard *kbd);


#endif