Allow up to four different internal shift keys.
parent
5baa93cb91
commit
fd883c1391
|
@ -22,9 +22,9 @@ SYSTEM_PASSTHROUGH # pass through MCP feedback
|
|||
|
||||
[MIDI]
|
||||
|
||||
# The Mk3's dedicated shift key is used to provide alternative functions
|
||||
# to some of the buttons and the faders.
|
||||
?F2 SHIFT RELEASE SHIFT
|
||||
# We use the Mk3's dedicated SHIFT button as our primary shift key, to provide
|
||||
# alternative functions to some of the buttons and the faders.
|
||||
?F2 SHIFT RELEASE SHIFT
|
||||
|
||||
# transport (assigned to the transport section on the bottom left)
|
||||
F#5 A7 # Stop
|
||||
|
@ -69,19 +69,23 @@ A#4 B5 # Control (MOD key)
|
|||
B4 C6 # Option (PERFORM key)
|
||||
D3 C#6 # Alt/Cmd (NOTES key)
|
||||
|
||||
# big encoder press/left/right/up/down assigned to the zoom/cursor keys
|
||||
# big encoder press/left/right/up/down is assigned to the zoom/cursor keys
|
||||
D2 C8 # Up
|
||||
E2 C#8 # Down
|
||||
D#2 D8 # Left
|
||||
C#2 D#8 # Right
|
||||
C2 E8 # Zoom
|
||||
|
||||
# The Mk3 only has one row of dedicated "channel buttons" on the top, which we
|
||||
# use for channel select. But we'd also like to have buttons for rec, solo and
|
||||
# mute, so we (rather arbitrarily) bind them to the shifted A..H and grid
|
||||
# buttons.
|
||||
# The Mk3 has one row of dedicated "channel buttons" at the top, right above
|
||||
# the display. Since we'd also like to use these for the channel-based
|
||||
# rec/solo/mute functions, we combine them with the SELECT, SOLO and MUTE
|
||||
# buttons as additional shift keys.
|
||||
|
||||
# track select (top row right above the display)
|
||||
?F#4 SHIFT2 RELEASE SHIFT2
|
||||
?G4 SHIFT3 RELEASE SHIFT3
|
||||
?G#4 SHIFT4 RELEASE SHIFT4
|
||||
|
||||
# top row, unshifted: track select
|
||||
G6 C2
|
||||
G#6 C#2
|
||||
A6 D2
|
||||
|
@ -91,9 +95,38 @@ C7 F2
|
|||
C#7 F#2
|
||||
D7 G2
|
||||
|
||||
# shifted top row
|
||||
# We assign these to the function keys F1..F8 here, but of course you can
|
||||
# remap these as needed.
|
||||
# SELECT: rec
|
||||
2^G6 C0
|
||||
2^G#6 C#0
|
||||
2^A6 D0
|
||||
2^A#6 D#0
|
||||
2^B6 E0
|
||||
2^C7 F0
|
||||
2^C#7 F#0
|
||||
2^D7 G0
|
||||
|
||||
# SOLO: solo
|
||||
3^G6 G#0
|
||||
3^G#6 A0
|
||||
3^A6 A#0
|
||||
3^A#6 B0
|
||||
3^B6 C1
|
||||
3^C7 C#1
|
||||
3^C#7 D1
|
||||
3^D7 D#1
|
||||
|
||||
# MUTE: mute
|
||||
4^G6 E1
|
||||
4^G#6 F1
|
||||
4^A6 F#1
|
||||
4^A#6 G1
|
||||
4^B6 G#1
|
||||
4^C7 A1
|
||||
4^C#7 A#1
|
||||
4^D7 B1
|
||||
|
||||
# We also assign these to the function keys F1..F8 when shifted. You may want
|
||||
# to remap these as needed.
|
||||
^G6 F#4
|
||||
^G#6 G4
|
||||
^A6 G#4
|
||||
|
@ -103,40 +136,10 @@ D7 G2
|
|||
^C#7 C5
|
||||
^D7 C#5
|
||||
|
||||
# shifted A..H keys = rec
|
||||
^F#2 C0
|
||||
^G2 C#0
|
||||
^G#2 D0
|
||||
^A2 D#0
|
||||
^A#2 E0
|
||||
^B2 F0
|
||||
^C3 F#0
|
||||
^C#3 G0
|
||||
|
||||
# upper half of grid, shifted = solo
|
||||
^C4-10 G#0
|
||||
^C#4-10 A0
|
||||
^D4-10 A#0
|
||||
^D#4-10 B0
|
||||
^G#3-10 C1
|
||||
^A3-10 C#1
|
||||
^A#3-10 D1
|
||||
^B3-10 D#1
|
||||
|
||||
# lower half of grid, shifted = mute
|
||||
^E3-10 E1
|
||||
^F3-10 F1
|
||||
^F#3-10 F#1
|
||||
^G3-10 G1
|
||||
^C3-10 G#1
|
||||
^C#3-10 A1
|
||||
^D3-10 A#1
|
||||
^D#3-10 B1
|
||||
|
||||
# The unshifted grid buttons are passed through unchanged, so that you can
|
||||
# still use them as drum pads (provided that you filter out all MIDI channels
|
||||
# except channel 10). Note that we use mod translations here, in order to
|
||||
# preserve the velocities.
|
||||
# The grid buttons are passed through unchanged, so that you can still use
|
||||
# them as drum pads (provided that you filter out all MIDI channels except
|
||||
# channel 10). Note that we use mod translations here, in order to preserve
|
||||
# the velocities.
|
||||
|
||||
C3[]-10 C3-10
|
||||
C#3[]-10 C#3-10
|
||||
|
@ -155,10 +158,9 @@ C#4[]-10 C#4-10
|
|||
D4[]-10 D4-10
|
||||
D#4[]-10 D#4-10
|
||||
|
||||
# Map the unshifted A..H buttons to program changes on channel 10 so that you
|
||||
# can quickly switch the sounds of your drumkit, drum patterns etc. (This is
|
||||
# just an example, you might want to disable these or remap them as you see
|
||||
# fit.)
|
||||
# Map the A..H buttons to program changes on channel 10 so that you can
|
||||
# quickly switch the sounds of your drumkit, drum patterns etc. (This is just
|
||||
# an example, you might want to disable these or remap them as you see fit.)
|
||||
|
||||
F#2 PC0-10
|
||||
G2 PC1-10
|
||||
|
|
12
midizap.c
12
midizap.c
|
@ -316,8 +316,9 @@ static stroke *find_stroke_data(stroke_data *sd,
|
|||
if (mod) *mod = sd[i].mod;
|
||||
return sd[i].s[index];
|
||||
} else if (sd[i].chan > chan ||
|
||||
(sd[i].chan == chan && sd[i].data > data))
|
||||
(sd[i].chan == chan && sd[i].data > data)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
} else {
|
||||
|
@ -520,7 +521,9 @@ static int note_octave(int n)
|
|||
static char *debug_key(translation *tr, char *name,
|
||||
int status, int chan, int data, int dir)
|
||||
{
|
||||
char *prefix = shift?"^":"", *suffix = "";
|
||||
char prefix[10] = "";
|
||||
if (shift) sprintf(prefix, "%d^", shift);
|
||||
char *suffix = "";
|
||||
strcpy(name, "??");
|
||||
switch (status) {
|
||||
case 0x90: {
|
||||
|
@ -785,7 +788,10 @@ send_strokes(translation *tr, uint8_t portno, int status, int chan,
|
|||
nkeys++;
|
||||
} else if (s->shift) {
|
||||
// toggle shift status
|
||||
shift = !shift;
|
||||
if (shift != s->shift)
|
||||
shift = s->shift;
|
||||
else
|
||||
shift = 0;
|
||||
} else if (!s->status) {
|
||||
// do nothing (NOP)
|
||||
;
|
||||
|
|
35
midizap.h
35
midizap.h
|
@ -83,6 +83,9 @@ typedef struct _stroke_data {
|
|||
uint8_t mod;
|
||||
} stroke_data;
|
||||
|
||||
#define N_SHIFTS 4 // number of distinct shift states
|
||||
#define N_ST (N_SHIFTS+1)
|
||||
|
||||
typedef struct _translation {
|
||||
struct _translation *next;
|
||||
char *name;
|
||||
|
@ -90,22 +93,24 @@ typedef struct _translation {
|
|||
regex_t regex;
|
||||
uint8_t portno;
|
||||
// these are indexed by shift status
|
||||
stroke_data *note[2];
|
||||
stroke_data *notes[2];
|
||||
stroke_data *pc[2];
|
||||
stroke_data *cc[2];
|
||||
stroke_data *ccs[2];
|
||||
stroke_data *pb[2];
|
||||
stroke_data *pbs[2];
|
||||
stroke_data *kp[2];
|
||||
stroke_data *kps[2];
|
||||
stroke_data *cp[2];
|
||||
stroke_data *cps[2];
|
||||
stroke_data *note[N_ST];
|
||||
stroke_data *notes[N_ST];
|
||||
stroke_data *pc[N_ST];
|
||||
stroke_data *cc[N_ST];
|
||||
stroke_data *ccs[N_ST];
|
||||
stroke_data *pb[N_ST];
|
||||
stroke_data *pbs[N_ST];
|
||||
stroke_data *kp[N_ST];
|
||||
stroke_data *kps[N_ST];
|
||||
stroke_data *cp[N_ST];
|
||||
stroke_data *cps[N_ST];
|
||||
// actual and allocated sizes (can be at most 16*128)
|
||||
uint16_t n_note[2], n_notes[2], n_pc[2], n_cc[2], n_ccs[2],
|
||||
n_pb[2], n_pbs[2], n_kp[2], n_kps[2], n_cp[2], n_cps[2];
|
||||
uint16_t a_note[2], a_notes[2], a_pc[2], a_cc[2], a_ccs[2],
|
||||
a_pb[2], a_pbs[2], a_kp[2], a_kps[2], a_cp[2], a_cps[2];
|
||||
uint16_t n_note[N_ST], n_notes[N_ST], n_pc[N_ST],
|
||||
n_cc[N_ST], n_ccs[N_ST], n_pb[N_ST], n_pbs[N_ST],
|
||||
n_kp[N_ST], n_kps[N_ST], n_cp[N_ST], n_cps[N_ST];
|
||||
uint16_t a_note[N_ST], a_notes[N_ST], a_pc[N_ST],
|
||||
a_cc[N_ST], a_ccs[N_ST], a_pb[N_ST], a_pbs[N_ST],
|
||||
a_kp[N_ST], a_kps[N_ST], a_cp[N_ST], a_cps[N_ST];
|
||||
} translation;
|
||||
|
||||
extern void reload_callback(void);
|
||||
|
|
213
readconfig.c
213
readconfig.c
|
@ -427,7 +427,7 @@ finish_translation_section(translation *tr)
|
|||
int k;
|
||||
|
||||
if (tr) {
|
||||
for (k=0; k<2; k++) {
|
||||
for (k=0; k<N_SHIFTS+1; k++) {
|
||||
finish_stroke_data(&tr->pc[k], &tr->n_pc[k], &tr->a_pc[k]);
|
||||
finish_stroke_data(&tr->note[k], &tr->n_note[k], &tr->a_note[k]);
|
||||
finish_stroke_data(&tr->cc[k], &tr->n_cc[k], &tr->a_cc[k]);
|
||||
|
@ -448,7 +448,7 @@ free_translation_section(translation *tr)
|
|||
if (!tr->is_default) {
|
||||
regfree(&tr->regex);
|
||||
}
|
||||
for (k=0; k<2; k++) {
|
||||
for (k=0; k<N_SHIFTS+1; k++) {
|
||||
free_stroke_data(tr->pc[k], tr->n_pc[k]);
|
||||
free_stroke_data(tr->note[k], tr->n_note[k]);
|
||||
free_stroke_data(tr->cc[k], tr->n_cc[k]);
|
||||
|
@ -625,7 +625,7 @@ print_stroke(stroke *s, int mod, int step, int n_steps, int *steps, int val)
|
|||
}
|
||||
printf("%s/%c ", str, s->press ? 'D' : 'U');
|
||||
} else if (s->shift) {
|
||||
printf("SHIFT ");
|
||||
printf("SHIFT%d ", s->shift);
|
||||
} else if (!s->status) {
|
||||
printf("NOP ");
|
||||
} else {
|
||||
|
@ -752,8 +752,8 @@ stroke **first_stroke;
|
|||
stroke *last_stroke;
|
||||
stroke **press_first_stroke;
|
||||
stroke **release_first_stroke;
|
||||
stroke **alt_press_stroke;
|
||||
stroke **alt_release_stroke;
|
||||
stroke **alt_press_stroke[N_SHIFTS];
|
||||
stroke **alt_release_stroke[N_SHIFTS];
|
||||
int is_keystroke, is_bidirectional, is_anyshift, is_midi, is_nop, mode;
|
||||
char *current_translation;
|
||||
char *key_name;
|
||||
|
@ -784,12 +784,12 @@ append_stroke(KeySym sym, int press)
|
|||
}
|
||||
|
||||
void
|
||||
append_shift(void)
|
||||
append_shift(int shift)
|
||||
{
|
||||
stroke *s = (stroke *)allocate(sizeof(stroke));
|
||||
|
||||
memset(s, 0, sizeof(stroke));
|
||||
s->shift = 1;
|
||||
s->shift = shift;
|
||||
if (*first_stroke) {
|
||||
last_stroke->next = s;
|
||||
} else {
|
||||
|
@ -1265,10 +1265,23 @@ parse_midi(char *tok, char *s, int lhs, int mode,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static int chk(stroke **s)
|
||||
{
|
||||
return !s || *s;
|
||||
}
|
||||
|
||||
static int chks(stroke **s[N_SHIFTS])
|
||||
{
|
||||
for (int i = 0; i < N_SHIFTS; i++)
|
||||
if (chk(s[i])) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
start_translation(translation *tr, char *which_key)
|
||||
{
|
||||
int k, status, data, step, n_steps, *steps, incr, dir, mod, swap;
|
||||
int status, data, step, n_steps, *steps, incr, dir, mod, swap;
|
||||
char buf[100];
|
||||
|
||||
//printf("start_translation(%s)\n", which_key);
|
||||
|
@ -1284,8 +1297,19 @@ start_translation(translation *tr, char *which_key)
|
|||
regular_key_down = 0;
|
||||
modifier_count = 0;
|
||||
midi_channel = 0;
|
||||
k = *which_key == '^' || (is_anyshift = *which_key == '?');
|
||||
if (parse_midi(which_key+k, buf, 1, 0, &status, &data, &step, &n_steps, &steps, &incr, &dir, &mod, &swap)) {
|
||||
int k = 0, offs = 0;
|
||||
if (isdigit(which_key[0]) && which_key[1] == '^') {
|
||||
offs = 2; k = which_key[0]-'0';
|
||||
if (k<1 || k>N_SHIFTS) {
|
||||
fprintf(stderr, "invalid shift key: [%s]%s\n", current_translation, which_key);
|
||||
return 1;
|
||||
}
|
||||
} else if (*which_key == '^') {
|
||||
offs = k = 1;
|
||||
} else if ((is_anyshift = *which_key == '?')) {
|
||||
offs = 1; k = 0;
|
||||
}
|
||||
if (parse_midi(which_key+offs, buf, 1, 0, &status, &data, &step, &n_steps, &steps, &incr, &dir, &mod, &swap)) {
|
||||
int chan = status & 0x0f;
|
||||
mode = incr?0:mod?2:1;
|
||||
switch (status & 0xf0) {
|
||||
|
@ -1297,31 +1321,31 @@ start_translation(translation *tr, char *which_key)
|
|||
return 1;
|
||||
}
|
||||
first_stroke = find_notes(tr, k, chan, data, dir>0, step);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_notes(tr, 0, chan, data, dir>0, step);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_notes(tr, i+1, chan, data, dir>0, step);
|
||||
}
|
||||
if (!dir) {
|
||||
is_bidirectional = 1;
|
||||
release_first_stroke = find_notes(tr, k, chan, data, 1, step);
|
||||
if (is_anyshift) {
|
||||
alt_release_stroke = find_notes(tr, 0, chan, data, 1, step);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_release_stroke[i] = find_notes(tr, i+1, chan, data, 1, step);
|
||||
}
|
||||
}
|
||||
} else if (mod) {
|
||||
// note mod
|
||||
first_stroke = find_note(tr, k, chan, data, 0, mod,
|
||||
step, n_steps, steps);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_note(tr, 0, chan, data, 0, mod,
|
||||
step, n_steps, steps);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_note(tr, i+1, chan, data, 0, mod,
|
||||
step, n_steps, steps);
|
||||
}
|
||||
} else {
|
||||
// note on/off
|
||||
first_stroke = find_note(tr, k, chan, data, 0, 0, 0, 0, 0);
|
||||
release_first_stroke = find_note(tr, k, chan, data, 1, 0, 0, 0, 0);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_note(tr, 0, chan, data, 0, 0, 0, 0, 0);
|
||||
alt_release_stroke = find_note(tr, 0, chan, data, 1, 0, 0, 0, 0);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_note(tr, i+1, chan, data, 0, 0, 0, 0, 0);
|
||||
alt_release_stroke[i] = find_note(tr, i+1, chan, data, 1, 0, 0, 0, 0);
|
||||
}
|
||||
is_keystroke = 1;
|
||||
}
|
||||
|
@ -1334,9 +1358,9 @@ start_translation(translation *tr, char *which_key)
|
|||
// the corresponding "release" sequence.
|
||||
first_stroke = find_pc(tr, k, chan, data, 0);
|
||||
release_first_stroke = find_pc(tr, k, chan, data, 1);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_pc(tr, 0, chan, data, 0);
|
||||
alt_release_stroke = find_pc(tr, 0, chan, data, 1);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_pc(tr, i+1, chan, data, 0);
|
||||
alt_release_stroke[i] = find_pc(tr, i+1, chan, data, 1);
|
||||
}
|
||||
is_keystroke = 1;
|
||||
break;
|
||||
|
@ -1348,8 +1372,8 @@ start_translation(translation *tr, char *which_key)
|
|||
return 1;
|
||||
}
|
||||
first_stroke = find_ccs(tr, k, chan, data, dir>0, step, incr>1);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_ccs(tr, 0, chan, data, dir>0, step, incr>1);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_ccs(tr, i+1, chan, data, dir>0, step, incr>1);
|
||||
}
|
||||
if (!dir) {
|
||||
// This is a bidirectional translation (=, ~). We first fill in the
|
||||
|
@ -1361,25 +1385,25 @@ start_translation(translation *tr, char *which_key)
|
|||
// so that we can fill in that part later.
|
||||
is_bidirectional = 1;
|
||||
release_first_stroke = find_ccs(tr, k, chan, data, 1, step, incr>1);
|
||||
if (is_anyshift) {
|
||||
alt_release_stroke = find_ccs(tr, 0, chan, data, 1, step, incr>1);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_release_stroke[i] = find_ccs(tr, i+1, chan, data, 1, step, incr>1);
|
||||
}
|
||||
}
|
||||
} else if (mod) {
|
||||
// cc mod
|
||||
first_stroke = find_cc(tr, k, chan, data, 0, mod,
|
||||
step, n_steps, steps);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_cc(tr, 0, chan, data, 0, mod,
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_cc(tr, i+1, chan, data, 0, mod,
|
||||
step, n_steps, steps);
|
||||
}
|
||||
} else {
|
||||
// cc on/off
|
||||
first_stroke = find_cc(tr, k, chan, data, 0, 0, 0, 0, 0);
|
||||
release_first_stroke = find_cc(tr, k, chan, data, 1, 0, 0, 0, 0);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_cc(tr, 0, chan, data, 0, 0, 0, 0, 0);
|
||||
alt_release_stroke = find_cc(tr, 0, chan, data, 1, 0, 0, 0, 0);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_cc(tr, i+1, chan, data, 0, 0, 0, 0, 0);
|
||||
alt_release_stroke[i] = find_cc(tr, i+1, chan, data, 1, 0, 0, 0, 0);
|
||||
}
|
||||
is_keystroke = 1;
|
||||
}
|
||||
|
@ -1392,31 +1416,31 @@ start_translation(translation *tr, char *which_key)
|
|||
return 1;
|
||||
}
|
||||
first_stroke = find_kps(tr, k, chan, data, dir>0, step);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_kps(tr, 0, chan, data, dir>0, step);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_kps(tr, i+1, chan, data, dir>0, step);
|
||||
}
|
||||
if (!dir) {
|
||||
is_bidirectional = 1;
|
||||
release_first_stroke = find_kps(tr, k, chan, data, 1, step);
|
||||
if (is_anyshift) {
|
||||
alt_release_stroke = find_kps(tr, 0, chan, data, 1, step);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_release_stroke[i] = find_kps(tr, i+1, chan, data, 1, step);
|
||||
}
|
||||
}
|
||||
} else if (mod) {
|
||||
// kp mod
|
||||
first_stroke = find_kp(tr, k, chan, data, 0, mod,
|
||||
step, n_steps, steps);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_kp(tr, 0, chan, data, 0, mod,
|
||||
step, n_steps, steps);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_kp(tr, i+1, chan, data, 0, mod,
|
||||
step, n_steps, steps);
|
||||
}
|
||||
} else {
|
||||
// kp on/off
|
||||
first_stroke = find_kp(tr, k, chan, data, 0, 0, 0, 0, 0);
|
||||
release_first_stroke = find_kp(tr, k, chan, data, 1, 0, 0, 0, 0);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_kp(tr, 0, chan, data, 0, 0, 0, 0, 0);
|
||||
alt_release_stroke = find_kp(tr, 0, chan, data, 1, 0, 0, 0, 0);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_kp(tr, i+1, chan, data, 0, 0, 0, 0, 0);
|
||||
alt_release_stroke[i] = find_kp(tr, i+1, chan, data, 1, 0, 0, 0, 0);
|
||||
}
|
||||
is_keystroke = 1;
|
||||
}
|
||||
|
@ -1429,31 +1453,31 @@ start_translation(translation *tr, char *which_key)
|
|||
return 1;
|
||||
}
|
||||
first_stroke = find_cps(tr, k, chan, dir>0, step);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_cps(tr, 0, chan, dir>0, step);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_cps(tr, i+1, chan, dir>0, step);
|
||||
}
|
||||
if (!dir) {
|
||||
is_bidirectional = 1;
|
||||
release_first_stroke = find_cps(tr, k, chan, 1, step);
|
||||
if (is_anyshift) {
|
||||
alt_release_stroke = find_cps(tr, 0, chan, 1, step);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_release_stroke[i] = find_cps(tr, i+1, chan, 1, step);
|
||||
}
|
||||
}
|
||||
} else if (mod) {
|
||||
// cp mod
|
||||
first_stroke = find_cp(tr, k, chan, 0, mod,
|
||||
step, n_steps, steps);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_cp(tr, 0, chan, 0, mod,
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_cp(tr, i+1, chan, 0, mod,
|
||||
step, n_steps, steps);
|
||||
}
|
||||
} else {
|
||||
// cp on/off
|
||||
first_stroke = find_cp(tr, k, chan, 0, 0, 0, 0, 0);
|
||||
release_first_stroke = find_cp(tr, k, chan, 1, 0, 0, 0, 0);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_cp(tr, 0, chan, 0, 0, 0, 0, 0);
|
||||
alt_release_stroke = find_cp(tr, 0, chan, 1, 0, 0, 0, 0);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_cp(tr, i+1, chan, 0, 0, 0, 0, 0);
|
||||
alt_release_stroke[i] = find_cp(tr, i+1, chan, 1, 0, 0, 0, 0);
|
||||
}
|
||||
is_keystroke = 1;
|
||||
}
|
||||
|
@ -1466,31 +1490,31 @@ start_translation(translation *tr, char *which_key)
|
|||
return 1;
|
||||
}
|
||||
first_stroke = find_pbs(tr, k, chan, dir>0, step);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_pbs(tr, 0, chan, dir>0, step);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_pbs(tr, i+1, chan, dir>0, step);
|
||||
}
|
||||
if (!dir) {
|
||||
is_bidirectional = 1;
|
||||
release_first_stroke = find_pbs(tr, k, chan, 1, step);
|
||||
if (is_anyshift) {
|
||||
alt_release_stroke = find_pbs(tr, 0, chan, 1, step);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_release_stroke[i] = find_pbs(tr, i+1, chan, 1, step);
|
||||
}
|
||||
}
|
||||
} else if (mod) {
|
||||
// pb mod
|
||||
first_stroke = find_pb(tr, k, chan, 0, mod,
|
||||
step, n_steps, steps);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_pb(tr, 0, chan, 0, mod,
|
||||
step, n_steps, steps);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_pb(tr, i+1, chan, 0, mod,
|
||||
step, n_steps, steps);
|
||||
}
|
||||
} else {
|
||||
// pb on/off
|
||||
first_stroke = find_pb(tr, k, chan, 0, 0, 0, 0, 0);
|
||||
release_first_stroke = find_pb(tr, k, chan, 1, 0, 0, 0, 0);
|
||||
if (is_anyshift) {
|
||||
alt_press_stroke = find_pb(tr, 0, chan, 0, 0, 0, 0, 0);
|
||||
alt_release_stroke = find_pb(tr, 0, chan, 1, 0, 0, 0, 0);
|
||||
if (is_anyshift) for (int i = 0; i < N_SHIFTS; i++) {
|
||||
alt_press_stroke[i] = find_pb(tr, i+1, chan, 0, 0, 0, 0, 0);
|
||||
alt_release_stroke[i] = find_pb(tr, i+1, chan, 1, 0, 0, 0, 0);
|
||||
}
|
||||
is_keystroke = 1;
|
||||
}
|
||||
|
@ -1504,13 +1528,11 @@ start_translation(translation *tr, char *which_key)
|
|||
fprintf(stderr, "syntax error: [%s]%s\n", current_translation, which_key);
|
||||
return 1;
|
||||
}
|
||||
if ((!first_stroke || *first_stroke) ||
|
||||
(is_bidirectional &&
|
||||
(!release_first_stroke || *release_first_stroke)) ||
|
||||
if (chk(first_stroke) ||
|
||||
(is_bidirectional && chk(release_first_stroke)) ||
|
||||
(is_anyshift &&
|
||||
((!alt_press_stroke || *alt_press_stroke) ||
|
||||
(is_bidirectional &&
|
||||
(!alt_release_stroke || *alt_release_stroke))))) {
|
||||
(chks(alt_press_stroke) ||
|
||||
(is_bidirectional && chks(alt_release_stroke))))) {
|
||||
fprintf(stderr, "already defined: [%s]%s\n", current_translation, which_key);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1585,7 +1607,7 @@ add_release(int all_keys)
|
|||
if (s->keysym) {
|
||||
append_stroke(s->keysym, s->press);
|
||||
} else if (s->shift) {
|
||||
append_shift();
|
||||
append_shift(s->shift);
|
||||
} else if (!s->status) {
|
||||
append_nop();
|
||||
} else {
|
||||
|
@ -1598,30 +1620,14 @@ add_release(int all_keys)
|
|||
}
|
||||
if (all_keys && is_anyshift) {
|
||||
// create a duplicate for any-shift translations (?)
|
||||
stroke *s = *press_first_stroke;
|
||||
first_stroke = alt_press_stroke;
|
||||
while (s) {
|
||||
if (s->keysym) {
|
||||
append_stroke(s->keysym, s->press);
|
||||
} else if (s->shift) {
|
||||
append_shift();
|
||||
} else if (!s->status) {
|
||||
append_nop();
|
||||
} else {
|
||||
append_midi(s->status, s->data,
|
||||
s->step, s->n_steps, s->steps,
|
||||
s->swap, s->incr, s->recursive);
|
||||
}
|
||||
s = s->next;
|
||||
}
|
||||
if (is_keystroke || is_bidirectional) {
|
||||
s = *release_first_stroke;
|
||||
first_stroke = alt_release_stroke;
|
||||
for (int i = 0; i < N_SHIFTS; i++) {
|
||||
stroke *s = *press_first_stroke;
|
||||
first_stroke = alt_press_stroke[i];
|
||||
while (s) {
|
||||
if (s->keysym) {
|
||||
append_stroke(s->keysym, s->press);
|
||||
} else if (s->shift) {
|
||||
append_shift();
|
||||
append_shift(s->shift);
|
||||
} else if (!s->status) {
|
||||
append_nop();
|
||||
} else {
|
||||
|
@ -1632,6 +1638,26 @@ add_release(int all_keys)
|
|||
s = s->next;
|
||||
}
|
||||
}
|
||||
if (is_keystroke || is_bidirectional) {
|
||||
for (int i = 0; i < N_SHIFTS; i++) {
|
||||
stroke *s = *release_first_stroke;
|
||||
first_stroke = alt_release_stroke[i];
|
||||
while (s) {
|
||||
if (s->keysym) {
|
||||
append_stroke(s->keysym, s->press);
|
||||
} else if (s->shift) {
|
||||
append_shift(s->shift);
|
||||
} else if (!s->status) {
|
||||
append_nop();
|
||||
} else {
|
||||
append_midi(s->status, s->data,
|
||||
s->step, s->n_steps, s->steps,
|
||||
s->swap, s->incr, s->recursive);
|
||||
}
|
||||
s = s->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1898,9 +1924,14 @@ read_config_file(void)
|
|||
case '\0': // no newline at eof
|
||||
if (!strcmp(tok, "RELEASE"))
|
||||
add_keystroke(tok, PRESS_RELEASE);
|
||||
else if (!strcmp(tok, "SHIFT"))
|
||||
append_shift();
|
||||
else if (!strcmp(tok, "NOP"))
|
||||
else if (!strncmp(tok, "SHIFT", 5)) {
|
||||
int shift = isdigit(tok[5])?tok[5]-'0':1;
|
||||
if ((tok[5] == 0 || (isdigit(tok[5]) && tok[6] == 0)) &&
|
||||
shift >= 1 && shift <= N_SHIFTS)
|
||||
append_shift(shift);
|
||||
else
|
||||
fprintf(stderr, "invalid shift key: [%s]%s\n", name, tok);
|
||||
} else if (!strcmp(tok, "NOP"))
|
||||
append_nop();
|
||||
else if (strncmp(tok, "XK", 2))
|
||||
add_midi(tok);
|
||||
|
|
Loading…
Reference in New Issue