/*-
- * Copyright (c) 2007, 2008 Edward Tomasz Napierała <trasz@FreeBSD.org>
+ * Copyright (c) 2007, 2008 Edward Tomasz Napiera�ła <trasz@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <assert.h>
#include <string.h>
-#include <strings.h>
#include <stdint.h>
#include <cairo/cairo.h>
+
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
}
}
-static void
+static void
draw_note(PianoKeyboard *pk, cairo_t* cr, int note)
{
int is_white = pk->notes[note].white;
int h = pk->notes[note].h;
if (pk->notes[note].pressed || pk->notes[note].sustained) {
- is_white = !is_white;
+ if (is_white) {
+ cairo_set_source_rgb (cr, 0.60f, 0.60f, 0.60f);
+ } else {
+ cairo_set_source_rgb (cr, 0.50f, 0.50f, 0.50f);
+ }
+ } else {
+ if (is_white) {
+ cairo_set_source_rgb (cr, 1.0f, 1.0f, 1.0f);
+ } else {
+ cairo_set_source_rgb (cr, 0.0f, 0.0f, 0.0f);
+ }
}
cairo_set_line_width (cr, 1.0);
- if (is_white) {
- cairo_set_source_rgb (cr, 1.0f, 1.0f, 1.0f);
- } else {
- cairo_set_source_rgb (cr, 0.0f, 0.0f, 0.0f);
- }
-
cairo_rectangle (cr, x, 0, w, h);
cairo_fill (cr);
}
}
-static int
+static int
press_key(PianoKeyboard *pk, int key)
{
assert(key >= 0);
else
pk->notes[key].sustained = 0;
+ if (pk->monophonic && pk->last_key != key) {
+ pk->notes[pk->last_key].pressed = 0;
+ pk->notes[pk->last_key].sustained = 0;
+ queue_note_draw(pk, pk->last_key);
+ }
+ pk->last_key = key;
+
pk->notes[key].pressed = 1;
g_signal_emit_by_name(GTK_WIDGET(pk), "note-on", key);
return 1;
}
-static int
+static int
release_key(PianoKeyboard *pk, int key)
{
assert(key >= 0);
rest (PianoKeyboard* pk)
{
g_signal_emit_by_name(GTK_WIDGET(pk), "rest");
-}
+}
-static void
+static void
stop_unsustained_notes(PianoKeyboard *pk)
{
int i;
}
}
-static void
+static void
stop_sustained_notes(PianoKeyboard *pk)
{
int i;
{
assert(pk->key_bindings != NULL);
- g_hash_table_insert(pk->key_bindings, (gpointer)key, (gpointer)((intptr_t)note));
+ g_hash_table_insert(pk->key_bindings, (const gpointer)key, (gpointer)((intptr_t)note));
}
static void
g_hash_table_remove_all(pk->key_bindings);
}
-static void
+static void
bind_keys_qwerty(PianoKeyboard *pk)
{
clear_notes(pk);
bind_key(pk, "p", 40);
}
-static void
+static void
bind_keys_qwertz(PianoKeyboard *pk)
{
bind_keys_qwerty(pk);
bind_key(pk, "p", 40);
}
-static gint
-keyboard_event_handler(GtkWidget *mk, GdkEventKey *event, gpointer notused)
+static gint
+keyboard_event_handler(GtkWidget *mk, GdkEventKey *event, gpointer ignored)
{
int note;
char *key;
GdkKeymapKey kk;
PianoKeyboard *pk = PIANO_KEYBOARD(mk);
+ (void) ignored;
+
/* We're not using event->keyval, because we need keyval with level set to 0.
E.g. if user holds Shift and presses '7', we want to get a '7', not '&'. */
kk.keycode = event->hardware_keycode;
if (event->type == GDK_KEY_RELEASE) {
rest (pk);
}
-
+
return TRUE;
}
return TRUE;
}
-static int
+static int
get_note_for_xy(PianoKeyboard *pk, int x, int y)
{
int height = GTK_WIDGET(pk)->allocation.height;
return -1;
}
-static gboolean
-mouse_button_event_handler(PianoKeyboard *pk, GdkEventButton *event, gpointer notused)
+static gboolean
+mouse_button_event_handler(PianoKeyboard *pk, GdkEventButton *event, gpointer ignored)
{
int x = event->x;
int y = event->y;
int note = get_note_for_xy(pk, x, y);
+ (void) ignored;
+
if (event->button != 1)
return TRUE;
return TRUE;
}
-static gboolean
-mouse_motion_event_handler(PianoKeyboard *pk, GdkEventMotion *event, gpointer notused)
+static gboolean
+mouse_motion_event_handler(PianoKeyboard *pk, GdkEventMotion *event, gpointer ignored)
{
int note;
+ (void) ignored;
+
if ((event->state & GDK_BUTTON1_MASK) == 0)
return TRUE;
note = get_note_for_xy(pk, event->x, event->y);
if (note != pk->note_being_pressed_using_mouse && note >= 0) {
-
+
if (pk->note_being_pressed_using_mouse >= 0)
release_key(pk, pk->note_being_pressed_using_mouse);
press_key(pk, note);
int i;
PianoKeyboard *pk = PIANO_KEYBOARD(widget);
cairo_t* cr = gdk_cairo_create (GDK_DRAWABLE (GTK_WIDGET(pk)->window));
-
+
gdk_cairo_region (cr, event->region);
cairo_clip (cr);
return TRUE;
}
-static void
-piano_keyboard_size_request(GtkWidget* widget, GtkRequisition *requisition)
+static void
+piano_keyboard_size_request(GtkWidget* w, GtkRequisition *requisition)
{
+ (void) w;
+
requisition->width = PIANO_KEYBOARD_DEFAULT_WIDTH;
requisition->height = PIANO_KEYBOARD_DEFAULT_HEIGHT;
}
/* Set up signals. */
piano_keyboard_signals[NOTE_ON_SIGNAL] = g_signal_new ("note-on",
- G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_TYPE_FROM_CLASS (klass), (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
0, NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
piano_keyboard_signals[NOTE_OFF_SIGNAL] = g_signal_new ("note-off",
- G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_TYPE_FROM_CLASS (klass), (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
0, NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
piano_keyboard_signals[REST_SIGNAL] = g_signal_new ("rest",
- G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_TYPE_FROM_CLASS (klass), (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
- widget_klass = (GtkWidgetClass*) klass;
+ widget_klass = (GtkWidgetClass*) klass;
widget_klass->expose_event = piano_keyboard_expose;
widget_klass->size_request = piano_keyboard_size_request;
0, /* value_table */
};
- mk_type = g_type_register_static(GTK_TYPE_DRAWING_AREA, "PianoKeyboard", &mk_info, 0);
+ mk_type = g_type_register_static(GTK_TYPE_DRAWING_AREA, "PianoKeyboard", &mk_info, (GTypeFlags)0);
}
return mk_type;
GtkWidget *
piano_keyboard_new(void)
{
- GtkWidget *widget = gtk_type_new(piano_keyboard_get_type());
+ GtkWidget *widget = (GtkWidget*)gtk_type_new(piano_keyboard_get_type());
PianoKeyboard *pk = PIANO_KEYBOARD(widget);
pk->enable_keyboard_cue = 0;
pk->octave = 4;
pk->note_being_pressed_using_mouse = -1;
- memset((void *)pk->notes, 0, sizeof(struct Note) * NNOTES);
+ pk->last_key = 0;
+ pk->monophonic = FALSE;
+ memset((void *)pk->notes, 0, sizeof(struct PKNote) * NNOTES);
pk->key_bindings = g_hash_table_new(g_str_hash, g_str_equal);
bind_keys_qwerty(pk);
pk->enable_keyboard_cue = enabled;
}
+void
+piano_keyboard_set_monophonic(PianoKeyboard *pk, gboolean monophonic)
+{
+ pk->monophonic = monophonic;
+}
+
void
piano_keyboard_sustain_press(PianoKeyboard *pk)
{
}
}
-void
+void
piano_keyboard_sustain_release(PianoKeyboard *pk)
{
if (pk->maybe_stop_sustained_notes)
{
assert(layout);
- if (!strcasecmp(layout, "QWERTY")) {
+ if (!g_ascii_strcasecmp(layout, "QWERTY")) {
bind_keys_qwerty(pk);
- } else if (!strcasecmp(layout, "QWERTZ")) {
+ } else if (!g_ascii_strcasecmp(layout, "QWERTZ")) {
bind_keys_qwertz(pk);
- } else if (!strcasecmp(layout, "AZERTY")) {
+ } else if (!g_ascii_strcasecmp(layout, "AZERTY")) {
bind_keys_azerty(pk);
} else {
return FALSE;
}
-