Magic Lantern Firmware Wiki
Register
Advertisement

Trying to understand GUI events on the 550D.

Event-dump-550D

gui_main_task[]

NSTUB( 0xFF01FF94, gui_main_task )

This retrieves events from the main message queue (see GUI Events) and calls a function from a jump table with 8 elements:

   // ff020760: GUI_CONTROL QueueClear
   // ff020878: gui_main_loop_bottom
   // sub_FF02090C
   // ff020968: guiother_cancel_all_event
   // ff0209f4: sub_FF0209F4
   // ff0209fc: j_handleGuiInit
   // ff020a04: gui_change_shoot_type
   // ff020a2c: gui_change_lcd_state

Event types are 0-7:

  • 0 = GUI control (includes button presses)
  • 1 = ?
  • 2 = ?
  • 3 = cancel other events?
  • 4 = shutter-related? also required for card detection?
  • 5 = IDLEHandler
  • 6 = GUI_CHANGE_SHOOT_TYPE
  • 7 = GUI_CHANGE_LCD_STATE

The event struct from 5D2 seems to be used, too (not sure whether the fields are the same).

event->type
event->param
event->obj
event->arg

GUI_CONTROL[]

It calls GUI_Control_Post(arg,obj,param). Sometimes it logs the event with DebugMsg.

If the event queue is clear; if yes, it returns. Not the normal path execution code. In some IDCs it is named QueueClear.

GUI_Control_Post / gui_massive_event_loop[]

This is a huge case statement, where codes like 0x830 are generated (and passed to CtrlSrv_try_post_something).

Many button press events have arg=0. In this case, code arrives at this jump table:

FF0932B0:	908ff104	addls	pc, pc, r4, lsl #2

For PRESS_INFO_BUTTON, p=00000007 and index is 8. Similar for SET and MENU, maybe for others.

IDLEHandler[]

From handleGuiInit, code arrives at IDLEHandler, where is a huge case statement.

IDLEHandler can be decompiled by GPL Tools/ARM console (but it's not done by default, because the function is too big). Result is huge (2400 lines), so it's better to save it to a file.

In [10]: d = deco.decompile(0xFF214D24)
In [11]: f = open("IDLEHandler.txt","w")
In [12]: print >> f, d
In [13]: f.close()

Also, let's try to guess how many arguments it has:

In [14]: funargs.getFuncSignature(0xFF214D24)
int IDLEHandler(arg0, arg1, arg2, arg3); 

IDLEHandler tests if arg1 is equal to various constants:

0x807: PRESS_RIGHT_BUTTON
0x809: PRESS_LEFT_BUTTON
0x80b: PRESS_UP_BUTTON
0x80d: PRESS_DOWN_BUTTON
0x80f: PRESS_MENU_BUTTON
0x829: PRESS_INFO_BUTTON
0x83A: PRESS_INDIAL_UP_BUTTON
0x83C: PRESS_INDIAL_RIGHT_BUTTON
0x83E: PRESS_INDIAL_DOWN_BUTTON
0x840: PRESS_INDIAL_LEFT_BUTTON
0x812: PRESS_SET_BUTTON
0x800: GOT_TOP_OF_CONTROL
0x802: INITIALIZE_CONTROLLER
0x10000000: PRESS_DISP_BUTTON
0x10000003: PICTURE_STYLE or PROTECTMIC BUTTON
0x10000019: START_MENU_WB_MODE
0x10000083: LOCAL_AEMODE_CHECK
0x1000008c: LOCAL_MOVIE_RECORD_STOP
0x1000009d: OTHER_NOTIFY_JOB_STATE
...

Some codes missed by the decompiler (because it does not handle jump tables):

PRESS_UNAVI_BUTTON
PRESS_SW1_BUTTON
UNPRESS_SW1_BUTTON
PRESS_SW2_BUTTON
UNPRESS_SW2_BUTTON
PRESS_LV_MOVIE_START_BUTTON

How it's called?[]

Excerpts from the HTML output of GPL Tools/ARM console:

handleGuiInit+444:             create_idleHandler_task()
create_idleHandler_task+12:    gui_task_create(@IDLEHandler, 0)
gui_task_create+140:           ctrlman_dispatch_event(ret_new_task_struct_FF2B4C24 /* points to arg0 */ , 0x802, 0, 0)
ctrlman_dispatch_event+96:     FUNC(*(arg0))(*(4 + arg0), arg1, arg2, arg3) => ret_FUNC(*(arg0))_FF2B4B20

Other ctrlman calls:

gui_task_create+140:	ctrlman_dispatch_event(ret_new_task_struct_FF2B4C24 /* points to arg0 */ , 0x802, 0, 0)
gui_task_destroy+204:	ctrlman_dispatch_event(0, 0x800, 0, 0)
sub_FF2B4FE8+88:	ctrlman_dispatch_event(*(0x1e640), arg1, arg2, arg3)
sub_FF2B50A8+20:	ctrlman_dispatch_event(arg0, 0x801, 0, 0)
sub_FF2B50A8+44:	ctrlman_dispatch_event(arg1, 0x800, 0, 0)

Hint: ctrlman_dispatch_event can be used to send events to gui tasks (like ML menu task or IDLEHandler task):

void send_event_to_IDLEHandler(int event)
{
    ctrlman_dispatch_event((void*)GMT_IDLEHANDLER_TASK, event, 0, 0);
}
void menu_send_event(int event)
{
    ctrlman_dispatch_event(gui_menu_task, event, 0, 0);
}

StartPlayMain_handler[]

This is another huge case statement, for the Play dialog.

UNPRESS_TELE_MAG_BUTTON
UNPRESS_WIDE_REDUCTION_BUTTON


Event dump[]

[MAGIC] EVENT: 0 f=ff020760 p=0000003f o=00000000 a=00000000
[GUI] IDLEHandler PRESS_SW1_BUTTON
[MAGIC] EVENT: 0 f=ff020760 p=00000040 o=00000000 a=00000000
[GUI] IDLEHandler UNPRESS_SW1_BUTTON
[MAGIC] EVENT: 0 f=ff020760 p=00000007 o=00000000 a=00000000
[GUI] GuiMainEventHandler.c PRESS_INFO_BUTTON  // that's Disp

Indy: check [GUI_E] debug messages ?

   990:   832.667 [GUI_E] GUI_Control:74 0x0
   991:   832.821 [GUI_M] GUICMD_LOCK_ON
...
   997:   836.476 [GUI_E] GUI_Control:76 0x0
   998:   836.691 [BIND] bindReceiveSwitch (19, 0)
   999:   836.947 [GUI_M] GUICMD_CLOSE_SLOT_COVER

Press/unpress parameter codes for event 0, as received by gui_main_task_550d:

1c/1d = left
1e/1f = up
1a/1b = right
20/21 = down
4/5 = set
3 = wheel right, 2 = wheel left
7 = disp
6 = menu
8 = direct print (it might be the Q button)
3f/40 = half shutter
56 = iso button? (a=10)
d/e = star button (zoom out) 
b/c = zoom in button (manual mode only?)
a = trash
mode switch also generates p=56, with a=9, e, 15, 7, charge battery pack.

Wanted: missing unpress codes.

Event codes (hex), as received by menu_handler in menu.c (enable debug.draw-event to see them on the screen):

Play          10000000
Q             10000005
AV            100000b5?!
Zoom in/out   10000048/49; depressing zoom in also generates an 81a
ISO           100000b5?!
LiveView      1000000d
DOF preview   10000048/49
Flash         100000a6?
Flash Off     100000a6?
LCD sensor    100000a6?
Mode Dial     100000a6?
Power Off     100000cb/cc
Power On      100000cd
Disp (info)       829
Up                80b/c
Down              80d/e
Right             807/8
Left              809/a
Set               812/3
Menu              ??? 
Shutter Half      48/49 and then b5
Shutter Full      ???

So, either 10000a6 and 10000b5 are some groups of events, or they are other kind of events triggered by those button presses (and overwrite the display too fast for me to see them).

Some interesting codes are at *(arg3).

Event 100000a6, *(arg3):

8000003d - timer?
8005001f - timer?
80050007 - timer?
80030014 - timer?
80020010 - LCD sensor
80000005 - flash on/off, wheel?
80030014 - wheel left?
80000004 - change focus mode between AF/MF (on the lens)
80030011 - sent when you zoom in/out
80030021 - change lens maybe

Those might be properties changed by this event.

Mode dial generates LOTS of a6 events!

Event 10000048:

*(arg3) is a counter (how many times you pressed the button?!)

Code and discussion[]

To be sorted[]

Arm.Indy also found some GUI events and listed them on the Properties page.

Advertisement