jpeg background support and scaling
[petitboot] / petitboot.c
index e7eff4c91fee02730173febe09c0794e3486cf78..84a76f62fc092903a35308ba899c12c24ed5ddae 100644 (file)
@@ -1,4 +1,5 @@
 #include <stdio.h>
+#include <string.h>
 #include <stdlib.h>
 #include <signal.h>
 #include <unistd.h>
@@ -7,19 +8,24 @@
 
 #include <linux/input.h>
 
+#undef _USE_X11
+
 #include <libtwin/twin.h>
-#include <libtwin/twin_fbdev.h>
-#include <libtwin/twin_x11.h>
 #include <libtwin/twin_linux_mouse.h>
 #include <libtwin/twin_png.h>
+#include <libtwin/twin_jpeg.h>
 
 #include "petitboot.h"
 #include "petitboot-paths.h"
 
-#define _USE_X11
-
-static twin_fbdev_t *pboot_fbdev;
+#ifdef _USE_X11
+#include <libtwin/twin_x11.h>
 static twin_x11_t *pboot_x11;
+#else
+#include <libtwin/twin_fbdev.h>
+static twin_fbdev_t *pboot_fbdev;
+#endif
+
 static twin_screen_t *pboot_screen;
 
 #define PBOOT_LEFT_PANE_SIZE           200
@@ -848,11 +854,58 @@ int pboot_remove_device(const char *dev_id)
        return TWIN_TRUE;
 }
 
+static void pboot_make_background(void)
+{
+       twin_pixmap_t   *filepic, *scaledpic;
+       const char      *background_path;
+
+       /* Set background pixmap */
+       LOG("loading background...");
+       background_path = artwork_pathname("background.jpg");
+       filepic = twin_jpeg_to_pixmap(background_path, TWIN_ARGB32);
+       LOG("%s\n", filepic ? "ok" : "failed");
+
+       if (filepic == NULL)
+               return;
+
+       if (pboot_screen->height == filepic->height &&
+           pboot_screen->width == filepic->width)
+               scaledpic = filepic;
+       else {
+               twin_fixed_t    sx, sy;
+               twin_operand_t  srcop;
+
+               scaledpic = twin_pixmap_create(TWIN_ARGB32,
+                                              pboot_screen->width,
+                                              pboot_screen->height);
+               if (scaledpic == NULL) {
+                       twin_pixmap_destroy(filepic);
+                       return;
+               }
+               sx = twin_fixed_div(twin_int_to_fixed(filepic->width),
+                                   twin_int_to_fixed(pboot_screen->width));
+               sy = twin_fixed_div(twin_int_to_fixed(filepic->height),
+                                   twin_int_to_fixed(pboot_screen->height));
+               
+               twin_matrix_scale(&filepic->transform, sx, sy);
+               srcop.source_kind = TWIN_PIXMAP;
+               srcop.u.pixmap = filepic;
+               twin_composite(scaledpic, 0, 0, &srcop, 0, 0,
+                              NULL, 0, 0, TWIN_SOURCE,
+                              pboot_screen->width, pboot_screen->height);
+               twin_pixmap_destroy(filepic);
+                              
+       }
+       twin_screen_set_background(pboot_screen, scaledpic);
+}
+
 static void exitfunc(void)
 {
+#ifndef _USE_X11
        if (pboot_fbdev)
                twin_fbdev_destroy(pboot_fbdev);
        pboot_fbdev = NULL;
+#endif
 }
 
 static void sigint(int sig)
@@ -863,9 +916,6 @@ static void sigint(int sig)
 
 int main(int argc, char **argv)
 {
-       twin_pixmap_t *pic;
-       const char *background_path;
-
        atexit(exitfunc);
        signal(SIGINT, sigint);
 
@@ -885,7 +935,6 @@ int main(int argc, char **argv)
        }
        pboot_screen = pboot_fbdev->screen;
        twin_linux_mouse_create(NULL, pboot_screen);
-#endif
 
        if (pboot_fbdev != NULL) {
                char *cursor_path = artwork_pathname("cursor");
@@ -897,14 +946,10 @@ int main(int argc, char **argv)
                                twin_get_default_cursor(&pboot_cursor_hx,
                                                        &pboot_cursor_hy);
        }
+#endif
 
        /* Set background pixmap */
-       background_path = artwork_pathname("background.png");
-       LOG("loading background: %s...", background_path);
-       pic = twin_png_to_pixmap(background_path, TWIN_ARGB32);
-       LOG("%s\n", pic ? "ok" : "failed");
-       if (pic)
-               twin_screen_set_background(pboot_screen, pic);
+       pboot_make_background();
 
        /* Init more stuffs */
        pboot_create_panels();
@@ -921,8 +966,10 @@ int main(int argc, char **argv)
        pboot_screen->event_filter = pboot_event_filter;
 
        /* Console switch */
+#ifndef _USE_X11
        if (pboot_fbdev)
                twin_fbdev_activate(pboot_fbdev);
+#endif
 
        /* Process events */
        twin_dispatch ();