int midi_engine_handle_event(void *ev) { struct key_event kk = {.is_synthetic = 0}; int *st; SDL_Event *e = ev; if (e->type != SCHISM_EVENT_MIDI) return 0; st = e->user.data1; if (midi_flags & MIDI_DISABLE_RECORD) { free(e->user.data1); return 1; } switch (e->user.code) { case SCHISM_EVENT_MIDI_NOTE: if (st[0] == MIDI_NOTEON) { kk.state = KEY_PRESS; } else { if (!(midi_flags & MIDI_RECORD_NOTEOFF)) { /* don't record noteoff? okay... */ break; } kk.state = KEY_RELEASE; } kk.midi_channel = st[1]+1; kk.midi_note = (st[2]+1 + midi_c5note) - 60; if (midi_flags & MIDI_RECORD_VELOCITY) kk.midi_volume = st[3]; else kk.midi_volume = 128; kk.midi_volume = (kk.midi_volume * midi_amplification) / 100; handle_key(&kk); break; case SCHISM_EVENT_MIDI_PITCHBEND: /* wheel */ kk.midi_channel = st[1]+1; kk.midi_volume = -1; kk.midi_note = -1; kk.midi_bend = st[0]; handle_key(&kk); break; case SCHISM_EVENT_MIDI_CONTROLLER: /* controller events */ break; case SCHISM_EVENT_MIDI_SYSTEM: switch (st[0]) { case 0x8: /* MIDI tick */ break; case 0xA: /* MIDI start */ case 0xB: /* MIDI continue */ song_start(); break; case 0xC: /* MIDI stop */ case 0xF: /* MIDI reset */ /* this is helpful when miditracking */ song_stop(); break; }; case SCHISM_EVENT_MIDI_SYSEX: /* but missing the F0 and the stop byte (F7) */ //len = *((unsigned int *)e->user.data1); //sysex = ((char *)e->user.data1)+sizeof(unsigned int); break; default: break; } free(e->user.data1); return 1; }
/* returns 1 if the key was handled */ static int handle_key_global(struct key_event * k) { int i, ins_mode; if (_mp_active == 2 && (k->mouse == MOUSE_CLICK && k->state == KEY_RELEASE)) { status.flags |= NEED_UPDATE; dialog_destroy_all(); _mp_active = 0; // eat it... return 1; } if ((!_mp_active) && k->state == KEY_PRESS && k->mouse == MOUSE_CLICK) { if (k->x >= 63 && k->x <= 77 && k->y >= 6 && k->y <= 7) { status.vis_style++; status.vis_style %= VIS_SENTINEL; status.flags |= NEED_UPDATE; return 1; } else if (k->y == 5 && k->x == 50) { minipop_slide(kbd_get_current_octave(), "Octave", 0, 8, kbd_set_current_octave, NULL, 50, 5); return 1; } else if (k->y == 4 && k->x >= 50 && k->x <= 52) { minipop_slide(song_get_current_speed(), "Speed", 1, 255, song_set_current_speed, song_set_initial_speed, 51, 4); return 1; } else if (k->y == 4 && k->x >= 54 && k->x <= 56) { minipop_slide(song_get_current_tempo(), "Tempo", 32, 255, song_set_current_tempo, song_set_initial_tempo, 55, 4); return 1; } else if (k->y == 3 && k->x >= 50 && k-> x <= 77) { if (page_is_instrument_list(status.current_page) || status.current_page == PAGE_SAMPLE_LIST || (!(status.flags & CLASSIC_MODE) && (status.current_page == PAGE_ORDERLIST_PANNING || status.current_page == PAGE_ORDERLIST_VOLUMES))) ins_mode = 0; else ins_mode = song_is_instrument_mode(); if (ins_mode) { minipop_slide(instrument_get_current(), "!", status.current_page == PAGE_INSTRUMENT_LIST ? 1 : 0, 99 /* FIXME */, instrument_set, NULL, 58, 3); } else { minipop_slide(sample_get_current(), "@", status.current_page == PAGE_SAMPLE_LIST ? 1 : 0, 99 /* FIXME */, sample_set, NULL, 58, 3); } } else if (k->y == 7 && k->x >= 11 && k->x <= 17) { minipop_slide(get_current_row(), "Row", 0, song_get_rows_in_pattern(get_current_pattern()), set_current_row, NULL, 14, 7); return 1; } else if (k->y == 6 && k->x >= 11 && k->x <= 17) { minipop_slide(get_current_pattern(), "Pattern", 0, csf_get_num_patterns(current_song), set_current_pattern, NULL, 14, 6); return 1; } else if (k->y == 5 && k->x >= 11 && k->x <= 17) { minipop_slide(song_get_current_order(), "Order", 0, csf_get_num_orders(current_song), set_current_order, NULL, 14, 5); return 1; } } else if ((!_mp_active) && k->mouse == MOUSE_DBLCLICK) { if (k->y == 4 && k->x >= 11 && k->x <= 28) { set_page(PAGE_SAVE_MODULE); return 1; } else if (k->y == 3 && k->x >= 11 && k->x <= 35) { set_page(PAGE_SONG_VARIABLES); return 1; } } /* shortcut */ if (k->mouse != MOUSE_NONE) { return 0; } /* first, check the truly global keys (the ones that still work if * a dialog's open) */ switch (k->sym) { case SDLK_RETURN: if ((k->mod & KMOD_CTRL) && k->mod & KMOD_ALT) { if (k->state == KEY_PRESS) return 1; toggle_display_fullscreen(); return 1; } break; case SDLK_m: if (k->mod & KMOD_CTRL) { if (k->state == KEY_RELEASE) return 1; video_mousecursor(MOUSE_CYCLE_STATE); return 1; } break; case SDLK_d: if (k->mod & KMOD_CTRL) { if (k->state == KEY_RELEASE) return 1; /* argh */ i = SDL_WM_GrabInput(SDL_GRAB_QUERY); if (i == SDL_GRAB_QUERY) i = currently_grabbed; currently_grabbed = i = (i != SDL_GRAB_ON ? SDL_GRAB_ON : SDL_GRAB_OFF); SDL_WM_GrabInput(i); status_text_flash(i ? "Mouse and keyboard grabbed, press Ctrl+D to release" : "Mouse and keyboard released"); return 1; } break; case SDLK_i: /* reset audio stuff? */ if (k->mod & KMOD_CTRL) { if (k->state == KEY_RELEASE) return 1; audio_reinit(); return 1; } break; case SDLK_e: /* This should reset everything display-related. */ if (k->mod & KMOD_CTRL) { if (k->state == KEY_RELEASE) return 1; font_init(); status.flags |= NEED_UPDATE; return 1; } break; case SDLK_HOME: if (!(k->mod & KMOD_ALT)) break; if (status.flags & DISKWRITER_ACTIVE) break; if (k->state == KEY_RELEASE) return 0; kbd_set_current_octave(kbd_get_current_octave() - 1); return 1; case SDLK_END: if (!(k->mod & KMOD_ALT)) break; if (status.flags & DISKWRITER_ACTIVE) break; if (k->state == KEY_RELEASE) return 0; kbd_set_current_octave(kbd_get_current_octave() + 1); return 1; default: break; } /* next, if there's no dialog, check the rest of the keys */ if (status.flags & DISKWRITER_ACTIVE) return 0; switch (k->sym) { case SDLK_q: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_PRESS) show_exit_prompt(); return 1; } break; case SDLK_n: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_PRESS) new_song_dialog(); return 1; } break; case SDLK_g: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_PRESS) show_song_timejump(); return 1; } break; case SDLK_p: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_PRESS) show_song_length(); return 1; } break; case SDLK_F1: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_CONFIG); } else if (k->mod & KMOD_SHIFT) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(status.current_page == PAGE_MIDI ? PAGE_MIDI_OUTPUT : PAGE_MIDI); } else if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_HELP); } else { break; } return 1; case SDLK_F2: if (k->mod & KMOD_CTRL) { if (status.current_page == PAGE_PATTERN_EDITOR) { _mp_finish(NULL); if (k->state == KEY_PRESS && status.dialog_type == DIALOG_NONE) { pattern_editor_length_edit(); } return 1; } if (status.dialog_type != DIALOG_NONE) return 0; } else if (NO_MODIFIER(k->mod)) { if (status.current_page == PAGE_PATTERN_EDITOR) { if (k->state == KEY_PRESS) { if (status.dialog_type & DIALOG_MENU) { return 0; } else if (status.dialog_type != DIALOG_NONE) { dialog_yes_NULL(); status.flags |= NEED_UPDATE; } else { _mp_finish(NULL); pattern_editor_display_options(); } } } else { if (status.dialog_type != DIALOG_NONE) return 0; _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_PATTERN_EDITOR); } return 1; } break; case SDLK_F3: if (status.dialog_type != DIALOG_NONE) return 0; if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_SAMPLE_LIST); } else { _mp_finish(NULL); if (k->mod & KMOD_CTRL) set_page(PAGE_LIBRARY_SAMPLE); break; } return 1; case SDLK_F4: if (status.dialog_type != DIALOG_NONE) return 0; if (NO_MODIFIER(k->mod)) { if (status.current_page == PAGE_INSTRUMENT_LIST) return 0; _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_INSTRUMENT_LIST); } else { if (k->mod & KMOD_SHIFT) return 0; _mp_finish(NULL); if (k->mod & KMOD_CTRL) set_page(PAGE_LIBRARY_INSTRUMENT); break; } return 1; case SDLK_F5: if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_PRESS) song_start(); } else if (k->mod & KMOD_SHIFT) { if (status.dialog_type != DIALOG_NONE) return 0; _mp_finish(NULL); if (k->state == KEY_RELEASE) set_page(PAGE_PREFERENCES); } else if (NO_MODIFIER(k->mod)) { if (song_get_mode() == MODE_STOPPED || (song_get_mode() == MODE_SINGLE_STEP && status.current_page == PAGE_INFO)) { _mp_finish(NULL); if (k->state == KEY_PRESS) song_start(); } if (k->state == KEY_PRESS) { if (status.dialog_type != DIALOG_NONE) return 0; _mp_finish(NULL); set_page(PAGE_INFO); } } else { break; } return 1; case SDLK_F6: if (k->mod & KMOD_SHIFT) { _mp_finish(NULL); if (k->state == KEY_PRESS) song_start_at_order(get_current_order(), 0); } else if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (k->state == KEY_PRESS) song_loop_pattern(get_current_pattern(), 0); } else { break; } return 1; case SDLK_F7: if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (k->state == KEY_PRESS) play_song_from_mark(); } else { break; } return 1; case SDLK_F8: if (k->mod & KMOD_SHIFT) { if (k->state == KEY_PRESS) song_pause(); } else if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (k->state == KEY_PRESS) song_stop(); status.flags |= NEED_UPDATE; } else { break; } return 1; case SDLK_F9: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_SHIFT) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_MESSAGE); } else if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_LOAD_MODULE); } else { break; } return 1; case SDLK_l: case SDLK_r: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_RELEASE) set_page(PAGE_LOAD_MODULE); } else { break; } return 1; case SDLK_s: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_RELEASE) save_song_or_save_as(); } else { break; } return 1; case SDLK_w: /* Ctrl-W _IS_ in IT, and hands don't leave home row :) */ if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_RELEASE) set_page(PAGE_SAVE_MODULE); } else { break; } return 1; case SDLK_F10: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_ALT) break; if (k->mod & KMOD_CTRL) break; _mp_finish(NULL); if (k->mod & KMOD_SHIFT) { if (k->state == KEY_PRESS) set_page(PAGE_EXPORT_MODULE); } else { if (k->state == KEY_PRESS) set_page(PAGE_SAVE_MODULE); } return 1; case SDLK_F11: if (status.dialog_type != DIALOG_NONE) return 0; if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (status.current_page == PAGE_ORDERLIST_PANNING) { if (k->state == KEY_PRESS) set_page(PAGE_ORDERLIST_VOLUMES); } else { if (k->state == KEY_PRESS) set_page(PAGE_ORDERLIST_PANNING); } } else if (k->mod & KMOD_CTRL) { if (k->state == KEY_PRESS) { _mp_finish(NULL); if (status.current_page == PAGE_LOG) { show_about(); } else { set_page(PAGE_LOG); } } } else if (k->state == KEY_PRESS && (k->mod & KMOD_ALT)) { _mp_finish(NULL); if (song_toggle_orderlist_locked()) status_text_flash("Order list locked"); else status_text_flash("Order list unlocked"); } else { break; } return 1; case SDLK_F12: if (status.dialog_type != DIALOG_NONE) return 0; if ((k->mod & KMOD_ALT) && status.current_page == PAGE_INFO) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_WATERFALL); } else if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_PALETTE_EDITOR); } else if (k->mod & KMOD_SHIFT) { _mp_finish(NULL); if (k->state == KEY_PRESS) { fontedit_return_page = status.current_page; set_page(PAGE_FONT_EDIT); } } else if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_SONG_VARIABLES); } else { break; } return 1; /* hack alert */ case SDLK_f: if (!(k->mod & KMOD_CTRL)) return 0; /* fall through */ case SDLK_SCROLLOCK: if (status.dialog_type != DIALOG_NONE) return 0; _mp_finish(NULL); if (k->mod & KMOD_ALT) { if (k->state == KEY_PRESS) { midi_flags ^= (MIDI_DISABLE_RECORD); status_text_flash("MIDI Input %s", (midi_flags & MIDI_DISABLE_RECORD) ? "Disabled" : "Enabled"); } return 1; } else { /* os x steals plain scroll lock for brightness, * so catch ctrl+scroll lock here as well */ if (k->state == KEY_PRESS) { midi_playback_tracing = (playback_tracing = !playback_tracing); status_text_flash("Playback tracing %s", (playback_tracing ? "enabled" : "disabled")); } return 1; } default: if (status.dialog_type != DIALOG_NONE) return 0; break; } /* got a bit ugly here, sorry */ i = k->sym; if (k->mod & KMOD_ALT) { switch (i) { case SDLK_F1: i = 0; break; case SDLK_F2: i = 1; break; case SDLK_F3: i = 2; break; case SDLK_F4: i = 3; break; case SDLK_F5: i = 4; break; case SDLK_F6: i = 5; break; case SDLK_F7: i = 6; break; case SDLK_F8: i = 7; break; default: return 0; }; if (k->state == KEY_RELEASE) return 1; song_toggle_channel_mute(i); status.flags |= NEED_UPDATE; return 1; } /* oh well */ return 0; }