Esempio n. 1
0
static void load_instrument_handle_key(struct key_event * k)
{
	if (k->state == KEY_RELEASE)
		return;
	if (k->sym == SDLK_ESCAPE && NO_MODIFIER(k->mod))
		set_page(PAGE_INSTRUMENT_LIST);
}
Esempio n. 2
0
static void palette_list_handle_key(struct key_event * k)
{
        int n = *selected_widget;

        if (!NO_MODIFIER(k->mod))
                return;

        if (k->state == KEY_RELEASE)
                return;

        switch (k->sym) {
        case SDLK_PAGEUP:
                n -= 3;
                break;
        case SDLK_PAGEDOWN:
                n += 3;
                break;
        default:
                return;
        }

        if (status.flags & CLASSIC_MODE) {
                if (n < 0)
                        return;
                if (n > 48)
                        n = 48;
        } else {
                n = CLAMP(n, 0, 48);
        }
        if (n != *selected_widget)
                change_focus_to(n);
}
static int thumbbar_prompt_value(struct widget *widget, struct key_event *k)
{
        int c;

        if (!NO_MODIFIER(k->mod)) {
                /* annoying */
                return 0;
        }
        if (k->sym == SDLK_MINUS) {
                if (widget->d.thumbbar.min >= 0)
                        return 0;
                c = '-';
        } else {
                c = numeric_key_event(k, 0);
                if (c < 0)
                        return 0;
                c += '0';
        }

        numprompt_create("Enter Value", thumbbar_prompt_finish, c);

        return 1;
}
Esempio n. 4
0
static int file_list_handle_key(struct key_event * k)
{
	int new_file = current_file;

	new_file = CLAMP(new_file, 0, flist.num_files - 1);

	if (k->mouse != MOUSE_NONE) {
		if (k->x >= 6 && k->x <= 67 && k->y >= 13 && k->y <= 47) {
			slash_search_mode = -1;
			if (k->mouse == MOUSE_SCROLL_UP) {
				new_file -= MOUSE_SCROLL_LINES;
			} else if (k->mouse == MOUSE_SCROLL_DOWN) {
				new_file += MOUSE_SCROLL_LINES;
			} else {
				new_file = top_file + (k->y - 13);
			}
		}
	} else if (slash_search_mode > -1) {
		int c = unicode_to_ascii(k->unicode);
		if (k->sym == SDLK_RETURN || k->sym == SDLK_ESCAPE) {
			if (k->state == KEY_PRESS)
				return 1;
			slash_search_mode = -1;
			status.flags |= NEED_UPDATE;
			return 1;
		} else if (k->sym == SDLK_BACKSPACE) {
			if (k->state == KEY_RELEASE)
				return 1;
			slash_search_mode--;
			status.flags |= NEED_UPDATE;
			reposition_at_slash_search();
			return 1;
		} else if (c >= 32) {
			if (k->state == KEY_RELEASE)
				return 1;
			if (slash_search_mode < PATH_MAX) {
				slash_search_str[ slash_search_mode ] = c;
				slash_search_mode++;
				reposition_at_slash_search();
				status.flags |= NEED_UPDATE;
			}
			return 1;
		}
	}

	switch (k->sym) {
	case SDLK_UP:
		new_file--;
		slash_search_mode = -1;
		break;
	case SDLK_DOWN:
		new_file++;
		slash_search_mode = -1;
		break;
	case SDLK_PAGEUP:
		new_file -= 35;
		slash_search_mode = -1;
		break;
	case SDLK_PAGEDOWN:
		new_file += 35;
		slash_search_mode = -1;
		break;
	case SDLK_HOME:
		new_file = 0;
		slash_search_mode = -1;
		break;
	case SDLK_END:
		new_file = flist.num_files - 1;
		slash_search_mode = -1;
		break;
	case SDLK_RETURN:
		if (k->state == KEY_PRESS)
			return 0;
		handle_enter_key();
		slash_search_mode = -1;
		return 1;
	case SDLK_DELETE:
		if (k->state == KEY_RELEASE)
			return 1;
		slash_search_mode = -1;
		if (flist.num_files > 0)
			dialog_create(DIALOG_OK_CANCEL, "Delete file?", do_delete_file, NULL, 1, NULL);
		return 1;
	case SDLK_ESCAPE:
		slash_search_mode = -1;
		if (k->state == KEY_RELEASE && NO_MODIFIER(k->mod))
			set_page(PAGE_INSTRUMENT_LIST);
		return 1;
	case SDLK_SLASH:
		if (k->orig_sym == SDLK_SLASH) {
			if (status.flags & CLASSIC_MODE) return 0;
			if (k->state == KEY_RELEASE)
				return 0;
			slash_search_mode = 0;
			status.flags |= NEED_UPDATE;
			return 1;
		}
	default:
		if (k->mouse == MOUSE_NONE)
			return 0;
	}

	if (k->mouse == MOUSE_CLICK) {
		if (k->state == KEY_RELEASE)
			return 0;
	} else if (k->mouse == MOUSE_DBLCLICK) {
		handle_enter_key();
		return 1;
	} else {
		if (k->state == KEY_PRESS)
			return 0;
	}

	new_file = CLAMP(new_file, 0, flist.num_files - 1);
	if (new_file < 0) new_file = 0;
	if (new_file != current_file) {
		current_file = new_file;
		file_list_reposition();
		status.flags |= NEED_UPDATE;
	}
	return 1;
}
Esempio n. 5
0
static int palette_list_handle_key_on_list(struct key_event * k)
{
        int new_palette = selected_palette;
        const int focus_offsets[] = { 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 10, 11, 12 };

        if (k->mouse == MOUSE_CLICK) {
                if (k->state == KEY_PRESS)
                        return 0;
                if (k->x < 56 || k->y < 27 || k->y > 46 || k->x > 76) return 0;
                new_palette = (k->y - 28);
                if (new_palette == selected_palette) {
                        // alright
                        if (selected_palette == -1) return 1;
                        palette_load_preset(selected_palette);
                        palette_apply();
                        update_thumbbars();
                        status.flags |= NEED_UPDATE;
                        return 1;
                }
        } else {
                if (k->state == KEY_RELEASE)
                        return 0;
                if (k->mouse == MOUSE_SCROLL_UP)
                        new_palette -= MOUSE_SCROLL_LINES;
                else if (k->mouse == MOUSE_SCROLL_DOWN)
                        new_palette += MOUSE_SCROLL_LINES;
        }

        switch (k->sym) {
        case SDLK_UP:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                if (--new_palette < -1) {
                        change_focus_to(47);
                        return 1;
                }
                break;
        case SDLK_DOWN:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                new_palette++;
                break;
        case SDLK_HOME:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                new_palette = 0;
                break;
        case SDLK_PAGEUP:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                if (new_palette == -1) {
                        change_focus_to(45);
                        return 1;
                }
                new_palette -= 16;
                break;
        case SDLK_END:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                new_palette = max_palette - 1;
                break;
        case SDLK_PAGEDOWN:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                new_palette += 16;
                break;
        case SDLK_RETURN:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                if (selected_palette == -1) return 1;
                palette_load_preset(selected_palette);
                palette_apply();
                update_thumbbars();
                status.flags |= NEED_UPDATE;
                return 1;
        case SDLK_RIGHT:
        case SDLK_TAB:
                if (k->mod & KMOD_SHIFT) {
                        change_focus_to(focus_offsets[selected_palette+1] + 29);
                        return 1;
                }
                if (!NO_MODIFIER(k->mod))
                        return 0;
                change_focus_to(focus_offsets[selected_palette+1] + 8);
                return 1;
        case SDLK_LEFT:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                change_focus_to(focus_offsets[selected_palette+1] + 29);
                return 1;
        default:
                if (k->mouse == MOUSE_NONE)
                        return 0;
        }

        if (new_palette < -1) new_palette = -1;
        else if (new_palette >= (max_palette-1)) new_palette = (max_palette-1);
        if (new_palette != selected_palette) {
                selected_palette = new_palette;
                status.flags |= NEED_UPDATE;
        }

        return 1;
}
Esempio n. 6
0
static int message_handle_key_editmode(struct key_event * k)
{
        int line_len, num_lines = -1;
        int new_cursor_line = cursor_line;
        int new_cursor_char = cursor_char;
        char *ptr;
        int doing_drag = 0;
        int clipl, clipr, cp;

        if (k->mouse == MOUSE_SCROLL_UP) {
                if (k->state == KEY_RELEASE)
                        return 0;
                new_cursor_line -= MOUSE_SCROLL_LINES;
        } else if (k->mouse == MOUSE_SCROLL_DOWN) {
                if (k->state == KEY_RELEASE)
                        return 0;
                new_cursor_line += MOUSE_SCROLL_LINES;
        } else if (k->mouse == MOUSE_CLICK && k->mouse_button == 2) {
                if (k->state == KEY_RELEASE)
                        status.flags |= CLIPPY_PASTE_SELECTION;
                return 1;
        } else if (k->mouse == MOUSE_CLICK) {
                if (k->x >= 2 && k->x <= 77 && k->y >= 13 && k->y <= 47) {
                        new_cursor_line = (k->y - 13) + top_line;
                        new_cursor_char = (k->x - 2);
                        if (k->sx != k->x || k->sy != k->y) {
                                /* yay drag operation */
                                cp = get_absolute_position(current_song->message, (k->sy-13)+top_line,
                                                        (k->sx-2));
                                widgets_message[0].clip_start = cp;
                                doing_drag = 1;
                        }
                }
        }

        line_len = get_nth_line(current_song->message, cursor_line, &ptr);


        switch (k->sym) {
        case SDLK_UP:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                if (k->state == KEY_RELEASE)
                        return 1;
                new_cursor_line--;
                break;
        case SDLK_DOWN:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                if (k->state == KEY_RELEASE)
                        return 1;
                new_cursor_line++;
                break;
        case SDLK_LEFT:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                if (k->state == KEY_RELEASE)
                        return 1;
                new_cursor_char--;
                break;
        case SDLK_RIGHT:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                if (k->state == KEY_RELEASE)
                        return 1;
                new_cursor_char++;
                break;
        case SDLK_PAGEUP:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                if (k->state == KEY_RELEASE)
                        return 1;
                new_cursor_line -= 35;
                break;
        case SDLK_PAGEDOWN:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                if (k->state == KEY_RELEASE)
                        return 1;
                new_cursor_line += 35;
                break;
        case SDLK_HOME:
                if (k->state == KEY_RELEASE)
                        return 1;
                if (k->mod & KMOD_CTRL)
                        new_cursor_line = 0;
                else
                        new_cursor_char = 0;
                break;
        case SDLK_END:
                if (k->state == KEY_RELEASE)
                        return 1;
                if (k->mod & KMOD_CTRL) {
                        num_lines = get_num_lines(current_song->message);
                        new_cursor_line = num_lines;
                } else {
                        new_cursor_char = line_len;
                }
                break;
        case SDLK_ESCAPE:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                if (k->state == KEY_RELEASE)
                        return 1;
                message_set_viewmode();
                memused_songchanged();
                return 1;
        case SDLK_BACKSPACE:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                if (k->state == KEY_RELEASE)
                        return 1;
                if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) {
                        _delete_selection();
                } else {
                        message_delete_char();
                }
                return 1;
        case SDLK_DELETE:
                if (!NO_MODIFIER(k->mod))
                        return 0;
                if (k->state == KEY_RELEASE)
                        return 1;
                if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) {
                        _delete_selection();
                } else {
                        message_delete_next_char();
                }
                return 1;
        default:
                if (k->mod & KMOD_CTRL) {
                        if (k->state == KEY_RELEASE)
                                return 1;
                        if (k->sym == SDLK_t) {
                                message_extfont = !message_extfont;
                                break;
                        } else if (k->sym == SDLK_y) {
                                clippy_select(NULL, NULL, 0);
                                message_delete_line();
                                break;
                        }
                } else if (k->mod & KMOD_ALT) {
                        if (k->state == KEY_RELEASE)
                                return 1;
                        if (k->sym == SDLK_c) {
                                prompt_message_clear();
                                return 1;
                        }
                } else if (k->mouse == MOUSE_NONE) {
                        if (k->unicode == '\r' || k->unicode == '\t'
                        || k->unicode >= 32) {
                                if (k->state == KEY_RELEASE)
                                        return 1;
                                if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) {
                                        _delete_selection();
                                }
                                if (k->mod & (KMOD_SHIFT|KMOD_CAPS)) {
                                        message_insert_char(toupper((unsigned int)k->unicode));
                                } else {
                                        message_insert_char(k->unicode);
                                }
                                return 1;
                        }
                        return 0;
                }

                if (k->mouse != MOUSE_CLICK)
                        return 0;

                if (k->state == KEY_RELEASE)
                        return 1;
                if (!doing_drag) {
                        clippy_select(NULL, NULL, 0);
                }
        }

        if (new_cursor_line != cursor_line) {
                if (num_lines == -1)
                        num_lines = get_num_lines(current_song->message);

                if (new_cursor_line < 0)
                        new_cursor_line = 0;
                else if (new_cursor_line > num_lines)
                        new_cursor_line = num_lines;

                /* make sure the cursor doesn't go past the new eol */
                line_len = get_nth_line(current_song->message, new_cursor_line, &ptr);
                if (new_cursor_char > line_len)
                        new_cursor_char = line_len;

                cursor_char = new_cursor_char;
                cursor_line = new_cursor_line;
        } else if (new_cursor_char != cursor_char) {
        /* we say "else" here ESPECIALLY because the mouse can only come
        in the top section - not because it's some clever optimization */
                if (new_cursor_char < 0) {
                        if (cursor_line == 0) {
                                new_cursor_char = cursor_char;
                        } else {
                                cursor_line--;
                                new_cursor_char =
                                        get_nth_line(current_song->message, cursor_line, &ptr);
                        }

                } else if (new_cursor_char >
                           get_nth_line(current_song->message, cursor_line, &ptr)) {
                        if (cursor_line == get_num_lines(current_song->message)) {
                                new_cursor_char = cursor_char;
                        } else {
                                cursor_line++;
                                new_cursor_char = 0;
                        }
                }
                cursor_char = new_cursor_char;
        }

        message_reposition();
        cursor_pos = get_absolute_position(current_song->message, cursor_line, cursor_char);

        if (doing_drag) {
                widgets_message[0].clip_end = cursor_pos;

                clipl = widgets_message[0].clip_start;
                clipr = widgets_message[0].clip_end;
                if (clipl > clipr) {
                        cp = clipl;
                        clipl = clipr;
                        clipr = cp;
                }
                clippy_select(widgets_message, (current_song->message+clipl), clipr-clipl);
        }

        status.flags |= NEED_UPDATE;

        return 1;
}
/* return: 1 = handled key, 0 = didn't */
int widget_handle_key(struct key_event * k)
{
        struct widget *widget = &ACTIVE_WIDGET;
        if (!widget)
                return 0;

        int n, onw, wx, fmin, fmax, pad;
        void (*changed)(void);
        enum widget_type current_type = widget->type;

        if (!(status.flags & DISKWRITER_ACTIVE)
            && (current_type == WIDGET_OTHER)
            && widget->d.other.handle_key(k))
                return 1;

        if (!(status.flags & DISKWRITER_ACTIVE) && k->mouse
            && (status.flags & CLASSIC_MODE)) {
                switch(current_type) {
                case WIDGET_NUMENTRY:
                        if (k->mouse_button == MOUSE_BUTTON_LEFT) {
                                k->sym = SDLK_MINUS;
                                k->mouse = MOUSE_NONE;
                        } else if (k->mouse_button == MOUSE_BUTTON_RIGHT) {
                                k->sym = SDLK_PLUS;
                                k->mouse = MOUSE_NONE;
                        }
                        break;
                default:
                        break;
                };
        }

        if (k->mouse == MOUSE_CLICK) {
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                switch (current_type) {
                case WIDGET_TOGGLE:
                        if (!NO_MODIFIER(k->mod))
                                return 0;
                        if (k->state == KEY_RELEASE)
                                return 1;
                        widget->d.toggle.state = !widget->d.toggle.state;
                        if (widget->changed) widget->changed();
                        status.flags |= NEED_UPDATE;
                        return 1;
                case WIDGET_MENUTOGGLE:
                        if (!NO_MODIFIER(k->mod))
                                return 0;
                        if (k->state == KEY_RELEASE)
                                return 1;
                        widget->d.menutoggle.state = (widget->d.menutoggle.state + 1)
                                % widget->d.menutoggle.num_choices;
                        if (widget->changed) widget->changed();
                        status.flags |= NEED_UPDATE;
                        return 1;
                default:
                        break;
                }
        } else if (k->mouse == MOUSE_DBLCLICK) {
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (current_type == WIDGET_PANBAR) {
                        if (!NO_MODIFIER(k->mod))
                                return 0;
                        widget->d.panbar.muted = !widget->d.panbar.muted;
                        changed = widget->changed;
                        if (changed) changed();
                        return 1;
                }
        }

        if (k->mouse == MOUSE_CLICK
            || (k->mouse == MOUSE_NONE && k->sym == SDLK_RETURN)) {
#if 0
                if (k->mouse && k->mouse_button == MOUSE_BUTTON_MIDDLE) {
                        if (status.flags & DISKWRITER_ACTIVE) return 0;
                        if (k->state == KEY_PRESS)
                                return 1;
                        status.flags |= CLIPPY_PASTE_SELECTION;
                        return 1;
                }
#endif
                if (k->mouse && (current_type == WIDGET_THUMBBAR
                || current_type == WIDGET_PANBAR)) {
                        if (status.flags & DISKWRITER_ACTIVE) return 0;

                        /* swallow it */
                        if (!k->on_target) return 0;

                        fmin = widget->d.thumbbar.min;
                        fmax = widget->d.thumbbar.max;
                        if (current_type == WIDGET_PANBAR) {
                                n = k->fx - ((widget->x + 11) * k->rx);
                                wx = (widget->width - 16) * k->rx;
                        } else {
                                n = k->fx - (widget->x * k->rx);
                                wx = (widget->width-1) * k->rx;
                        }
                        if (n < 0) n = 0;
                        else if (n >= wx) n = wx;
                        n = fmin + ((n * (fmax - fmin)) / wx);

                        if (n < fmin)
                                n = fmin;
                        else if (n > fmax)
                                n = fmax;
                        if (current_type == WIDGET_PANBAR) {
                                widget->d.panbar.muted = 0;
                                widget->d.panbar.surround = 0;
                                if (k->x - widget->x < 11) return 1;
                                if (k->x - widget->x > 19) return 1;
                        }
                        numentry_change_value(widget, n);
                        return 1;
                }
                if (k->mouse) {
                        switch (widget->type) {
                        case WIDGET_BUTTON:
                                pad = widget->d.button.padding+1;
                                break;
                        case WIDGET_TOGGLEBUTTON:
                                pad = widget->d.togglebutton.padding+1;
                                break;
                        default:
                                pad = 0;
                        };
                        onw = ((signed) k->x < widget->x
                               || (signed) k->x >= widget->x + widget->width + pad
                               || (signed) k->y != widget->y) ? 0 : 1;
                        n = (k->state == KEY_RELEASE && onw) ? 1 : 0;
                        if (widget->depressed != n) status.flags |= NEED_UPDATE;
                        widget->depressed = n;
                        if (current_type != WIDGET_TEXTENTRY && current_type != WIDGET_NUMENTRY) {
                                if (k->state == KEY_PRESS || !onw)
                                        return 1;
                        } else if (!onw) {
                                return 1;
                        }
                } else {
                        n = (k->state == KEY_PRESS) ? 1 : 0;
                        if (widget->depressed != n)
                                status.flags |= NEED_UPDATE;
                        else if (k->state == KEY_RELEASE)
                                return 1; // swallor
                        widget->depressed = n;
                        if (k->state == KEY_PRESS)
                                return 1;
                }

                if (k->mouse) {
                        switch(current_type) {
                        case WIDGET_MENUTOGGLE:
                        case WIDGET_BUTTON:
                        case WIDGET_TOGGLEBUTTON:
                                if (k->on_target && widget->activate) widget->activate();
                        default:
                                break;
                        };
                } else if (current_type != WIDGET_OTHER) {
                        if (widget->activate) widget->activate();
                }

                switch (current_type) {
                case WIDGET_OTHER:
                        break;
                case WIDGET_TEXTENTRY:
                        if (status.flags & DISKWRITER_ACTIVE) return 0;
                        /* LOL WOW THIS SUCKS */
                        if (k->mouse == MOUSE_CLICK && k->on_target) {
                                /* position cursor */
                                n = k->x - widget->x;
                                n = CLAMP(n, 0, widget->width - 1);
                                wx = k->sx - widget->x;
                                wx = CLAMP(wx, 0, widget->width - 1);
                                widget->d.textentry.cursor_pos = n+widget->d.textentry.firstchar;
                                wx  = wx+widget->d.textentry.firstchar;
                                if (widget->d.textentry.cursor_pos >= (signed) strlen(widget->d.textentry.text))
                                        widget->d.textentry.cursor_pos = strlen(widget->d.textentry.text);
                                if (wx >= (signed) strlen(widget->d.textentry.text))
                                        wx = strlen(widget->d.textentry.text);
                                status.flags |= NEED_UPDATE;
                        }

                        /* for a text entry, the only thing enter does is run the activate callback.
                        thus, if no activate callback is defined, the key wasn't handled */
                        return (widget->activate != NULL);

                case WIDGET_NUMENTRY:
                        if (status.flags & DISKWRITER_ACTIVE) return 0;
                        if (k->mouse == MOUSE_CLICK && k->on_target) {
                                /* position cursor */
                                n = k->x - widget->x;
                                n = CLAMP(n, 0, widget->width - 1);
                                wx = k->sx - widget->x;
                                wx = CLAMP(wx, 0, widget->width - 1);
                                if (n >= widget->width)
                                        n = widget->width-1;
                                *widget->d.numentry.cursor_pos = n;
                                status.flags |= NEED_UPDATE;
                        }

                        break;

                case WIDGET_TOGGLEBUTTON:
                        if (status.flags & DISKWRITER_ACTIVE) return 0;
                        if (widget->d.togglebutton.group) {
                                /* this also runs the changed callback and redraws the button(s) */
                                togglebutton_set(widgets, *selected_widget, 1);
                                return 1;
                        }
                        /* else... */
                        widget->d.togglebutton.state = !widget->d.togglebutton.state;
                        /* and fall through */
                case WIDGET_BUTTON:
                        /* maybe buttons should ignore the changed callback, and use activate instead...
                        (but still call the changed callback for togglebuttons if they *actually* changed) */
                        if (widget->changed) widget->changed();
                        status.flags |= NEED_UPDATE;
                        return 1;
                default:
                        break;
                }
                return 0;
        }

        /* a WIDGET_OTHER that *didn't* handle the key itself needs to get run through the switch
        statement to account for stuff like the tab key */
        if (k->state == KEY_RELEASE)
                return 0;

        if (k->mouse == MOUSE_SCROLL_UP && current_type == WIDGET_NUMENTRY) {
                k->sym = SDLK_MINUS;
        } else if (k->mouse == MOUSE_SCROLL_DOWN && current_type == WIDGET_NUMENTRY) {
                k->sym = SDLK_PLUS;
        }

        switch (k->sym) {
        case SDLK_ESCAPE:
                /* this is to keep the text entries from taking the key hostage and inserting '<-'
                characters instead of showing the menu */
                return 0;
        case SDLK_UP:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (!NO_MODIFIER(k->mod))
                        return 0;
                change_focus_to(widget->next.up);
                return 1;
        case SDLK_DOWN:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (!NO_MODIFIER(k->mod))
                        return 0;
                change_focus_to(widget->next.down);
                return 1;
        case SDLK_TAB:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (k->mod & KMOD_SHIFT) {
                        _backtab();
                        return 1;
                }
                if (!NO_MODIFIER(k->mod))
                        return 0;
                change_focus_to(widget->next.tab);
                return 1;
        case SDLK_LEFT:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                switch (current_type) {
                case WIDGET_BITSET:
                    if (NO_MODIFIER(k->mod))
                        bitset_move_cursor(widget, -1);
                    break;
                case WIDGET_NUMENTRY:
                        if (!NO_MODIFIER(k->mod)) {
                                return 0;
                        }
                        numentry_move_cursor(widget, -1);
                        return 1;
                case WIDGET_TEXTENTRY:
                        if (!NO_MODIFIER(k->mod)) {
                                return 0;
                        }
                        textentry_move_cursor(widget, -1);
                        return 1;
                case WIDGET_PANBAR:
                        widget->d.panbar.muted = 0;
                        widget->d.panbar.surround = 0;
                        /* fall through */
                case WIDGET_THUMBBAR:
                        /* I'm handling the key modifiers differently than Impulse Tracker, but only
                        because I think this is much more useful. :) */
                        n = 1;
                        if (k->mod & (KMOD_ALT | KMOD_META))
                                n *= 8;
                        if (k->mod & KMOD_SHIFT)
                                n *= 4;
                        if (k->mod & KMOD_CTRL)
                                n *= 2;
                        n = widget->d.numentry.value - n;
                        numentry_change_value(widget, n);
                        return 1;
                default:
                        if (!NO_MODIFIER(k->mod))
                                return 0;
                        change_focus_to(widget->next.left);
                        return 1;
                }
                break;
        case SDLK_RIGHT:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                /* pretty much the same as left, but with a few small
                 * changes here and there... */
                switch (current_type) {
                case WIDGET_BITSET:
                    if (NO_MODIFIER(k->mod))
                        bitset_move_cursor(widget, 1);
                    break;
                case WIDGET_NUMENTRY:
                        if (!NO_MODIFIER(k->mod)) {
                                return 0;
                        }
                        numentry_move_cursor(widget, 1);
                        return 1;
                case WIDGET_TEXTENTRY:
                        if (!NO_MODIFIER(k->mod)) {
                                return 0;
                        }
                        textentry_move_cursor(widget, 1);
                        return 1;
                case WIDGET_PANBAR:
                        widget->d.panbar.muted = 0;
                        widget->d.panbar.surround = 0;
                        /* fall through */
                case WIDGET_THUMBBAR:
                        n = 1;
                        if (k->mod & (KMOD_ALT | KMOD_META))
                                n *= 8;
                        if (k->mod & KMOD_SHIFT)
                                n *= 4;
                        if (k->mod & KMOD_CTRL)
                                n *= 2;
                        n = widget->d.numentry.value + n;
                        numentry_change_value(widget, n);
                        return 1;
                default:
                        if (!NO_MODIFIER(k->mod))
                                return 0;
                        change_focus_to(widget->next.right);
                        return 1;
                }
                break;
        case SDLK_HOME:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                /* Impulse Tracker only does home/end for the thumbbars.
                 * This stuff is all extra. */
                switch (current_type) {
                case WIDGET_NUMENTRY:
                        if (!NO_MODIFIER(k->mod))
                                return 0;
                        *(widget->d.numentry.cursor_pos) = 0;
                        status.flags |= NEED_UPDATE;
                        return 1;
                case WIDGET_TEXTENTRY:
                        if (!NO_MODIFIER(k->mod))
                                return 0;
                        widget->d.textentry.cursor_pos = 0;
                        status.flags |= NEED_UPDATE;
                        return 1;
                case WIDGET_PANBAR:
                        widget->d.panbar.muted = 0;
                        widget->d.panbar.surround = 0;
                        /* fall through */
                case WIDGET_THUMBBAR:
                        n = widget->d.thumbbar.min;
                        numentry_change_value(widget, n);
                        return 1;
                default:
                        break;
                }
                break;
        case SDLK_END:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                switch (current_type) {
                case WIDGET_NUMENTRY:
                        if (!NO_MODIFIER(k->mod))
                                return 0;
                        *(widget->d.numentry.cursor_pos) = widget->width - 1;
                        status.flags |= NEED_UPDATE;
                        return 1;
                case WIDGET_TEXTENTRY:
                        if (!NO_MODIFIER(k->mod))
                                return 0;
                        widget->d.textentry.cursor_pos = strlen(widget->d.textentry.text);
                        status.flags |= NEED_UPDATE;
                        return 1;
                case WIDGET_PANBAR:
                        widget->d.panbar.muted = 0;
                        widget->d.panbar.surround = 0;
                        /* fall through */
                case WIDGET_THUMBBAR:
                        n = widget->d.thumbbar.max;
                        numentry_change_value(widget, n);
                        return 1;
                default:
                        break;
                }
                break;
        case SDLK_SPACE:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                switch (current_type) {
                case WIDGET_BITSET:
                    if (!NO_MODIFIER(k->mod))
                        return 0;
                    widget->d.bitset.value ^= (1 << *widget->d.bitset.cursor_pos);
                        if (widget->changed) widget->changed();
                    status.flags |= NEED_UPDATE;
                    return 1;
                case WIDGET_TOGGLE:
                        if (!NO_MODIFIER(k->mod))
                                return 0;
                        widget->d.toggle.state = !widget->d.toggle.state;
                        if (widget->changed) widget->changed();
                        status.flags |= NEED_UPDATE;
                        return 1;
                case WIDGET_MENUTOGGLE:
                        if (!NO_MODIFIER(k->mod))
                                return 0;
                        widget->d.menutoggle.state = (widget->d.menutoggle.state + 1)
                                % widget->d.menutoggle.num_choices;
                        if (widget->changed) widget->changed();
                        status.flags |= NEED_UPDATE;
                        return 1;
                case WIDGET_PANBAR:
                        if (!NO_MODIFIER(k->mod))
                                return 0;
                        widget->d.panbar.muted = !widget->d.panbar.muted;
                        changed = widget->changed;
                        change_focus_to(widget->next.down);
                        if (changed) changed();
                        return 1;
                default:
                        break;
                }
                break;
        case SDLK_BACKSPACE:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (current_type == WIDGET_NUMENTRY) {
                        if (widget->d.numentry.reverse) {
                                /* woot! */
                                widget->d.numentry.value /= 10;
                                if (widget->changed) widget->changed();
                                status.flags |= NEED_UPDATE;
                                return 1;
                        }
                }

                /* this ought to be in a separate function. */
                if (current_type != WIDGET_TEXTENTRY)
                        break;
                if (!widget->d.textentry.text[0]) {
                        /* nothing to do */
                        return 1;
                }
                if (k->mod & KMOD_CTRL) {
                        /* clear the whole field */
                        widget->d.textentry.text[0] = 0;
                        widget->d.textentry.cursor_pos = 0;
                } else {
                        if (widget->d.textentry.cursor_pos == 0) {
                                /* act like ST3 */
                                text_delete_next_char(widget->d.textentry.text,
                                                      &(widget->d.textentry.cursor_pos),
                                                      widget->d.textentry.max_length);
                        } else {
                                text_delete_char(widget->d.textentry.text,
                                                 &(widget->d.textentry.cursor_pos),
                                                 widget->d.textentry.max_length);
                        }
                }
                if (widget->changed) widget->changed();
                status.flags |= NEED_UPDATE;
                return 1;
        case SDLK_DELETE:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (current_type != WIDGET_TEXTENTRY)
                        break;
                if (!widget->d.textentry.text[0]) {
                        /* nothing to do */
                        return 1;
                }
                text_delete_next_char(widget->d.textentry.text,
                                      &(widget->d.textentry.cursor_pos), widget->d.textentry.max_length);
                if (widget->changed) widget->changed();
                status.flags |= NEED_UPDATE;
                return 1;
        case SDLK_PLUS:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (current_type == WIDGET_NUMENTRY && NO_MODIFIER(k->mod)) {
                        numentry_change_value(widget, widget->d.numentry.value + 1);
                        return 1;
                }
                break;
        case SDLK_MINUS:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (current_type == WIDGET_NUMENTRY && NO_MODIFIER(k->mod)) {
                        numentry_change_value(widget, widget->d.numentry.value - 1);
                        return 1;
                }
                break;
        case SDLK_l:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (current_type == WIDGET_PANBAR) {
                        if (k->mod & KMOD_ALT) {
                                song_set_pan_scheme(PANS_LEFT);
                                return 1;
                        } else if (NO_MODIFIER(k->mod)) {
                                widget->d.panbar.muted = 0;
                                widget->d.panbar.surround = 0;
                                numentry_change_value(widget, 0);
                                return 1;
                        }
                }
                break;
        case SDLK_m:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (current_type == WIDGET_PANBAR) {
                        if (k->mod & KMOD_ALT) {
                                song_set_pan_scheme(PANS_MONO);
                                return 1;
                        } else if (NO_MODIFIER(k->mod)) {
                                widget->d.panbar.muted = 0;
                                widget->d.panbar.surround = 0;
                                numentry_change_value(widget, 32);
                                return 1;
                        }
                }
                break;
        case SDLK_r:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (current_type == WIDGET_PANBAR) {
                        if (k->mod & KMOD_ALT) {
                                song_set_pan_scheme(PANS_RIGHT);
                                return 1;
                        } else if (NO_MODIFIER(k->mod)) {
                                widget->d.panbar.muted = 0;
                                widget->d.panbar.surround = 0;
                                numentry_change_value(widget, 64);
                                return 1;
                        }
                }
                break;
        case SDLK_s:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (current_type == WIDGET_PANBAR) {
                        if (k->mod & KMOD_ALT) {
                                song_set_pan_scheme(PANS_STEREO);
                                return 1;
                        } else if(NO_MODIFIER(k->mod)) {
                                widget->d.panbar.muted = 0;
                                widget->d.panbar.surround = 1;
                                if (widget->changed) widget->changed();
                                status.flags |= NEED_UPDATE;
                                return 1;
                        }
                }
                break;
        case SDLK_a:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) {
                        song_set_pan_scheme(PANS_AMIGA);
                        return 1;
                }
                break;
#if 0
        case SDLK_x:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) {
                        song_set_pan_scheme(PANS_CROSS);
                        return 1;
                }
                break;
#endif
        case SDLK_SLASH:
        case SDLK_KP_DIVIDE:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) {
                        song_set_pan_scheme(PANS_SLASH);
                        return 1;
                }
                break;
        case SDLK_BACKSLASH:
                if (status.flags & DISKWRITER_ACTIVE) return 0;
                if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) {
                        song_set_pan_scheme(PANS_BACKSLASH);
                        return 1;
                }
                break;
        default:
                /* this avoids a warning about all the values of an enum not being handled.
                (sheesh, it's already hundreds of lines long as it is!) */
                break;
        }
        if (status.flags & DISKWRITER_ACTIVE) return 0;

        /* if we're here, that mess didn't completely handle the key (gosh...) so now here's another mess. */
        switch (current_type) {
        case WIDGET_MENUTOGGLE:
                if (menutoggle_handle_key(widget, k))
                        return 1;
                break;
        case WIDGET_BITSET:
                if (bitset_handle_key(widget, k))
                        return 1;
                break;
        case WIDGET_NUMENTRY:
                if (numentry_handle_digit(widget, k))
                        return 1;
                break;
        case WIDGET_THUMBBAR:
        case WIDGET_PANBAR:
                if (thumbbar_prompt_value(widget, k))
                        return 1;
                break;
        case WIDGET_TEXTENTRY:
                if ((k->mod & (KMOD_CTRL | KMOD_ALT | KMOD_META)) == 0
                                && textentry_add_char(widget, k->unicode))
                        return 1;
                break;
        default:
                break;
        }

        /* if we got down here the key wasn't handled */
        return 0;
}
Esempio n. 8
0
static int _handle_ime(struct key_event *k)
{
	int c, m;
	static int alt_numpad = 0;
	static int alt_numpad_c = 0;
	static int digraph_n = 0;
	static int digraph_c = 0;
	static int cs_unicode = 0;
	static int cs_unicode_c = 0;
	struct key_event fake;

	if (ACTIVE_PAGE.selected_widget > -1 && ACTIVE_PAGE.selected_widget < ACTIVE_PAGE.total_widgets
	    && ACTIVE_PAGE.widgets[ACTIVE_PAGE.selected_widget].accept_text) {
		if (digraph_n == -1 && k->state == KEY_RELEASE) {
			digraph_n = 0;

		} else if (!(status.flags & CLASSIC_MODE) && (k->sym == SDLK_LCTRL || k->sym == SDLK_RCTRL)) {
			if (k->state == KEY_RELEASE && digraph_n >= 0) {
				digraph_n++;
				if (digraph_n >= 2)
					status_text_flash_bios("Enter digraph:");
			}
		} else if (k->sym == SDLK_LSHIFT || k->sym == SDLK_RSHIFT) {
			/* do nothing */
		} else if (!NO_MODIFIER((k->mod&~KMOD_SHIFT)) || (c=k->unicode) == 0 || digraph_n < 2) {
			if (k->state == KEY_PRESS && k->mouse == MOUSE_NONE) {
				if (digraph_n > 0) status_text_flash(" ");
				digraph_n = -1;
			}
		} else if (digraph_n >= 2) {
			if (k->state == KEY_RELEASE)
				return 1;
			if (!digraph_c) {
				digraph_c = c;
				status_text_flash_bios("Enter digraph: %c", c);
			} else {
				memset(&fake, 0, sizeof(fake));
				fake.unicode = char_digraph(digraph_c, c);
				if (fake.unicode) {
					status_text_flash_bios("Enter digraph: %c%c -> %c",
							       digraph_c, c, fake.unicode);
				} else {
					status_text_flash_bios("Enter digraph: %c%c -> INVALID", digraph_c, c);
				}
				digraph_n = digraph_c = 0;
				if (fake.unicode) {
					fake.is_synthetic = 3;
					handle_key(&fake);
					fake.state = KEY_RELEASE;
					handle_key(&fake);
				}
			}
			return 1;
		} else {
			if (digraph_n > 0) status_text_flash(" ");
			digraph_n = 0;
		}

		/* ctrl+shift -> unicode character */
		if ((k->sym==SDLK_LCTRL || k->sym==SDLK_RCTRL || k->sym==SDLK_LSHIFT || k->sym==SDLK_RSHIFT)) {
			if (k->state == KEY_RELEASE && cs_unicode_c > 0) {
				memset(&fake, 0, sizeof(fake));
				fake.unicode = char_unicode_to_cp437(cs_unicode);
				if (fake.unicode) {
					status_text_flash_bios("Enter Unicode: U+%04X -> %c",
							       cs_unicode, fake.unicode);
					fake.is_synthetic = 3;
					handle_key(&fake);
					fake.state = KEY_RELEASE;
					handle_key(&fake);
				} else {
					status_text_flash_bios("Enter Unicode: U+%04X -> INVALID", cs_unicode);
				}
				cs_unicode = cs_unicode_c = 0;
				alt_numpad = alt_numpad_c = 0;
				digraph_n = digraph_c = 0;
				return 1;
			}
		} else if (!(status.flags & CLASSIC_MODE) && (k->mod & KMOD_CTRL) && (k->mod & KMOD_SHIFT)) {
			if (cs_unicode_c >= 0) {
				/* bleh... */
				m = k->mod;
				k->mod = 0;
				c = kbd_char_to_hex(k);
				k->mod = m;
				if (c == -1) {
					cs_unicode = cs_unicode_c = -1;
				} else {
					if (k->state == KEY_PRESS) return 1;
					cs_unicode *= 16;
					cs_unicode += c;
					cs_unicode_c++;
					digraph_n = digraph_c = 0;
					status_text_flash_bios("Enter Unicode: U+%04X", cs_unicode);
					return 1;
				}
			}
		} else {
			cs_unicode = cs_unicode_c = 0;
		}

		/* alt+numpad -> char number */
		if (k->sym == SDLK_LALT || k->sym == SDLK_RALT
		    || k->sym == SDLK_LMETA || k->sym == SDLK_RMETA) {
			if (k->state == KEY_RELEASE && alt_numpad_c > 0 && (alt_numpad & 255) > 0) {
				memset(&fake, 0, sizeof(fake));
				fake.unicode = alt_numpad & 255;
				if (!(status.flags & CLASSIC_MODE))
					status_text_flash_bios("Enter DOS/ASCII: %d -> %c",
							       (int)fake.unicode, (int)fake.unicode);
				fake.is_synthetic = 3;
				handle_key(&fake);
				fake.state = KEY_RELEASE;
				handle_key(&fake);
				alt_numpad = alt_numpad_c = 0;
				digraph_n = digraph_c = 0;
				cs_unicode = cs_unicode_c = 0;
				return 1;
			}
		} else if (k->mod & KMOD_ALT && !(k->mod & (KMOD_CTRL|KMOD_SHIFT))) {
			if (alt_numpad_c >= 0) {
				m = k->mod;
				k->mod = 0;
				c = numeric_key_event(k, 1); /* kp only */
				k->mod = m;
				if (c == -1 || c > 9) {
					alt_numpad = alt_numpad_c = -1;
				} else {
					if (k->state == KEY_PRESS) return 1;
					alt_numpad *= 10;
					alt_numpad += c;
					alt_numpad_c++;
					if (!(status.flags & CLASSIC_MODE))
						status_text_flash_bios("Enter DOS/ASCII: %d", (int)alt_numpad);
					return 1;
				}
			}
		} else {
			alt_numpad = alt_numpad_c = 0;
		}
	} else {
		cs_unicode = cs_unicode_c = 0;
		alt_numpad = alt_numpad_c = 0;
		digraph_n = digraph_c = 0;
	}

	return 0;
}
Esempio n. 9
0
/* 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;
}
Esempio n. 10
0
/* this is the important one */
void handle_key(struct key_event *k)
{
	if (_handle_ime(k))
		return;

	/* okay... */
	if (!(status.flags & DISKWRITER_ACTIVE) && ACTIVE_PAGE.pre_handle_key) {
		if (ACTIVE_PAGE.pre_handle_key(k)) return;
	}

	if (handle_key_global(k)) return;
	if (!(status.flags & DISKWRITER_ACTIVE) && menu_handle_key(k)) return;
	if (widget_handle_key(k)) return;

	/* now check a couple other keys. */
	switch (k->sym) {
	case SDLK_LEFT:
		if (k->state == KEY_RELEASE) return;
		if (status.flags & DISKWRITER_ACTIVE) return;
		if ((k->mod & KMOD_CTRL) && status.current_page != PAGE_PATTERN_EDITOR) {
			_mp_finish(NULL);
			if (song_get_mode() == MODE_PLAYING)
				song_set_current_order(song_get_current_order() - 1);
			return;
		}
		break;
	case SDLK_RIGHT:
		if (k->state == KEY_RELEASE) return;
		if (status.flags & DISKWRITER_ACTIVE) return;
		if ((k->mod & KMOD_CTRL) && status.current_page != PAGE_PATTERN_EDITOR) {
			_mp_finish(NULL);
			if (song_get_mode() == MODE_PLAYING)
				song_set_current_order(song_get_current_order() + 1);
			return;
		}
		break;
	case SDLK_ESCAPE:
		/* TODO | Page key handlers should return true/false depending on if the key was handled
		   TODO | (same as with other handlers), and the escape key check should go *after* the
		   TODO | page gets a chance to grab it. This way, the load sample page can switch back
		   TODO | to the sample list on escape like it's supposed to. (The status.current_page
		   TODO | checks above won't be necessary, either.) */
		if (NO_MODIFIER(k->mod) && status.dialog_type == DIALOG_NONE
		    && status.current_page != PAGE_LOAD_SAMPLE
		    && status.current_page != PAGE_LOAD_INSTRUMENT) {
			if (k->state == KEY_RELEASE) return;
			if (_mp_active) {
				_mp_finish(NULL);
				return;
			}
			menu_show();
			return;
		}
		break;
	case SDLK_SLASH:
		if (k->state == KEY_RELEASE) return;
		if (status.flags & DISKWRITER_ACTIVE) return;
		if (k->orig_sym == SDLK_KP_DIVIDE) {
			kbd_set_current_octave(kbd_get_current_octave() - 1);
		}
		return;
	case SDLK_ASTERISK:
		if (k->state == KEY_RELEASE) return;
		if (status.flags & DISKWRITER_ACTIVE) return;
		if (k->orig_sym == SDLK_KP_MULTIPLY) {
			kbd_set_current_octave(kbd_get_current_octave() + 1);
		}
		return;
	case SDLK_LEFTBRACKET:
		if (k->state == KEY_RELEASE) break;
		if (status.flags & DISKWRITER_ACTIVE) return;
		if (k->mod & KMOD_SHIFT) {
			song_set_current_speed(song_get_current_speed() - 1);
			status_text_flash("Speed set to %d frames per row", song_get_current_speed());
			if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) {
				song_set_initial_speed(song_get_current_speed());
			}
		} else if ((k->mod & KMOD_CTRL) && !(status.flags & CLASSIC_MODE)) {
			song_set_current_tempo(song_get_current_tempo() - 1);
			status_text_flash("Tempo set to %d frames per row", song_get_current_tempo());
			if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) {
				song_set_initial_tempo(song_get_current_tempo());
			}
		} else if (NO_MODIFIER(k->mod)) {
			song_set_current_global_volume(song_get_current_global_volume() - 1);
			status_text_flash("Global volume set to %d", song_get_current_global_volume());
			if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) {
				song_set_initial_global_volume(song_get_current_global_volume());
			}
		}
		return;
	case SDLK_RIGHTBRACKET:
		if (k->state == KEY_RELEASE) break;
		if (status.flags & DISKWRITER_ACTIVE) return;
		if (k->mod & KMOD_SHIFT) {
			song_set_current_speed(song_get_current_speed() + 1);
			status_text_flash("Speed set to %d frames per row", song_get_current_speed());
			if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) {
				song_set_initial_speed(song_get_current_speed());
			}
		} else if ((k->mod & KMOD_CTRL) && !(status.flags & CLASSIC_MODE)) {
			song_set_current_tempo(song_get_current_tempo() + 1);
			status_text_flash("Tempo set to %d frames per row", song_get_current_tempo());
			if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) {
				song_set_initial_tempo(song_get_current_tempo());
			}
		} else if (NO_MODIFIER(k->mod)) {
			song_set_current_global_volume(song_get_current_global_volume() + 1);
			status_text_flash("Global volume set to %d", song_get_current_global_volume());
			if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) {
				song_set_initial_global_volume(song_get_current_global_volume());
			}
		}
		return;

	default:
		break;
	}

	/* and if we STILL didn't handle the key, pass it to the page.
	 * (or dialog, if one's active) */
	if (status.dialog_type & DIALOG_BOX) {
		dialog_handle_key(k);
	} else {
		if (status.flags & DISKWRITER_ACTIVE) return;
		if (ACTIVE_PAGE.handle_key) ACTIVE_PAGE.handle_key(k);
	}
}