static gboolean piano_keyboard_expose(GtkWidget *widget, GdkEventExpose *event) { 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); for (i = 0; i < NNOTES; i++) { GdkRectangle r; r.x = pk->notes[i].x; r.y = 0; r.width = pk->notes[i].w; r.height = pk->notes[i].h; switch (gdk_region_rect_in (event->region, &r)) { case GDK_OVERLAP_RECTANGLE_PART: case GDK_OVERLAP_RECTANGLE_IN: draw_note (pk, cr, i); break; default: break; } } cairo_destroy (cr); return TRUE; }
static gint keyboard_event_handler(GtkWidget *mk, GdkEventKey *event, gpointer ignored) { int note; char *key; guint keyval; 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; kk.level = 0; kk.group = 0; keyval = gdk_keymap_lookup_key(NULL, &kk); key = gdk_keyval_name(gdk_keyval_to_lower(keyval)); if (key == NULL) { g_message("gtk_keyval_name() returned NULL; please report this."); return FALSE; } note = key_binding(pk, key); if (note < 0) { /* Key was not bound. Maybe it's one of the keys handled in jack-keyboard.c. */ return FALSE; } if (note == 128) { if (event->type == GDK_KEY_RELEASE) { rest (pk); } return TRUE; } note += pk->octave * 12; assert(note >= 0); assert(note < NNOTES); if (event->type == GDK_KEY_PRESS) { press_key(pk, note); } else if (event->type == GDK_KEY_RELEASE) { release_key(pk, note); } return TRUE; }
static void piano_keyboard_size_allocate(GtkWidget *widget, GtkAllocation *allocation) { /* XXX: Are these two needed? */ g_return_if_fail(widget != NULL); g_return_if_fail(allocation != NULL); widget->allocation = *allocation; recompute_dimensions(PIANO_KEYBOARD(widget)); if (GTK_WIDGET_REALIZED(widget)) { gdk_window_move_resize (widget->window, allocation->x, allocation->y, allocation->width, allocation->height); } }
GtkWidget * piano_keyboard_new(void) { GtkWidget *widget = (GtkWidget*)gtk_type_new(piano_keyboard_get_type()); PianoKeyboard *pk = PIANO_KEYBOARD(widget); pk->maybe_stop_sustained_notes = 0; pk->sustain_new_notes = 0; pk->enable_keyboard_cue = 0; pk->octave = 4; pk->note_being_pressed_using_mouse = -1; 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); return widget; }