Blame keyboard.c

Ivan Mahonin 452870
Ivan Mahonin 452870
#include "app.h"
Ivan Mahonin 452870
Ivan Mahonin 452870
Ivan Mahonin 452870
Ivan Mahonin 843e7a
int keyInit(Key *k, Layout *l) {
Ivan Mahonin 8864eb
  CLEARFROM(k, l);
Ivan Mahonin 843e7a
  k->l = l;
Ivan Mahonin 63daec
  
Ivan Mahonin 63daec
  inputPrepareKeysyms(&k->keySym, &k->keySym2, &k->isLetter, &k->isKeypad);
Ivan Mahonin 63daec
  if (!k->label[0]) keysymString(k->keySym, k->label);
Ivan Mahonin 63daec
  if (!k->label2[0]) keysymString(k->keySym2, k->label2);
Ivan Mahonin 63daec
  
Ivan Mahonin 843e7a
  textLayoutInit(&k->tl, &k->l->kbd->app->graph, k->label);
Ivan Mahonin 061fcf
  textLayoutInit(&k->tl2, &k->l->kbd->app->graph, k->label2);
Ivan Mahonin 452870
  
Ivan Mahonin 452870
  return 1;
Ivan Mahonin 452870
}
Ivan Mahonin 452870
Ivan Mahonin 452870
Ivan Mahonin 452870
void keyDeinit(Key *k) {
Ivan Mahonin 843e7a
  keyUp(k, 1);
Ivan Mahonin 843e7a
  textLayoutDeinit(&k->tl);
Ivan Mahonin 843e7a
  textLayoutDeinit(&k->tl2);
Ivan Mahonin 452870
}
Ivan Mahonin 452870
Ivan Mahonin 452870
  
Ivan Mahonin d942fc
void keyInvalidateRect(Key* k) {
Ivan Mahonin d942fc
  if (k->orig) k = k->orig;
Ivan Mahonin d942fc
  while(k) {
Ivan Mahonin d942fc
    appInvalidateRect(k->l->kbd->app, k->x, k->y, k->w, k->h);
Ivan Mahonin d942fc
    k = k->clone;
Ivan Mahonin d942fc
  }
Ivan Mahonin d942fc
}
Ivan Mahonin d942fc
Ivan Mahonin d942fc
Ivan Mahonin 452870
void keyDraw(Key *k, int cx, int cy, int cw, int ch) {
Ivan Mahonin 452870
  if ( k->x + k->w <= cx || k->x >= cx + cw
Ivan Mahonin 452870
    || k->y + k->h <= cy || k->y >= cy + ch ) return;
Ivan Mahonin 843e7a
  
Ivan Mahonin 63daec
  App *app = k->l->kbd->app;
Ivan Mahonin 63daec
  
Ivan Mahonin 63daec
  int active = k->down;
Ivan Mahonin 5b6cfc
  int longActive = k->longDown;
Ivan Mahonin 5b6cfc
  if (k->orig) {
Ivan Mahonin d942fc
    active = k->orig->down;
Ivan Mahonin 5b6cfc
    longActive = k->orig->longDown;
Ivan Mahonin 5b6cfc
  }
Ivan Mahonin 5b6cfc
  
Ivan Mahonin 5b6cfc
  active = !!active;
Ivan Mahonin 5b6cfc
  if (active && longActive) active = 2; 
Ivan Mahonin 5b6cfc
  
Ivan Mahonin 569832
  if (!active && (k->flags & KF_MOD))
Ivan Mahonin 5b6cfc
    active = !!(app->input.modifiers & (unsigned int)k->optValue);
Ivan Mahonin 843e7a
  
Ivan Mahonin db2d04
  int w = k->w - 2*KEY_BORDER;
Ivan Mahonin db2d04
  int h = k->h - 2*KEY_BORDER;
Ivan Mahonin 37122c
  int highlight = !!(k->flags & KF_HIGHLIGHT);
Ivan Mahonin 37122c
  graphDrawButton(&k->l->kbd->app->graph, k->x + KEY_BORDER, k->y + KEY_BORDER, w, h, active, highlight);
Ivan Mahonin 843e7a
  
Ivan Mahonin 4b2399
  TextLayout *tl = &k->tl;
Ivan Mahonin 843e7a
  TextLayout *tl2 = &k->tl2;
Ivan Mahonin 63daec
  if (inputChooseKeysym(app->input.modifiers, k->keySym, k->keySym2, k->isLetter, k->isKeypad))
Ivan Mahonin 63daec
    tl = tl2, tl2 = &k->tl; // swap labels
Ivan Mahonin 843e7a
  
Ivan Mahonin dbe1a1
  int lx, lx2, ly, ly2, lw, lw2, lh, lh2;
Ivan Mahonin db2d04
  lx = lx2 = k->x + w/2;
Ivan Mahonin db2d04
  ly = ly2 = k->y + h/2;
Ivan Mahonin db2d04
  lw = lw2 = w - w/8;
Ivan Mahonin db2d04
  lh = lh2 = h - h/8;
Ivan Mahonin 061fcf
  if (!k->isLetter && k->label2[0]) {
Ivan Mahonin db2d04
    lx -= w/8;
Ivan Mahonin db2d04
    ly += h/8;
Ivan Mahonin db2d04
    lw -= w/4;
Ivan Mahonin db2d04
    lh -= h/4;
Ivan Mahonin dbe1a1
    
Ivan Mahonin db2d04
    lx2 += w/4;
Ivan Mahonin db2d04
    ly2 -= h/4;
Ivan Mahonin db2d04
    lw2 -= w/2;
Ivan Mahonin db2d04
    lh2 -= h/2;
Ivan Mahonin 843e7a
  }
Ivan Mahonin 061fcf
  
Ivan Mahonin 37122c
  textLayoutDraw(tl, lx, ly, lw, lh, active, highlight);
Ivan Mahonin 061fcf
  if (!k->isLetter)
Ivan Mahonin 37122c
    textLayoutDraw(tl2, lx2, ly2, lw2, lh2, active, highlight);
Ivan Mahonin 452870
}
Ivan Mahonin 452870
Ivan Mahonin 452870
Ivan Mahonin 843e7a
void keyDown(Key *k, int x, int y) {
Ivan Mahonin d942fc
  if (k->orig)
Ivan Mahonin d942fc
    return keyDown(k->orig, x, y);
Ivan Mahonin 843e7a
  if (k->down == 2) k->down = 1;
Ivan Mahonin 843e7a
  if (k->down) return;
Ivan Mahonin 843e7a
  
Ivan Mahonin 843e7a
  Keyboard *kbd = k->l->kbd;
Ivan Mahonin 452870
  k->down = 1;
Ivan Mahonin 843e7a
  
Ivan Mahonin 63daec
  if (k->flags & KF_MOVE) {
Ivan Mahonin 63daec
    k->mx = x;
Ivan Mahonin 63daec
    k->my = y;
Ivan Mahonin 63daec
  } else
Ivan Mahonin 63daec
  if (k->flags & KF_SIZE) {
Ivan Mahonin 7aad5f
    #ifdef TOP_RESIZE
Ivan Mahonin 7aad5f
    k->my = y;
Ivan Mahonin 7aad5f
    #else
Ivan Mahonin 63daec
    k->mx = kbd->app->w - x;
Ivan Mahonin 63daec
    k->my = kbd->app->h - y;
Ivan Mahonin 7aad5f
    #endif
Ivan Mahonin 843e7a
  }
Ivan Mahonin 63daec
  
Ivan Mahonin 843e7a
  if (k->flags & KF_HOLD) {
Ivan Mahonin 843e7a
    k->down = 2;
Ivan Mahonin 843e7a
    // insert to held list
Ivan Mahonin 843e7a
    if (!k->prevHeld && !k->nextHeld && kbd->firstHeld != k) {
Ivan Mahonin 843e7a
      k->nextHeld = kbd->firstHeld;
Ivan Mahonin 843e7a
      if (k->nextHeld) k->nextHeld->prevHeld = k;
Ivan Mahonin 843e7a
      kbd->firstHeld = k;
Ivan Mahonin 843e7a
    }
Ivan Mahonin 843e7a
  }
Ivan Mahonin 843e7a
  
Ivan Mahonin 843e7a
  // choose keySym
Ivan Mahonin 63daec
  unsigned int keySym = inputChooseKeysym(kbd->app->input.modifiers, k->keySym, k->keySym2, k->isLetter, k->isKeypad)
Ivan Mahonin 63daec
                      ? k->keySym2 : k->keySym;
Ivan Mahonin 843e7a
  
Ivan Mahonin 63daec
  // press
Ivan Mahonin 843e7a
  if (keySym) {
Ivan Mahonin 843e7a
    k->downKeycode = inputKeycode(&kbd->app->input, keySym);
Ivan Mahonin 843e7a
    if (k->downKeycode) inputEvent(&kbd->app->input, k->downKeycode, 1);
Ivan Mahonin 843e7a
  }
Ivan Mahonin 843e7a
  
Ivan Mahonin 843e7a
  // redraw
Ivan Mahonin d942fc
  keyInvalidateRect(k);
Ivan Mahonin 843e7a
}
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
void keyMotion(Key *k, int x, int y) {
Ivan Mahonin d942fc
  if (k->orig)
Ivan Mahonin d942fc
    return keyMotion(k->orig, x, y);
Ivan Mahonin 843e7a
  App *app = k->l->kbd->app;
Ivan Mahonin 843e7a
  if (k->flags & KF_MOVE) {
Ivan Mahonin 51e530
    appMove(app, app->x + x - k->mx, app->y + y - k->my, app->w, app->h, 0);
Ivan Mahonin 843e7a
  } else
Ivan Mahonin 843e7a
  if (k->flags & KF_SIZE) {
Ivan Mahonin 7aad5f
    #ifdef TOP_RESIZE
Ivan Mahonin 51e530
    appMove(app, app->x, app->y - k->my + y, app->w, app->h + k->my - y, 0);
Ivan Mahonin 7aad5f
    #else
Ivan Mahonin 51e530
    appMove(app, app->x, app->y, x + k->mx, y + k->my, 0);
Ivan Mahonin 7aad5f
    #endif
Ivan Mahonin 843e7a
  }
Ivan Mahonin 452870
}
Ivan Mahonin 452870
Ivan Mahonin 452870
Ivan Mahonin 5b6cfc
void keyLongDown(Key *k) {
Ivan Mahonin 5b6cfc
  if (k->orig)
Ivan Mahonin 5b6cfc
    return keyLongDown(k->orig);
Ivan Mahonin 5b6cfc
  if (k->down != 2 || k->longDown)
Ivan Mahonin 5b6cfc
    return;
Ivan Mahonin 5b6cfc
Ivan Mahonin 5b6cfc
  // remove from held list, this key will not unhold automatically
Ivan Mahonin 5b6cfc
  if (k->prevHeld || k->nextHeld || k->l->kbd->firstHeld == k) {
Ivan Mahonin 5b6cfc
    if (k->nextHeld) k->nextHeld->prevHeld = k->prevHeld;
Ivan Mahonin 5b6cfc
    if (k->prevHeld) k->prevHeld->nextHeld = k; else k->l->kbd->firstHeld = k->nextHeld;
Ivan Mahonin 5b6cfc
    k->nextHeld = k->prevHeld = NULL;
Ivan Mahonin 5b6cfc
  }
Ivan Mahonin 5b6cfc
  
Ivan Mahonin 5b6cfc
  LOGDBG("key: long down: activated");
Ivan Mahonin 5b6cfc
  k->longDown = 1;
Ivan Mahonin 5b6cfc
  keyInvalidateRect(k);
Ivan Mahonin 5b6cfc
}
Ivan Mahonin 5b6cfc
Ivan Mahonin 5b6cfc
Ivan Mahonin 843e7a
void keyUp(Key *k, int force) {
Ivan Mahonin d942fc
  if (k->orig) {
Ivan Mahonin d942fc
    // clones must not be in held list
Ivan Mahonin d942fc
    assert( !(k->prevHeld || k->nextHeld || k->l->kbd->firstHeld == k) );
Ivan Mahonin d942fc
    return keyUp(k->orig, force);
Ivan Mahonin d942fc
  }
Ivan Mahonin d942fc
  if (!force && k->down != 1)
Ivan Mahonin d942fc
    return;
Ivan Mahonin 843e7a
  
Ivan Mahonin 843e7a
  Keyboard *kbd = k->l->kbd;
Ivan Mahonin 843e7a
  int wasDown = k->down;
Ivan Mahonin 452870
  k->down = 0;
Ivan Mahonin 5b6cfc
  k->longDown = 0;
Ivan Mahonin 843e7a
  
Ivan Mahonin 843e7a
  // release key
Ivan Mahonin 843e7a
  if (k->downKeycode) {
Ivan Mahonin 843e7a
    inputEvent(&kbd->app->input, k->downKeycode, 0);
Ivan Mahonin 843e7a
    k->downKeycode = 0;
Ivan Mahonin 843e7a
  }
Ivan Mahonin 843e7a
  
Ivan Mahonin d942fc
  
Ivan Mahonin 843e7a
  // remove from held list
Ivan Mahonin 843e7a
  if (k->prevHeld || k->nextHeld || kbd->firstHeld == k) {
Ivan Mahonin 843e7a
    if (k->nextHeld) k->nextHeld->prevHeld = k->prevHeld;
Ivan Mahonin 843e7a
    if (k->prevHeld) k->prevHeld->nextHeld = k; else kbd->firstHeld = k->nextHeld;
Ivan Mahonin 843e7a
    k->nextHeld = k->prevHeld = NULL;
Ivan Mahonin 843e7a
  }
Ivan Mahonin 63daec
Ivan Mahonin 63daec
  // following action should be done only for real button up
Ivan Mahonin 63daec
  if (!wasDown)
Ivan Mahonin 63daec
    return;
Ivan Mahonin 63daec
  
Ivan Mahonin 63daec
  if (k->flags & KF_CLOSE)
Ivan Mahonin 63daec
    appStop(kbd->app, 0);
Ivan Mahonin 63daec
  if (k->flags & KF_LAYOUT)
Ivan Mahonin 63daec
    keyboardSwitchLayout(kbd, k->optValue);
Ivan Mahonin 843e7a
  
Ivan Mahonin 843e7a
  // on releasing a regular key release all held special keys
Ivan Mahonin 37122c
  if (!force && !(k->flags & KF_SPECIAL))
Ivan Mahonin 843e7a
    keyboardRelaseHeld(kbd);
Ivan Mahonin 843e7a
  
Ivan Mahonin 843e7a
  // redraw
Ivan Mahonin d942fc
  keyInvalidateRect(k);
Ivan Mahonin 843e7a
}
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
int layoutInit(Layout *l, Keyboard *kbd) {
Ivan Mahonin 843e7a
  LOGDBG("layout: init");
Ivan Mahonin 8864eb
  
Ivan Mahonin 8864eb
  CLEARFROM(l, kbd);
Ivan Mahonin 843e7a
  l->kbd = kbd;
Ivan Mahonin 63daec
  
Ivan Mahonin 63daec
  if (!l->keysCount)
Ivan Mahonin 63daec
    return 1;
Ivan Mahonin 63daec
  
Ivan Mahonin 37122c
  l->hidden = 0;
Ivan Mahonin 37122c
  
Ivan Mahonin 63daec
  // fix keys coords
Ivan Mahonin 63daec
  Key *k = &l->keys[0];
Ivan Mahonin 061fcf
  int x0 = k->ox;
Ivan Mahonin 061fcf
  int y0 = k->oy;
Ivan Mahonin 061fcf
  int x1 = x0 + k->ow;
Ivan Mahonin 061fcf
  int y1 = y0 + k->oh;
Ivan Mahonin 63daec
  for(int i = 1; i < l->keysCount; ++i) {
Ivan Mahonin 63daec
    k = &l->keys[i];
Ivan Mahonin 63daec
    Key *p = k - 1;
Ivan Mahonin 63daec
    
Ivan Mahonin 63daec
    // coord < 0 means relative offset from previos key -1
Ivan Mahonin 63daec
    // zero coord of size means copy value from previous key
Ivan Mahonin 061fcf
    if (!k->ox) k->ox = p->ox; else
Ivan Mahonin 061fcf
      if (k->ox < 0) k->ox = p->ox + p->ow - k->ox - 1;
Ivan Mahonin 061fcf
    if (!k->oy) k->oy = p->oy; else
Ivan Mahonin 061fcf
      if (k->oy < 0) k->oy = p->oy + p->oh - k->oy - 1;
Ivan Mahonin 061fcf
    if (!k->ow) k->ow = p->ow;
Ivan Mahonin 061fcf
    if (!k->oh) k->oh = p->oh;
Ivan Mahonin 63daec
    
Ivan Mahonin 63daec
    // calc bounds
Ivan Mahonin 061fcf
    if (x0 > k->ox) x0 = k->ox;
Ivan Mahonin 061fcf
    if (y0 > k->oy) y0 = k->oy;
Ivan Mahonin 061fcf
    if (x1 < k->ox + k->ow) x1 = k->ox + k->ow;
Ivan Mahonin 061fcf
    if (y1 < k->oy + k->oh) y1 = k->oy + k->oh;
Ivan Mahonin 37122c
    
Ivan Mahonin 37122c
    if ((k->flags & KF_LAYOUT) && k->optValue == LI_REVERT)
Ivan Mahonin 37122c
      l->hidden = 1;
Ivan Mahonin 63daec
  }
Ivan Mahonin 63daec
    
Ivan Mahonin 63daec
  // fix layout size
Ivan Mahonin 061fcf
  if (!l->ow) l->ow = x1 + x0;
Ivan Mahonin 061fcf
  if (!l->oh) l->oh = y1 + y0;
Ivan Mahonin 37122c
  LOGDBG("layout: init: size x0=%d y0=%d x1=%d y1=%d w=%d h=%d, hedden: %d", x0, y0, x1, y1, l->ow, l->oh, l->hidden);
Ivan Mahonin 63daec
Ivan Mahonin 63daec
  // init keys
Ivan Mahonin 061fcf
  for(int i = 0; i < l->keysCount; ++i) {
Ivan Mahonin 843e7a
    if (!keyInit(&l->keys[i], l)) {
Ivan Mahonin 843e7a
      for(--i; i >= 0; --i) keyDeinit(&l->keys[i]);
Ivan Mahonin 843e7a
      return 0;
Ivan Mahonin 843e7a
    }
Ivan Mahonin 061fcf
  }
Ivan Mahonin 061fcf
  
Ivan Mahonin 843e7a
  return 1;
Ivan Mahonin 843e7a
}
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
void layoutDeinit(Layout *l) {
Ivan Mahonin 843e7a
  LOGDBG("layout: deinit");
Ivan Mahonin 843e7a
  layoutMouseUp(l);
Ivan Mahonin 843e7a
  for(int i = 0; i < l->keysCount; ++i)
Ivan Mahonin 843e7a
    keyDeinit(&l->keys[i]);
Ivan Mahonin 843e7a
}
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
Ivan Mahonin 061fcf
void layoutResize(Layout *l) {
Ivan Mahonin 061fcf
  if (l->w == l->kbd->app->w && l->h == l->kbd->app->h) return;
Ivan Mahonin 061fcf
  LOGDBG("layout: resize w=%d h=%d", l->kbd->app->w, l->kbd->app->h);
Ivan Mahonin 061fcf
  l->w = l->kbd->app->w;
Ivan Mahonin 061fcf
  l->h = l->kbd->app->h;
Ivan Mahonin 061fcf
  float kx = l->w/(float)l->ow;
Ivan Mahonin 061fcf
  float ky = l->h/(float)l->oh;
Ivan Mahonin 061fcf
  for(int i = 0; i < l->keysCount; ++i) {
Ivan Mahonin 061fcf
    Key *k = &l->keys[i];
Ivan Mahonin 061fcf
    k->x = (int)(k->ox*kx + 0.5f);
Ivan Mahonin 061fcf
    k->y = (int)(k->oy*ky + 0.5f);
Ivan Mahonin 4b2399
    k->w = (int)((k->ox + k->ow)*kx + 0.5f) - k->x;
Ivan Mahonin 4b2399
    k->h = (int)((k->oy + k->oh)*ky + 0.5f) - k->y;
Ivan Mahonin 061fcf
  }
Ivan Mahonin 061fcf
}
Ivan Mahonin 061fcf
Ivan Mahonin 061fcf
Ivan Mahonin 843e7a
void layoutDraw(Layout *l, int cx, int cy, int cw, int ch) {
Ivan Mahonin 843e7a
  for(int i = 0; i < l->keysCount; ++i)
Ivan Mahonin 843e7a
    keyDraw(&l->keys[i], cx, cy, cw, ch);
Ivan Mahonin 843e7a
}
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
void layoutMouseDown(Layout *l, int x, int y) {
Ivan Mahonin 843e7a
  LOGDBG("layout: mouse down: x=%d y=%d", x, y);
Ivan Mahonin 843e7a
  for(int i = l->keysCount - 1; i >= 0; --i) {
Ivan Mahonin 843e7a
    Key *k = &l->keys[i];
Ivan Mahonin 843e7a
    if ( k->x <= x && x < k->x + k->w
Ivan Mahonin 843e7a
      && k->y <= y && y < k->y + k->h )
Ivan Mahonin 843e7a
    {
Ivan Mahonin 843e7a
      if (l->downKey != k) {
Ivan Mahonin 843e7a
        layoutMouseUp(l);
Ivan Mahonin 843e7a
        l->downKey = k;
Ivan Mahonin 843e7a
        keyDown(k, x, y);
Ivan Mahonin 843e7a
      }
Ivan Mahonin 843e7a
      break;
Ivan Mahonin 843e7a
    }
Ivan Mahonin 843e7a
  }
Ivan Mahonin 843e7a
}
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
void layoutMouseMotion(Layout *l, int x, int y) {
Ivan Mahonin 843e7a
  LOGDBG("layout: mouse motion: x=%d y=%d", x, y);
Ivan Mahonin 843e7a
  if (!l->downKey) return;
Ivan Mahonin 843e7a
  keyMotion(l->downKey, x, y);
Ivan Mahonin 843e7a
}
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
Ivan Mahonin 5b6cfc
void layoutMouseLongDown(Layout *l) {
Ivan Mahonin 5b6cfc
  LOGDBG("layout: mouse long down");
Ivan Mahonin 5b6cfc
  if (!l->downKey) return;
Ivan Mahonin 5b6cfc
  keyLongDown(l->downKey);
Ivan Mahonin 5b6cfc
}
Ivan Mahonin 5b6cfc
Ivan Mahonin 5b6cfc
Ivan Mahonin 843e7a
void layoutMouseUp(Layout *l) {
Ivan Mahonin 843e7a
  LOGDBG("layout: mouse up");
Ivan Mahonin 843e7a
  if (!l->downKey) return;
Ivan Mahonin 843e7a
  keyUp(l->downKey, 0);
Ivan Mahonin 843e7a
  l->downKey = NULL;
Ivan Mahonin 452870
}
Ivan Mahonin 452870
Ivan Mahonin 452870
Ivan Mahonin 452870
Ivan Mahonin 452870
int keyboardInit(Keyboard *kbd, App *app) {
Ivan Mahonin 452870
  LOGDBG("keyboard: init");
Ivan Mahonin 8864eb
  
Ivan Mahonin 8864eb
  CLEARFROM(kbd, app);
Ivan Mahonin 452870
  kbd->app = app;
Ivan Mahonin 8864eb
  
Ivan Mahonin 061fcf
  kbd->lastModifiers = kbd->app->input.modifiers;
Ivan Mahonin 843e7a
  kbd->current = kbd->layoutsCount > 0 ? kbd->layouts : NULL;
Ivan Mahonin 1d2586
  kbd->lastVisible = kbd->current;
Ivan Mahonin 63daec
  
Ivan Mahonin 843e7a
  for(int i = 0; i < kbd->layoutsCount; ++i) {
Ivan Mahonin 843e7a
    if (!layoutInit(&kbd->layouts[i], kbd)) {
Ivan Mahonin 843e7a
      for(--i; i >= 0; --i) layoutDeinit(&kbd->layouts[i]);
Ivan Mahonin 452870
      return 0;
Ivan Mahonin 452870
    }
Ivan Mahonin 843e7a
  }
Ivan Mahonin 63daec
Ivan Mahonin 63daec
  // fix size
Ivan Mahonin 63daec
  for(int i = 0; i < kbd->layoutsCount; ++i) {
Ivan Mahonin 061fcf
    if (kbd->ow < kbd->layouts[i].ow) kbd->ow = kbd->layouts[i].ow;
Ivan Mahonin 061fcf
    if (kbd->oh < kbd->layouts[i].oh) kbd->oh = kbd->layouts[i].oh;
Ivan Mahonin 63daec
  }
Ivan Mahonin 061fcf
  LOGDBG("keyboard: init: size ow=%d oh=%d", kbd->ow, kbd->oh);
Ivan Mahonin 63daec
  
Ivan Mahonin d942fc
  // search clones
Ivan Mahonin d942fc
  for(int ila = 0; ila < kbd->layoutsCount; ++ila)
Ivan Mahonin d942fc
  for(int ika = 0; ika < kbd->layouts[ila].keysCount; ++ika) {
Ivan Mahonin d942fc
    Key *a = &kbd->layouts[ila].keys[ika];
Ivan Mahonin d942fc
    
Ivan Mahonin d942fc
    if (!a->orig)
Ivan Mahonin d942fc
    for(int ilb = ila; ilb < kbd->layoutsCount; ++ilb)
Ivan Mahonin d942fc
    for(int ikb = ilb==ila ? ika+1: 0; ikb < kbd->layouts[ilb].keysCount; ++ikb) {
Ivan Mahonin d942fc
      Key *b = &kbd->layouts[ilb].keys[ikb];
Ivan Mahonin d942fc
      if ( a->flags    == b->flags
Ivan Mahonin d942fc
        && a->optValue == b->optValue
Ivan Mahonin d942fc
        && a->keySym   == b->keySym
Ivan Mahonin d942fc
        && a->keySym2  == b->keySym2 )
Ivan Mahonin d942fc
      {
Ivan Mahonin d942fc
        b->orig = a;
Ivan Mahonin d942fc
        b->clone = a->clone;
Ivan Mahonin d942fc
        a->clone = b;
Ivan Mahonin d942fc
      }
Ivan Mahonin d942fc
    }
Ivan Mahonin d942fc
  }
Ivan Mahonin d942fc
  
Ivan Mahonin 51e530
  //appMove(app, app->x, app->y, kbd->ow, kbd->oh, 0);
Ivan Mahonin 452870
  return 1;
Ivan Mahonin 452870
}
Ivan Mahonin 452870
Ivan Mahonin 452870
Ivan Mahonin 452870
void keyboardDeinit(Keyboard *kbd) {
Ivan Mahonin 452870
  LOGDBG("keyboard: deinit");
Ivan Mahonin 452870
  keyboardMouseUp(kbd);
Ivan Mahonin 843e7a
  for(int i = 0; i < kbd->layoutsCount; ++i)
Ivan Mahonin 843e7a
    layoutDeinit(&kbd->layouts[i]);
Ivan Mahonin 843e7a
}
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
void keyboardResize(Keyboard *kbd) {
Ivan Mahonin 061fcf
  if (kbd->current)
Ivan Mahonin 061fcf
    layoutResize(kbd->current);
Ivan Mahonin 061fcf
}
Ivan Mahonin 061fcf
Ivan Mahonin 061fcf
Ivan Mahonin 061fcf
void keyboardUpdateModifiers(Keyboard* kbd) {
Ivan Mahonin 061fcf
  if (kbd->lastModifiers == kbd->app->input.modifiers) return;
Ivan Mahonin 061fcf
  LOGDBG("keyboard: update modifiers");
Ivan Mahonin 061fcf
  kbd->lastModifiers = kbd->app->input.modifiers;
Ivan Mahonin 061fcf
  appInvalidateRect(kbd->app, 0, 0, kbd->app->w, kbd->app->h);
Ivan Mahonin 452870
}
Ivan Mahonin 452870
Ivan Mahonin 452870
Ivan Mahonin 452870
void keyboardDraw(Keyboard *kbd, int cx, int cy, int cw, int ch) {
Ivan Mahonin 843e7a
  if (!kbd->current) return;
Ivan Mahonin 843e7a
  layoutDraw(kbd->current, cx, cy, cw, ch);
Ivan Mahonin 452870
}
Ivan Mahonin 452870
Ivan Mahonin 452870
Ivan Mahonin 452870
void keyboardMouseDown(Keyboard *kbd, int x, int y) {
Ivan Mahonin 843e7a
  LOGDBG("keyboard: mouse down: x=%d y=%d", x, y);
Ivan Mahonin 843e7a
  if (!kbd->current) return;
Ivan Mahonin 843e7a
  layoutMouseDown(kbd->current, x, y);
Ivan Mahonin 843e7a
}
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
void keyboardMouseMotion(Keyboard *kbd, int x, int y) {
Ivan Mahonin 843e7a
  LOGDBG("keyboard: mouse motion: x=%d y=%d", x, y);
Ivan Mahonin 843e7a
  if (!kbd->current) return;
Ivan Mahonin 843e7a
  layoutMouseMotion(kbd->current, x, y);
Ivan Mahonin 452870
}
Ivan Mahonin 452870
Ivan Mahonin 452870
Ivan Mahonin 5b6cfc
void keyboardMouseLongDown(Keyboard *kbd) {
Ivan Mahonin 5b6cfc
  LOGDBG("keyboard: mouse long down");
Ivan Mahonin 5b6cfc
  if (!kbd->current) return;
Ivan Mahonin 5b6cfc
  layoutMouseLongDown(kbd->current);
Ivan Mahonin 5b6cfc
}
Ivan Mahonin 5b6cfc
Ivan Mahonin 5b6cfc
Ivan Mahonin 452870
void keyboardMouseUp(Keyboard *kbd) {
Ivan Mahonin 843e7a
  LOGDBG("keyboard: mouse up");
Ivan Mahonin 843e7a
  if (!kbd->current) return;
Ivan Mahonin 843e7a
  layoutMouseUp(kbd->current);
Ivan Mahonin 843e7a
}
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
void keyboardRelaseHeld(Keyboard *kbd) {
Ivan Mahonin 843e7a
  LOGDBG("keyboard: release held");
Ivan Mahonin 843e7a
  while(kbd->firstHeld) keyUp(kbd->firstHeld, 1);
Ivan Mahonin 843e7a
}
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
void keyboardSwitchLayout(Keyboard *kbd, int index) {
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
  if (!kbd->layoutsCount) return;
Ivan Mahonin d942fc
Ivan Mahonin 1d2586
  int prevIndex = (kbd->lastVisible ? kbd->lastVisible : kbd->current) - kbd->layouts;
Ivan Mahonin d942fc
Ivan Mahonin d942fc
  LOGDBG("keyboard: switch layout: prevIndex=%d nextIndex=%d", prevIndex, index);
Ivan Mahonin d942fc
  //keyboardRelaseHeld(kbd);
Ivan Mahonin 843e7a
Ivan Mahonin 843e7a
  if (index == LI_PREV) {
Ivan Mahonin 37122c
    for(int i = 1; i <= kbd->layoutsCount; ++i) {
Ivan Mahonin 37122c
      index = (prevIndex + kbd->layoutsCount - i) % kbd->layoutsCount;
Ivan Mahonin 37122c
      if (!kbd->layouts[index].hidden) break;
Ivan Mahonin 37122c
    }
Ivan Mahonin 843e7a
  } else
Ivan Mahonin 843e7a
  if (index == LI_NEXT) {
Ivan Mahonin 37122c
    for(int i = 1; i <= kbd->layoutsCount; ++i) {
Ivan Mahonin 37122c
      index = (prevIndex + i) % kbd->layoutsCount;
Ivan Mahonin 37122c
      if (!kbd->layouts[index].hidden) break;
Ivan Mahonin 37122c
    }
Ivan Mahonin 843e7a
  } else
Ivan Mahonin 843e7a
  if (index == LI_REVERT) {
Ivan Mahonin 1d2586
    if (!kbd->lastVisible) {
Ivan Mahonin 37122c
      LOGWRN("keyboard: switch layout: cannot revert");
Ivan Mahonin d942fc
      return;
Ivan Mahonin 37122c
    }
Ivan Mahonin 1d2586
    index = kbd->lastVisible - kbd->layouts;
Ivan Mahonin 843e7a
  }
Ivan Mahonin 843e7a
  
Ivan Mahonin 843e7a
  if (index < 0 || index >= kbd->layoutsCount) {
Ivan Mahonin 843e7a
    LOGWRN("keyboard: switch layout: bad index %d", index);
Ivan Mahonin 843e7a
    return;
Ivan Mahonin 452870
  }
Ivan Mahonin 843e7a
  
Ivan Mahonin d942fc
  LOGDBG("keyboard: switch layout: actual index=%d", index);
Ivan Mahonin 843e7a
  kbd->current = &kbd->layouts[index];
Ivan Mahonin 1d2586
  if (!kbd->current->hidden)
Ivan Mahonin 1d2586
    kbd->lastVisible = kbd->current;
Ivan Mahonin 061fcf
  
Ivan Mahonin 061fcf
  keyboardResize(kbd);
Ivan Mahonin 061fcf
  appInvalidateRect(kbd->app, 0, 0, kbd->app->w, kbd->app->h);
Ivan Mahonin 452870
}
Ivan Mahonin 843e7a