Add PS3 countdown timer
authorGeoff Levand <geoffrey.levand@am.sony.com>
Thu, 9 Jul 2009 17:40:44 +0000 (10:40 -0700)
committerGeoff Levand <geoffrey.levand@am.sony.com>
Thu, 9 Jul 2009 17:40:44 +0000 (10:40 -0700)
Add countdown timer support to the PS3 UI programs.

Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
ui/common/ps3.c
ui/common/ps3.h
ui/ncurses/ps3-cui.c

index 5c83289ec254c4716fa706995b41a55b45f6f1d2..abe269200a988cb68099b476556c7f11933f69f3 100644 (file)
@@ -49,6 +49,11 @@ static const struct os_area_db_id id_flags =
        .owner = OS_AREA_DB_OWNER_PETITBOOT, /* 3 */
        .key = 3,
 };
+static const struct os_area_db_id id_timeout =
+{
+       .owner = OS_AREA_DB_OWNER_PETITBOOT, /* 3 */
+       .key = 4,
+};
 
 struct ps3_flash_ctx {
        FILE *dev;
@@ -59,6 +64,8 @@ struct ps3_flash_ctx {
 
 static void ps3_flash_close(struct ps3_flash_ctx *fc)
 {
+       assert(fc->dev);
+
        fclose(fc->dev);
        fc->dev = NULL;
 }
@@ -104,19 +111,25 @@ int ps3_flash_get_values(struct ps3_flash_values *values)
        struct ps3_flash_ctx fc;
        uint64_t tmp;
 
-       memset(values, 0, sizeof(*values));
+       /* Set default values. */
+
+       values->default_item = 0;
+       values->timeout = ps3_timeout_forever;
+       values->video_mode = 1;
 
        result = ps3_flash_open(&fc, "r");
 
        if (result)
-               return -1;
+               goto done;
 
        result = os_area_db_read(&fc.db, &fc.header, fc.dev);
 
+       ps3_flash_close(&fc);
+
        if (result) {
                pb_log("%s: os_area_db_read failed: %s\n", __func__,
                        strerror(errno));
-               goto fail;
+               goto done;
        }
 
        sum = result = os_area_db_get(&fc.db, &id_default_item, &tmp);
@@ -124,21 +137,25 @@ int ps3_flash_get_values(struct ps3_flash_values *values)
        if (!result)
                values->default_item = (uint32_t)tmp;
 
-       sum += result = os_area_db_get(&fc.db, &id_video_mode, &tmp);
+       result = os_area_db_get(&fc.db, &id_timeout, &tmp);
 
        if (!result)
-               values->video_mode = (uint16_t)tmp;
+               values->timeout = (uint8_t)tmp;
 
+       sum += result = os_area_db_get(&fc.db, &id_video_mode, &tmp);
 
-       pb_log("%s: default_item: %u\n", __func__, values->default_item);
-       pb_log("%s: video_mode:   %u\n", __func__, values->video_mode);
+       if (!result)
+               values->video_mode = (uint16_t)tmp;
 
-       ps3_flash_close(&fc);
-       return !!sum;
+done:
+       pb_log("%s: default_item: %x\n", __func__,
+               (unsigned int)values->default_item);
+       pb_log("%s: timeout: %u\n", __func__,
+               (unsigned int)values->timeout);
+       pb_log("%s: video_mode:   %u\n", __func__,
+               (unsigned int)values->video_mode);
 
-fail:
-       ps3_flash_close(&fc);
-       return -1;
+       return (result || sum) ? -1 : 0;
 }
 
 /**
@@ -177,6 +194,8 @@ int ps3_flash_set_values(const struct ps3_flash_values *values)
                }
        }
 
+       /* timeout is currently read-only, set with ps3-bl-option */
+
        result = os_area_db_set_32(&fc.db, &id_default_item,
                values->default_item);
        result += os_area_db_set_16(&fc.db, &id_video_mode,
index 8a7fe1cf539506865c90a71a973d25a7b33449d4..c7a0c48190c0aa660f6ae54444220b427ba8d1c9 100644 (file)
@@ -33,9 +33,14 @@ enum ps3_flash_flags {
        ps3_flag_telnet = 1,
 };
 
+enum ps3_timeouts {
+       ps3_timeout_forever = 255,
+};
+
 /**
  * struct ps3_flash_values - Values from PS3 flash memory.
  * @default_item: The default menu item.
+ * @timeout: The timeout in seconds.
  * @video_mode: The default video_mode.
  * @flags: Logical OR of enum ps3_flash_flags.
  */
@@ -44,6 +49,7 @@ struct ps3_flash_values {
        uint32_t default_item;
        uint16_t video_mode;
        /* uint16_t flags; */
+       uint8_t timeout;
 };
 
 int ps3_flash_get_values(struct ps3_flash_values *values);
index f166c8830cf54a748080e4205e853344c5940df1..e4ea6374c160a718157198c3697150f55b1d5f72 100644 (file)
@@ -21,9 +21,7 @@
 /*
  * TODO
  * removable media event
- * resize after video mode change
  * ncurses mouse support
- * timeout
  */
 
 #if defined(HAVE_CONFIG_H)
@@ -36,6 +34,7 @@
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/time.h>
 
 #include "log/log.h"
 #include "talloc/talloc.h"
@@ -282,6 +281,21 @@ static int ps3_hot_key(struct pmenu __attribute__((unused)) *menu,
        return c;
 }
 
+/**
+ * ps3_timer_update - Timer callback.
+ */
+
+static void ps3_timer_update(struct ui_timer *timer, unsigned int timeout)
+{
+       struct ps3_cui *ps3 = ps3_from_cui(cui_from_timer(timer));
+
+       //FIXME: make scr:timer.
+       // nc_scr_timer_update(&ps3.mm->scr, timeout);
+
+       nc_scr_status_printf(&ps3->mm->scr,
+               "Welcome to Petitboot (timeout %u sec)", timeout);
+}
+
 /**
  * ps3_mm_init - Setup the main menu instance.
  */
@@ -434,6 +448,10 @@ static void sig_handler(int signum)
        DBGS("%d\n", signum);
 
        switch (signum) {
+       case SIGALRM:
+               if (ps3.cui)
+                       ui_timer_sigalrm(&ps3.cui->timer);
+               break;
        case SIGWINCH:
                if (ps3.cui)
                        cui_resize(ps3.cui);
@@ -491,8 +509,9 @@ int main(int argc, char *argv[])
        pb_log("--- pb-cui ---\n");
 
        sa.sa_handler = sig_handler;
-       result = sigaction(SIGINT, &sa, NULL);
+       result = sigaction(SIGALRM, &sa, NULL);
        result += sigaction(SIGHUP, &sa, NULL);
+       result += sigaction(SIGINT, &sa, NULL);
        result += sigaction(SIGTERM, &sa, NULL);
        result += sigaction(SIGWINCH, &sa, NULL);
 
@@ -523,6 +542,13 @@ int main(int argc, char *argv[])
        ps3.mm = ps3_mm_init(&ps3);
        ps3.svm = ps3_svm_init(&ps3);
 
+       if (ps3.values.timeout == ps3_timeout_forever)
+               ui_timer_disable(&ps3.cui->timer);
+       else {
+               ps3.cui->timer.update_display = ps3_timer_update;
+               ui_timer_init(&ps3.cui->timer, ps3.values.timeout);
+       }
+
        cui_result = cui_run(ps3.cui, ps3.mm, ps3.values.default_item);
 
        pmenu_delete(ps3.mm);