/** * Mouse motion callback * */ gint scorearea_motion_notify (GtkWidget * widget, GdkEventButton * event) { DenemoProject *gui = Denemo.project; if (gui == NULL || gui->movement == NULL) return FALSE; if (Denemo.scorearea == NULL) return FALSE; gint allocated_height = get_widget_height (Denemo.scorearea); gint line_height = allocated_height * gui->movement->system_height; if(dragging_outside) { gint incrx, incry; incrx=incry=0; if(((gint)((last_event_x - event->x_root)/gui->movement->zoom)) != 0) { incrx = -(last_event_x - event->x_root)/gui->movement->zoom; last_event_x = event->x_root; } if( ((gint)((last_event_y - event->y_root)/gui->movement->zoom)) != 0) { incry = -(last_event_y - event->y_root)/gui->movement->zoom; last_event_y = event->y_root; } if((dragging_outside==DRAG_DIRECTION_RIGHT) && (incrx > 1) || ((dragging_outside==DRAG_DIRECTION_LEFT) && (incrx < -1)) || ((dragging_outside==DRAG_DIRECTION_UP) && (incry < 0)) || ((dragging_outside==DRAG_DIRECTION_DOWN) && (incry > 0))) extend_selection(dragging_outside); return TRUE; } if (event->y < 0) event->y = 0.0; gint line_num = ((int) event->y) / line_height; if (last_directive && (GDK_SHIFT_MASK & event->state) && (GDK_CONTROL_MASK & event->state)) { gint incrx, incry; incrx=incry=0; if(((gint)((last_event_x - event->x_root)/gui->movement->zoom)) != 0) { incrx = (last_event_x - event->x_root)/gui->movement->zoom; last_event_x = event->x_root; } if( ((gint)((last_event_y - event->y_root)/gui->movement->zoom)) != 0) { incry = (last_event_y - event->y_root)/gui->movement->zoom; last_event_y = event->y_root; } if(last_directive->graphic) { last_directive->gx -= incrx; last_directive->gy -= incry; } else { last_directive->tx -= incrx; last_directive->ty -= incry; } draw_score_area(); return TRUE; } if(gui->movement->recording && dragging_audio) { if(gui->movement->recording->type == DENEMO_RECORDING_MIDI) { #if 0 //This is moving only the NoteOn, so it could be moved later than the note off, and indeed later than a later note in the stream //- quite a bit more work needed to drag MIDI to correct the timing. smf_event_t *midievent; GList *marked_onset = gui->movement->marked_onset; if(marked_onset) { midievent = ((DenemoRecordedNote *)marked_onset->data)->event; gint shift = 2500*(event->x_root - last_event_x)/gui->movement->zoom; g_debug (" %f (%f %f)",shift/(double)gui->movement->recording->samplerate, midievent->time_seconds, ((DenemoRecordedNote *)marked_onset->data)->timing/(double)gui->movement->recording->samplerate) ; ((DenemoRecordedNote *)marked_onset->data)->timing += shift; midievent->time_seconds += shift/(double)gui->movement->recording->samplerate; } #endif g_warning("No drag for MIDI yet"); return TRUE; } gui->movement->recording->leadin -= 500*(event->x_root - last_event_x)/gui->movement->zoom;//g_debug("%d %d => %d\n", (int)(10*last_event_x), (int)(10*event->x_root), (int)(10*last_event_x) - (int)(10*event->x_root)); last_event_x = event->x_root; update_leadin_widget ( gui->movement->recording->leadin/(double)gui->movement->recording->samplerate); gtk_widget_queue_draw(Denemo.scorearea); return TRUE; } if(gui->movement->recording && dragging_tempo) { gdouble change = (event->x_root - last_event_x)/gui->movement->zoom; last_event_x = event->x_root; struct placement_info pi; get_placement_from_coordinates (&pi, event->x, 0, gui->lefts[line_num], gui->rights[line_num], gui->scales[line_num]); change /= pi.measure_number; update_tempo_widget ( change); set_tempo (); score_status (Denemo.project, TRUE); exportmidi (NULL, gui->movement); gtk_widget_queue_draw(Denemo.scorearea); return TRUE; } #define DENEMO_MINIMUM_SYSTEM_HEIGHT (0.01) if (dragging_separator) { gui->movement->system_height = event->y / get_widget_height (Denemo.scorearea); if (gui->movement->system_height < DENEMO_MINIMUM_SYSTEM_HEIGHT) gui->movement->system_height = DENEMO_MINIMUM_SYSTEM_HEIGHT; if (gui->movement->system_height > 1.0) gui->movement->system_height = 1.0; scorearea_configure_event (Denemo.scorearea, NULL); draw_score_area(); return TRUE; } if (line_height - ((int) event->y - 8) % line_height < 12) gdk_window_set_cursor (gtk_widget_get_window (Denemo.window), gdk_cursor_new (GDK_SB_V_DOUBLE_ARROW)); else gdk_window_set_cursor (gtk_widget_get_window (Denemo.window), gdk_cursor_new (GDK_LEFT_PTR)); //FIXME? does this take time/hog memory transform_coords (&event->x, &event->y); //g_debug("Marked %d\n", gui->movement->markstaffnum); if (gui->lefts[line_num] == 0) return TRUE; if (lh_down || (selecting && gui->movement->markstaffnum)) { struct placement_info pi; pi.the_staff = NULL; if (event->y < 0) get_placement_from_coordinates (&pi, event->x, 0, gui->lefts[line_num], gui->rights[line_num], gui->scales[line_num]); else get_placement_from_coordinates (&pi, event->x, event->y, gui->lefts[line_num], gui->rights[line_num], gui->scales[line_num]); if (pi.the_staff == NULL) return TRUE; //could not place the cursor if (pi.the_measure != NULL) { /*don't place cursor in a place that is not there */ change_staff (gui->movement, pi.staff_number, pi.the_staff); gui->movement->currentmeasurenum = pi.measure_number; gui->movement->currentmeasure = pi.the_measure; gui->movement->currentobject = pi.the_obj; gui->movement->cursor_x = pi.cursor_x; gui->movement->cursor_appending = (gui->movement->cursor_x == (gint) (g_list_length ((objnode *) ((DenemoMeasure*)gui->movement->currentmeasure->data)->objects))); set_cursor_y_from_click (gui, event->y); if (lh_down & !selecting) { if (gui->movement->markstaffnum) set_point (NULL, NULL); else set_mark (NULL, NULL); selecting = TRUE; } calcmarkboundaries (gui->movement); if (event->state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) perform_command (event->state, GESTURE_MOVE, event->state & GDK_BUTTON1_MASK); /* redraw to show new cursor position */ draw_score_area(); } } if (Denemo.project->midi_destination & MIDICONDUCT) { advance_time (0.01); return TRUE; } return TRUE; }
static void SDL_handle_events(void) { SDL_Event event; assert(pthread_equal(pthread_self(), dosemu_pthread_self)); if (render_is_updating()) return; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_WINDOWEVENT: switch (event.window.event) { case SDL_WINDOWEVENT_FOCUS_GAINED: v_printf("SDL: focus in\n"); render_gain_focus(); if (config.X_background_pause && !dosemu_user_froze) unfreeze_dosemu(); break; case SDL_WINDOWEVENT_FOCUS_LOST: v_printf("SDL: focus out\n"); render_lose_focus(); if (config.X_background_pause && !dosemu_user_froze) freeze_dosemu(); break; case SDL_WINDOWEVENT_RESIZED: /* very strange things happen: if renderer size was explicitly * set, SDL reports mouse coords relative to that. Otherwise * it reports mouse coords relative to the window. */ SDL_RenderGetLogicalSize(renderer, &m_x_res, &m_y_res); if (!m_x_res || !m_y_res) { m_x_res = event.window.data1; m_y_res = event.window.data2; } update_mouse_coords(); SDL_redraw(); break; case SDL_WINDOWEVENT_EXPOSED: SDL_redraw(); break; case SDL_WINDOWEVENT_ENTER: /* ignore fake enter events */ if (config.X_fullscreen) break; mouse_drag_to_corner(m_x_res, m_y_res); break; } break; case SDL_KEYDOWN: { if (wait_kup) break; SDL_Keysym keysym = event.key.keysym; if ((keysym.mod & KMOD_CTRL) && (keysym.mod & KMOD_ALT)) { if (keysym.sym == SDLK_HOME || keysym.sym == SDLK_k) { force_grab = 0; toggle_grab(keysym.sym == SDLK_k); break; } else if (keysym.sym == SDLK_f) { toggle_fullscreen_mode(); /* some versions of SDL re-send the keydown events after the * full-screen switch. We need to filter them out to prevent * the infinite switching loop. */ wait_kup = 1; break; } } if (vga.mode_class == TEXT && (keysym.sym == SDLK_LSHIFT || keysym.sym == SDLK_RSHIFT)) { copypaste = 1; /* enable cursor for copy/paste */ if (!m_cursor_visible) SDL_ShowCursor(SDL_ENABLE); } } #if CONFIG_SDL_SELECTION clear_if_in_selection(); #endif #ifdef X_SUPPORT #if HAVE_XKB if (x11_display && config.X_keycode) SDL_process_key_xkb(x11_display, event.key); else #endif #endif SDL_process_key(event.key); break; case SDL_KEYUP: { SDL_Keysym keysym = event.key.keysym; wait_kup = 0; if (copypaste && (keysym.sym == SDLK_LSHIFT || keysym.sym == SDLK_RSHIFT)) { copypaste = 0; if (!m_cursor_visible) SDL_ShowCursor(SDL_DISABLE); } #ifdef X_SUPPORT #if HAVE_XKB if (x11_display && config.X_keycode) SDL_process_key_xkb(x11_display, event.key); else #endif #endif SDL_process_key(event.key); break; } case SDL_MOUSEBUTTONDOWN: { int buttons = SDL_GetMouseState(NULL, NULL); #if CONFIG_SDL_SELECTION if (window_has_focus() && !shift_pressed()) { clear_selection_data(); } else if (vga.mode_class == TEXT && !grab_active) { if (event.button.button == SDL_BUTTON_LEFT) start_selection(x_to_col(event.button.x, m_x_res), y_to_row(event.button.y, m_y_res)); else if (event.button.button == SDL_BUTTON_RIGHT) start_extend_selection(x_to_col(event.button.x, m_x_res), y_to_row(event.button.y, m_y_res)); else if (event.button.button == SDL_BUTTON_MIDDLE) { char *paste = SDL_GetClipboardText(); if (paste) paste_text(paste, strlen(paste), "utf8"); } break; } #endif /* CONFIG_SDL_SELECTION */ mouse_move_buttons(buttons & SDL_BUTTON(1), buttons & SDL_BUTTON(2), buttons & SDL_BUTTON(3)); break; } case SDL_MOUSEBUTTONUP: { int buttons = SDL_GetMouseState(NULL, NULL); #if CONFIG_SDL_SELECTION if (vga.mode_class == TEXT && !grab_active) { t_unicode *sel = end_selection(); if (sel) { char *send_text = get_selection_string(sel, "utf8"); SDL_SetClipboardText(send_text); free(send_text); } } #endif /* CONFIG_SDL_SELECTION */ mouse_move_buttons(buttons & SDL_BUTTON(1), buttons & SDL_BUTTON(2), buttons & SDL_BUTTON(3)); break; } case SDL_MOUSEMOTION: #if CONFIG_SDL_SELECTION extend_selection(x_to_col(event.motion.x, m_x_res), y_to_row(event.motion.y, m_y_res)); #endif /* CONFIG_SDL_SELECTION */ if (grab_active) mouse_move_relative(event.motion.xrel, event.motion.yrel, m_x_res, m_y_res); else mouse_move_absolute(event.motion.x, event.motion.y, m_x_res, m_y_res); break; case SDL_MOUSEWHEEL: mouse_move_wheel(-event.wheel.y); break; case SDL_QUIT: leavedos(0); break; default: v_printf("PAS ENCORE TRAITE %x\n", event.type); /* TODO */ break; } } #ifdef X_SUPPORT if (x11_display && !use_bitmap_font && vga.mode_class == TEXT && X_handle_text_expose()) { /* need to check separately because SDL_VIDEOEXPOSE is eaten by SDL */ redraw_text_screen(); } #endif }