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