https://bitbucket.org/hudson/magic-lantern
Raw File
Tip revision: c326bc9a68a6bde8f07621fd89cb1cf9c67080f4 authored by a1ex on 22 October 2013, 21:31:00 UTC
Close branch 60d.
Tip revision: c326bc9
gui.c
/** \file
 * Magic Lantern GUI main task.
 *
 * Overrides the DryOS gui_main_task() to be able to re-map events.
 */
/*
 * Copyright (C) 2009 Trammell Hudson <hudson+ml@osresearch.net>
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 */

#include "dryos.h"
#include "property.h"
#include "bmp.h"
#include "config.h"
#include "consts-60d.109.h"
#include "lens.h"

CONFIG_INT("swap.menu", swap_menu, 0);

void gui_unlock( void )
{
	//~ gui_lock( 0, 1, 2 );
	uint32_t x = 0x41000000;
	prop_request_change(0x80020009, &x, 4);
}


//~ int button_center_lvafframe = BGMT_PRESS_SET;

// halfshutter press is easier to detect from GUI events (PROP_HALFSHUTTER works only in LV mode)
int halfshutter_pressed = 0;
int get_halfshutter_pressed() 
{ 
	return halfshutter_pressed; 
}

int zoom_in_pressed = 0;
int zoom_out_pressed = 0;
//~ int set_pressed = 0;
int get_zoom_in_pressed() { return zoom_in_pressed; }
int get_zoom_out_pressed() { return zoom_out_pressed; }
//~ int get_set_pressed() { return set_pressed; }

struct semaphore * gui_sem;

int handle_buttons_active = 0;
struct event fake_event;
struct semaphore * fake_sem;


struct gui_main_struct {
	void *			obj;		// off_0x00;
	uint32_t		counter;	// off_0x04;
	uint32_t		off_0x08;
	uint32_t		counter_60d;    //off_0x0c;
	uint32_t		off_0x10;
	uint32_t		off_0x14;
	uint32_t		off_0x18;
	uint32_t		off_0x1c;
	uint32_t		off_0x20;
	uint32_t		off_0x24;
	uint32_t		off_0x28;
	uint32_t		off_0x2c;
	struct msg_queue *	msg_queue_60d;	// off_0x30;
	struct msg_queue *	msg_queue;	// off_0x34;
	struct msg_queue *	msg_queue_550d;	// off_0x38;
	uint32_t		off_0x3c;
};

extern struct gui_main_struct gui_main_struct;

struct gui_timer_struct
{
	void *			obj;	// off_0x00
};

extern struct gui_timer_struct gui_timer_struct;

extern void* gui_main_task_functbl;

//~ CONFIG_INT("set.on.halfshutter", set_on_halfshutter, 1);

// return 0 if you want to block this event
static int handle_buttons(struct event * event)
{

	if (event->type == 0 && event->param != 0x56)
 	{
		idle_wakeup_reset_counters();
 	}

	static int kev = 0;
	
	// volume adjust (FLASH + UP/DOWN) and ISO adjust (FLASH + LEFT/RIGHT)
	/*
	if (shooting_mode == SHOOTMODE_MOVIE && gui_state == GUISTATE_IDLE && FLASH_BTN_MOVIE_MODE)
	{
		if (event->type == 0 && event->param == BGMT_PRESS_UP)
		{
			volume_up();
			falsecolor_cancel();
			return 0;
		}
		if (event->type == 0 && event->param == BGMT_PRESS_DOWN)
		{
			volume_down();
			falsecolor_cancel();
			return 0;
		}
		if (event->type == 0 && event->param == BGMT_PRESS_LEFT)
		{
			iso_toggle(-1);
			falsecolor_cancel();
			return 0;
		}
		if (event->type == 0 && event->param == BGMT_PRESS_RIGHT)
		{
			iso_toggle(1);
			falsecolor_cancel();
			return 0;
		}
	}*/
	

	if (swap_menu && event != &fake_event)
	{
		if (event->type == 0 && event->param == BGMT_TRASH)
		{
			fake_simple_button(BGMT_MENU);
			return 0;
		}
		if (event->type == 0 && event->param == BGMT_MENU)
		{
			fake_simple_button(BGMT_TRASH);
			return 0;
		}
	}
	
	if (event->type == 0 && event->param == BGMT_TRASH)
	{
		if (!gui_menu_shown() && gui_state == GUISTATE_IDLE) 
		{
			give_semaphore( gui_sem );
			return 0;
		}
		else if (gui_menu_shown())
		{
			gui_stop_menu();
			return 0;
		}
	}

	if (event->type == 0 && event->param == BGMT_UNLOCK && MENU_MODE)
	{
		if (!gui_menu_shown()) 
		{
			give_semaphore( gui_sem );
			return 0;
		}
		else if (gui_menu_shown())
		{
			gui_stop_menu();
			return 0;
		}
	}
	
	if (get_draw_event())
	{
		if (event->type == 0)
		{
			kev++;
			bmp_printf(FONT_SMALL, 0, 400, "Ev%d[%d]: p=%8x *o=%8x/%8x/%8x a=%8x", 
				kev,
				event->type, 
				event->param, 
				event->obj ? ((int)event->obj & 0xf0000000 ? (int)event->obj : *(int*)(event->obj)) : 0,
				event->obj ? ((int)event->obj & 0xf0000000 ? (int)event->obj : *(int*)(event->obj + 4)) : 0,
				event->obj ? ((int)event->obj & 0xf0000000 ? (int)event->obj : *(int*)(event->obj + 8)) : 0,
				event->arg);
/*			console_printf("Ev%d[%d]: p=%8x *o=%8x/%8x/%8x a=%8x\ns", 
				kev,
				event->type, 
				event->param, 
				event->obj ? ((int)event->obj & 0xf0000000 ? event->obj : *(uint32_t*)(event->obj)) : 0,
				event->obj ? ((int)event->obj & 0xf0000000 ? event->obj : *(uint32_t*)(event->obj + 4)) : 0,
				event->obj ? ((int)event->obj & 0xf0000000 ? event->obj : *(uint32_t*)(event->obj + 8)) : 0,
				event->arg);*/
			//msleep(250);
		}
#if 0
		// simple debugging of memory location - focus data in memory maybe?
		static int ii = 0;
		ii++;
		bmp_printf(FONT_SMALL, 0, ii*15, "%08x %08x %08x %08x %08x", *(uint32_t*)(0x54B4), *(uint32_t*)(0x54B4+0xC), *(uint32_t*)(0x54B4+0x10), *(uint32_t*)(0x54B4+0x18), *(uint32_t*)(0x54B4+0x22));
		if (ii>30) ii = 0;
#endif

	}
	
	if (gui_menu_shown() && event->type == 0) // some buttons hard to detect from main menu loop
	{
		if (lv_drawn() && event->param == BGMT_UNPRESS_ZOOMIN_MAYBE)
		{
			gui_hide_menu( 2 );
			lens_focus_stop();
			return 0;
		}
		if (lv_drawn() && event->param == BGMT_PRESS_ZOOMIN_MAYBE)
		{
			gui_hide_menu( 50 );
			lens_focus_start( get_focus_dir() );
			return 0;
		}
	}
	if (gui_menu_shown())
	{
		if (event->type == 0 && event->param == 0x5a) return 0;
	}
	
	/*
	if (get_lcd_sensor_shortcuts() && event->type == 0 && display_sensor_neg == 0 && DISPLAY_SENSOR_POWERED) // button presses while display sensor is covered
	{ // those are shortcut keys
		if (!gui_menu_shown())
		{
			if (event->param == BGMT_PRESS_UP)
			{
				adjust_backlight_level(1);
				return 0;
			}
			else if (event->param == BGMT_PRESS_DOWN)
			{
				adjust_backlight_level(-1);
				return 0;
			}
		}
		if (lv_drawn())
		{
			if (event->param == BGMT_PRESS_LEFT)
			{
				kelvin_toggle(-1);
				return 0;
			}
			else if (event->param == BGMT_PRESS_RIGHT)
			{
				kelvin_toggle(1);
				return 0;
			}
		}
	}*/

	if (event->type == 0)
	{
		if (is_follow_focus_active() && !is_manual_focus() && !gui_menu_shown() && lv_drawn() && gui_state == GUISTATE_IDLE)
		{
			switch(event->param)
			{
				case BGMT_PRESS_LEFT:
					lens_focus_start(1 * get_follow_focus_dir_h());
					return 0;
				case BGMT_PRESS_RIGHT:
					lens_focus_start(-1 * get_follow_focus_dir_h());
					return 0;
				case BGMT_PRESS_UP:
					lens_focus_start(5 * get_follow_focus_dir_v());
					return 0;
				case BGMT_PRESS_DOWN:
					lens_focus_start(-5 * get_follow_focus_dir_v());
					return 0;
				case BGMT_UNPRESS_UDLR:
					lens_focus_stop();
					return 1;
			}
		}
	}
	
	if (event->type == 0)
	{
		if (event->param == BGMT_PRESS_HALFSHUTTER) halfshutter_pressed = 1;
		if (event->param == BGMT_UNPRESS_HALFSHUTTER) halfshutter_pressed = 0;
	}
	
	// force a SET press in photo mode when you adjust the settings and press half-shutter
	/*
	if (set_on_halfshutter && event->type == 0 && event->param == BGMT_PRESS_HALFSHUTTER && gui_state == GUISTATE_PLAYMENU && !lv_drawn() && !gui_menu_shown())
	{
		fake_simple_button(BGMT_PRESS_SET);
		fake_simple_button(BGMT_UNPRESS_SET);
	}*/
	
	// for faster zoom in in Play mode
	if (event->type == 0)
	{
		if (event->param == BGMT_PRESS_ZOOMIN_MAYBE) {zoom_in_pressed = 1; zoom_out_pressed = 0; }
		if (event->param == BGMT_UNPRESS_ZOOMIN_MAYBE) {zoom_in_pressed = 0; zoom_out_pressed = 0; }
		if (event->param == BGMT_PRESS_ZOOMOUT_MAYBE) { zoom_out_pressed = 1; zoom_in_pressed = 0; }
		if (event->param == BGMT_UNPRESS_ZOOMOUT_MAYBE) { zoom_out_pressed = 0; zoom_in_pressed = 0; }
 	}

	// override DISP button in LiveView mode
	
	/*if (event->type == 0 && event->param == BGMT_DISP && lv_drawn() && zebra_should_run())
	{
		if (lv_disp_mode == 0)
			return toggle_disp_mode();
		else
			schedule_disp_mode_change();
	}*/

	if (lv_drawn() && !gui_menu_shown() && event->type == 0 && event->param == BGMT_DISP)
	{
		redraw();
	}

	// MENU while recording => force a redraw
	if (recording && event->type == 0 && event->param == BGMT_MENU)
	{
		redraw();
	}
	
	// stop intervalometer with MENU or PLAY
	if (event->type == 0 && (event->param == BGMT_MENU || event->param == BGMT_PLAY) && !gui_menu_shown())
		intervalometer_stop();
		
	
	// zoom overlay
	
	if (get_zoom_overlay_mode() && recording == 2 && event->type == 0 && event->param == BGMT_UNPRESS_ZOOMIN_MAYBE)
	{
		zoom_overlay_toggle();
		return 0;
	}

	if (lv_drawn() && get_zoom_overlay() && event->type == 0 && event->param == BGMT_PRESS_ZOOMIN_MAYBE)
	{
		zoom_overlay_toggle();
		return 0;
	}

	if (lv_drawn() && get_zoom_overlay_mode() && event->type == 0 && lv_dispsize == 1 && event->param == BGMT_PRESS_ZOOMIN_MAYBE)
 	{
		// magic zoom toggled by zoom in
		if (get_zoom_overlay_mode() == 3 && !get_halfshutter_pressed())
		{
			zoom_overlay_toggle();
			return 0;
		}
 	}
	/*
	if (get_lcd_sensor_shortcuts() && get_zoom_overlay_z() && lv_dispsize == 1 && event->type == 0 && event->param == BGMT_PRESS_ZOOMIN_MAYBE && display_sensor_neg == 0 && DISPLAY_SENSOR_POWERED)
	{
		zoom_overlay_toggle();
		return 0;
	}*/
	
	/*
	if (recording && get_zoom_overlay_mode())
	{
		if (event->type == 0 && event->param == BGMT_PRESS_LEFT)
			move_lv_afframe(-200, 0);
		if (event->type == 0 && event->param == BGMT_PRESS_RIGHT)
			move_lv_afframe(200, 0);
		if (event->type == 0 && event->param == BGMT_PRESS_UP)
			move_lv_afframe(0, -200);
		if (event->type == 0 && event->param == BGMT_PRESS_DOWN)
			move_lv_afframe(0, 200);
	}*/


/*
	
	if (event->param == 0 && *(uint32_t*)(event->obj) == PROP_SHUTTER)
	{
		int value = *(int*)(event->obj + 4);
		bmp_printf(FONT_LARGE, 0, 0, "Tv %d", value);
		DEBUG("Tv %d", value);
	}
	if (event->param == 0 && *(uint32_t*)(event->obj) == PROP_APERTURE)
	{
		int value = *(int*)(event->obj + 4);
		bmp_printf(FONT_LARGE, 0, 0, "Av %d", value);
		DEBUG("Av %d", value);
		
		static int old = 0;
		
		if (old && lv_drawn())
		{
			if (display_sensor)
			{
				if (value != old)
				{
					int newiso = lens_info.raw_iso + value - old;
					if (newiso >= 72 && newiso <= 120)
					{
						lens_set_rawiso(newiso);
					}
					else return 0;
				}
			}
		}
		old = value; 

	}
	if (event->param == 5 && *(uint32_t*)(event->obj) == 0x80010001)
	{
		DEBUG("limit");
		bmp_printf(FONT_MED, 0, 0, "Limit %8x %8x %8x %8x", 
			*(uint32_t*)(event->obj + 4), 
			*(uint32_t*)(event->obj + 8), 
			event->param,
			event->arg);
	}
	
	*/
	
	// quick access to some menu items
	
	if (event->type == 0 && event->param == BGMT_Q && !gui_menu_shown())
	{
		if (CURRENT_DIALOG_MAYBE == DLG_ISO)
		{
			select_menu("Expo", 0);
			give_semaphore( gui_sem ); 
			return 0;
		}
		/*else if (CURRENT_DIALOG_MAYBE == DLG_WB)
		{
			select_menu("Expo", 1);
			give_semaphore( gui_sem ); 
			return 0;
		}
		else if (CURRENT_DIALOG_MAYBE == DLG_FOCUS_MODE)
		{
			select_menu("Shoot", 5);
			give_semaphore( gui_sem ); 
			return 0;
		}
		else if (CURRENT_DIALOG_MAYBE == DLG_DRIVE_MODE)
		{
			select_menu("Shoot", 3);
			give_semaphore( gui_sem ); 
			return 0;
		}
		else if (CURRENT_DIALOG_MAYBE == DLG_PICTURE_STYLE)
		{
			select_menu("Expo", 7);
			give_semaphore( gui_sem ); 
			return 0;
		}
		else if (CURRENT_DIALOG_MAYBE == DLG_FLASH_AE)
		{
			select_menu("Expo", 9);
			give_semaphore( gui_sem ); 
			return 0;
		}
		else if (CURRENT_DIALOG_MAYBE == DLG_PICQ)
		{
			select_menu("Debug", 2);
			give_semaphore( gui_sem ); 
			return 0;
		}
		else if (lv_dispsize > 1)
		{
			select_menu("LiveV", 7);
			give_semaphore( gui_sem ); 
			return 0;
		}*/
		
	}

	/*
	if (event->param == 0 && *(uint32_t*)(event->obj) == PROP_APERTURE)
	{
		int value = *(int*)(event->obj + 4);
		//~ bmp_printf(FONT_LARGE, 0, 0, "Av %d", value);
		//~ DEBUG("Av %d", value);
		
		static int old = 0;
		
		if (get_lcd_sensor_shortcuts() && get_dof_adjust() && old && lv_drawn())
		{
			if (display_sensor)
			{
				if (value != old)
				{
					int newiso = lens_info.raw_iso + value - old;
					if (newiso >= 72 && newiso <= 120)
					{
						lens_set_rawiso(newiso);
					}
					else return 0;
				}
			}
		}
		old = value; 
	}*/
	
	// movie mode shortcut
	if (event->type == 0 && event->param == BGMT_LV && (CURRENT_DIALOG_MAYBE == DLG_DRIVE_MODE || CURRENT_DIALOG_MAYBE == DLG_ISO || CURRENT_DIALOG_MAYBE == DLG_FOCUS_MODE || CURRENT_DIALOG_MAYBE == DLG_METERING))
	{
		if (shooting_mode != SHOOTMODE_MOVIE)
		{
			set_shooting_mode(SHOOTMODE_MOVIE);
			return 0;
		}
	}
	
	// enable LiveV stuff in Play mode
	if (event->type == 0 && PLAY_MODE)
	{
		if (event->param == BGMT_UNLOCK)
		{
			livev_playback_toggle();
			return 0;
		}
		else
			livev_playback_reset();
	}

	if (event->type == 0 && event->param == BGMT_LV && (gui_state == GUISTATE_QR || PLAY_MODE))
	{
		schedule_transparent_overlay();
		return 0;
	}

	// move transparent overlay
	extern int transparent_overlay;
	if (transparent_overlay && lv_drawn() && gui_state == GUISTATE_IDLE && !gui_menu_shown())
	{
		if (event->type == 0 && event->param == BGMT_PRESS_UP)
		{
			transparent_overlay_offset(0, -40);
			return 0;
		}
		if (event->type == 0 && event->param == BGMT_PRESS_DOWN)
		{
			transparent_overlay_offset(0, 40);
			return 0;
		}
		if (event->type == 0 && event->param == BGMT_PRESS_LEFT)
		{
			transparent_overlay_offset(-40, 0);
			return 0;
		}
		if (event->type == 0 && event->param == BGMT_PRESS_RIGHT)
		{
			transparent_overlay_offset(40, 0);
			return 0;
		}
		if (event->type == 0 && event->param == BGMT_PRESS_SET)
		{
			transparent_overlay_offset_clear();
			transparent_overlay_offset(0, 0);
			return 0;
		}
	}
	if (event->type == 0 && event->param == BGMT_PLAY)
	{
		extern int transparent_overlay;
		transparent_overlay = 0;
	}

	return 1;
}

// if called from handle_buttons, only last fake button will be executed
// if called from some other task, the function waits until the previous fake button was handled
void fake_simple_button(int bgmt_code)
{
	if (!handle_buttons_active) take_semaphore(fake_sem, 0);
	fake_event.type = 0,
	fake_event.param = bgmt_code, 
	fake_event.obj = 0,
	fake_event.arg = 0,
	msg_queue_post(gui_main_struct.msg_queue_60d, &fake_event, 0, 0);
}

static void gui_main_task_60d()
{
	fake_sem = create_named_semaphore("fake_sem", 1);
	bmp_sem_init();
	struct event * event = NULL;
	int index = 0;
	void* funcs[GMT_NFUNCS];
	memcpy(funcs, (void*)GMT_FUNCTABLE, 4*GMT_NFUNCS);
	gui_init_end();
	while(1)
	{
		msg_queue_receive(gui_main_struct.msg_queue_60d, &event, 0);
		gui_main_struct.counter_60d--;
		if (event == NULL) continue;
		index = event->type;
		if ((index >= GMT_NFUNCS) || (index < 0))
			continue;

		//~ if (event->type != 2)
			//~ console_printf("%d %d %d\n", event->type, event->param, event->arg);
		
		if (!magic_is_off())
		{
			handle_buttons_active = 1;
			int should_handle = handle_buttons(event);
			handle_buttons_active = 0;
			
			if (should_handle == 0) 
				goto bottom;
		}
		
		BMP_SEM(
			void(*f)(struct event *) = funcs[index];
			f(event);
		)

bottom:
		if (event == &fake_event) 
		{
			give_semaphore(fake_sem);
		}
	}
} 

// 5D2 has a different version for gui_main_task

TASK_OVERRIDE( gui_main_task, gui_main_task_60d );
back to top