Index: src/add-ons/screen_savers/Jamfile
===================================================================
--- src/add-ons/screen_savers/Jamfile	(revision 33261)
+++ src/add-ons/screen_savers/Jamfile	(working copy)
@@ -3,8 +3,9 @@
 SubInclude HAIKU_TOP src add-ons screen_savers debugnow ;
 SubInclude HAIKU_TOP src add-ons screen_savers flurry ;
 SubInclude HAIKU_TOP src add-ons screen_savers haiku ;
+SubInclude HAIKU_TOP src add-ons screen_savers icons ;
 SubInclude HAIKU_TOP src add-ons screen_savers ifs ;
 SubInclude HAIKU_TOP src add-ons screen_savers message ;
+SubInclude HAIKU_TOP src add-ons screen_savers simpleclock ;
 SubInclude HAIKU_TOP src add-ons screen_savers slideshowsaver ;
 SubInclude HAIKU_TOP src add-ons screen_savers spider ;
-SubInclude HAIKU_TOP src add-ons screen_savers simpleclock ;
Index: src/add-ons/screen_savers/icons/IconDisplay.cpp
===================================================================
--- src/add-ons/screen_savers/icons/IconDisplay.cpp	(revision 0)
+++ src/add-ons/screen_savers/icons/IconDisplay.cpp	(revision 0)
@@ -0,0 +1,120 @@
+/*
+	Copyright 2009 Vincent Duvert, vincent.duvert@free.fr
+	All rights reserved. Distributed under the terms of the MIT License.
+*/
+
+#include "IconDisplay.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <Bitmap.h>
+#include <IconUtils.h>
+
+
+#define RAND_BETWEEN(a, b) ((rand() % ((b) - (a) + 1) + (a)))
+#define SHOW_TICKS_MIN 20
+#define SHOW_TICKS_MAX 50
+#define STAY_TICKS_MIN 50
+#define STAY_TICKS_MAX 100
+#define HIDE_TICKS_MIN 20
+#define HIDE_TICKS_MAX 50
+
+
+IconDisplay::IconDisplay()
+	:
+	fIsRunning(false),
+	fBitmap(NULL)
+{
+}
+
+
+IconDisplay::~IconDisplay()
+{
+	delete fBitmap;
+}
+
+
+void
+IconDisplay::Run(VectorIcon* icon, BRect frame)
+{
+	delete fBitmap;
+
+	fBitmap = new BBitmap(BRect(0, 0, frame.Width(), frame.Height()), 0,
+		B_RGBA32);
+	BIconUtils::GetVectorIcon(icon->data, icon->size, fBitmap);
+
+	fState = 0;
+	fTicks = 0;
+	fDelay = RAND_BETWEEN(SHOW_TICKS_MIN, SHOW_TICKS_MAX);
+	fFrame = frame;
+
+	fIsRunning = true;
+}
+
+
+void
+IconDisplay::ClearOn(BView* view)
+{
+	if (!fIsRunning || fState == 2)
+		return;
+
+	view->FillRect(fFrame);
+}
+
+
+void
+IconDisplay::DrawOn(BView* view, uint32 delta)
+{
+	if (!fIsRunning)
+		return;
+
+	fTicks += delta;
+
+	rgb_color backColor = view->HighColor();
+
+	switch (fState) {
+		case 0: // Progressive showing
+			if (fTicks < fDelay)
+				backColor.alpha = (fTicks * 255) / fDelay;
+			else
+				fState++;
+		break;
+
+		case 1: // Completed showing
+			backColor.alpha = 255;
+			fTicks = 0;
+			fDelay = RAND_BETWEEN(STAY_TICKS_MIN, STAY_TICKS_MAX);
+			fState++;
+		break;
+
+		case 2: // Waiting
+			if (fTicks < fDelay)
+				return;
+			fTicks = 0;
+			backColor.alpha = 255;
+			fDelay = RAND_BETWEEN(HIDE_TICKS_MIN, HIDE_TICKS_MAX);
+			fState++;
+			return;
+		break;
+
+		case 3: // Progressive hiding
+			if (fTicks < fDelay) {
+				backColor.alpha = 255 - (fTicks * 255) / fDelay;
+			} else {
+				backColor.alpha = 0;
+				fState++;
+			}
+		break;
+
+		default: // Finished
+			fIsRunning = false;
+			return;
+		break;
+	};
+
+	view->SetHighColor(backColor);
+	view->DrawBitmap(fBitmap, BPoint(fFrame.left, fFrame.top));
+	backColor.alpha = 255;
+	view->SetHighColor(backColor);
+}
Index: src/add-ons/screen_savers/icons/IconsSaver.h
===================================================================
--- src/add-ons/screen_savers/icons/IconsSaver.h	(revision 0)
+++ src/add-ons/screen_savers/icons/IconsSaver.h	(revision 0)
@@ -0,0 +1,39 @@
+/*
+	Copyright 2009 Vincent Duvert, vincent.duvert@free.fr
+	All rights reserved. Distributed under the terms of the MIT License.
+*/
+
+#ifndef ICONS_SAVER_H
+#define ICONS_SAVER_H
+
+#include <List.h>
+#include <ScreenSaver.h>
+
+
+class IconDisplay;
+
+
+class IconsSaver: public BScreenSaver {
+public:
+								IconsSaver(BMessage* archive, image_id);
+	virtual						~IconsSaver();
+
+	virtual	status_t			StartSaver(BView *view, bool preview);
+	virtual	void				StopSaver();
+
+	virtual	void				Draw(BView *view, int32 frame);
+
+	virtual	void				StartConfig(BView* view);
+
+private:
+	BList						fVectorIcons;
+	int32						fVectorIconsCount;
+	IconDisplay*				fIcons;
+
+	BBitmap*					fBackBitmap;
+	BView*						fBackView;
+
+	uint16						fMinSize, fMaxSize;
+};
+
+#endif
Index: src/add-ons/screen_savers/icons/IconDisplay.h
===================================================================
--- src/add-ons/screen_savers/icons/IconDisplay.h	(revision 0)
+++ src/add-ons/screen_savers/icons/IconDisplay.h	(revision 0)
@@ -0,0 +1,44 @@
+/*
+	Copyright 2009 Vincent Duvert, vincent.duvert@free.fr
+	All rights reserved. Distributed under the terms of the MIT License.
+*/
+
+#ifndef ICON_DISPLAY_H
+#define ICON_DISPLAY_H
+
+#include <Rect.h>
+#include <View.h>
+
+struct VectorIcon {
+        uint8* data;
+        size_t size;
+};
+
+
+class BBitmap;
+
+
+class IconDisplay {
+public:
+								IconDisplay();
+								~IconDisplay();
+	
+			void				Run(VectorIcon* icon, BRect frame);
+	inline	bool				IsRunning() { return fIsRunning; };
+	inline	BRect				GetFrame() { return fFrame; };
+
+			void				ClearOn(BView* view);
+			void				DrawOn(BView* view, uint32 delta);
+
+private:
+	bool						fIsRunning;
+	uint8						fState;
+	
+	int32						fTicks;
+	int32						fDelay;
+
+	BBitmap*					fBitmap;
+	BRect						fFrame;
+};
+
+#endif
Index: src/add-ons/screen_savers/icons/Jamfile
===================================================================
--- src/add-ons/screen_savers/icons/Jamfile	(revision 0)
+++ src/add-ons/screen_savers/icons/Jamfile	(revision 0)
@@ -0,0 +1,8 @@
+SubDir HAIKU_TOP src add-ons screen_savers icons ;
+
+UseLibraryHeaders icon ;
+
+ScreenSaver Icons :
+	IconDisplay.cpp IconsSaver.cpp : 
+	be libscreensaver.so libicon.a $(TARGET_LIBSUPC++)
+;
Index: src/add-ons/screen_savers/icons/IconsSaver.cpp
===================================================================
--- src/add-ons/screen_savers/icons/IconsSaver.cpp	(revision 0)
+++ src/add-ons/screen_savers/icons/IconsSaver.cpp	(revision 0)
@@ -0,0 +1,202 @@
+/*
+	Copyright 2009 Vincent Duvert, vincent.duvert@free.fr
+	All rights reserved. Distributed under the terms of the MIT License.
+*/
+
+#include "IconsSaver.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <Bitmap.h>
+#include <MimeType.h>
+#include <StringView.h>
+
+#include "IconDisplay.h"
+
+
+#define MAX_ICONS 15
+#define MAX_SIZE 20 // In percentage of the screen width
+#define MIN_SIZE 5 // Same here
+#define RAND_BETWEEN(a, b) ((rand() % ((b) - (a) + 1) + (a)))
+
+
+const rgb_color kBackgroundColor = ui_color(B_DESKTOP_COLOR);
+
+
+BScreenSaver* instantiate_screen_saver(BMessage* msg, image_id image)
+{
+	return new IconsSaver(msg, image);
+}
+
+
+IconsSaver::IconsSaver(BMessage* msg, image_id image)
+	:
+	BScreenSaver(msg, image),
+	fVectorIconsCount(0),
+	fIcons(NULL),
+	fBackBitmap(NULL),
+	fBackView(NULL),
+	fMinSize(0),
+	fMaxSize(0)
+{
+}
+
+
+IconsSaver::~IconsSaver()
+{
+}
+
+
+status_t
+IconsSaver::StartSaver(BView *view, bool /*preview*/)
+{
+	if (fVectorIconsCount <= 0) {
+		// Load the vector icons from the MIME types
+		BMessage types;
+		BMimeType::GetInstalledTypes(&types);
+
+		for (int32 index = 0 ; ; index++) {
+			const char* type;
+			if (types.FindString("types", index, &type) != B_OK)
+				break;
+
+			BMimeType mimeType(type);
+			uint8* vectorData = NULL;
+			size_t size = 0;
+
+			if (mimeType.GetIcon(&vectorData, &size) != B_OK || size == 0)
+				continue;
+
+			VectorIcon* icon = new VectorIcon;
+			icon->data = vectorData;
+			icon->size = size;
+
+			fVectorIcons.AddItem(icon);
+		}
+
+		fVectorIconsCount = fVectorIcons.CountItems();
+	}
+
+	srand(system_time() % INT_MAX);
+
+	BRect screenRect(0, 0, view->Frame().Width(), view->Frame().Height());
+	fBackBitmap = new BBitmap(screenRect, B_RGBA32, true);
+	if (!fBackBitmap->IsValid())
+		return B_NO_MEMORY;
+
+	fBackView = new BView(screenRect, "back view", 0, 0);
+	if (fBackView == NULL)
+		return B_NO_MEMORY;
+
+	fBackView->SetViewColor(kBackgroundColor);
+	fBackView->SetHighColor(kBackgroundColor);
+
+	fBackBitmap->AddChild(fBackView);
+	if (fBackBitmap->Lock()) {
+		fBackView->FillRect(fBackView->Frame());
+		fBackView->SetDrawingMode(B_OP_ALPHA);
+		fBackView->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
+		fBackView->Sync();
+		fBackBitmap->Unlock();
+	}
+
+	fIcons = new IconDisplay[MAX_ICONS];
+
+	fMaxSize = (screenRect.IntegerWidth() * MAX_SIZE) / 100;
+	fMinSize = (screenRect.IntegerWidth() * MIN_SIZE) / 100;
+	if (fMaxSize > 255)
+		fMaxSize = 255;
+
+	if (fMaxSize > screenRect.IntegerHeight())
+		fMaxSize = screenRect.IntegerHeight();
+
+	if (fMinSize > fMaxSize)
+		fMinSize = fMaxSize;
+
+	return B_OK;
+}
+
+
+void
+IconsSaver::StopSaver()
+{
+	delete[] fIcons;
+}
+
+
+void
+IconsSaver::Draw(BView *view, int32 frame)
+{
+	static int32 previousFrame = 0;
+
+	// Update drawing
+	if (fBackBitmap->Lock()) {
+		for (uint8 i = 0 ; i < MAX_ICONS ; i++) {
+			fIcons[i].ClearOn(fBackView);
+		}
+
+		int32 delta = frame - previousFrame;
+
+		for (uint8 i = 0 ; i < MAX_ICONS ; i++) {
+			fIcons[i].DrawOn(fBackView, delta);
+		}
+		fBackView->Sync();
+		fBackBitmap->Unlock();
+	}
+
+	// Sync the view with the back buffer
+	view->DrawBitmap(fBackBitmap);
+	previousFrame = frame;
+
+	if (fVectorIconsCount <= 0)
+		return;
+
+	// Restart one icon
+	for (uint8 i = 0 ; i < MAX_ICONS ; i++) {
+		if (!fIcons[i].IsRunning()) {
+			uint16 size = RAND_BETWEEN(fMinSize, fMaxSize);
+			uint16 maxX = view->Frame().IntegerWidth() - size;
+			uint16 maxY = view->Frame().IntegerHeight() - size;
+
+			BRect iconFrame(0, 0, size, size);
+			iconFrame.OffsetTo(RAND_BETWEEN(0, maxX), RAND_BETWEEN(0, maxY));
+
+			// Check that the icon doesn't overlap with others
+			for (uint8 j = 0 ; j < MAX_ICONS ; j++) {
+				if (fIcons[j].IsRunning() &&
+					iconFrame.Intersects(fIcons[j].GetFrame()))
+					return;
+			}
+
+			int32 index = RAND_BETWEEN(0, fVectorIconsCount - 1);
+
+			fIcons[i].Run((VectorIcon*)fVectorIcons.ItemAt(index), iconFrame);
+
+			return;
+		}
+	}
+}
+
+
+void
+IconsSaver::StartConfig(BView* view)
+{
+	const uint8 spacer = 5;
+	BRect frame = view->Frame();
+	BRect position(spacer, spacer, frame.Width() - 2 * spacer, 0);
+
+	view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
+
+	BStringView* stringView = new BStringView(position, "", "Icons");
+	stringView->SetFont(be_bold_font);
+	stringView->ResizeToPreferred();
+	position.top += stringView->Frame().Height();
+	view->AddChild(stringView);
+
+	stringView = new BStringView(position, "", "By Vincent Duvert");
+	stringView->ResizeToPreferred();
+	position.top += stringView->Frame().Height();
+	view->AddChild(stringView);
+}
+
