static QState buttons_state(struct Buttons *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: SERIALSTR("(b2)"); return Q_HANDLED(); case BUTTONS_WAIT_SIGNAL: return Q_TRAN(buttons_waiting); case BUTTONS_SIGNAL: if ((uint16_t)(Q_PAR(me)) & 0b0001) { DS(button1, BUTTON_PRESSED_SIGNAL); } else { DS(button1, BUTTON_RELEASED_SIGNAL); } if ((uint16_t)(Q_PAR(me)) & 0b0010) { DS(button2, BUTTON_PRESSED_SIGNAL); } else { DS(button2, BUTTON_RELEASED_SIGNAL); } if ((uint16_t)(Q_PAR(me)) & 0b0100) { DS(button3, BUTTON_PRESSED_SIGNAL); } else { DS(button3, BUTTON_RELEASED_SIGNAL); } if ((uint16_t)(Q_PAR(me)) & 0b1000) { DS(button4, BUTTON_PRESSED_SIGNAL); } else { DS(button4, BUTTON_RELEASED_SIGNAL); } return Q_HANDLED(); } return Q_SUPER(QHsm_top); }
static QState uiTop(struct UI *me) { const struct Time *time; switch (Q_SIG(me)) { case Q_ENTRY_SIG: lcd_clear(); lcd_showdigits("6789"); break; case WATCHDOG_SIGNAL: // TODO: watchdog reset return Q_HANDLED(); case TEMPERATURE_SIGNAL: SERIALSTR("uiTop: TS\r\n"); return Q_HANDLED(); case TIME_SIGNAL: time = (const struct Time*)(Q_PAR(me)); Q_ASSERT( time->ht >= '0' && time->ht <= '9' ); Q_ASSERT( time->h1 >= '0' && time->h1 <= '9' ); Q_ASSERT( time->mt >= '0' && time->mt <= '9' ); Q_ASSERT( time->m1 >= '0' && time->m1 <= '9' ); show_time(time); return Q_HANDLED(); case CURRENT_TEMPERATURE_SIGNAL: /* Handle this signal here, so that no matter where the UI is, the current temperature will be available when it's finished. */ me->ti = (int16_t) Q_PAR(me); return Q_HANDLED(); case BUTTON_CANCEL_PRESS_SIGNAL: return Q_TRAN(uiRun); } return Q_SUPER(QHsm_top); }
/* helper functions ........................................................*/ void TServer_deferRequest(TServer *me) { if (me->deferredRequest.sig == 0) { /* the request NOT deferred yet? */ me->deferredRequest.sig = Q_SIG(me); me->deferredRequest.par = Q_PAR(me); printf("deferring request #%d\n", (int)me->deferredRequest.par); } else { printf("!!! cannot defer request #%d\n", (int)Q_PAR(me)); } }
/** * Wait here until the interrupt state machine tells us it's finished the * TWI requests. Reject any further TWI requests. */ static QState twiBusyState(struct TWI *me) { uint8_t index; uint8_t sreg; struct TWIRequest **requestp; switch (Q_SIG(me)) { case Q_ENTRY_SIG: //SERIALSTR("TWI > twiBusyState\r\n"); start_request(me); return Q_HANDLED(); case Q_EXIT_SIG: //SERIALSTR("TWI < twiBusyState\r\n"); sreg = SREG; cli(); me->requests[0] = 0; me->requests[1] = 0; me->requestIndex = 0; SREG = sreg; return Q_HANDLED(); case TWI_REQUEST_SIGNAL: SERIALSTR("TWI got excess TWI_REQUEST_SIGNAL\r\n"); requestp = (struct TWIRequest **)((uint16_t)Q_PAR(me)); if (requestp[0] && requestp[0]->signal) { requestp[0]->status = TWI_QUEUE_FULL; post(requestp[0]->qactive, requestp[0]->signal, (QParam)((uint16_t)requestp[0])); } if (requestp[1] && requestp[1]->signal) { requestp[1]->status = TWI_QUEUE_FULL; post(requestp[1]->qactive, requestp[1]->signal, (QParam)((uint16_t)requestp[1])); } return Q_HANDLED(); case TWI_REPLY_SIGNAL: index = (uint8_t) Q_PAR(me); //SERIALSTR("TWI got TWI_REPLY_SIGNAL index="); //serial_send_int(index); //SERIALSTR("\r\n"); post(me->requests[index]->qactive, me->requests[index]->signal, (QParam)((uint16_t)(me->requests[index]))); return Q_HANDLED(); case TWI_FINISHED_SIGNAL: return Q_TRAN(twiState); } return Q_SUPER(twiState); }
/*..........................................................................*/ QState AlarmClock_timekeeping(AlarmClock * const me) { QState status; switch (Q_SIG(me)) { case Q_ENTRY_SIG: { /* timeout in one second and every second */ QActive_armX(&me->super, 0U, BSP_TICKS_PER_SEC, BSP_TICKS_PER_SEC); status = Q_HANDLED(); break; } case Q_EXIT_SIG: { QActive_disarmX(&me->super, 0U); status = Q_HANDLED(); break; } case Q_INIT_SIG: { status = Q_TRAN(&AlarmClock_mode24hr); break; } case CLOCK_12H_SIG: { status = Q_TRAN(&AlarmClock_mode12hr); break; } case CLOCK_24H_SIG: { status = Q_TRAN(&AlarmClock_mode24hr); break; } case ALARM_SIG: { printf("Wake up!!!\n"); status = Q_HANDLED(); break; } case ALARM_SET_SIG: case ALARM_ON_SIG: case ALARM_OFF_SIG: { /* synchronously dispatch to the orthogonal component */ Q_SIG(&me->alarm) = Q_SIG(me); Q_PAR(&me->alarm) = Q_PAR(me); QHSM_DISPATCH(&me->alarm.super); status = Q_HANDLED(); break; } case TERMINATE_SIG: { status = Q_TRAN(&AlarmClock_final); break; } default: { status = Q_SUPER(&QHsm_top); break; } } return status; }
/*..........................................................................*/ QState NumEntry_integer(NumEntry *me) { switch (Q_SIG(me)) { case DIGIT_0_SIG: /* intentionally fall through */ case DIGIT_1_9_SIG: { NumEntry_insert(me, Q_PAR(me)); return Q_HANDLED(); } case POINT_SIG: { NumEntry_insert(me, Q_PAR(me)); return Q_TRAN(&NumEntry_fraction); } } return Q_SUPER(&NumEntry_top); }
/*..........................................................................*/ QState AlarmClock_mode24hr(AlarmClock *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { printf("*** 24-hour mode\n"); return Q_HANDLED(); } case Q_TIMEOUT_SIG: { /* timeout in one second */ QActive_arm((QActive *)me, BSP_TICKS_PER_SEC); if (++me->current_time == 24*60) { /* roll over in 24-hr mode? */ me->current_time = 0; } printf("%02d:%02d\n", me->current_time/60, me->current_time%60); /* synchronously dispatch to the orthogonal component */ Q_SIG(&me->alarm) = TIME_SIG; Q_PAR(&me->alarm) = me->current_time; Alarm_dispatch(&me->alarm); return Q_HANDLED(); } } return Q_SUPER(&AlarmClock_timekeeping); }
/*..........................................................................*/ QState AlarmClock_mode12hr(AlarmClock * const me) { QState status; switch (Q_SIG(me)) { case Q_ENTRY_SIG: { printf("*** 12-hour mode\n"); status = Q_HANDLED(); break; } case Q_TIMEOUT_SIG: { uint32_t h; /* temporary variable to hold hour */ if (++me->current_time == 12U * 60U) { /* roll over in 12-hr mode? */ me->current_time = 0U; } h = me->current_time / 60U; printf("%02d:%02d %s\n", (h % 12U) ? (h % 12U) : 12U, me->current_time % 60U, (h / 12U) ? "PM" : "AM"); /* synchronously dispatch to the orthogonal component */ Q_SIG(&me->alarm) = TIME_SIG; Q_PAR(&me->alarm) = me->current_time; QHSM_DISPATCH(&me->alarm.super); status = Q_HANDLED(); break; } default: { status = Q_SUPER(&AlarmClock_timekeeping); break; } } return status; }
/*..........................................................................*/ QState Alarm_on(Alarm *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { printf("*** Alarm ON %02ld:%02ld\n", me->alarm_time/60, me->alarm_time%60); fflush(stdout); return Q_HANDLED(); } case ALARM_SET_SIG: { printf("*** Cannot set Alarm when it is ON\n"); fflush(stdout); return Q_HANDLED(); } case ALARM_OFF_SIG: { return Q_TRAN(&Alarm_off); } case TIME_SIG: { if (Q_PAR(me) == me->alarm_time) { printf("ALARM!!!\n"); /* asynchronously post the event to the container AO */ QActive_post((QActive *)&AO_AlarmClock, ALARM_SIG, 0); } return Q_HANDLED(); } } return Q_IGNORED(); }
static QState twiState(struct TWI *me) { struct TWIRequest **requestp; struct TWIRequest *request; switch (Q_SIG(me)) { case Q_ENTRY_SIG: twi.ready = 73; return Q_HANDLED(); case TWI_REQUEST_SIGNAL: //SERIALSTR("TWI Got TWI_REQUEST_SIGNAL\r\n"); requestp = (struct TWIRequest **)((uint16_t)Q_PAR(me)); Q_ASSERT( requestp ); request = *requestp; Q_ASSERT( request ); Q_ASSERT( ! me->requests[0] ); me->requests[0] = request; requestp++; request = *requestp; Q_ASSERT( ! me->requests[1] ); me->requests[1] = request; me->requestIndex = 0; return Q_TRAN(twiBusyState); } return Q_SUPER(&QHsm_top); }
static QState mmi_giga_pan(struct mmi_ao *me) { char tmp[17]; switch (Q_SIG(me)) { case Q_ENTRY_SIG: prog_init_giga_pan(); lcd_clear(); lcd_write(0, 0, "Giga pan", 0); snprintf(tmp, sizeof(tmp), "%dx%d tiles", giga_info.tiles.x, giga_info.tiles.y); lcd_write(0, 1, tmp, 0); return Q_HANDLED(); case Q_EXIT_SIG: return Q_HANDLED(); case Q_TIMEOUT_SIG: return Q_HANDLED(); case SIG_KEY_PRESS: switch (Q_PAR(me)) { case KEY_ENTER: QActive_post((QActive *) &prog_ao, SIG_PROG_START, PROG_GIGA_PAN); return Q_TRAN(mmi_busy); case KEY_LEFT: return Q_TRAN(mmi_navigate); } return Q_HANDLED();; } return Q_SUPER(&QHsm_top); }
/*..........................................................................*/ QState AlarmClock_mode12hr(AlarmClock *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { printf("*** 12-hour mode\n"); return Q_HANDLED(); } case Q_TIMEOUT_SIG: { uint32_t h; /* temporary variable to hold hour */ /* timeout in one second */ QActive_arm((QActive *)me, BSP_TICKS_PER_SEC); if (++me->current_time == 12*60) { /* roll over in 12-hr mode? */ me->current_time = 0; } h = me->current_time/60; printf("%02d:%02d %s\n", (h % 12) ? (h % 12) : 12, me->current_time % 60, (h / 12) ? "PM" : "AM"); /* synchronously dispatch to the orthogonal component */ Q_SIG(&me->alarm) = TIME_SIG; Q_PAR(&me->alarm) = me->current_time; Alarm_dispatch(&me->alarm); return Q_HANDLED(); } } return Q_SUPER(&AlarmClock_timekeeping); }
static QState mmi_busy(struct mmi_ao *me) { static const char busy_char[] = ". "; static uint8_t busy_index; switch (Q_SIG(me)) { case Q_ENTRY_SIG: // Print hello message lcd_clear(); lcd_write(0, 0, "Busy ...", 0); QActive_arm((QActive *) me, TIMEOUT_BUSY); return Q_HANDLED(); case Q_EXIT_SIG: QActive_disarm((QActive *) me); return Q_HANDLED(); case Q_TIMEOUT_SIG: lcd_char(15, 0, busy_char[busy_index]); busy_index = (busy_index + 1) % (sizeof(busy_char) - 1); QActive_arm((QActive *) me, TIMEOUT_BUSY); return Q_HANDLED(); case SIG_KEY_PRESS: if (Q_PAR(me) == KEY_LEFT) { QActive_post((QActive *) &prog_ao, SIG_PROG_STOP, 0); return Q_TRAN(mmi_navigate); } return Q_HANDLED(); case SIG_PROG_DONE: return Q_TRAN(mmi_navigate); } return Q_SUPER(&QHsm_top); }
/*..........................................................................*/ QState AlarmClock_mode24hr(AlarmClock * const me) { QState status; switch (Q_SIG(me)) { case Q_ENTRY_SIG: { printf("*** 24-hour mode\n"); status = Q_HANDLED(); break; } case Q_TIMEOUT_SIG: { /* roll over in 24-hr mode? */ if (++me->current_time == 24U*60U) { me->current_time = 0U; } printf("%02d:%02d\n", me->current_time / 60U, me->current_time % 60U); /* synchronously dispatch to the orthogonal component */ Q_SIG(&me->alarm) = TIME_SIG; Q_PAR(&me->alarm) = me->current_time; QHSM_DISPATCH(&me->alarm.super); status = Q_HANDLED(); break; } default: { status = Q_SUPER(&AlarmClock_timekeeping); break; } } return status; }
static QState buttons_waiting(struct Buttons *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: SERIALSTR("<+bw>"); DS(button1, BUTTON_RELEASED_SIGNAL); DS(button2, BUTTON_RELEASED_SIGNAL); DS(button3, BUTTON_RELEASED_SIGNAL); me->up_counter = 3; return Q_HANDLED(); case BUTTONS_SIGNAL: if ((uint16_t)(Q_PAR(me)) == 0) { me->up_counter --; if (me->up_counter) { return Q_HANDLED(); } else { SERIALSTR("@"); return Q_TRAN(buttons_state); } } else { me->up_counter = 3; return Q_HANDLED(); } case Q_EXIT_SIG: SERIALSTR("<-bw>"); return Q_HANDLED(); } return Q_SUPER(buttons_state); }
/*..........................................................................*/ QState NumEntry_negative(NumEntry *me) { switch (Q_SIG(me)) { case DIGIT_0_SIG: { ; /* explicitly ignore */ return Q_HANDLED(); } case DIGIT_1_9_SIG: { NumEntry_insert(me, Q_PAR(me)); return Q_TRAN(&NumEntry_integer); } case POINT_SIG: { NumEntry_insert(me, Q_PAR(me)); return Q_TRAN(&NumEntry_fraction); } } return Q_SUPER(&NumEntry_top); }
static QState mmi_show_msg(struct mmi_ao *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: QActive_arm((QActive *) me, TICKS(Q_PAR(me) * 1000)); return Q_HANDLED(); case Q_EXIT_SIG: QActive_disarm((QActive *) me); return Q_HANDLED(); case Q_TIMEOUT_SIG: return Q_TRAN(mmi_navigate); case SIG_KEY_PRESS: if (Q_PAR(me) == KEY_ENTER) { return Q_TRAN(mmi_navigate); } return Q_HANDLED();; } return Q_SUPER(&QHsm_top); }
/*..........................................................................*/ QState Bomb_off(Bomb *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { LED_off(); return Q_HANDLED(); } case ARM_SIG: { me->ctr = Q_PAR(me) * 4; /* arm the downcounter */ return Q_TRAN(&Bomb_timing); } } return Q_IGNORED(); }
/*..........................................................................*/ QState AlarmClock_timekeeping(AlarmClock *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { /* timeout in one second */ QActive_arm((QActive *)me, BSP_TICKS_PER_SEC); return Q_HANDLED(); } case Q_EXIT_SIG: { QActive_disarm((QActive *)me); return Q_HANDLED(); } case Q_INIT_SIG: { return Q_TRAN(&AlarmClock_mode24hr); } case CLOCK_12H_SIG: { return Q_TRAN(&AlarmClock_mode12hr); } case CLOCK_24H_SIG: { return Q_TRAN(&AlarmClock_mode24hr); } case ALARM_SIG: { printf("Wake up!!!\n"); return Q_HANDLED(); } case ALARM_SET_SIG: case ALARM_ON_SIG: case ALARM_OFF_SIG: { /* synchronously dispatch to the orthogonal component */ Q_SIG(&me->alarm) = Q_SIG(me); Q_PAR(&me->alarm) = Q_PAR(me); Alarm_dispatch(&me->alarm); return Q_HANDLED(); } case TERMINATE_SIG: { return Q_TRAN(&AlarmClock_final); } } return Q_SUPER(&QHsm_top); }
static QState Ble_disconnected(Ble* const me) { switch(Q_SIG(me)) { case ANCS_SIG: if (Q_PAR(me) != BLE_ANCS_C_EVT_DISCOVERY_COMPLETE) return Q_HANDLED(); // iOS specific delay because we cannot add a CCCD to close to starting // encryption. return Q_TRAN(&Ble_ancs_setup_wait); default: return Q_SUPER(&QHsm_top); } }
/*..........................................................................*/ QState NumEntry_zero(NumEntry *me) { switch (Q_SIG(me)) { case DIGIT_0_SIG: { ; /* explicitly ignore */ return Q_HANDLED(); } case NEG_SIG: { me->str[NUM_STR_WIDTH - 2] = '-'; Video_printStrAt(me->x, me->y, me->color, me->str); return Q_TRAN(&NumEntry_negative); } case DIGIT_1_9_SIG: { NumEntry_insert(me, Q_PAR(me)); return Q_TRAN(&NumEntry_integer); } case POINT_SIG: { NumEntry_insert(me, Q_PAR(me)); return Q_TRAN(&NumEntry_fraction); } } return Q_SUPER(&NumEntry_top); }
/*..........................................................................*/ QState TServer_idle(TServer *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { printf("-> idle\n"); TServer_recallRequest(me); /* recall the request */ return Q_HANDLED(); } case NEW_REQUEST_SIG: { printf("Processing request #%d\n", (int)Q_PAR(me)); return Q_TRAN(&TServer_receiving); } } return Q_SUPER(&TServer_operational); }
QState LEDSEQ_Process(LedSeq * const me) { QState status; switch (Q_SIG(me)) { case LEDSEQ_START_SIG: /* Reset the seq to its first step. */ me->state[Q_PAR(me)] = 0; LEDSEQ_UpdateActive(me); LEDSEQ_Run(me); status = Q_HANDLED(); break; case LEDSEQ_STOP_SIG: /* Stop the seq. */ me->state[Q_PAR(me)] = LEDSEQ_STOP; LEDSEQ_UpdateActive(me); LEDSEQ_Run(me); status = Q_HANDLED(); break; case Q_TIMEOUT_SIG: LEDSEQ_Run(me); status = Q_HANDLED(); break; default: status = Q_SUPER(&QHsm_top); break; } return status; }
/*..........................................................................*/ QState Cruncher_processing(Cruncher * const me) { QState status; switch (Q_SIG(me)) { case Q_ENTRY_SIG: { QACTIVE_POST(&me->super, CRUNCH_SIG, 0); me->sum = 0.0; status = Q_HANDLED(); break; } case CRUNCH_SIG: { uint32_t i = Q_PAR(me); uint32_t n = i; i += 100U; for (; n < i; ++n) { if ((n & 1) == 0) { me->sum += 1.0/(2*n + 1); } else { me->sum -= 1.0/(2*n + 1); } } if (i < 0x07000000U) { QACTIVE_POST(&me->super, CRUNCH_SIG, i); status = Q_HANDLED(); } else { BSP_result(me->sum); status = Q_TRAN(&Cruncher_processing); } break; } case ECHO_SIG: { BSP_echo(me->sum); status = Q_HANDLED(); break; } case TERMINATE_SIG: { status = Q_TRAN(&Cruncher_final); break; } default: { status = Q_SUPER(&QHsm_top); break; } } return status; }
static QState uiRun(struct UI *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: lcd_buttons(LCD_BUTTONS_ENTER_UP_DOWN); show_temperature(me->ti); show_time(gettimep()); return Q_HANDLED(); case BUTTON_ENTER_PRESS_SIGNAL: return Q_TRAN(uiMenuMaybeSettime); case BUTTON_UP_PRESS_SIGNAL: return Q_TRAN(uiShowMax); case BUTTON_DOWN_PRESS_SIGNAL: return Q_TRAN(uiShowMin); case CURRENT_TEMPERATURE_SIGNAL: me->ti = (int16_t) Q_PAR(me); show_temperature(me->ti); } return Q_SUPER(uiTop); }
QState s_light_off(ao_light_t * const me) { QState status; switch (Q_SIG(me)) { case Q_ENTRY_SIG: light_off(); status = Q_HANDLED(); break; case LIGHT_TIMER_SIG: me->timer = (uint32_t)Q_PAR(me); status = Q_TRAN(&s_light_timer); break; case LIGHT_ON_SIG: status = Q_TRAN(&s_light_on); break; default: status = Q_SUPER(&QHsm_top); break; } return status; }
static QState uiMenuCalibrateGetTemperature(struct UI *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: BSP_get_temperature(); /* Only need one tick to get the temperature, since we're guaranteed to be arriving here very near the start of a tick period. But take two anyway, to be sure. */ QActive_armX((QActive*)me, 1, 2); return Q_HANDLED(); case TEMPERATURE_SIGNAL: SERIALSTR("<okok>"); me->ti = Q_PAR(me); show_temperature_cal(me); return Q_TRAN(uiMenuCalibratePause); case Q_TIMEOUT1_SIG: /* Nothing has happened - give up. */ SERIALSTR("<BLAH>"); return Q_TRAN(uiMenuCalibratePause); } return Q_SUPER(uiMenuCalibrateDeferExit); }
/*..........................................................................*/ QState Alarm_off(Alarm *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: { /* while in the off state, the alarm is kept in decimal format */ me->alarm_time = (me->alarm_time/60)*100 + me->alarm_time%60; printf("*** Alarm OFF %02ld:%02ld\n", me->alarm_time/100, me->alarm_time%100); fflush(stdout); return Q_HANDLED(); } case Q_EXIT_SIG: { /* upon exit, the alarm is converted to binary format */ me->alarm_time = (me->alarm_time/100)*60 + me->alarm_time%100; return Q_HANDLED(); } case ALARM_ON_SIG: { /* alarm in range? */ if ((me->alarm_time / 100 < 24) && (me->alarm_time % 100 < 60)) { return Q_TRAN(&Alarm_on); } else { /* alarm out of range -- clear and don't transition */ me->alarm_time = 0; printf("*** Alarm reset %02ld:%02ld\n", me->alarm_time/100, me->alarm_time%100); return Q_HANDLED(); } } case ALARM_SET_SIG: { /* while setting, the alarm is kept in decimal format */ me->alarm_time = (10 * me->alarm_time + Q_PAR(me)) % 10000; printf("*** Alarm SET %02ld:%02ld\n", me->alarm_time/100, me->alarm_time%100); fflush(stdout); return Q_HANDLED(); } } return Q_IGNORED(); }
static void defer(struct UI *me) { me->deferredSignal = Q_SIG(me); me->deferredParam = Q_PAR(me); }
/** * Navigate state. * Navigates the menu structure using the following buttons: * - up => go to previous item * - down => go to next item * - left => go to parent item * - right => go to child item */ static QState mmi_navigate(struct mmi_ao *me) { switch (Q_SIG(me)) { case Q_ENTRY_SIG: update_screen(me); return Q_HANDLED(); case Q_EXIT_SIG: return Q_HANDLED(); case SIG_ENCODER: switch (menu_cur->typ) { case MENU_TYP_PARAM: if (modify_param(menu_cur->param, Q_PAR(me), me->shift)) { print_param(menu_cur->param); if (menu_cur->cmd != CMD_NONE) QActive_post((QActive *) me, SIG_MMI_CMD, menu_cur->cmd); } break; default: break; } return Q_HANDLED(); case SIG_MMI_CMD: return execute_cmd(me, Q_PAR(me)); case SIG_MMI_SHOW_MSG: return Q_TRAN(mmi_show_msg); case SIG_KEY_PRESS: switch (Q_PAR(me)) { case KEY_UP: // Go to previous item if (menu_prev()) update_screen(me); break; case KEY_DOWN: // Go to next item if (menu_next()) update_screen(me); break; case KEY_LEFT: // Go to parent item if (menu_parent()) update_screen(me); break; case KEY_RIGHT: // Go to sub item if (menu_sub()) update_screen(me); break; case KEY_ENTER: me->shift = 1; switch (menu_cur->typ) { case MENU_TYP_CMD: // Execute command if (menu_cur->cmd) QActive_post((QActive *) me, SIG_MMI_CMD, menu_cur->cmd); break; case MENU_TYP_SUB: // Go to sub item if (menu_sub()) update_screen(me); break; default: break; } break; } return Q_HANDLED(); case SIG_KEY_RELEASE: switch (Q_PAR(me)) { case KEY_ENTER: me->shift = 0; default: break; } return Q_HANDLED(); case SIG_PROG_START: return Q_TRAN(mmi_busy); break; } return Q_SUPER(&QHsm_top); }