コード例 #1
0
ファイル: display.c プロジェクト: L-ios/ibus-fbterm
static void calculate_status_win()
{
	if (!property_list) {
		status_bar_win.w = 0;
		return;
	}

	unsigned i, w = 0;
	for (i = 0; ; i++) {
		IBusProperty *prop = ibus_prop_list_get(property_list, i);
		if (!prop) break;

		w += text_width(prop->label->text);
	}

	status_bar_win.x = cursor_x;
	status_bar_win.y = get_cursor_y() + 2 * WIN_INTERVAL + GAP;
	status_bar_win.w = FW(w + property_list->properties->len) + 2 * MARGIN;
	status_bar_win.h = WIN_HEIGHT;

	if (status_bar_win.x + status_bar_win.w > SW) {
		if (status_bar_win.w > SW) status_bar_win.x = 0;
		else status_bar_win.x = SW - status_bar_win.w;
	}
}
コード例 #2
0
ファイル: display.c プロジェクト: L-ios/ibus-fbterm
static void calculate_lookup_win()
{
	if (!lookup_table) {
		lookup_table_win.w = 0;
		return;
	}

	unsigned i, w = 0;
	for (i = 0; ; i++) {
		IBusText *text = ibus_lookup_table_get_candidate(lookup_table, i);
		if (!text) break;

		w += text_width(text->text);
	}

	lookup_table_win.x = cursor_x;
	lookup_table_win.y = get_cursor_y() + WIN_INTERVAL + GAP;
	lookup_table_win.w = FW(w + 3 * lookup_table->page_size) + 2 * MARGIN;
	lookup_table_win.h = WIN_HEIGHT;

	if (lookup_table_win.x + lookup_table_win.w > SW) {
		if (lookup_table_win.w > SW) lookup_table_win.x = 0;
		else lookup_table_win.x = SW - lookup_table_win.w;
	}
}
コード例 #3
0
ファイル: edit.cpp プロジェクト: sidpoison/dokun
void Edit::on_enter()
{
#ifdef __windows__
    if(Keyboard::is_pressed(0x0D))
#endif	
#ifdef __gnu_linux__	
	if(Keyboard::is_pressed(0xff0d))
#endif		
	{
		if(is_multilined()) // a multilined editor
		{
			if(get_text().length() >= get_character_limit()) // if text length has reached character_limit
			{
				// double the height of the edit
				set_height(get_height() * 2); // GOOD!
				// add to the character_limit (new character_limit)
				set_character_limit(get_character_limit() + get_character_limit());  // ???
				// newline???
				set_text(get_text() + "\n");
				// reset cursor x position
				set_cursor_x(0);
				// set cursor y position
				int char_height = 12;
				set_cursor_y(get_cursor_y() + char_height);
			}
		}
	}	
}
コード例 #4
0
ファイル: bcpan.C プロジェクト: Cuchulain/cinelerra
int BC_Pan::button_press_event()
{
	// there are two modes of operation...
	if (popup)
	{	if (popup->is_event_win() && get_button_down() && get_buttonpress() == 1)
		{
			active = 1;
			x_origin = popup->get_cursor_x();
			y_origin = popup->get_cursor_y();
			stick_x_origin = stick_x;
			stick_y_origin = stick_y;
			return 1;
		} else
		{
			deactivate();
			return 0;
		}
	}
	if(is_event_win() && get_button_down() && get_buttonpress() == 1)
	{
		hide_tooltip();
		activate();
		active = 1;
		x_origin = get_cursor_x();
		y_origin = get_cursor_y();
		stick_x_origin = stick_x;
		stick_y_origin = stick_y;
		draw_popup();
		return 1;
	}
	return 0;
}
コード例 #5
0
ファイル: bcpot.C プロジェクト: Cuchulain/cinelerra
int BC_Pot::cursor_motion_event()
{
	if(top_level->button_down &&
		top_level->event_win == win &&
		status == POT_DN)
	{
		float angle = coords_to_angle(get_cursor_x(), get_cursor_y());

		if(prev_angle >= 0 && prev_angle < 90 &&
			angle >= 270 && angle < 360)
		{
			angle_correction -= 360;
		}
		else
		if(prev_angle >= 270 && prev_angle < 360 &&
			angle >= 0 && angle < 90)
		{
			angle_correction += 360;
		}

		prev_angle = angle;

		if(percentage_to_value(
			angle_to_percentage(angle + angle_correction - angle_offset)))
		{
			set_tooltip(get_caption());
			draw(1);
			handle_event();
		}
		return 1;
	}
	return 0;
}
コード例 #6
0
int CompressorCanvas::cursor_motion_event()
{
	if(current_operation == DRAG)
	{
		int x = get_cursor_x();
		int y = get_cursor_y();
		CLAMP(x, 0, get_w());
		CLAMP(y, 0, get_h());
		double x_db = (double)(1 - (double)x / get_w()) * plugin->config.min_db;
		double y_db = (double)y / get_h() * plugin->config.min_db;
		plugin->config.levels.values[current_point].x = x_db;
		plugin->config.levels.values[current_point].y = y_db;
		((CompressorWindow*)plugin->thread->window)->update();
		plugin->send_configure_change();
		return 1;
//plugin->config.dump();
	}
	else
// Change cursor over points
	if(is_event_win() && cursor_inside())
	{
		int new_cursor = CROSS_CURSOR;

		for(int i = 0; i < plugin->config.levels.total; i++)
		{
			double x_db = plugin->config.get_x(i);
			double y_db = plugin->config.get_y(i);

			int x = (int)(((double)1 - x_db / plugin->config.min_db) * get_w());
			int y = (int)(y_db / plugin->config.min_db * get_h());

			if(get_cursor_x() < x + POINT_W / 2 && get_cursor_x() >= x - POINT_W / 2 &&
				get_cursor_y() < y + POINT_W / 2 && get_cursor_y() >= y - POINT_W / 2)
			{
				new_cursor = UPRIGHT_ARROW_CURSOR;
				break;
			}
		}


		if(new_cursor != get_cursor())
		{
			set_cursor(new_cursor, 0, 1);
		}
	}
	return 0;
}
コード例 #7
0
void TimeBar::update(int flush)
{
	draw_time();
// Need to redo these when range is drawn to get the background updated.
	update_labels();
	update_points();


 	EDL *edl = get_edl();
	int64_t pixel = -1;

// Draw highlight position
	if(edl &&
		(highlighted || current_operation == TIMEBAR_DRAG) &&
		get_cursor_x() >= 0 &&
		get_cursor_y() < get_w())
	{
//printf("TimeBar::update %d %d\n", __LINE__, get_cursor_x());
		double position = pixel_to_position(get_cursor_x());

		position = get_edl()->align_to_frame(position, 0);
		pixel = position_to_pixel(position);
		update_clock(position);
	}

	if(pixel < 0) 
	{
		double position = test_highlight();
		if(position >= 0) pixel = position_to_pixel(position);
	}


	if(pixel >= 0 && pixel < get_w())
	{
		set_color(mwindow->theme->timebar_cursor_color);
		set_line_dashes(1);
//printf("TimeBar::update %d pane=%d pixel=%jd\n", __LINE__, pane->number, pixel);
		draw_line(pixel, 0, pixel, get_h());
		set_line_dashes(0);
	}
	

 	if(edl)
 	{
 		int64_t pixel = position_to_pixel(
 			edl->local_session->get_selectionstart(1));
// Draw insertion point position.
 		set_color(mwindow->theme->timebar_cursor_color);
 		draw_line(pixel, 0, pixel, get_h());
 	}

	update_highlights();

// Get the labels to show	
	show_window(0);
	flash(flush);
//printf("TimeBar::update %d this=%p %d\n", __LINE__, this, current_operation);
}
コード例 #8
0
int RecordMonitorCanvas::cursor_motion_event()
{
//SET_TRACE
	if( window->current_operation == MONITOR_TRANSLATE ) {
//SET_TRACE
		record->set_translation(
			get_cursor_x() - window->cursor_x_origin + window->translate_x_origin,
			get_cursor_y() - window->cursor_y_origin + window->translate_y_origin);
//SET_TRACE
	}

	return 0;
}
コード例 #9
0
ファイル: scopewindow.C プロジェクト: Cuchulain/cinelerra
int ScopePanel::cursor_motion_event()
{
	if(is_dragging)
	{
		int x = get_cursor_x();
		int y = get_cursor_y();
		CLAMP(x, 0, get_w() - 1);
		CLAMP(y, 0, get_h() - 1);
		update_point(x, y);
		return 1;
	}
	return 0;
}
コード例 #10
0
int RecordMonitorCanvas::button_press_event()
{

	if(Canvas::button_press_event()) return 1;
	if( mwindow->edl->session->vconfig_in->driver == SCREENCAPTURE ) {
		window->current_operation = MONITOR_TRANSLATE;
		window->translate_x_origin = record->video_x;
		window->translate_y_origin = record->video_y;
		window->cursor_x_origin = get_cursor_x();
		window->cursor_y_origin = get_cursor_y();
	}

	return 0;
}
コード例 #11
0
int CompressorCanvas::button_press_event()
{
// Check existing points
	if(is_event_win() && cursor_inside())
	{
		for(int i = 0; i < plugin->config.levels.total; i++)
		{
			double x_db = plugin->config.get_x(i);
			double y_db = plugin->config.get_y(i);

			int x = (int)(((double)1 - x_db / plugin->config.min_db) * get_w());
			int y = (int)(y_db / plugin->config.min_db * get_h());

			if(get_cursor_x() < x + POINT_W / 2 && get_cursor_x() >= x - POINT_W / 2 &&
				get_cursor_y() < y + POINT_W / 2 && get_cursor_y() >= y - POINT_W / 2)
			{
				current_operation = DRAG;
				current_point = i;
				return 1;
			}
		}



// Create new point
		double x_db = (double)(1 - (double)get_cursor_x() / get_w()) * plugin->config.min_db;
		double y_db = (double)get_cursor_y() / get_h() * plugin->config.min_db;

		current_point = plugin->config.set_point(x_db, y_db);
		current_operation = DRAG;
		((CompressorWindow*)plugin->thread->window)->update();
		plugin->send_configure_change();
		return 1;
	}
	return 0;
//plugin->config.dump();
}
コード例 #12
0
ファイル: bcpan.C プロジェクト: Cuchulain/cinelerra
int BC_Pan::cursor_motion_event()
{
	if(popup && get_button_down() && get_buttonpress() == 1)
	{
		stick_x = stick_x_origin + get_cursor_x() - x_origin;
		stick_y = stick_y_origin + get_cursor_y() - y_origin;
		CLAMP(stick_x, 0, virtual_r * 2);
		CLAMP(stick_y, 0, virtual_r * 2);
		stick_to_values();
		draw_popup();
		handle_event();
		return 1;
	}
	return 0;
}
コード例 #13
0
ファイル: cls.c プロジェクト: ZefyerSoftware/LibFalcon
void cls() {
  unsigned char cursor_x = get_cursor_x();
  unsigned char cursor_y = get_cursor_y();
  unsigned short *video_memory = get_video_memory();
  unsigned char attributeByte = (0 << 4) | (15 & 0x0F);
  unsigned short blank = 0x20 | (attributeByte << 8);

  int i;
  for (i = 0; i < 80 * 25; i++) {
    video_memory[i] = blank;
  }

  cursor_x = 0;
  cursor_y = 0;
  move_cursor();
}
コード例 #14
0
ファイル: scopewindow.C プロジェクト: Cuchulain/cinelerra
int ScopePanel::button_press_event()
{
	if(is_event_win() && cursor_inside())
	{
		gui->clear_points(1);
	
		is_dragging = 1;
		int x = get_cursor_x();
		int y = get_cursor_y();
		CLAMP(x, 0, get_w() - 1);
		CLAMP(y, 0, get_h() - 1);
		update_point(x, y);
		return 1;
	}
	return 0;
}
コード例 #15
0
ファイル: display.c プロジェクト: L-ios/ibus-fbterm
static void calculate_auxiliary_win()
{
	if (!auxiliary_text) {
		auxiliary_text_win.w = 0;
		return;
	}

	auxiliary_text_win.x = cursor_x;
	auxiliary_text_win.y = get_cursor_y() + GAP;
	auxiliary_text_win.w = FW(text_width(auxiliary_text->text)) + 2 * MARGIN;
	auxiliary_text_win.h = WIN_HEIGHT;

	if (auxiliary_text_win.x + auxiliary_text_win.w > SW) {
		if (auxiliary_text_win.w > SW) auxiliary_text_win.x = 0;
		else auxiliary_text_win.x = SW - auxiliary_text_win.w;
	}
}
コード例 #16
0
int PerspectiveCanvas::cursor_motion_event()
{
	if(state != PerspectiveCanvas::NONE)
	{
		int w = get_w() - 1;
		int h = get_h() - 1;
		if(state == PerspectiveCanvas::DRAG)
		{
			plugin->set_current_x((float)(get_cursor_x() - start_cursor_x) / w * 100 + start_x1);
			plugin->set_current_y((float)(get_cursor_y() - start_cursor_y) / h * 100 + start_y1);
		}
		else
		if(state == PerspectiveCanvas::DRAG_FULL)
		{
			plugin->config.x1 = ((float)(get_cursor_x() - start_cursor_x) / w * 100 + start_x1);
			plugin->config.y1 = ((float)(get_cursor_y() - start_cursor_y) / h * 100 + start_y1);
			plugin->config.x2 = ((float)(get_cursor_x() - start_cursor_x) / w * 100 + start_x2);
			plugin->config.y2 = ((float)(get_cursor_y() - start_cursor_y) / h * 100 + start_y2);
			plugin->config.x3 = ((float)(get_cursor_x() - start_cursor_x) / w * 100 + start_x3);
			plugin->config.y3 = ((float)(get_cursor_y() - start_cursor_y) / h * 100 + start_y3);
			plugin->config.x4 = ((float)(get_cursor_x() - start_cursor_x) / w * 100 + start_x4);
			plugin->config.y4 = ((float)(get_cursor_y() - start_cursor_y) / h * 100 + start_y4);
		}
		else
		if(state == PerspectiveCanvas::ZOOM)
		{
			float center_x = (start_x1 +
				start_x2 +
				start_x3 +
				start_x4) / 4;
			float center_y = (start_y1 +
				start_y2 +
				start_y3 +
				start_y4) / 4;
			float zoom = (float)(get_cursor_y() - start_cursor_y + 640) / 640;
			plugin->config.x1 = center_x + (start_x1 - center_x) * zoom;
			plugin->config.y1 = center_y + (start_y1 - center_y) * zoom;
			plugin->config.x2 = center_x + (start_x2 - center_x) * zoom;
			plugin->config.y2 = center_y + (start_y2 - center_y) * zoom;
			plugin->config.x3 = center_x + (start_x3 - center_x) * zoom;
			plugin->config.y3 = center_y + (start_y3 - center_y) * zoom;
			plugin->config.x4 = center_x + (start_x4 - center_x) * zoom;
			plugin->config.y4 = center_y + (start_y4 - center_y) * zoom;
		}
		plugin->thread->window->update_canvas();
		plugin->thread->window->update_coord();
		plugin->send_configure_change();
		return 1;
	}

	return 0;
}
コード例 #17
0
ファイル: bcpot.C プロジェクト: Cuchulain/cinelerra
int BC_Pot::button_press_event()
{
	if(!tooltip_on) top_level->hide_tooltip();
	if(top_level->event_win == win && enabled)
	{
		if(status == POT_HIGH || status == POT_UP)
		{
			if(get_buttonpress() == 4)
			{
				increase_value();
				show_value_tooltip();
				draw(1);
				handle_event();
			}
			else
			if(get_buttonpress() == 5)
			{
				decrease_value();
				show_value_tooltip();
				draw(1);
				handle_event();
			}
			else
			{
				status = POT_DN;
				start_cursor_angle = coords_to_angle(get_cursor_x(), get_cursor_y());
				start_needle_angle = percentage_to_angle(get_percentage());
				angle_offset = start_cursor_angle - start_needle_angle;
				prev_angle = start_cursor_angle;
				angle_correction = 0;
				draw(1);
				top_level->deactivate();
				top_level->active_subwindow = this;
				show_value_tooltip();
			}
			return 1;
		}
	}
	return 0;
}
コード例 #18
0
int PerspectiveCanvas::button_press_event()
{
	if(is_event_win() && cursor_inside())
	{
// Set current point
		int x1, y1, x2, y2, x3, y3, x4, y4;
		int cursor_x = get_cursor_x();
		int cursor_y = get_cursor_y();
		plugin->thread->window->calculate_canvas_coords(x1, y1, x2, y2, x3, y3, x4, y4);

		float distance1 = DISTANCE(cursor_x, cursor_y, x1, y1);
		float distance2 = DISTANCE(cursor_x, cursor_y, x2, y2);
		float distance3 = DISTANCE(cursor_x, cursor_y, x3, y3);
		float distance4 = DISTANCE(cursor_x, cursor_y, x4, y4);
// printf("PerspectiveCanvas::button_press_event %f %d %d %d %d\n", 
// distance3,
// cursor_x,
// cursor_y,
// x3,
// y3);
		float min = distance1;
		plugin->config.current_point = 0;
		if(distance2 < min)
		{
			min = distance2;
			plugin->config.current_point = 1;
		}
		if(distance3 < min)
		{
			min = distance3;
			plugin->config.current_point = 2;
		}
		if(distance4 < min)
		{
			min = distance4;
			plugin->config.current_point = 3;
		}

		if(plugin->config.mode == AffineEngine::SHEER)
		{
			if(plugin->config.current_point == 1)
				plugin->config.current_point = 0;
			else
			if(plugin->config.current_point == 2)
				plugin->config.current_point = 3;
		}
		start_cursor_x = cursor_x;
		start_cursor_y = cursor_y;

		if(alt_down() || shift_down())
		{
			if(alt_down())
				state = PerspectiveCanvas::DRAG_FULL;
			else
				state = PerspectiveCanvas::ZOOM;

// Get starting positions
			start_x1 = plugin->config.x1;
			start_y1 = plugin->config.y1;
			start_x2 = plugin->config.x2;
			start_y2 = plugin->config.y2;
			start_x3 = plugin->config.x3;
			start_y3 = plugin->config.y3;
			start_x4 = plugin->config.x4;
			start_y4 = plugin->config.y4;
		}
		else
		{
			state = PerspectiveCanvas::DRAG;

// Get starting positions
			start_x1 = plugin->get_current_x();
			start_y1 = plugin->get_current_y();
		}
		plugin->thread->window->update_coord();
		plugin->thread->window->update_canvas();
		return 1;
	}

	return 0;
}
コード例 #19
0
ファイル: printf.c プロジェクト: SHyx0rmZ/kernel3
/**
 * Prints a character to the screen, is used
 * by kprintf and kputs
 *
 * @param c Character to print
 **/
void kputch(unsigned char c)
{
    unsigned short *where;
    unsigned att = get_attribute() << 8;


    if(c == 0x08)
    {
		/// ! SELBER SCHREIBEN !
        if(get_cursor_x() != 0) set_cursor_x(get_cursor_x() - 1);
    }

	//
    else if(c == 0x09)
    {
        int newx;

		/// ! SELBER SCHREIBEN !
        newx = (get_cursor_x() + 8) & ~(8 - 1);

        set_cursor_x(newx);
    }

	// Carriage return? Set the cursor to the beginning of the current line
    else if(c == '\r')
    {
		/// ! SELBER SCHREIBEN !
        set_cursor_x(0);
    }

	// Linefeed? Set the cursor to the next line
    else if(c == '\n')
    {
		/// ! SELBER SCHREIBEN !
        set_cursor_x(0);
        set_cursor_y(get_cursor_y() + 1);
    }

    else if(c >= ' ')
    {
		/// ! SELBER SCHREIBEN !
        //FIXME: get_textmemptr() doesn't work here (whyever...)
        where = (unsigned short*)0xB8000 + (get_cursor_y() * 80 + get_cursor_x());
        *where = c | att;
        set_cursor_x(get_cursor_x() + 1);
    }

	/// ! SELBER SCHREIBEN !

    // More than 80 lines? Scroll the screen
    if(get_cursor_x() >= 80)
    {
        set_cursor_x(0);
        set_cursor_y(get_cursor_y() + 1);
    }

	/// ! SELBER SCHREIBEN !

    // Scroll the screen and move the cursor
    scroll_screen();
    move_cursor();
}
コード例 #20
0
ファイル: game.cpp プロジェクト: Gaxx42/Purgatory
void Game::handle_events(Player *player)
{
    SDL_Rect    *tmp;
    Box         *tmpbox;

    //The mouse offsets
    int32_t x = 0;
    int32_t y = 0;

    //Handle events for player
    //If a key was pressed
    if( event.type == SDL_KEYDOWN )
    {
        //Adjust the velocity
        switch( event.key.keysym.sym )
        {
            case SDLK_UP:
                player->jump();
                break;
            case SDLK_LEFT:
                player->set_x_vel(player->get_x_vel() - PLAYER_VEL);
                break;
            case SDLK_RIGHT:
                player->set_x_vel(player->get_x_vel() + PLAYER_VEL);
                break;
            default:
                break;
        }
    }
    //If a key was released
    else if( event.type == SDL_KEYUP )
    {
        //Adjust the velocity
        switch( event.key.keysym.sym )
        {
            case SDLK_UP:
                //Nothing to do here really. Set some flags maybe.
                break;
            case SDLK_LEFT:
                player->set_x_vel(player->get_x_vel() + PLAYER_VEL);
                break;
            case SDLK_RIGHT:
                player->set_x_vel(player->get_x_vel() - PLAYER_VEL);
                break;
            default:
                break;
        }
    }
    //If a mouse button was pressed
    else if( event.type == SDL_MOUSEBUTTONDOWN )
    {
        //If the left mouse button was pressed
        if( event.button.button == SDL_BUTTON_LEFT )
        {
            mouseleft_flag = YES;
        }
        //If the right mouse button was pressed
        if( event.button.button == SDL_BUTTON_RIGHT )
        {
            mouseright_flag = YES;
        }
    }
    else if( event.type == SDL_MOUSEBUTTONUP )
    {
        //If the left mouse button was pressed
        if( event.button.button == SDL_BUTTON_LEFT )
        {
            mouseleft_flag = NO;
        }
        //If the right mouse button was pressed
        if( event.button.button == SDL_BUTTON_RIGHT )
        {
            mouseright_flag = NO;
        }
    }
    //If mouse moved
    else if( event.type == SDL_MOUSEMOTION )
    {
        set_cursor(event.button.x, event.button.y);
    }
    if(mouseleft_flag == YES)
    {
        //Get the mouse offsets
        x = get_cursor_x() + camera_x();
        y = get_cursor_y() + camera_y();

        add(new Box(x,y,DEF_BOX_SIZE,DEF_BOX_SIZE, YES));
    }
    if(mouseright_flag == YES)
    {
        SDL_Rect eraser;
        //Get the mouse offsets
        eraser.x = get_cursor_x() + camera_x();
        eraser.y = get_cursor_y() + camera_y();
        eraser.h = DEF_BOX_SIZE;
        eraser.w = DEF_BOX_SIZE;
        //If the mouse is over the box
        start_over();
        while(get_curr())
        {
            tmpbox = get_curr();
            if(tmpbox != NULL)
            {
                tmp = tmpbox->get_box();
            }

            if(check_collision(tmp, &eraser))
            {
                remove();
            }
            traverse();
        }

    }


}
コード例 #21
0
void GraphicCanvas::process(int buttonpress, int motion, int draw)
{
	int got_button = 0;
	int center_y = get_h() / 2;
	int out_of_order = 0;
	ArrayList<GraphicPoint*> *points;
	double *envelope;
	const int debug = 0;


	if(state == GraphicCanvas::NONE)
	{
		points = &plugin->config.points;
		envelope = plugin->envelope;
	}
	else
	{
		points = &temp_points;
		envelope = temp_envelope;
	}

	plugin->calculate_envelope(points, envelope);


// spectrogram
	if(draw)
	{
		clear_box(0, 0, get_w(), get_h());


		int niquist = plugin->PluginAClient::project_sample_rate / 2;
		int total_frames = plugin->get_gui_update_frames();
		GraphicGUIFrame *frame = (GraphicGUIFrame*)plugin->get_gui_frame();

		if(frame)
		{
			delete plugin->last_frame;
			plugin->last_frame = frame;
		}
		else
		{
			frame = plugin->last_frame;
		}

// Draw most recent frame
		if(frame)
		{
			set_color(MEGREY);
			int y1 = 0;
			int y2 = 0;


			for(int i = 0; i < get_w(); i++)
			{
				int freq = Freq::tofreq(i * TOTALFREQS / get_w());
				int index = (int64_t)freq * (int64_t)frame->window_size / 2 / niquist;
				if(index < frame->window_size / 2)
				{
					double magnitude = frame->data[index] / 
						frame->freq_max * 
						frame->time_max;
					y2 = (int)(get_h() - 
						(DB::todb(magnitude) - INFINITYGAIN) *
						get_h() / 
						-INFINITYGAIN);
					CLAMP(y2, 0, get_h() - 1);
					if(i > 0)
					{
						draw_line(i - 1, y1, i, y2);
//printf(" %.0f", frame->data[index]);
					}
					y1 = y2;
				}
			}
//printf( "\n");

			total_frames--;
		}






// Delete remaining frames
		while(total_frames > 0)
		{
			PluginClientFrame *frame = plugin->get_gui_frame();

			if(frame) delete frame;
			total_frames--;
		}
	}


// Determine if active point is out of order
	if(plugin->active_point_exists())
	{
		GraphicPoint *active_point = points->get(plugin->active_point);
		for(int i = 0; i < points->size(); i++)
		{
			if(i == plugin->active_point)
			{
				if(i < points->size() - 1 &&
					active_point->freq >= points->get(i + 1)->freq ||
					i > 0 &&
					active_point->freq <= points->get(i - 1)->freq)
				{
					out_of_order = 1;
				}
				break;
			}
		}
	}


	if(motion)
	{
		if(state == GraphicCanvas::DRAG_POINT)
		{
			int point_x = get_cursor_x() + x_diff;
			int point_y = get_cursor_y() + y_diff;
			CLAMP(point_x, 0, get_w());
			CLAMP(point_y, 0, get_h());
			
			int frequency = Freq::tofreq(point_x * TOTALFREQS / get_w());
			double magnitude_db = (double)(center_y - point_y) * MAXMAGNITUDE / center_y;
			int minfreq = Freq::tofreq(0);
			int maxfreq = Freq::tofreq(TOTALFREQS - 1);

			CLAMP(frequency, minfreq, maxfreq);
			CLAMP(magnitude_db, -MAXMAGNITUDE, MAXMAGNITUDE);
			if(plugin->active_point >= 0)
			{
				GraphicPoint *active_point = points->get(plugin->active_point);
				active_point->freq = frequency;
				active_point->value = magnitude_db;
			}

// Redraw with new value
			process(0, 0, 1);
			save_temps();
			plugin->send_configure_change();
			gui->update_textboxes();
			return;
		}
	}

// Magnitude bars
	if(draw)
	{
		set_color(GREEN);
		set_line_dashes(1);
		for(int i = 1; i < MAJOR_DIVISIONS; i++)
		{
			int y = i * get_h() / (MAJOR_DIVISIONS - 1);
			draw_line(0, y, get_w(), y);
		}
		set_line_dashes(0);
	}

	int y1 = 0;
	if(draw) set_color(WHITE);

// Control points, cursor change and control point selection
	int new_cursor = CROSS_CURSOR;
	for(int i = 0; i < points->size(); i++)
	{
		GraphicPoint *point = points->get(i);
		int x = Freq::fromfreq(point->freq) * get_w() / TOTALFREQS;
		int y = freq_to_y(point->freq, points, envelope);

		if(draw)
		{
			y1 = y;
// Draw point under cursor if out of order
			if(i == plugin->active_point && out_of_order) 
				y1 = get_cursor_y() + y_diff;

			if(i == plugin->active_point)
				draw_box(x - BOX_SIZE / 2, y1 - BOX_SIZE / 2, BOX_SIZE, BOX_SIZE);
			else
				draw_rectangle(x - BOX_SIZE / 2, y1 - BOX_SIZE / 2, BOX_SIZE, BOX_SIZE);
		}

		if(motion && 
			state == GraphicCanvas::NONE &&
			is_event_win() && 
			cursor_inside())
		{
			if(get_cursor_x() >= x - BOX_SIZE / 2 &&
				get_cursor_y() >= y - BOX_SIZE / 2 &&
				get_cursor_x() < x + BOX_SIZE / 2 &&
				get_cursor_y() < y + BOX_SIZE / 2)
			{
				new_cursor = UPRIGHT_ARROW_CURSOR;
			}
		}
		
		if(buttonpress &&
			state == GraphicCanvas::NONE &&
			is_event_win() && 
			cursor_inside() &&
			!got_button)
		{
			if(get_cursor_x() >= x - BOX_SIZE / 2 &&
				get_cursor_y() >= y - BOX_SIZE / 2 &&
				get_cursor_x() < x + BOX_SIZE / 2 &&
				get_cursor_y() < y + BOX_SIZE / 2)
			{
				plugin->active_point = i;
				state = GraphicCanvas::DRAG_POINT;
				new_temps();
				points = &temp_points;
				envelope = temp_envelope;

				x_diff = x - get_cursor_x();
				y_diff = y - get_cursor_y();
				got_button = 1;
				process(0, 0, 1);
				save_temps();
				plugin->send_configure_change();
				gui->update_textboxes();
			}
		}
	}

	if(motion && new_cursor != get_cursor())
	{
		set_cursor(new_cursor, 0, 1);
	}

// Envelope line;
	y1 = 0;
	set_line_width(2);
	for(int i = 0; i < get_w(); i++)
	{
		int y = freq_to_y(Freq::tofreq(i * TOTALFREQS / get_w()), 
			points, 
			envelope);

		if(draw)
		{
			if(i > 0) draw_line(i - 1, y1, i, y);
		}


		y1 = y;
	}
	set_line_width(1);

	if(buttonpress && !got_button)
	{
		if(is_event_win() && cursor_inside())
		{
			GraphicPoint *new_point = new GraphicPoint;
			new_point->freq = Freq::tofreq(get_cursor_x() * 
				TOTALFREQS / 
				get_w());
			new_point->value = (double)(center_y - get_cursor_y()) * 
				MAXMAGNITUDE / 
				center_y;
			state = GraphicCanvas::DRAG_POINT;
			new_temps();
			points = &temp_points;
			envelope = temp_envelope;

			insert_point(new_point);
			plugin->active_point = points->number_of(new_point);
			x_diff = 0;
			y_diff = 0;

// Redraw with new point
			process(0, 0, 1);
			save_temps();
			plugin->send_configure_change();
			gui->update_textboxes();
		}
	}


	if(draw) 
	{
		flash();
	}
}