Don't block udev if udev-helper sleeps
[petitboot] / petitboot.c
index b443280bcd6326bae110915c45d8b2af5a7416f9..ea7dc57619d1df9f540f6a8642182f3a621f5777 100644 (file)
@@ -5,6 +5,8 @@
 #include <unistd.h>
 #include <syscall.h>
 #include <assert.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
 
 #include <linux/input.h>
 
@@ -28,7 +30,8 @@ static twin_fbdev_t *pboot_fbdev;
 
 static twin_screen_t *pboot_screen;
 
-#define PBOOT_INITIAL_MESSAGE          "Petitboot v0.0.1"
+#define PBOOT_INITIAL_MESSAGE          \
+       "video hack: 0=default 1=720p 2=1080i 3=1080p"  
 
 #define PBOOT_LEFT_PANE_SIZE           160
 #define PBOOT_LEFT_PANE_COLOR          0x80000000
@@ -138,6 +141,8 @@ static pboot_lpane_t        *pboot_lpane;
 static pboot_rpane_t   *pboot_rpane;
 static pboot_spane_t   *pboot_spane;
 
+static int pboot_vmode_change = -1;
+
 /* XXX move to twin */
 static inline twin_bool_t twin_rect_intersect(twin_rect_t r1,
                                              twin_rect_t r2)
@@ -686,6 +691,11 @@ static twin_bool_t pboot_lpane_event (twin_window_t            *window,
        return TWIN_FALSE;
 }
 
+static void pboot_quit(void)
+{
+       kill(0, SIGINT);
+}
+
 twin_bool_t pboot_event_filter(twin_screen_t       *screen,
                               twin_event_t         *event)
 {
@@ -701,6 +711,25 @@ twin_bool_t pboot_event_filter(twin_screen_t           *screen,
                                               pboot_cursor_hy);
                break;
        case TwinEventKeyDown:
+               /* Gross hack for video modes, need something better ! */
+               switch(event->u.key.key) {
+               case KEY_0:
+                       pboot_vmode_change = 0; /* auto */
+                       pboot_quit();
+                       return TWIN_TRUE;
+               case KEY_1:
+                       pboot_vmode_change = 3; /* 720p */
+                       pboot_quit();
+                       return TWIN_TRUE;
+               case KEY_2:
+                       pboot_vmode_change = 4; /* 1080i */
+                       pboot_quit();
+                       return TWIN_TRUE;
+               case KEY_3:
+                       pboot_vmode_change = 5; /* 1080p */
+                       pboot_quit();
+                       return TWIN_TRUE;
+               }
        case TwinEventKeyUp:
                twin_screen_set_cursor(pboot_screen, NULL, 0, 0);
                break;
@@ -978,12 +1007,22 @@ static void pboot_make_background(void)
        twin_screen_set_background(pboot_screen, scaledpic);
 }
 
+#define PS3FB_IOCTL_SETMODE          _IOW('r',  1, int)
+#define PS3FB_IOCTL_GETMODE          _IOR('r',  2, int)
+
 static void exitfunc(void)
 {
 #ifndef _USE_X11
        if (pboot_fbdev)
                twin_fbdev_destroy(pboot_fbdev);
        pboot_fbdev = NULL;
+       if (pboot_vmode_change != -1) {
+               int fd = open("/dev/fb0", O_RDWR);
+               if (fd >= 0)
+                       ioctl(fd, PS3FB_IOCTL_SETMODE,
+                             (unsigned long)&pboot_vmode_change);
+               close(fd);
+       }
 #endif
 }
 
@@ -993,8 +1032,35 @@ static void sigint(int sig)
        syscall(__NR_exit);
 }
 
+static void usage(const char *progname)
+{
+       fprintf(stderr, "Usage: %s [-u] [-h]\n", progname);
+}
+
 int main(int argc, char **argv)
 {
+       int c;
+       int udev_trigger = 0;
+
+       for (;;) {
+               c = getopt(argc, argv, "u::h");
+               if (c == -1)
+                       break;
+
+               switch (c) {
+               case 'u':
+                       udev_trigger = 1;
+                       break;
+               case 'h':
+                       usage(argv[0]);
+                       return EXIT_SUCCESS;
+               default:
+                       fprintf(stderr, "Unknown option '%c'\n", c);
+                       usage(argv[0]);
+                       return EXIT_FAILURE;
+               }
+       }
+
        atexit(exitfunc);
        signal(SIGINT, sigint);
 
@@ -1016,7 +1082,7 @@ int main(int argc, char **argv)
        twin_linux_mouse_create(NULL, pboot_screen);
 
        if (pboot_fbdev != NULL) {
-               char *cursor_path = artwork_pathname("cursor");
+               char *cursor_path = artwork_pathname("cursor.gz");
                pboot_cursor = twin_load_X_cursor(cursor_path, 2,
                                                  &pboot_cursor_hx,
                                                  &pboot_cursor_hy);
@@ -1035,7 +1101,7 @@ int main(int argc, char **argv)
        pboot_create_rpane();
        pboot_create_spane();
 
-       if (!pboot_start_device_discovery()) {
+       if (!pboot_start_device_discovery(udev_trigger)) {
                LOG("Couldn't start device discovery!\n");
                return 1;
        }