Index: Makefile.in
===================================================================
--- Makefile.in	(revision 468)
+++ Makefile.in	(working copy)
@@ -37,7 +37,7 @@
 OBJ          = motion.o logger.o conf.o draw.o jpegutils.o vloopback_motion.o $(VIDEO_OBJ) \
 			   netcam.o netcam_ftp.o netcam_jpeg.o netcam_wget.o track.o \
 			   alg.o event.o picture.o rotate.o webhttpd.o \
-			   stream.o @FFMPEG_OBJ@
+			   stream.o @FFMPEG_OBJ@ @SDL_OBJ@
 SRC          = $(OBJ:.o=.c)
 DOC          = CHANGELOG COPYING CREDITS INSTALL README motion_guide.html
 EXAMPLES     = *.conf motion.init-Debian motion.init-RH motion.init-FreeBSD.sh
Index: sdl.c
===================================================================
--- sdl.c	(revision 0)
+++ sdl.c	(revision 0)
@@ -0,0 +1,179 @@
+/*
+ *    sdl.c
+ *
+ *    sdl functions for motion.
+ *    Copyright 2009 by Peter Holik (peter@holik.at)
+ *    This software is distributed under the GNU public license version 2
+ *    See also the file 'COPYING'.
+ */
+#include "sdl.h"
+#include <SDL/SDL.h>
+
+static int cur_width;
+static int cur_height;
+static int is_full_screen;
+static int fs_screen_width;
+static int fs_screen_height;
+
+static SDL_Surface *screen;
+static SDL_Overlay *overlay;
+
+static int sdl_video_open(int width, int height)
+{
+    int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
+    int w,h;
+
+    if (is_full_screen) flags |= SDL_FULLSCREEN;
+    else                flags |= SDL_RESIZABLE;
+
+    if (is_full_screen && fs_screen_width) {
+        w = fs_screen_width;
+        h = fs_screen_height;
+    } else if (width > fs_screen_width || height > fs_screen_height) {
+        w = fs_screen_width;
+        h = fs_screen_height;
+    } else {
+        w = width;
+        h = height;
+    }
+    /* 32 because framebuffer is usually initalized to 8 and
+       you have to use fbset with -depth to make it working */
+    screen = SDL_SetVideoMode(w, h, 32, flags);
+
+    if (!screen) {
+        motion_log(LOG_ERR, 1,"%s: Unable to set video mode: %s", __FUNCTION__, 
+                   SDL_GetError());
+        return -1;
+    }
+    motion_log(LOG_INFO, 0, "%s: SDL dimension %d x %d fullscreen %d BytesPerPixel %d", 
+               __FUNCTION__, screen->w, screen->h, is_full_screen, 
+               screen->format->BytesPerPixel);
+
+    SDL_WM_SetCaption("motion", "motion");
+    SDL_ShowCursor(SDL_DISABLE);
+
+    if (cur_width != width || cur_height != height) {
+        cur_width  = width;
+        cur_height = height;
+
+        if (overlay) SDL_FreeYUVOverlay(overlay);
+
+        overlay = SDL_CreateYUVOverlay(cur_width, cur_height,
+                                   SDL_YV12_OVERLAY, screen);
+        if (!overlay) {
+            motion_log(LOG_ERR, 1, "%s: Could not create overlay: %s", 
+                       __FUNCTION__, SDL_GetError());
+            sdl_stop();
+        } else
+            motion_log(LOG_INFO, 0, "%s: SDL created %dx%dx%d %s overlay",
+                       __FUNCTION__, overlay->w,overlay->h,overlay->planes,
+                       overlay->hw_overlay?"hardware":"software");
+    }
+    return overlay == NULL;
+}
+
+int sdl_start(int width, int height)
+{
+    putenv("SDL_NOMOUSE=1");
+
+    if (screen) return 0;
+
+    motion_log(LOG_INFO, 0, "%s: SDL start", __FUNCTION__);
+
+    if (SDL_Init(SDL_INIT_VIDEO)) {
+        motion_log(LOG_ERR, 1, "%s: Could not initialize SDL - %s",
+                   __FUNCTION__, SDL_GetError());
+        return -1;
+    }
+    const SDL_VideoInfo *vi = SDL_GetVideoInfo();
+    fs_screen_width  = vi->current_w;
+    fs_screen_height = vi->current_h;
+
+    if (sdl_video_open(width, height)) return -1;
+
+    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
+    SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
+    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
+    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
+    SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_IGNORE);
+    SDL_EventState(SDL_MOUSEBUTTONUP, SDL_IGNORE);
+    SDL_EventState(SDL_KEYUP, SDL_IGNORE);
+    SDL_EventState(SDL_JOYBUTTONDOWN, SDL_IGNORE);
+    SDL_EventState(SDL_JOYBUTTONUP, SDL_IGNORE);
+    SDL_EventState(SDL_JOYAXISMOTION, SDL_IGNORE);
+    SDL_EventState(SDL_JOYBALLMOTION, SDL_IGNORE);
+    SDL_EventState(SDL_JOYHATMOTION, SDL_IGNORE);
+    SDL_EventState(SDL_VIDEORESIZE, SDL_IGNORE);
+
+    return 0;
+}
+
+void sdl_put(unsigned char *image, int width, int height)
+{
+    SDL_Event event;
+
+    if (screen && overlay) {
+        SDL_Rect rect;
+        float aspect_ratio = (float)width / height;
+        int pic_width, pic_height;
+
+        if (width != cur_width || height != cur_height)
+            sdl_video_open(width, height);
+
+        if (SDL_MUSTLOCK(screen))
+            if (SDL_LockSurface(screen) < 0) return;
+
+        SDL_LockYUVOverlay(overlay);
+        memcpy(overlay->pixels[0], image, width * height);
+        memcpy(overlay->pixels[2], image + (width * height), (width * height / 4));
+        memcpy(overlay->pixels[1], image + (width * height * 5 / 4), (width * height / 4));
+        SDL_UnlockYUVOverlay(overlay);
+
+        if (SDL_MUSTLOCK(screen))
+            SDL_UnlockSurface(screen);
+
+        pic_height = screen->h;
+        pic_width = pic_height * aspect_ratio;
+        if (pic_width > screen->w) {
+            pic_width = screen->w;
+            pic_height = pic_width / aspect_ratio;
+        }
+        rect.x = (screen->w - pic_width) / 2;
+        rect.y = (screen->h - pic_height) / 2;
+        rect.w = pic_width;
+        rect.h = pic_height;
+
+        if (SDL_DisplayYUVOverlay(overlay, &rect))
+            motion_log(LOG_ERR, 1, "%s: SDL_DisplayYUVOverlay: %s", 
+                       __FUNCTION__, SDL_GetError());
+
+        if (SDL_PollEvent(&event)) {
+            if ((event.type == SDL_QUIT ||
+                (event.type == SDL_KEYDOWN &&
+                 event.key.keysym.sym == SDLK_ESCAPE)))
+                sdl_stop();
+            else if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_f) {
+                is_full_screen = !is_full_screen;
+                sdl_video_open(width, height);
+            }
+            else if (event.type == SDL_VIDEORESIZE)
+                screen = SDL_SetVideoMode(event.resize.w, event.resize.h,
+                                          screen->format->BitsPerPixel,
+                                          screen->flags);
+        }
+    }
+}
+
+void sdl_stop(void)
+{
+    if (screen) {
+        motion_log(LOG_INFO, 0, "%s: SDL quit", __FUNCTION__);
+        SDL_ShowCursor(SDL_ENABLE);
+        if (overlay) {
+            SDL_FreeYUVOverlay(overlay);
+            overlay = NULL;
+        }
+        SDL_Quit();
+        screen = NULL;
+    }
+}
Index: conf.c
===================================================================
--- conf.c	(revision 468)
+++ conf.c	(working copy)
@@ -86,6 +86,9 @@
     ffmpeg_bps:                     DEF_FFMPEG_BPS,
     ffmpeg_vbr:                     DEF_FFMPEG_VBR,
     ffmpeg_video_codec:             DEF_FFMPEG_CODEC,
+#ifdef HAVE_SDL
+    sdl_threadnr:                   0,
+#endif
     ipv6_enabled:                   0,
     stream_port:                    0,
     stream_quality:                 50,
@@ -741,7 +744,20 @@
     print_bool
     },
 #endif /* HAVE_FFMPEG */
+#ifdef HAVE_SDL
     {
+    "sdl_threadnr",
+    "\n############################################################\n"
+    "# SDL Window\n"
+    "############################################################\n\n"
+    "# Number of motion thread to show in SDL Window (default: 0 = disabled)",
+    1,
+    CONF_OFFSET(sdl_threadnr),
+    copy_int,
+    print_int
+    },
+#endif /* HAVE_SDL */
+    {
     "use_extpipe",    
     "\n############################################################\n"
     "# External pipe to video encoder\n"    
Index: sdl.h
===================================================================
--- sdl.h	(revision 0)
+++ sdl.h	(revision 0)
@@ -0,0 +1,17 @@
+/*  sdl.h
+ *
+ *  Include file for sdl.c
+ *      Copyright 2009 by Peter Holik (peter@holik.at)
+ *      This software is distributed under the GNU public license version 2
+ *      See also the file 'COPYING'.
+ */
+#ifndef _INCLUDE_SDL_H
+#define _INCLUDE_SDL_H
+
+#include "motion.h"
+
+int sdl_start(int width, int height);
+void sdl_put(unsigned char *image, int width, int height);
+void sdl_stop(void);
+
+#endif
Index: conf.h
===================================================================
--- conf.h	(revision 468)
+++ conf.h	(working copy)
@@ -62,6 +62,9 @@
     int ffmpeg_vbr;
     int ffmpeg_deinterlace;
     const char *ffmpeg_video_codec;
+#ifdef HAVE_SDL
+    int sdl_threadnr;
+#endif
     int ipv6_enabled;
     int stream_port;
     int stream_quality;
Index: configure.in
===================================================================
--- configure.in	(revision 468)
+++ configure.in	(working copy)
@@ -206,6 +206,44 @@
 fi
 
 
+#
+# Check for sdl library
+#
+SDL_SUPPORT="no"
+AC_ARG_WITH(sdl,
+[  --with-sdl              Compile with sdl support.],
+[],
+[withval="no"])
+AC_MSG_CHECKING(for sdl)
+if test "x$withval" = "xno"; then
+	AC_MSG_RESULT(skipped)
+else
+	if test "${FreeBSD}" != ""; then
+		CONFIG_SDL='sdl11-config'
+	else
+		CONFIG_SDL='sdl-config'
+	fi
+	if test -z "`($CONFIG_SDL --version) 2>/dev/null`" ;then
+		AC_MSG_RESULT(no)
+		if test "$withval" = "yes"; then
+			echo ""
+			echo "****************************************************"
+			echo "* sdl-config could not be found. Please install it *"
+			echo "* and remove the --with-sdl configure argument.    *"
+			echo "* libSDL can be found at http://www.libsdl.org     *"
+			echo "****************************************************"
+			echo ""
+		fi
+	else
+		AC_MSG_RESULT(yes)
+		SDL_SUPPORT="yes"
+		TEMP_LIBS="$TEMP_LIBS `${CONFIG_SDL} --libs`"
+		TEMP_CFLAGS="${TEMP_CFLAGS} `${CONFIG_SDL} --cflags`"
+		AC_DEFINE([HAVE_SDL],1,[Define to 1 if you have SDL support])
+		SDL_OBJ="sdl.o"
+		AC_SUBST(SDL_OBJ)
+	fi
+fi
 
 #
 # Check for the special mmx accelerated jpeg library
@@ -1192,6 +1230,12 @@
 	fi
 fi
 
+if test "${SDL_SUPPORT}" = "yes"; then
+	echo "SDL support:         Yes"
+else
+	echo "SDL support:         No"
+fi
+
 if test "${FFMPEG_OK}" = "found"; then
 	echo "FFmpeg support:      Yes"
 else
Index: motion.c
===================================================================
--- motion.c	(revision 468)
+++ motion.c	(working copy)
@@ -1946,6 +1946,10 @@
         if (cnt->conf.setup_mode) {
             event(cnt, EVENT_IMAGE, cnt->imgs.out, NULL, &cnt->pipe, cnt->currenttime_tm);
             event(cnt, EVENT_STREAM, cnt->imgs.out, NULL, NULL, cnt->currenttime_tm);
+#ifdef HAVE_SDL
+            if (cnt_list[0]->conf.sdl_threadnr == cnt->threadnr)
+                event(cnt, EVENT_SDL_PUT, cnt->imgs.out, NULL, NULL, cnt->currenttime_tm);
+#endif
         } else {
             event(cnt, EVENT_IMAGE, cnt->current_image->image, NULL, 
                   &cnt->pipe, &cnt->current_image->timestamp_tm);
@@ -1953,6 +1957,11 @@
             if (!cnt->conf.stream_motion || cnt->shots == 1)
                 event(cnt, EVENT_STREAM, cnt->current_image->image, NULL, NULL, 
                       &cnt->current_image->timestamp_tm);
+#ifdef HAVE_SDL
+            if (cnt_list[0]->conf.sdl_threadnr == cnt->threadnr)
+                event(cnt, EVENT_SDL_PUT, cnt->current_image->image, NULL, NULL,
+                      &cnt->current_image->timestamp_tm);
+#endif
         }
 
         event(cnt, EVENT_IMAGEM, cnt->imgs.out, NULL, &cnt->mpipe, cnt->currenttime_tm);
@@ -2528,6 +2537,11 @@
             start_motion_thread(cnt_list[i], &thread_attr);
         }
 
+#ifdef HAVE_SDL
+    if (cnt_list[0]->conf.sdl_threadnr > 0)
+        sdl_start(cnt_list[cnt_list[1] != NULL ? cnt_list[0]->conf.sdl_threadnr : 0]->conf.width,
+                  cnt_list[cnt_list[1] != NULL ? cnt_list[0]->conf.sdl_threadnr : 0]->conf.height);
+#endif
         /* Create a thread for the control interface if requested. Create it
          * detached and with 'motion_web_control' as the thread function.
          */
@@ -2608,6 +2622,9 @@
 
     } while (restart); /* loop if we're supposed to restart */
 
+#ifdef HAVE_SDL
+    sdl_stop();
+#endif
     // Be sure that http control exits fine
     cnt_list[0]->finish = 1;
     SLEEP(1, 0);
Index: motion.h
===================================================================
--- motion.h	(revision 468)
+++ motion.h	(working copy)
@@ -62,6 +62,9 @@
 #include "stream.h"
 #include "webhttpd.h"
 
+#ifdef HAVE_SDL
+#include "sdl.h"
+#endif
 /**
  * ATTRIBUTE_UNUSED:
  *
Index: motion-dist.conf.in
===================================================================
--- motion-dist.conf.in	(revision 468)
+++ motion-dist.conf.in	(working copy)
@@ -301,7 +301,13 @@
 # (default: off)
 ffmpeg_deinterlace off
 
+############################################################
+# SDL Window
+############################################################
 
+# Number of motion thread to show in SDL Window (default: 0 = disabled)
+0
+
 ############################################################
 # External pipe to video encoder
 # Replacement for FFMPEG builtin encoder for ffmpeg_output_movies only.
Index: config.h.in
===================================================================
--- config.h.in	(revision 468)
+++ config.h.in	(working copy)
@@ -24,6 +24,9 @@
 /* Define to 1 if you have PostgreSQL support */
 #undef HAVE_PGSQL
 
+/* Define to 1 if you have SDL support */
+#undef HAVE_SDL
+
 /* Define to 1 if you have the <signal.h> header file. */
 #undef HAVE_SIGNAL_H
 
Index: event.c
===================================================================
--- event.c	(revision 468)
+++ event.c	(working copy)
@@ -227,6 +227,16 @@
         stream_put(cnt, img);
 }
 
+#ifdef HAVE_SDL
+static void event_sdl_put(struct context *cnt, int type ATTRIBUTE_UNUSED,
+            unsigned char *img, char *dummy1 ATTRIBUTE_UNUSED,
+            void *dummy2 ATTRIBUTE_UNUSED, struct tm *tm ATTRIBUTE_UNUSED)
+{
+    sdl_put(img, cnt->imgs.width, cnt->imgs.height);
+}
+#endif
+
+
 #if !defined(WITHOUT_V4L) && !defined(BSD)
 static void event_vid_putpipe(struct context *cnt, int type ATTRIBUTE_UNUSED,
             unsigned char *img, char *dummy ATTRIBUTE_UNUSED, void *devpipe,
@@ -766,6 +776,12 @@
     EVENT_IMAGE_SNAPSHOT,
     event_image_snapshot
     },
+#ifdef HAVE_SDL
+    {
+    EVENT_SDL_PUT,
+    event_sdl_put
+    },
+#endif
 #if !defined(WITHOUT_V4L) && !defined(BSD)
     {
     EVENT_IMAGE,
Index: event.h
===================================================================
--- event.h	(revision 468)
+++ event.h	(working copy)
@@ -30,6 +30,7 @@
 #define EVENT_AREA_DETECTED     17
 #define EVENT_CAMERA_LOST       18
 #define EVENT_FFMPEG_PUT        19
+#define EVENT_SDL_PUT           20
 
 
 typedef void(* event_handler)(struct context *, int, unsigned char *, char *, void *, struct tm *);
Index: logger.c
===================================================================
--- logger.c	(revision 468)
+++ logger.c	(working copy)
@@ -77,7 +77,7 @@
 {
     int errno_save, n;
     char buf[1024];
-#if (!defined(BSD)) && (!(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE)
+#if (!defined(BSD)) 
     char msg_buf[100];
 #endif
     va_list ap;
