From 9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80 Mon Sep 17 00:00:00 2001
From: maxim-yurchuk <maxim-yurchuk@yandex-team.com>
Date: Wed, 9 Oct 2024 12:29:46 +0300
Subject: publishFullContrib: true for ydb

<HIDDEN_URL>
commit_hash:c82a80ac4594723cebf2c7387dec9c60217f603e
---
 .../src/platform/AmigaOS/agg_platform_support.cpp  |  977 ++++++++++++
 .../src/platform/BeOS/agg_platform_support.cpp     |  990 ++++++++++++
 .../src/platform/X11/agg_platform_support.cpp      | 1601 +++++++++++++++++++
 .../agg24-svn/src/platform/mac/agg_mac_pmap.cpp    |  298 ++++
 .../src/platform/mac/agg_platform_support.cpp      | 1053 +++++++++++++
 .../src/platform/sdl/agg_platform_support.cpp      |  708 +++++++++
 .../src/platform/win32/agg_platform_support.cpp    | 1655 ++++++++++++++++++++
 .../agg24-svn/src/platform/win32/agg_win32_bmp.cpp |  631 ++++++++
 8 files changed, 7913 insertions(+)
 create mode 100644 contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp
 create mode 100644 contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp
 create mode 100644 contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp
 create mode 100644 contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp
 create mode 100644 contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp
 create mode 100644 contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp
 create mode 100644 contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp
 create mode 100644 contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp

(limited to 'contrib/python/matplotlib/py2/extern/agg24-svn/src/platform')

diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp
new file mode 100644
index 0000000000..b14d09cd1c
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp
@@ -0,0 +1,977 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software 
+// is granted provided this copyright notice appears in all copies. 
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+//          mcseemagg@yahoo.com
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// class platform_support
+//
+//----------------------------------------------------------------------------
+
+#include "platform/agg_platform_support.h"
+#include "util/agg_color_conv_rgb8.h"
+
+#include <sys/time.h>
+#include <cstring>
+
+#include <classes/requester.h>
+#include <classes/window.h>
+#include <datatypes/pictureclass.h>
+#include <proto/exec.h>
+#include <proto/datatypes.h>
+#include <proto/dos.h>
+#include <proto/graphics.h>
+#include <proto/intuition.h>
+#include <proto/keymap.h>
+#include <proto/Picasso96API.h>
+#include <proto/utility.h>
+
+Library* DataTypesBase = 0;
+Library* GraphicsBase = 0;
+Library* IntuitionBase = 0;
+Library* KeymapBase = 0;
+Library* P96Base = 0;
+
+DataTypesIFace* IDataTypes = 0;
+GraphicsIFace* IGraphics = 0;
+IntuitionIFace* IIntuition = 0;
+KeymapIFace* IKeymap = 0;
+P96IFace* IP96 = 0;
+
+Class* RequesterClass = 0;
+Class* WindowClass = 0;
+
+
+namespace agg
+{
+	void handle_idcmp(Hook* hook, APTR win, IntuiMessage* msg);
+
+	//------------------------------------------------------------------------
+	class platform_specific
+	{
+	public:
+		platform_specific(platform_support& support, pix_format_e format,
+			bool flip_y);
+		~platform_specific();
+		bool handle_input();
+		bool load_img(const char* file, unsigned idx, rendering_buffer* rbuf);
+		bool create_img(unsigned idx, rendering_buffer* rbuf, unsigned width,
+			unsigned height);
+		bool make_bitmap();
+	public:
+		platform_support& m_support;
+		RGBFTYPE m_ftype;
+		pix_format_e m_format;
+		unsigned m_bpp;
+		BitMap* m_bitmap;
+		bool m_flip_y;
+		uint16 m_width;
+		uint16 m_height;
+		APTR m_window_obj;
+		Window* m_window;
+		Hook* m_idcmp_hook;
+		unsigned m_input_flags;
+		bool m_dragging;
+		double m_start_time;
+		uint16 m_last_key;
+		BitMap* m_img_bitmaps[platform_support::max_images];
+	};
+
+	//------------------------------------------------------------------------
+	platform_specific::platform_specific(platform_support& support,
+		pix_format_e format, bool flip_y) :
+		m_support(support),
+		m_ftype(RGBFB_NONE),
+		m_format(format),
+		m_bpp(0),
+		m_bitmap(0),
+		m_flip_y(flip_y),
+		m_width(0),
+		m_height(0),
+		m_window_obj(0),
+		m_window(0),
+		m_idcmp_hook(0),
+		m_input_flags(0),
+		m_dragging(false),
+		m_start_time(0.0),
+		m_last_key(0)
+	{
+		switch ( format )
+		{
+		case pix_format_gray8:
+			// Not supported.
+			break;
+		case pix_format_rgb555:
+			m_ftype = RGBFB_R5G5B5;
+			m_bpp = 15;
+			break;
+		case pix_format_rgb565:
+			m_ftype = RGBFB_R5G6B5;
+			m_bpp = 16;
+			break;
+		case pix_format_rgb24:
+			m_ftype = RGBFB_R8G8B8;
+			m_bpp = 24;
+			break;
+		case pix_format_bgr24:
+			m_ftype = RGBFB_B8G8R8;
+			m_bpp = 24;
+			break;
+		case pix_format_bgra32:
+			m_ftype = RGBFB_B8G8R8A8;
+			m_bpp = 32;
+			break;
+		case pix_format_abgr32:
+			m_ftype = RGBFB_A8B8G8R8;
+			m_bpp = 32;
+			break;
+		case pix_format_argb32:
+			m_ftype = RGBFB_A8R8G8B8;
+			m_bpp = 32;
+			break;
+        case pix_format_rgba32:
+			m_ftype = RGBFB_R8G8B8A8;
+			m_bpp = 32;
+			break;
+		}
+
+		for ( unsigned i = 0; i < platform_support::max_images; ++i )
+		{
+			m_img_bitmaps[i] = 0;
+		}
+	}
+
+	//------------------------------------------------------------------------
+	platform_specific::~platform_specific()
+	{
+		IIntuition->DisposeObject(m_window_obj);
+
+		IP96->p96FreeBitMap(m_bitmap);
+
+		for ( unsigned i = 0; i < platform_support::max_images; ++i )
+		{
+			IP96->p96FreeBitMap(m_img_bitmaps[i]);
+		}
+
+		if ( m_idcmp_hook != 0 )
+		{
+			IExec->FreeSysObject(ASOT_HOOK, m_idcmp_hook);
+		}
+	}
+
+	//------------------------------------------------------------------------
+	bool platform_specific::handle_input()
+	{
+		int16 code = 0;
+		uint32 result = 0;
+		Object* obj = reinterpret_cast<Object*>(m_window_obj);
+
+		while ( (result = IIntuition->IDoMethod(obj, WM_HANDLEINPUT,
+				&code)) != WMHI_LASTMSG )
+		{
+			switch ( result & WMHI_CLASSMASK )
+			{
+			case WMHI_CLOSEWINDOW:
+				return true;
+				break;
+			case WMHI_INTUITICK:
+				if ( !m_support.wait_mode() )
+				{
+					m_support.on_idle();
+				}
+				break;
+			case WMHI_NEWSIZE:
+				if ( make_bitmap() )
+				{
+					m_support.trans_affine_resizing(m_width, m_height);
+					m_support.on_resize(m_width, m_height);
+					m_support.force_redraw();
+				}
+				break;
+			}
+		}
+
+		return false;
+	}		
+
+	//------------------------------------------------------------------------
+	bool platform_specific::load_img(const char* file, unsigned idx,
+		rendering_buffer* rbuf)
+	{
+		if ( m_img_bitmaps[idx] != 0 )
+		{
+			IP96->p96FreeBitMap(m_img_bitmaps[idx]);
+			m_img_bitmaps[idx] = 0;
+		}
+
+		bool result = false;
+
+		Object* picture = IDataTypes->NewDTObject(const_cast<STRPTR>(file),
+			DTA_GroupID, GID_PICTURE,
+			PDTA_DestMode, PMODE_V43,
+			PDTA_Remap, FALSE,
+			TAG_END);
+		if ( picture != 0 )
+		{
+			gpLayout layout;
+			layout.MethodID = DTM_PROCLAYOUT;
+			layout.gpl_GInfo = 0;
+			layout.gpl_Initial = 1;
+			ULONG loaded = IDataTypes->DoDTMethodA(picture, 0, 0,
+				reinterpret_cast<Msg>(&layout));
+			if ( loaded != 0 )
+			{
+				BitMap* src_bitmap = 0;
+				IDataTypes->GetDTAttrs(picture,
+					PDTA_ClassBitMap, &src_bitmap,
+					TAG_END);
+
+				bool supported = false;
+
+				RGBFTYPE ftype = static_cast<RGBFTYPE>(IP96->p96GetBitMapAttr(
+					src_bitmap, P96BMA_RGBFORMAT));
+
+				switch ( ftype )
+				{
+				case RGBFB_R8G8B8:
+					supported = true;
+					break;
+				default:
+					m_support.message("File uses unsupported graphics mode.");
+					break;
+				}
+
+				if ( supported )  {
+					uint16 width = IP96->p96GetBitMapAttr(src_bitmap,
+						P96BMA_WIDTH);
+					uint16 height = IP96->p96GetBitMapAttr(src_bitmap,
+						P96BMA_HEIGHT);
+
+					m_img_bitmaps[idx] = IP96->p96AllocBitMap(width, height,
+						m_bpp, BMF_USERPRIVATE, 0, m_ftype);
+					if ( m_img_bitmaps[idx] != 0 )
+					{
+						int8u* buf = reinterpret_cast<int8u*>(
+							IP96->p96GetBitMapAttr(m_img_bitmaps[idx],
+							P96BMA_MEMORY));
+						int bpr = IP96->p96GetBitMapAttr(m_img_bitmaps[idx],
+							P96BMA_BYTESPERROW);
+						int stride = (m_flip_y) ? -bpr : bpr;
+						rbuf->attach(buf, width, height, stride);
+
+						// P96 sets the alpha to zero so it can't be used to
+						// color convert true color modes.
+						if ( m_bpp == 32 )
+						{
+							RenderInfo ri;
+							int32 lock = IP96->p96LockBitMap(src_bitmap,
+								reinterpret_cast<uint8*>(&ri),
+								sizeof(RenderInfo));
+
+							rendering_buffer rbuf_src;
+							rbuf_src.attach(
+								reinterpret_cast<int8u*>(ri.Memory),
+								width, height, (m_flip_y) ?
+									-ri.BytesPerRow : ri.BytesPerRow);
+
+							switch ( m_format )
+							{
+							case pix_format_bgra32:
+								color_conv(rbuf, &rbuf_src,
+									color_conv_rgb24_to_bgra32());
+								break;
+							case pix_format_abgr32:
+								color_conv(rbuf, &rbuf_src,
+									color_conv_rgb24_to_abgr32());
+								break;
+							case pix_format_argb32:
+								color_conv(rbuf, &rbuf_src,
+									color_conv_rgb24_to_argb32());
+								break;
+							case pix_format_rgba32:
+								color_conv(rbuf, &rbuf_src,
+									color_conv_rgb24_to_rgba32());
+								break;
+							}
+
+							IP96->p96UnlockBitMap(src_bitmap, lock);
+						}
+						else
+						{
+							IGraphics->BltBitMap(src_bitmap, 0, 0,
+								m_img_bitmaps[idx], 0, 0, width, height,
+								ABC|ABNC, 0xFF, 0);
+						}
+
+						result = true;
+					}
+				}
+			}
+		}
+
+		IGraphics->WaitBlit();
+		IDataTypes->DisposeDTObject(picture);
+
+		return result;
+	}
+
+	//------------------------------------------------------------------------
+	bool platform_specific::create_img(unsigned idx, rendering_buffer* rbuf,
+		unsigned width, unsigned height)
+	{
+		if ( m_img_bitmaps[idx] != 0 )
+		{
+			IP96->p96FreeBitMap(m_img_bitmaps[idx]);
+			m_img_bitmaps[idx] = 0;
+		}
+
+		m_img_bitmaps[idx] = IP96->p96AllocBitMap(width, height,
+			m_bpp, BMF_USERPRIVATE, m_bitmap, m_ftype);
+		if ( m_img_bitmaps[idx] != 0 )
+		{
+			int8u* buf = reinterpret_cast<int8u*>(
+				IP96->p96GetBitMapAttr(m_img_bitmaps[idx],
+				P96BMA_MEMORY));
+			int bpr = IP96->p96GetBitMapAttr(m_img_bitmaps[idx],
+				P96BMA_BYTESPERROW);
+			int stride = (m_flip_y) ? -bpr : bpr;
+
+			rbuf->attach(buf, width, height, stride);
+
+			return true;
+		}
+
+		return false;
+	}
+
+	//------------------------------------------------------------------------
+	bool platform_specific::make_bitmap()
+	{
+		uint32 width = 0;
+		uint32 height = 0;
+		IIntuition->GetWindowAttrs(m_window,
+			WA_InnerWidth, &width,
+			WA_InnerHeight, &height,
+			TAG_END);
+
+		BitMap* bm = IP96->p96AllocBitMap(width, height, m_bpp,
+			BMF_USERPRIVATE|BMF_CLEAR, 0, m_ftype);
+		if ( bm == 0 )
+		{
+			return false;
+		}
+
+		int8u* buf = reinterpret_cast<int8u*>(
+			IP96->p96GetBitMapAttr(bm, P96BMA_MEMORY));
+		int bpr = IP96->p96GetBitMapAttr(bm, P96BMA_BYTESPERROW);
+		int stride = (m_flip_y) ? -bpr : bpr;
+
+		m_support.rbuf_window().attach(buf, width, height, stride);
+
+		if ( m_bitmap != 0 )
+		{
+			IP96->p96FreeBitMap(m_bitmap);
+			m_bitmap = 0;
+		}
+
+		m_bitmap = bm;
+		m_width = width;
+		m_height = height;
+
+		return true;
+	}
+
+	//------------------------------------------------------------------------
+	platform_support::platform_support(pix_format_e format, bool flip_y) :
+		m_specific(new platform_specific(*this, format, flip_y)),
+		m_format(format),
+		m_bpp(m_specific->m_bpp),
+		m_window_flags(0),
+		m_wait_mode(true),
+		m_flip_y(flip_y),
+		m_initial_width(10),
+		m_initial_height(10)
+	{
+		std::strncpy(m_caption, "Anti-Grain Geometry", 256);
+	}
+
+	//------------------------------------------------------------------------
+	platform_support::~platform_support()
+	{
+		delete m_specific;
+	}
+
+	//------------------------------------------------------------------------
+	void platform_support::caption(const char* cap)
+	{
+		std::strncpy(m_caption, cap, 256);
+		if ( m_specific->m_window != 0 )
+		{
+			const char* ignore = reinterpret_cast<const char*>(-1);
+			IIntuition->SetWindowAttr(m_specific->m_window,
+				WA_Title, m_caption, sizeof(char*));
+		}
+	}
+
+	//------------------------------------------------------------------------
+	void platform_support::start_timer()
+	{
+		timeval tv;
+		gettimeofday(&tv, 0);
+		m_specific->m_start_time = tv.tv_secs + tv.tv_micro/1e6;
+	}
+
+	//------------------------------------------------------------------------
+	double platform_support::elapsed_time() const
+	{
+		timeval tv;
+		gettimeofday(&tv, 0);
+		double end_time = tv.tv_secs + tv.tv_micro/1e6;
+
+		double elasped_seconds = end_time - m_specific->m_start_time;
+		double elasped_millis = elasped_seconds*1e3;
+
+		return elasped_millis;
+	}
+
+	//------------------------------------------------------------------------
+	void* platform_support::raw_display_handler()
+	{
+		return 0;	// Not available.
+	}
+
+	//------------------------------------------------------------------------
+	void platform_support::message(const char* msg)
+	{
+		APTR req = IIntuition->NewObject(RequesterClass, 0,
+			REQ_TitleText, "Anti-Grain Geometry",
+			REQ_Image, REQIMAGE_INFO,
+			REQ_BodyText, msg,
+			REQ_GadgetText, "_Ok",
+			TAG_END);
+		if ( req == 0 )
+		{
+			IDOS->Printf("Message: %s\n", msg);
+			return;
+		}
+
+		orRequest reqmsg;
+		reqmsg.MethodID = RM_OPENREQ;
+		reqmsg.or_Attrs = 0;
+		reqmsg.or_Window = m_specific->m_window;
+		reqmsg.or_Screen = 0;
+		
+		IIntuition->IDoMethodA(reinterpret_cast<Object*>(req),
+			reinterpret_cast<Msg>(&reqmsg));
+		IIntuition->DisposeObject(req);
+	}
+
+	//------------------------------------------------------------------------
+	bool platform_support::init(unsigned width, unsigned height,
+		unsigned flags)
+	{
+		if( m_specific->m_ftype == RGBFB_NONE )
+		{
+			message("Unsupported mode requested.");
+			return false;
+		}
+
+		m_window_flags = flags;
+
+		m_specific->m_idcmp_hook = reinterpret_cast<Hook*>(
+			IExec->AllocSysObjectTags(ASOT_HOOK,
+				ASOHOOK_Entry, handle_idcmp,
+				ASOHOOK_Data, this,
+				TAG_END));
+		if ( m_specific->m_idcmp_hook == 0 )
+		{
+			return false;
+		}
+
+		m_specific->m_window_obj = IIntuition->NewObject(WindowClass, 0,
+				WA_Title, m_caption,
+				WA_AutoAdjustDClip, TRUE,
+				WA_InnerWidth, width,
+				WA_InnerHeight, height,
+				WA_Activate, TRUE,
+				WA_SmartRefresh, TRUE,
+				WA_NoCareRefresh, TRUE,
+				WA_CloseGadget, TRUE,
+				WA_DepthGadget, TRUE,
+				WA_SizeGadget, (flags & agg::window_resize) ? TRUE : FALSE,
+				WA_DragBar, TRUE,
+				WA_AutoAdjust, TRUE,
+				WA_ReportMouse, TRUE,
+				WA_RMBTrap, TRUE,
+				WA_MouseQueue, 1,
+				WA_IDCMP,
+					IDCMP_NEWSIZE |
+					IDCMP_MOUSEBUTTONS |
+					IDCMP_MOUSEMOVE |
+					IDCMP_RAWKEY |
+					IDCMP_INTUITICKS,
+				WINDOW_IDCMPHook, m_specific->m_idcmp_hook,
+				WINDOW_IDCMPHookBits,
+					IDCMP_MOUSEBUTTONS |
+					IDCMP_MOUSEMOVE |
+					IDCMP_RAWKEY,
+				TAG_END);
+		if ( m_specific->m_window_obj == 0 )
+		{
+			return false;
+		}
+
+		Object* obj = reinterpret_cast<Object*>(m_specific->m_window_obj);
+		m_specific->m_window =
+			reinterpret_cast<Window*>(IIntuition->IDoMethod(obj, WM_OPEN));
+		if ( m_specific->m_window == 0 )
+		{
+			return false;
+		}
+
+		RGBFTYPE ftype = static_cast<RGBFTYPE>(IP96->p96GetBitMapAttr(
+			m_specific->m_window->RPort->BitMap, P96BMA_RGBFORMAT));
+
+		switch ( ftype )
+		{
+		case RGBFB_A8R8G8B8:
+		case RGBFB_B8G8R8A8:
+		case RGBFB_R5G6B5PC:
+			break;
+		default:
+			message("Unsupported screen mode.\n");
+			return false;
+		}
+
+		if ( !m_specific->make_bitmap() )
+		{
+			return false;
+		}
+
+		m_initial_width = width;
+		m_initial_height = height;
+
+		on_init();
+		on_resize(width, height);
+		force_redraw();
+
+		return true;
+	}
+
+	//------------------------------------------------------------------------
+	int platform_support::run()
+	{
+		uint32 window_mask = 0;
+		IIntuition->GetAttr(WINDOW_SigMask, m_specific->m_window_obj,
+			&window_mask);
+		uint32 wait_mask = window_mask | SIGBREAKF_CTRL_C;
+
+		bool done = false;
+
+		while ( !done )
+		{
+			uint32 sig_mask = IExec->Wait(wait_mask);
+			if ( sig_mask & SIGBREAKF_CTRL_C )
+			{
+				done = true;
+			}
+			else
+			{
+				done = m_specific->handle_input();
+			}
+		}
+
+		return 0;
+	}
+
+	//------------------------------------------------------------------------
+	const char* platform_support::img_ext() const
+	{
+		return ".bmp";
+	}
+
+	//------------------------------------------------------------------------
+	const char* platform_support::full_file_name(const char* file_name)
+	{
+		return file_name;
+	}
+
+	//------------------------------------------------------------------------
+	bool platform_support::load_img(unsigned idx, const char* file)
+	{
+		if ( idx < max_images )
+		{
+			static char fn[1024];
+			std::strncpy(fn, file, 1024);
+			int len = std::strlen(fn);
+			if ( len < 4 || std::strcmp(fn + len - 4, ".bmp") != 0 )
+			{
+				std::strncat(fn, ".bmp", 1024);
+			}
+
+			return m_specific->load_img(fn, idx, &m_rbuf_img[idx]);
+		}
+
+		return false;
+	}
+
+	//------------------------------------------------------------------------
+	bool platform_support::save_img(unsigned idx, const char* file)
+	{
+		message("Not supported");
+		return false;
+	}
+
+	//------------------------------------------------------------------------
+	bool platform_support::create_img(unsigned idx, unsigned width,
+		unsigned height)
+	{
+		if ( idx < max_images )
+		{
+			if ( width == 0 )
+			{
+				width = m_specific->m_width;
+			}
+
+			if ( height == 0 )
+			{
+				height = m_specific->m_height;
+			}
+
+			return m_specific->create_img(idx, &m_rbuf_img[idx], width,
+				height);
+		}
+
+		return false;
+	}
+
+	//------------------------------------------------------------------------
+	void platform_support::force_redraw()
+	{
+		on_draw();
+		update_window();
+	}
+
+	//------------------------------------------------------------------------
+	void platform_support::update_window()
+	{
+		// Note this function does automatic color conversion.
+		IGraphics->BltBitMapRastPort(m_specific->m_bitmap, 0, 0,
+			m_specific->m_window->RPort, m_specific->m_window->BorderLeft,
+			m_specific->m_window->BorderTop, m_specific->m_width,
+			m_specific->m_height, ABC|ABNC);
+	}
+
+	//------------------------------------------------------------------------
+	void platform_support::on_init() {}
+	void platform_support::on_resize(int sx, int sy) {}
+	void platform_support::on_idle() {}
+	void platform_support::on_mouse_move(int x, int y, unsigned flags) {}
+	void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {}
+	void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {}
+	void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {}
+	void platform_support::on_ctrl_change() {}
+	void platform_support::on_draw() {}
+	void platform_support::on_post_draw(void* raw_handler) {}
+
+	//------------------------------------------------------------------------
+	void handle_idcmp(Hook* hook, APTR obj, IntuiMessage* msg)
+	{
+		platform_support* app =
+			reinterpret_cast<platform_support*>(hook->h_Data);
+		Window* window = app->m_specific->m_window;
+
+		int16 x = msg->MouseX - window->BorderLeft;
+
+		int16 y = 0;
+		if ( app->flip_y() )
+		{
+			y = window->Height - window->BorderBottom - msg->MouseY;
+		}
+		else
+		{
+			y = msg->MouseY - window->BorderTop;
+		}
+
+		switch ( msg->Class )
+		{
+		case IDCMP_MOUSEBUTTONS:
+			if ( msg->Code & IECODE_UP_PREFIX )
+			{
+				if ( msg->Code == SELECTUP )
+				{
+					app->m_specific->m_input_flags = mouse_left;
+					app->m_specific->m_dragging = false;
+				}
+				else if ( msg->Code == MENUUP )
+				{
+					app->m_specific->m_input_flags = mouse_right;
+					app->m_specific->m_dragging = false;
+				}
+				else
+				{
+					return;
+				}
+
+
+				if ( app->m_ctrls.on_mouse_button_up(x, y) )
+				{
+					app->on_ctrl_change();
+					app->force_redraw();
+				}
+
+				app->on_mouse_button_up(x, y, app->m_specific->m_input_flags);
+			}
+			else
+			{
+				if ( msg->Code == SELECTDOWN )
+				{
+					app->m_specific->m_input_flags = mouse_left;
+					app->m_specific->m_dragging = true;
+				}
+				else if ( msg->Code == MENUDOWN )
+				{
+					app->m_specific->m_input_flags = mouse_right;
+					app->m_specific->m_dragging = true;
+				}
+				else
+				{
+					return;
+				}
+
+				app->m_ctrls.set_cur(x, y);
+				if ( app->m_ctrls.on_mouse_button_down(x, y) )
+				{
+					app->on_ctrl_change();
+					app->force_redraw();
+				}
+				else
+				{
+					if ( app->m_ctrls.in_rect(x, y) )
+					{
+						if ( app->m_ctrls.set_cur(x, y) )
+						{
+							app->on_ctrl_change();
+							app->force_redraw();
+						}
+					}
+					else
+					{
+						app->on_mouse_button_down(x, y,
+							app->m_specific->m_input_flags);
+					}
+				}
+			}
+			break;
+		case IDCMP_MOUSEMOVE:
+			if ( app->m_specific->m_dragging )  {
+				if ( app->m_ctrls.on_mouse_move(x, y,
+					 app->m_specific->m_input_flags & mouse_left) != 0 )
+				{
+					app->on_ctrl_change();
+					app->force_redraw();
+				}
+				else
+				{
+					if ( !app->m_ctrls.in_rect(x, y) )
+					{
+						app->on_mouse_move(x, y,
+							app->m_specific->m_input_flags);
+					}
+				}
+			}
+			break;
+		case IDCMP_RAWKEY:
+		{
+			static InputEvent ie = { 0 };
+			ie.ie_Class = IECLASS_RAWKEY;
+			ie.ie_Code = msg->Code;
+			ie.ie_Qualifier = msg->Qualifier;
+
+			static const unsigned BUF_SIZE = 16;
+			static char key_buf[BUF_SIZE];
+			int16 num_chars = IKeymap->MapRawKey(&ie, key_buf, BUF_SIZE, 0);
+
+			uint32 code = 0x00000000;
+			switch ( num_chars )
+			{
+			case 1:
+				code = key_buf[0];
+				break;
+			case 2:
+				code = key_buf[0]<<8 | key_buf[1];
+				break;
+			case 3:
+				code = key_buf[0]<<16 | key_buf[1]<<8 | key_buf[2];
+				break;
+			}
+
+			uint16 key_code = 0;
+
+			if ( num_chars == 1 )
+			{
+				if ( code >= IECODE_ASCII_FIRST && code <= IECODE_ASCII_LAST )
+				{
+					key_code = code;
+				}
+			}
+
+			if ( key_code == 0 )
+			{
+				switch ( code )
+				{
+				case 0x00000008: key_code = key_backspace;	break;
+				case 0x00000009: key_code = key_tab;		break;
+				case 0x0000000D: key_code = key_return;		break;
+				case 0x0000001B: key_code = key_escape;		break;
+				case 0x0000007F: key_code = key_delete;		break;
+				case 0x00009B41:
+				case 0x00009B54: key_code = key_up;			break;
+				case 0x00009B42:
+				case 0x00009B53: key_code = key_down;		break;
+				case 0x00009B43:
+				case 0x009B2040: key_code = key_right;		break;
+				case 0x00009B44:
+				case 0x009B2041: key_code = key_left;		break;
+				case 0x009B307E: key_code = key_f1;			break;
+				case 0x009B317E: key_code = key_f2;			break;
+				case 0x009B327E: key_code = key_f3;			break;
+				case 0x009B337E: key_code = key_f4;			break;
+				case 0x009B347E: key_code = key_f5;			break;
+				case 0x009B357E: key_code = key_f6;			break;
+				case 0x009B367E: key_code = key_f7;			break;
+				case 0x009B377E: key_code = key_f8;			break;
+				case 0x009B387E: key_code = key_f9;			break;
+				case 0x009B397E: key_code = key_f10;		break;
+				case 0x009B3F7E: key_code = key_scrollock;	break;
+				}
+			}
+
+			if ( ie.ie_Code & IECODE_UP_PREFIX )
+			{
+				if ( app->m_specific->m_last_key != 0 )
+				{
+					bool left = (key_code == key_left) ? true : false;
+					bool right = (key_code == key_right) ? true : false;
+					bool down = (key_code == key_down) ? true : false;
+					bool up = (key_code == key_up) ? true : false;
+
+					if ( app->m_ctrls.on_arrow_keys(left, right, down, up) )
+					{
+						app->on_ctrl_change();
+						app->force_redraw();
+					}
+					else
+					{
+						app->on_key(x, y, app->m_specific->m_last_key, 0);
+					}
+
+					app->m_specific->m_last_key = 0;
+				}
+			}
+			else
+			{
+				app->m_specific->m_last_key = key_code;
+			}
+			break;
+		}
+		default:
+			break;
+		}
+	}
+}
+
+//----------------------------------------------------------------------------
+int agg_main(int argc, char* argv[]);
+bool open_libs();
+void close_libs();
+
+//----------------------------------------------------------------------------
+bool open_libs()
+{
+	DataTypesBase = IExec->OpenLibrary("datatypes.library", 51);
+	GraphicsBase = IExec->OpenLibrary("graphics.library", 51);
+	IntuitionBase = IExec->OpenLibrary("intuition.library", 51);
+	KeymapBase = IExec->OpenLibrary("keymap.library", 51);
+	P96Base = IExec->OpenLibrary("Picasso96API.library", 2);
+
+	IDataTypes = reinterpret_cast<DataTypesIFace*>(
+		IExec->GetInterface(DataTypesBase, "main", 1, 0));
+	IGraphics = reinterpret_cast<GraphicsIFace*>(
+		IExec->GetInterface(GraphicsBase, "main", 1, 0));
+	IIntuition = reinterpret_cast<IntuitionIFace*>(
+		IExec->GetInterface(IntuitionBase, "main", 1, 0));
+	IKeymap = reinterpret_cast<KeymapIFace*>(
+		IExec->GetInterface(KeymapBase, "main", 1, 0));
+	IP96 = reinterpret_cast<P96IFace*>(
+		IExec->GetInterface(P96Base, "main", 1, 0));
+
+	if ( IDataTypes == 0 ||
+		 IGraphics == 0 ||
+		 IIntuition == 0 ||
+		 IKeymap == 0 ||
+		 IP96 == 0 )
+	{
+		close_libs();
+		return false;
+	}
+	else
+	{
+		return true;
+	}
+}
+
+//----------------------------------------------------------------------------
+void close_libs()
+{
+	IExec->DropInterface(reinterpret_cast<Interface*>(IP96));
+	IExec->DropInterface(reinterpret_cast<Interface*>(IKeymap));
+	IExec->DropInterface(reinterpret_cast<Interface*>(IIntuition));
+	IExec->DropInterface(reinterpret_cast<Interface*>(IGraphics));
+	IExec->DropInterface(reinterpret_cast<Interface*>(IDataTypes));
+
+	IExec->CloseLibrary(P96Base);
+	IExec->CloseLibrary(KeymapBase);
+	IExec->CloseLibrary(IntuitionBase);
+	IExec->CloseLibrary(GraphicsBase);
+	IExec->CloseLibrary(DataTypesBase);
+}
+
+//----------------------------------------------------------------------------
+int main(int argc, char* argv[])
+{
+	if ( !open_libs() )  {
+		IDOS->Printf("Can't open libraries.\n");
+		return -1;
+	}
+
+	ClassLibrary* requester =
+		IIntuition->OpenClass("requester.class", 51, &RequesterClass);
+	ClassLibrary* window =
+		IIntuition->OpenClass("window.class", 51, &WindowClass);
+	if ( requester == 0 || window == 0 )
+	{
+		IDOS->Printf("Can't open classes.\n");
+		IIntuition->CloseClass(requester);
+		IIntuition->CloseClass(window);
+		close_libs();
+		return -1;
+	}
+
+	int rc = agg_main(argc, argv);
+
+	IIntuition->CloseClass(window);
+	IIntuition->CloseClass(requester);
+	close_libs();
+
+	return rc;
+}
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp
new file mode 100644
index 0000000000..078e141ccb
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp
@@ -0,0 +1,990 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software 
+// is granted provided this copyright notice appears in all copies. 
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: superstippi@gmx.de
+//----------------------------------------------------------------------------
+//
+// class platform_support
+//
+//----------------------------------------------------------------------------
+
+#include <new>
+#include <stdio.h>
+
+#include <Alert.h>
+#include <Application.h>
+#include <Bitmap.h>
+#include <Message.h>
+#include <MessageRunner.h>
+#include <Messenger.h>
+#include <Path.h>
+#include <Roster.h>
+#include <TranslationUtils.h>
+#include <View.h>
+#include <Window.h>
+
+#include <string.h>
+#include "platform/agg_platform_support.h"
+#include "util/agg_color_conv_rgb8.h"
+
+using std::nothrow;
+
+
+static void
+attach_buffer_to_BBitmap(agg::rendering_buffer& buffer, BBitmap* bitmap, bool flipY)
+{
+    uint8* bits = (uint8*)bitmap->Bits();
+    uint32 width = bitmap->Bounds().IntegerWidth() + 1;
+    uint32 height = bitmap->Bounds().IntegerHeight() + 1;
+    int32 bpr = bitmap->BytesPerRow();
+    if (flipY) {
+// XXX: why don't I have to do this?!?
+//        bits += bpr * (height - 1);
+        bpr = -bpr;
+    }
+    buffer.attach(bits, width, height, bpr);
+}
+
+
+static color_space
+pix_format_to_color_space(agg::pix_format_e format)
+{
+    color_space bitmapFormat = B_NO_COLOR_SPACE;
+    switch (format) {
+        case agg::pix_format_rgb555:
+
+            bitmapFormat = B_RGB15;
+            break;
+
+        case agg::pix_format_rgb565:
+
+            bitmapFormat = B_RGB16;
+            break;
+
+        case agg::pix_format_rgb24:
+        case agg::pix_format_bgr24:
+
+            bitmapFormat = B_RGB24;
+            break;
+
+        case agg::pix_format_rgba32:
+        case agg::pix_format_argb32:
+        case agg::pix_format_abgr32:
+        case agg::pix_format_bgra32:
+
+            bitmapFormat = B_RGBA32;
+            break;
+    }
+    return bitmapFormat;
+}
+
+
+// #pragma mark -
+
+
+class AGGView : public BView {
+ public:
+                            AGGView(BRect frame, agg::platform_support* agg,
+                                    agg::pix_format_e format, bool flipY);
+    virtual                 ~AGGView();
+
+    virtual void            AttachedToWindow();
+    virtual void            DetachedFromWindow();
+
+    virtual void            MessageReceived(BMessage* message);
+    virtual void            Draw(BRect updateRect);
+    virtual void            FrameResized(float width, float height);
+
+    virtual void            KeyDown(const char* bytes, int32 numBytes);
+
+    virtual void            MouseDown(BPoint where);
+    virtual void            MouseMoved(BPoint where, uint32 transit,
+                               const BMessage* dragMesage);
+    virtual void            MouseUp(BPoint where);
+
+            BBitmap*        Bitmap() const;
+
+            uint8           LastKeyDown() const;
+            uint32          MouseButtons();
+
+            void            Update();
+            void            ForceRedraw();
+
+            unsigned        GetKeyFlags();
+
+ private:
+    BBitmap*                fBitmap;
+    agg::pix_format_e       fFormat;
+    bool                    fFlipY;
+
+    agg::platform_support*  fAGG;
+
+    uint32                  fMouseButtons;
+    int32                   fMouseX;
+    int32                   fMouseY;
+
+    uint8                   fLastKeyDown;
+
+    bool                    fRedraw;
+
+    BMessageRunner*         fPulse;
+    bigtime_t               fLastPulse;
+    bool                    fEnableTicks;
+};
+
+AGGView::AGGView(BRect frame,
+                 agg::platform_support* agg,
+                 agg::pix_format_e format,
+                 bool flipY)
+    : BView(frame, "AGG View", B_FOLLOW_ALL,
+            B_FRAME_EVENTS | B_WILL_DRAW),
+      fFormat(format),
+      fFlipY(flipY),
+
+      fAGG(agg),
+
+      fMouseButtons(0),
+      fMouseX(-1),
+      fMouseY(-1),
+      
+      fLastKeyDown(0),
+
+      fRedraw(true),
+
+      fPulse(NULL),
+      fLastPulse(0),
+      fEnableTicks(true)
+{
+    SetViewColor(B_TRANSPARENT_32_BIT);
+    
+    frame.OffsetTo(0.0, 0.0);
+    fBitmap = new BBitmap(frame, 0, pix_format_to_color_space(fFormat));
+    if (fBitmap->IsValid()) {
+        attach_buffer_to_BBitmap(fAGG->rbuf_window(), fBitmap, fFlipY);
+    } else {
+        delete fBitmap;
+        fBitmap = NULL;
+    }
+}
+
+
+AGGView::~AGGView()
+{
+    delete fBitmap;
+    delete fPulse;
+}
+
+
+void
+AGGView::AttachedToWindow()
+{
+    BMessage message('tick');
+    BMessenger target(this, Looper());
+    delete fPulse;
+//    BScreen screen;
+//    TODO: calc screen retrace
+    fPulse = new BMessageRunner(target, &message, 40000);
+
+    // make sure we call this once
+    fAGG->on_resize(Bounds().IntegerWidth() + 1,
+                    Bounds().IntegerHeight() + 1);
+    MakeFocus();
+}
+
+
+void
+AGGView::DetachedFromWindow()
+{
+    delete fPulse;
+    fPulse = NULL;
+}
+
+
+void
+AGGView::MessageReceived(BMessage* message)
+{
+    bigtime_t now = system_time();
+    switch (message->what) {
+        case 'tick':
+            // drop messages that have piled up
+            if (/*now - fLastPulse > 30000*/fEnableTicks) {
+                fLastPulse = now;
+                if (!fAGG->wait_mode())
+                    fAGG->on_idle();
+                Window()->PostMessage('entk', this);
+                fEnableTicks = false;
+            } else {
+//                printf("dropping tick message (%lld)\n", now - fLastPulse);
+            }
+            break;
+        case 'entk':
+            fEnableTicks = true;
+            if (now - fLastPulse > 30000) {
+                fLastPulse = now;
+                if (!fAGG->wait_mode())
+                    fAGG->on_idle();
+            }
+            break;
+        default:
+            BView::MessageReceived(message);
+            break;
+    }
+}
+
+
+void
+AGGView::Draw(BRect updateRect)
+{
+    if (fBitmap) {
+        if (fRedraw) {
+            fAGG->on_draw();
+            fRedraw = false;
+        }
+        if (fFormat == agg::pix_format_bgra32) {
+            DrawBitmap(fBitmap, updateRect, updateRect);
+        } else {
+            BBitmap* bitmap = new BBitmap(fBitmap->Bounds(), 0, B_RGBA32);
+
+            agg::rendering_buffer rbufSrc;
+            attach_buffer_to_BBitmap(rbufSrc, fBitmap, false);
+
+            agg::rendering_buffer rbufDst;
+            attach_buffer_to_BBitmap(rbufDst, bitmap, false);
+
+            switch(fFormat) {
+                case agg::pix_format_rgb555:
+                    agg::color_conv(&rbufDst, &rbufSrc,
+                                    agg::color_conv_rgb555_to_bgra32());
+                    break;
+                case agg::pix_format_rgb565:
+                    agg::color_conv(&rbufDst, &rbufSrc,
+                                    agg::color_conv_rgb565_to_bgra32());
+                    break;
+                case agg::pix_format_rgb24:
+                    agg::color_conv(&rbufDst, &rbufSrc,
+                                    agg::color_conv_rgb24_to_bgra32());
+                    break;
+                case agg::pix_format_bgr24:
+                    agg::color_conv(&rbufDst, &rbufSrc,
+                                    agg::color_conv_bgr24_to_bgra32());
+                    break;
+                case agg::pix_format_rgba32:
+                    agg::color_conv(&rbufDst, &rbufSrc,
+                                    agg::color_conv_rgba32_to_bgra32());
+                    break;
+                case agg::pix_format_argb32:
+                    agg::color_conv(&rbufDst, &rbufSrc,
+                                    agg::color_conv_argb32_to_bgra32());
+                    break;
+                case agg::pix_format_abgr32:
+                    agg::color_conv(&rbufDst, &rbufSrc,
+                                    agg::color_conv_abgr32_to_bgra32());
+                    break;
+                case agg::pix_format_bgra32:
+                    agg::color_conv(&rbufDst, &rbufSrc,
+                                    agg::color_conv_bgra32_to_bgra32());
+                    break;
+            }
+            DrawBitmap(bitmap, updateRect, updateRect);
+            delete bitmap;
+        }
+    } else {
+        FillRect(updateRect);
+    }
+}
+
+
+void
+AGGView::FrameResized(float width, float height)
+{
+    BRect r(0.0, 0.0, width, height);
+    BBitmap* bitmap = new BBitmap(r, 0, pix_format_to_color_space(fFormat));
+    if (bitmap->IsValid()) {
+        delete fBitmap;
+        fBitmap = bitmap;
+           attach_buffer_to_BBitmap(fAGG->rbuf_window(), fBitmap, fFlipY);
+
+        fAGG->trans_affine_resizing((int)width + 1,
+                                    (int)height + 1);
+
+        // pass the event on to AGG
+        fAGG->on_resize((int)width + 1, (int)height + 1);
+        
+        fRedraw = true;
+        Invalidate();
+    } else
+        delete bitmap;
+}
+
+
+void
+AGGView::KeyDown(const char* bytes, int32 numBytes)
+{
+    if (bytes && numBytes > 0) {
+        fLastKeyDown = bytes[0];
+
+        bool left  = false;
+        bool up    = false;
+        bool right = false;
+        bool down  = false;
+
+        switch (fLastKeyDown) {
+
+            case B_LEFT_ARROW:
+                left = true;
+                break;
+
+            case B_UP_ARROW:
+                up = true;
+                break;
+
+            case B_RIGHT_ARROW:
+                right = true;
+                break;
+
+            case B_DOWN_ARROW:
+                down = true;
+                break;
+        }
+
+/*            case key_f2:                        
+fAGG->copy_window_to_img(agg::platform_support::max_images - 1);
+fAGG->save_img(agg::platform_support::max_images - 1, "screenshot");
+break;
+}*/
+
+
+        if (fAGG->m_ctrls.on_arrow_keys(left, right, down, up)) {
+            fAGG->on_ctrl_change();
+            fAGG->force_redraw();
+        } else {
+            fAGG->on_key(fMouseX, fMouseY, fLastKeyDown, GetKeyFlags());
+        }
+//        fAGG->on_key(fMouseX, fMouseY, fLastKeyDown, GetKeyFlags());
+
+    }
+}
+
+
+void
+AGGView::MouseDown(BPoint where)
+{
+    BMessage* currentMessage = Window()->CurrentMessage();
+    if (currentMessage) {
+        if (currentMessage->FindInt32("buttons", (int32*)&fMouseButtons) < B_OK)
+            fMouseButtons = B_PRIMARY_MOUSE_BUTTON;
+    } else
+        fMouseButtons = B_PRIMARY_MOUSE_BUTTON;
+
+    fMouseX = (int)where.x;
+    fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y;
+
+    // pass the event on to AGG
+    if (fMouseButtons == B_PRIMARY_MOUSE_BUTTON) {
+        // left mouse button -> see if to handle in controls
+        fAGG->m_ctrls.set_cur(fMouseX, fMouseY);
+        if (fAGG->m_ctrls.on_mouse_button_down(fMouseX, fMouseY)) {
+            fAGG->on_ctrl_change();
+            fAGG->force_redraw();
+        } else {
+            if (fAGG->m_ctrls.in_rect(fMouseX, fMouseY)) {
+                if (fAGG->m_ctrls.set_cur(fMouseX, fMouseY)) {
+                    fAGG->on_ctrl_change();
+                    fAGG->force_redraw();
+                }
+            } else {
+                fAGG->on_mouse_button_down(fMouseX, fMouseY, GetKeyFlags());
+            }
+        }
+    } else if (fMouseButtons & B_SECONDARY_MOUSE_BUTTON) {
+        // right mouse button -> simple
+        fAGG->on_mouse_button_down(fMouseX, fMouseY, GetKeyFlags());
+    }
+    SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
+}
+
+
+void
+AGGView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMesage)
+{
+    // workarround missed mouse up events
+    // (if we react too slowly, app_server might have dropped events)
+    BMessage* currentMessage = Window()->CurrentMessage();
+    int32 buttons = 0;
+    if (currentMessage->FindInt32("buttons", &buttons) < B_OK) {
+        buttons = 0;
+    }
+    if (!buttons)
+        MouseUp(where);
+
+    fMouseX = (int)where.x;
+    fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y;
+
+    // pass the event on to AGG
+    if (fAGG->m_ctrls.on_mouse_move(fMouseX, fMouseY,
+                                    (GetKeyFlags() & agg::mouse_left) != 0)) {
+        fAGG->on_ctrl_change();
+        fAGG->force_redraw();
+    } else {
+        if (!fAGG->m_ctrls.in_rect(fMouseX, fMouseY)) {
+            fAGG->on_mouse_move(fMouseX, fMouseY, GetKeyFlags());
+        }
+    }
+}
+
+
+void
+AGGView::MouseUp(BPoint where)
+{
+    fMouseX = (int)where.x;
+    fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y;
+
+    // pass the event on to AGG
+    if (fMouseButtons == B_PRIMARY_MOUSE_BUTTON) {
+        fMouseButtons = 0;
+
+        if (fAGG->m_ctrls.on_mouse_button_up(fMouseX, fMouseY)) {
+            fAGG->on_ctrl_change();
+            fAGG->force_redraw();
+        }
+        fAGG->on_mouse_button_up(fMouseX, fMouseY, GetKeyFlags());
+    } else if (fMouseButtons == B_SECONDARY_MOUSE_BUTTON) {
+        fMouseButtons = 0;
+
+        fAGG->on_mouse_button_up(fMouseX, fMouseY, GetKeyFlags());
+    }
+}
+
+
+BBitmap*
+AGGView::Bitmap() const
+{
+    return fBitmap;
+}
+
+
+uint8
+AGGView::LastKeyDown() const
+{
+    return fLastKeyDown;
+}
+
+
+uint32
+AGGView::MouseButtons()
+{
+    uint32 buttons = 0;
+    if (LockLooper()) {
+        buttons = fMouseButtons;
+        UnlockLooper();
+    }
+    return buttons;
+}
+
+
+void
+AGGView::Update()
+{
+    // trigger display update
+    if (LockLooper()) {
+        Invalidate();
+        UnlockLooper();
+    }
+}
+
+
+void
+AGGView::ForceRedraw()
+{
+    // force a redraw (fRedraw = true;)
+    // and trigger display update
+    if (LockLooper()) {
+        fRedraw = true;
+        Invalidate();
+        UnlockLooper();
+    }
+}
+
+
+unsigned
+AGGView::GetKeyFlags()
+{
+    uint32 buttons = fMouseButtons;
+    uint32 mods = modifiers();
+    unsigned flags = 0;
+    if (buttons & B_PRIMARY_MOUSE_BUTTON)   flags |= agg::mouse_left;
+    if (buttons & B_SECONDARY_MOUSE_BUTTON) flags |= agg::mouse_right;
+    if (mods & B_SHIFT_KEY)                 flags |= agg::kbd_shift;
+    if (mods & B_COMMAND_KEY)               flags |= agg::kbd_ctrl;
+    return flags;
+}
+
+// #pragma mark -
+
+
+class AGGWindow : public BWindow {
+ public:
+                    AGGWindow()
+                    : BWindow(BRect(-50.0, -50.0, -10.0, -10.0),
+                              "AGG Application", B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS)
+                    {
+                    }
+
+    virtual bool    QuitRequested()
+                    {
+                        be_app->PostMessage(B_QUIT_REQUESTED);
+                        return true;
+                    }
+
+            bool    Init(BRect frame, agg::platform_support* agg, agg::pix_format_e format,
+                              bool flipY, uint32 flags)
+                    {
+                        MoveTo(frame.LeftTop());
+                        ResizeTo(frame.Width(), frame.Height());
+
+                        SetFlags(flags);
+
+                        frame.OffsetTo(0.0, 0.0);
+                        fView = new AGGView(frame, agg, format, flipY);
+                        AddChild(fView);
+
+                        return fView->Bitmap() != NULL;
+                    }
+
+
+        AGGView*    View() const
+                    {
+                        return fView;
+                    }
+ private:
+    AGGView*        fView;
+};
+
+// #pragma mark -
+
+
+class AGGApplication : public BApplication {
+ public:
+                    AGGApplication()
+                    : BApplication("application/x-vnd.AGG-AGG")
+                    {
+                        fWindow = new AGGWindow();
+                    }
+
+    virtual void    ReadyToRun()
+                    {
+                        if (fWindow) {
+                            fWindow->Show();
+                        }
+                    }
+
+    virtual bool    Init(agg::platform_support* agg, int width, int height,
+                         agg::pix_format_e format, bool flipY, uint32 flags)
+                    {
+                        BRect r(50.0, 50.0,
+                                50.0 + width - 1.0,
+                                50.0 + height - 1.0);
+                        uint32 windowFlags = B_ASYNCHRONOUS_CONTROLS;
+                        if (!(flags & agg::window_resize))
+                            windowFlags |= B_NOT_RESIZABLE;
+
+                        return fWindow->Init(r, agg, format, flipY, windowFlags);;
+                    }
+
+
+        AGGWindow*  Window() const
+                    {
+                        return fWindow;
+                    }
+
+ private:
+    AGGWindow*      fWindow;
+};
+
+
+// #pragma mark -
+
+
+namespace agg
+{
+
+class platform_specific {
+ public:
+                    platform_specific(agg::platform_support* agg,
+                                      agg::pix_format_e format, bool flip_y)
+                        : fAGG(agg),
+                          fApp(NULL),
+                          fFormat(format),
+                          fFlipY(flip_y),
+                          fTimerStart(system_time())
+                    {
+                        memset(fImages, 0, sizeof(fImages));
+                        fApp = new AGGApplication();
+                        fAppPath[0] = 0;
+                        // figure out where we're running from
+                        app_info info;
+                        status_t ret = fApp->GetAppInfo(&info);
+                        if (ret >= B_OK) {
+                            BPath path(&info.ref);
+                            ret = path.InitCheck();
+                            if (ret >= B_OK) {
+                                ret = path.GetParent(&path);
+                                if (ret >= B_OK) {
+                                    sprintf(fAppPath, "%s", path.Path());
+                                } else {
+                                    fprintf(stderr, "getting app parent folder failed: %s\n", strerror(ret));
+                                }
+                            } else {
+                                fprintf(stderr, "making app path failed: %s\n", strerror(ret));
+                            }
+                        } else {
+                            fprintf(stderr, "GetAppInfo() failed: %s\n", strerror(ret));
+                        }
+                    }
+                    ~platform_specific()
+                    {
+                        for (int32 i = 0; i < agg::platform_support::max_images; i++)
+                            delete fImages[i];
+                        delete fApp;
+                    }
+
+    bool            Init(int width, int height, unsigned flags)
+                    {
+                        return fApp->Init(fAGG, width, height, fFormat, fFlipY, flags);
+                    }
+
+    int             Run()
+                    {
+                        status_t ret = B_NO_INIT;
+                        if (fApp) {
+                            fApp->Run();
+                            ret = B_OK;
+                        }
+                        return ret;
+                    }
+
+    void            SetTitle(const char* title)
+                    {
+                        if (fApp && fApp->Window() && fApp->Window()->Lock()) {
+                            fApp->Window()->SetTitle(title);
+                            fApp->Window()->Unlock();
+                        }
+                    }
+    void            StartTimer()
+                    {
+                        fTimerStart = system_time();
+                    }
+    double          ElapsedTime() const
+                    {
+                        return (system_time() - fTimerStart) / 1000.0;
+                    }
+
+    void            ForceRedraw()
+                    {
+                        fApp->Window()->View()->ForceRedraw();
+                    }
+    void            UpdateWindow()
+                    {
+                        fApp->Window()->View()->Update();
+                    }
+
+
+    agg::platform_support*  fAGG;
+    AGGApplication*     fApp;
+    agg::pix_format_e    fFormat;
+    bool                fFlipY;
+    bigtime_t           fTimerStart;
+    BBitmap*            fImages[agg::platform_support::max_images];
+
+    char                fAppPath[B_PATH_NAME_LENGTH];
+    char                fFilePath[B_PATH_NAME_LENGTH];
+};
+
+
+    //------------------------------------------------------------------------
+    platform_support::platform_support(pix_format_e format, bool flip_y) :
+        m_specific(new platform_specific(this, format, flip_y)),
+        m_format(format),
+        m_bpp(32/*m_specific->m_bpp*/),
+        m_window_flags(0),
+        m_wait_mode(true),
+        m_flip_y(flip_y),
+        m_initial_width(10),
+        m_initial_height(10)
+    {
+        strcpy(m_caption, "Anti-Grain Geometry Application");
+    }
+
+
+    //------------------------------------------------------------------------
+    platform_support::~platform_support()
+    {
+        delete m_specific;
+    }
+
+    //------------------------------------------------------------------------
+    void platform_support::caption(const char* cap)
+    {
+        strcpy(m_caption, cap);
+        m_specific->SetTitle(cap);
+    }
+
+    //------------------------------------------------------------------------
+    void platform_support::start_timer()
+    {
+        m_specific->StartTimer();
+    }
+
+    //------------------------------------------------------------------------
+    double platform_support::elapsed_time() const
+    {
+        return m_specific->ElapsedTime();
+    }
+
+    //------------------------------------------------------------------------
+    void* platform_support::raw_display_handler()
+    {
+        // TODO: if we ever support BDirectWindow here, that would
+        // be the frame buffer pointer with offset to the window top left
+        return NULL;
+    }
+
+    //------------------------------------------------------------------------
+    void platform_support::message(const char* msg)
+    {
+        BAlert* alert = new BAlert("AGG Message", msg, "Ok");
+        alert->Go(/*NULL*/);
+    }
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::init(unsigned width, unsigned height, unsigned flags)
+    {
+        m_initial_width = width;
+        m_initial_height = height;
+        m_window_flags = flags;
+
+        if (m_specific->Init(width, height, flags)) {
+            on_init();
+            return true;
+        }
+
+        return false;
+    }
+
+
+    //------------------------------------------------------------------------
+    int platform_support::run()
+    {
+        return m_specific->Run();
+    }
+
+
+    //------------------------------------------------------------------------
+    const char* platform_support::img_ext() const { return ".ppm"; }
+
+
+    const char* platform_support::full_file_name(const char* file_name)
+    {
+        sprintf(m_specific->fFilePath, "%s/%s", m_specific->fAppPath, file_name);
+        return m_specific->fFilePath;
+    }
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::load_img(unsigned idx, const char* file)
+    {
+        if (idx < max_images)
+        {
+            char path[B_PATH_NAME_LENGTH];
+            sprintf(path, "%s/%s%s", m_specific->fAppPath, file, img_ext());
+            BBitmap* transBitmap = BTranslationUtils::GetBitmap(path);
+            if (transBitmap && transBitmap->IsValid()) {
+                if(transBitmap->ColorSpace() != B_RGB32 && transBitmap->ColorSpace() != B_RGBA32) {
+                    // ups we got a smart ass Translator making our live harder
+                    delete transBitmap;
+                    return false;
+                }
+
+                color_space format = B_RGB24;
+
+                switch (m_format) {
+                    case pix_format_gray8:
+                        format = B_GRAY8;
+                        break;
+                    case pix_format_rgb555:
+                        format = B_RGB15;
+                        break;
+                    case pix_format_rgb565:
+                        format = B_RGB16;
+                        break;
+                    case pix_format_rgb24:
+                        format = B_RGB24_BIG;
+                        break;
+                    case pix_format_bgr24:
+                        format = B_RGB24;
+                        break;
+                    case pix_format_abgr32:
+                    case pix_format_argb32:
+                    case pix_format_bgra32:
+                        format = B_RGB32;
+                        break;
+                    case pix_format_rgba32:
+                        format = B_RGB32_BIG;
+                        break;
+                }
+                BBitmap* bitmap = new (nothrow) BBitmap(transBitmap->Bounds(), 0, format);
+                if (!bitmap || !bitmap->IsValid()) {
+                    fprintf(stderr, "failed to allocate temporary bitmap!\n");
+                    delete transBitmap;
+                    delete bitmap;
+                    return false;
+                }
+
+                delete m_specific->fImages[idx];
+
+                rendering_buffer rbuf_tmp;
+                attach_buffer_to_BBitmap(rbuf_tmp, transBitmap, m_flip_y);
+        
+                m_specific->fImages[idx] = bitmap;
+        
+                attach_buffer_to_BBitmap(m_rbuf_img[idx], bitmap, m_flip_y);
+        
+                rendering_buffer* dst = &m_rbuf_img[idx];
+
+                switch(m_format)
+                {
+                case pix_format_gray8:
+                    return false;
+//                  color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray8()); break;
+                    break;
+        
+                case pix_format_rgb555:
+                    color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb555()); break;
+                    break;
+        
+                case pix_format_rgb565:
+                    color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb565()); break;
+                    break;
+        
+                case pix_format_rgb24:
+                    color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb24()); break;
+                    break;
+        
+                case pix_format_bgr24:
+                    color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr24()); break;
+                    break;
+        
+                case pix_format_abgr32:
+                    color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_abgr32()); break;
+                    break;
+        
+                case pix_format_argb32:
+                    color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_argb32()); break;
+                    break;
+        
+                case pix_format_bgra32:
+                    color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgra32()); break;
+                    break;
+        
+                case pix_format_rgba32:
+                    color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgba32()); break;
+                    break;
+                }
+                delete transBitmap;
+                
+                return true;
+
+            } else {
+                fprintf(stderr, "failed to load bitmap: '%s'\n", full_file_name(file));
+            }
+        }
+        return false;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::save_img(unsigned idx, const char* file)
+    {
+        // TODO: implement using BTranslatorRoster and friends
+        return false;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::create_img(unsigned idx, unsigned width, unsigned height)
+    {
+        if(idx < max_images)
+        {
+            if(width  == 0) width  = m_specific->fApp->Window()->View()->Bitmap()->Bounds().IntegerWidth() + 1;
+            if(height == 0) height = m_specific->fApp->Window()->View()->Bitmap()->Bounds().IntegerHeight() + 1;
+            BBitmap* bitmap = new BBitmap(BRect(0.0, 0.0, width - 1, height - 1), 0, B_RGBA32);;
+            if (bitmap && bitmap->IsValid()) {
+                delete m_specific->fImages[idx];
+                m_specific->fImages[idx] = bitmap;
+                attach_buffer_to_BBitmap(m_rbuf_img[idx], bitmap, m_flip_y);
+                return true;
+            } else {
+                delete bitmap;
+            }
+        }
+        return false;
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_support::force_redraw()
+    {
+        m_specific->ForceRedraw();
+    }
+
+
+
+    //------------------------------------------------------------------------
+    void platform_support::update_window()
+    {
+        m_specific->UpdateWindow();
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_support::on_init() {}
+    void platform_support::on_resize(int sx, int sy) {}
+    void platform_support::on_idle() {}
+    void platform_support::on_mouse_move(int x, int y, unsigned flags) {}
+    void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {}
+    void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {}
+    void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {}
+    void platform_support::on_ctrl_change() {}
+    void platform_support::on_draw() {}
+    void platform_support::on_post_draw(void* raw_handler) {}
+}
+
+
+
+
+
+
+//----------------------------------------------------------------------------
+int agg_main(int argc, char* argv[]);
+
+
+
+int
+main(int argc, char* argv[])
+{
+    return agg_main(argc, argv);
+}
+
+
+
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp
new file mode 100644
index 0000000000..46b874d738
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp
@@ -0,0 +1,1601 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software 
+// is granted provided this copyright notice appears in all copies. 
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+//          mcseemagg@yahoo.com
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// class platform_support. X11 version.
+//
+//----------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <time.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+#include "agg_basics.h"
+#include "agg_pixfmt_gray.h"
+#include "agg_pixfmt_rgb.h"
+#include "agg_pixfmt_rgba.h"
+#include "util/agg_color_conv_rgb8.h"
+#include "platform/agg_platform_support.h"
+
+
+namespace agg
+{
+    //------------------------------------------------------------------------
+    class platform_specific
+    {
+    public:
+        platform_specific(pix_format_e format, bool flip_y);
+        ~platform_specific();
+        
+        void caption(const char* capt);
+        void put_image(const rendering_buffer* src);
+       
+        pix_format_e         m_format;
+        pix_format_e         m_sys_format;
+        int                  m_byte_order;
+        bool                 m_flip_y;
+        unsigned             m_bpp;
+        unsigned             m_sys_bpp;
+        Display*             m_display;
+        int                  m_screen;
+        int                  m_depth;
+        Visual*              m_visual;
+        Window               m_window;
+        GC                   m_gc;
+        XImage*              m_ximg_window;
+        XSetWindowAttributes m_window_attributes;
+        Atom                 m_close_atom;
+        unsigned char*       m_buf_window;
+        unsigned char*       m_buf_img[platform_support::max_images];
+        unsigned             m_keymap[256];
+       
+        bool m_update_flag;
+        bool m_resize_flag;
+        bool m_initialized;
+        //bool m_wait_mode;
+        clock_t m_sw_start;
+    };
+
+
+
+    //------------------------------------------------------------------------
+    platform_specific::platform_specific(pix_format_e format, bool flip_y) :
+        m_format(format),
+        m_sys_format(pix_format_undefined),
+        m_byte_order(LSBFirst),
+        m_flip_y(flip_y),
+        m_bpp(0),
+        m_sys_bpp(0),
+        m_display(0),
+        m_screen(0),
+        m_depth(0),
+        m_visual(0),
+        m_window(0),
+        m_gc(0),
+        m_ximg_window(0),
+        m_close_atom(0),
+
+        m_buf_window(0),
+        
+        m_update_flag(true), 
+        m_resize_flag(true),
+        m_initialized(false)
+        //m_wait_mode(true)
+    {
+        memset(m_buf_img, 0, sizeof(m_buf_img));
+
+        unsigned i;
+        for(i = 0; i < 256; i++)
+        {
+            m_keymap[i] = i;
+        }
+
+        m_keymap[XK_Pause&0xFF] = key_pause;
+        m_keymap[XK_Clear&0xFF] = key_clear;
+
+        m_keymap[XK_KP_0&0xFF] = key_kp0;
+        m_keymap[XK_KP_1&0xFF] = key_kp1;
+        m_keymap[XK_KP_2&0xFF] = key_kp2;
+        m_keymap[XK_KP_3&0xFF] = key_kp3;
+        m_keymap[XK_KP_4&0xFF] = key_kp4;
+        m_keymap[XK_KP_5&0xFF] = key_kp5;
+        m_keymap[XK_KP_6&0xFF] = key_kp6;
+        m_keymap[XK_KP_7&0xFF] = key_kp7;
+        m_keymap[XK_KP_8&0xFF] = key_kp8;
+        m_keymap[XK_KP_9&0xFF] = key_kp9;
+
+        m_keymap[XK_KP_Insert&0xFF]    = key_kp0;
+        m_keymap[XK_KP_End&0xFF]       = key_kp1;   
+        m_keymap[XK_KP_Down&0xFF]      = key_kp2;
+        m_keymap[XK_KP_Page_Down&0xFF] = key_kp3;
+        m_keymap[XK_KP_Left&0xFF]      = key_kp4;
+        m_keymap[XK_KP_Begin&0xFF]     = key_kp5;
+        m_keymap[XK_KP_Right&0xFF]     = key_kp6;
+        m_keymap[XK_KP_Home&0xFF]      = key_kp7;
+        m_keymap[XK_KP_Up&0xFF]        = key_kp8;
+        m_keymap[XK_KP_Page_Up&0xFF]   = key_kp9;
+        m_keymap[XK_KP_Delete&0xFF]    = key_kp_period;
+        m_keymap[XK_KP_Decimal&0xFF]   = key_kp_period;
+        m_keymap[XK_KP_Divide&0xFF]    = key_kp_divide;
+        m_keymap[XK_KP_Multiply&0xFF]  = key_kp_multiply;
+        m_keymap[XK_KP_Subtract&0xFF]  = key_kp_minus;
+        m_keymap[XK_KP_Add&0xFF]       = key_kp_plus;
+        m_keymap[XK_KP_Enter&0xFF]     = key_kp_enter;
+        m_keymap[XK_KP_Equal&0xFF]     = key_kp_equals;
+
+        m_keymap[XK_Up&0xFF]           = key_up;
+        m_keymap[XK_Down&0xFF]         = key_down;
+        m_keymap[XK_Right&0xFF]        = key_right;
+        m_keymap[XK_Left&0xFF]         = key_left;
+        m_keymap[XK_Insert&0xFF]       = key_insert;
+        m_keymap[XK_Home&0xFF]         = key_delete;
+        m_keymap[XK_End&0xFF]          = key_end;
+        m_keymap[XK_Page_Up&0xFF]      = key_page_up;
+        m_keymap[XK_Page_Down&0xFF]    = key_page_down;
+
+        m_keymap[XK_F1&0xFF]           = key_f1;
+        m_keymap[XK_F2&0xFF]           = key_f2;
+        m_keymap[XK_F3&0xFF]           = key_f3;
+        m_keymap[XK_F4&0xFF]           = key_f4;
+        m_keymap[XK_F5&0xFF]           = key_f5;
+        m_keymap[XK_F6&0xFF]           = key_f6;
+        m_keymap[XK_F7&0xFF]           = key_f7;
+        m_keymap[XK_F8&0xFF]           = key_f8;
+        m_keymap[XK_F9&0xFF]           = key_f9;
+        m_keymap[XK_F10&0xFF]          = key_f10;
+        m_keymap[XK_F11&0xFF]          = key_f11;
+        m_keymap[XK_F12&0xFF]          = key_f12;
+        m_keymap[XK_F13&0xFF]          = key_f13;
+        m_keymap[XK_F14&0xFF]          = key_f14;
+        m_keymap[XK_F15&0xFF]          = key_f15;
+
+        m_keymap[XK_Num_Lock&0xFF]     = key_numlock;
+        m_keymap[XK_Caps_Lock&0xFF]    = key_capslock;
+        m_keymap[XK_Scroll_Lock&0xFF]  = key_scrollock;
+
+        switch(m_format)
+        {
+        default: break;
+        case pix_format_gray8:
+        case pix_format_sgray8:
+            m_bpp = 8;
+            break;
+
+        case pix_format_gray16:
+            m_bpp = 16;
+            break;
+
+        case pix_format_gray32:
+            m_bpp = 32;
+            break;
+
+        case pix_format_rgb565:
+        case pix_format_rgb555:
+            m_bpp = 16;
+            break;
+
+        case pix_format_rgb24:
+        case pix_format_bgr24:
+        case pix_format_srgb24:
+        case pix_format_sbgr24:
+            m_bpp = 24;
+            break;
+
+        case pix_format_bgra32:
+        case pix_format_abgr32:
+        case pix_format_argb32:
+        case pix_format_rgba32:
+        case pix_format_sbgra32:
+        case pix_format_sabgr32:
+        case pix_format_sargb32:
+        case pix_format_srgba32:
+            m_bpp = 32;
+            break;
+
+        case pix_format_rgb48:
+        case pix_format_bgr48:
+            m_bpp = 48;
+            break;
+
+        case pix_format_bgra64:
+        case pix_format_abgr64:
+        case pix_format_argb64:
+        case pix_format_rgba64:
+            m_bpp = 64;
+            break;
+
+        case pix_format_rgb96:
+        case pix_format_bgr96:
+            m_bpp = 96;
+            break;
+
+        case pix_format_bgra128:
+        case pix_format_abgr128:
+        case pix_format_argb128:
+        case pix_format_rgba128:
+            m_bpp = 128;
+            break;
+        }
+        m_sw_start = clock();
+    }
+
+    //------------------------------------------------------------------------
+    platform_specific::~platform_specific()
+    {
+    }
+
+    //------------------------------------------------------------------------
+    void platform_specific::caption(const char* capt)
+    {
+        XTextProperty tp;
+        tp.value = (unsigned char *)capt;
+        tp.encoding = XA_WM_NAME;
+        tp.format = 8;
+        tp.nitems = strlen(capt);
+        XSetWMName(m_display, m_window, &tp);
+        XStoreName(m_display, m_window, capt);
+        XSetIconName(m_display, m_window, capt);
+        XSetWMIconName(m_display, m_window, &tp);
+    }
+
+    
+    //------------------------------------------------------------------------
+    void platform_specific::put_image(const rendering_buffer* src)
+    {    
+        if(m_ximg_window == 0) return;
+        m_ximg_window->data = (char*)m_buf_window;
+        
+        if(m_format == m_sys_format)
+        {
+            XPutImage(m_display, 
+                      m_window, 
+                      m_gc, 
+                      m_ximg_window, 
+                      0, 0, 0, 0,
+                      src->width(), 
+                      src->height());
+        }
+        else
+        {
+            int row_len = src->width() * m_sys_bpp / 8;
+            unsigned char* buf_tmp = 
+                new unsigned char[row_len * src->height()];
+            
+            rendering_buffer rbuf_tmp;
+            rbuf_tmp.attach(buf_tmp, 
+                            src->width(), 
+                            src->height(), 
+                            m_flip_y ? -row_len : row_len);
+
+            switch(m_sys_format)            
+            {
+                default: break;
+                case pix_format_rgb555:
+                    switch(m_format)
+                    {
+                        default: break;
+                        case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgb555()); break;
+                        case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555()); break;
+                        case pix_format_rgb24:  color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgb555());  break;
+                        case pix_format_bgr24:  color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb555());  break;
+                        case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgb555()); break;
+                        case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgb555()); break;
+                        case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgb555()); break;
+                        case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgb555()); break;
+                    }
+                    break;
+                    
+                case pix_format_rgb565:
+                    switch(m_format)
+                    {
+                        default: break;
+                        case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgb565()); break;
+                        case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb565()); break;
+                        case pix_format_rgb24:  color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgb565());  break;
+                        case pix_format_bgr24:  color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb565());  break;
+                        case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgb565()); break;
+                        case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgb565()); break;
+                        case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgb565()); break;
+                        case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgb565()); break;
+                    }
+                    break;
+                    
+                case pix_format_rgba32:
+                    switch(m_format)
+                    {
+                        default: break;
+                        case pix_format_sgray8:   convert<pixfmt_srgba32, pixfmt_sgray8>(&rbuf_tmp, src);    break;
+                        case pix_format_gray8:    convert<pixfmt_srgba32, pixfmt_gray8>(&rbuf_tmp, src);     break;
+                        case pix_format_gray16:   convert<pixfmt_srgba32, pixfmt_gray16>(&rbuf_tmp, src);    break;
+                        case pix_format_gray32:   convert<pixfmt_srgba32, pixfmt_gray32>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb555:   color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgba32()); break;
+                        case pix_format_rgb565:   color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgba32()); break;
+                        case pix_format_srgb24:   convert<pixfmt_srgba32, pixfmt_srgb24>(&rbuf_tmp, src);    break;
+                        case pix_format_sbgr24:   convert<pixfmt_srgba32, pixfmt_sbgr24>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb24:    convert<pixfmt_srgba32, pixfmt_rgb24>(&rbuf_tmp, src);     break;
+                        case pix_format_bgr24:    convert<pixfmt_srgba32, pixfmt_bgr24>(&rbuf_tmp, src);     break;
+                        case pix_format_srgba32:  convert<pixfmt_srgba32, pixfmt_srgba32>(&rbuf_tmp, src);   break;
+                        case pix_format_sargb32:  convert<pixfmt_srgba32, pixfmt_sargb32>(&rbuf_tmp, src);   break;
+                        case pix_format_sabgr32:  convert<pixfmt_srgba32, pixfmt_sabgr32>(&rbuf_tmp, src);   break;
+                        case pix_format_sbgra32:  convert<pixfmt_srgba32, pixfmt_sbgra32>(&rbuf_tmp, src);   break;
+                        case pix_format_rgba32:   convert<pixfmt_srgba32, pixfmt_rgba32>(&rbuf_tmp, src);    break;
+                        case pix_format_argb32:   convert<pixfmt_srgba32, pixfmt_argb32>(&rbuf_tmp, src);    break;
+                        case pix_format_abgr32:   convert<pixfmt_srgba32, pixfmt_abgr32>(&rbuf_tmp, src);    break;
+                        case pix_format_bgra32:   convert<pixfmt_srgba32, pixfmt_bgra32>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb48:    convert<pixfmt_srgba32, pixfmt_rgb48>(&rbuf_tmp, src);     break;
+                        case pix_format_bgr48:    convert<pixfmt_srgba32, pixfmt_bgr48>(&rbuf_tmp, src);     break;
+                        case pix_format_rgba64:   convert<pixfmt_srgba32, pixfmt_rgba64>(&rbuf_tmp, src);    break;
+                        case pix_format_argb64:   convert<pixfmt_srgba32, pixfmt_argb64>(&rbuf_tmp, src);    break;
+                        case pix_format_abgr64:   convert<pixfmt_srgba32, pixfmt_abgr64>(&rbuf_tmp, src);    break;
+                        case pix_format_bgra64:   convert<pixfmt_srgba32, pixfmt_bgra64>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb96:    convert<pixfmt_srgba32, pixfmt_rgb96>(&rbuf_tmp, src);     break;
+                        case pix_format_bgr96:    convert<pixfmt_srgba32, pixfmt_bgr96>(&rbuf_tmp, src);     break;
+                        case pix_format_rgba128:  convert<pixfmt_srgba32, pixfmt_rgba128>(&rbuf_tmp, src);   break;
+                        case pix_format_argb128:  convert<pixfmt_srgba32, pixfmt_argb128>(&rbuf_tmp, src);   break;
+                        case pix_format_abgr128:  convert<pixfmt_srgba32, pixfmt_abgr128>(&rbuf_tmp, src);   break;
+                        case pix_format_bgra128:  convert<pixfmt_srgba32, pixfmt_bgra128>(&rbuf_tmp, src);   break;
+                    }
+                    break;
+                    
+                case pix_format_abgr32:
+                    switch(m_format)
+                    {
+                        default: break;
+                        case pix_format_sgray8:   convert<pixfmt_sabgr32, pixfmt_sgray8>(&rbuf_tmp, src);    break;
+                        case pix_format_gray8:    convert<pixfmt_sabgr32, pixfmt_gray8>(&rbuf_tmp, src);     break;
+                        case pix_format_gray16:   convert<pixfmt_sabgr32, pixfmt_gray16>(&rbuf_tmp, src);    break;
+                        case pix_format_gray32:   convert<pixfmt_sabgr32, pixfmt_gray32>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_abgr32()); break;
+                        case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_abgr32()); break;
+                        case pix_format_srgb24:   convert<pixfmt_sabgr32, pixfmt_srgb24>(&rbuf_tmp, src);    break;
+                        case pix_format_sbgr24:   convert<pixfmt_sabgr32, pixfmt_sbgr24>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb24:    convert<pixfmt_sabgr32, pixfmt_rgb24>(&rbuf_tmp, src);     break;
+                        case pix_format_bgr24:    convert<pixfmt_sabgr32, pixfmt_bgr24>(&rbuf_tmp, src);     break;
+                        case pix_format_srgba32:  convert<pixfmt_sabgr32, pixfmt_srgba32>(&rbuf_tmp, src);   break;
+                        case pix_format_sargb32:  convert<pixfmt_sabgr32, pixfmt_sargb32>(&rbuf_tmp, src);   break;
+                        case pix_format_sabgr32:  convert<pixfmt_sabgr32, pixfmt_sabgr32>(&rbuf_tmp, src);   break;
+                        case pix_format_sbgra32:  convert<pixfmt_sabgr32, pixfmt_sbgra32>(&rbuf_tmp, src);   break;
+                        case pix_format_rgba32:   convert<pixfmt_sabgr32, pixfmt_rgba32>(&rbuf_tmp, src);    break;
+                        case pix_format_argb32:   convert<pixfmt_sabgr32, pixfmt_argb32>(&rbuf_tmp, src);    break;
+                        case pix_format_abgr32:   convert<pixfmt_sabgr32, pixfmt_abgr32>(&rbuf_tmp, src);    break;
+                        case pix_format_bgra32:   convert<pixfmt_sabgr32, pixfmt_bgra32>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb48:    convert<pixfmt_sabgr32, pixfmt_rgb48>(&rbuf_tmp, src);     break;
+                        case pix_format_bgr48:    convert<pixfmt_sabgr32, pixfmt_bgr48>(&rbuf_tmp, src);     break;
+                        case pix_format_rgba64:   convert<pixfmt_sabgr32, pixfmt_rgba64>(&rbuf_tmp, src);    break;
+                        case pix_format_argb64:   convert<pixfmt_sabgr32, pixfmt_argb64>(&rbuf_tmp, src);    break;
+                        case pix_format_abgr64:   convert<pixfmt_sabgr32, pixfmt_abgr64>(&rbuf_tmp, src);    break;
+                        case pix_format_bgra64:   convert<pixfmt_sabgr32, pixfmt_bgra64>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb96:    convert<pixfmt_sabgr32, pixfmt_rgb96>(&rbuf_tmp, src);     break;
+                        case pix_format_bgr96:    convert<pixfmt_sabgr32, pixfmt_bgr96>(&rbuf_tmp, src);     break;
+                        case pix_format_rgba128:  convert<pixfmt_sabgr32, pixfmt_rgba128>(&rbuf_tmp, src);   break;
+                        case pix_format_argb128:  convert<pixfmt_sabgr32, pixfmt_argb128>(&rbuf_tmp, src);   break;
+                        case pix_format_abgr128:  convert<pixfmt_sabgr32, pixfmt_abgr128>(&rbuf_tmp, src);   break;
+                        case pix_format_bgra128:  convert<pixfmt_sabgr32, pixfmt_bgra128>(&rbuf_tmp, src);   break;
+                    }
+                    break;
+                    
+                case pix_format_argb32:
+                    switch(m_format)
+                    {
+                        default: break;
+                        case pix_format_sgray8:   convert<pixfmt_sargb32, pixfmt_sgray8>(&rbuf_tmp, src);    break;
+                        case pix_format_gray8:    convert<pixfmt_sargb32, pixfmt_gray8>(&rbuf_tmp, src);     break;
+                        case pix_format_gray16:   convert<pixfmt_sargb32, pixfmt_gray16>(&rbuf_tmp, src);    break;
+                        case pix_format_gray32:   convert<pixfmt_sargb32, pixfmt_gray32>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_argb32()); break;
+                        case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_argb32()); break;
+                        case pix_format_srgb24:   convert<pixfmt_sargb32, pixfmt_srgb24>(&rbuf_tmp, src);    break;
+                        case pix_format_sbgr24:   convert<pixfmt_sargb32, pixfmt_sbgr24>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb24:    convert<pixfmt_sargb32, pixfmt_rgb24>(&rbuf_tmp, src);     break;
+                        case pix_format_bgr24:    convert<pixfmt_sargb32, pixfmt_bgr24>(&rbuf_tmp, src);     break;
+                        case pix_format_srgba32:  convert<pixfmt_sargb32, pixfmt_srgba32>(&rbuf_tmp, src);   break;
+                        case pix_format_sargb32:  convert<pixfmt_sargb32, pixfmt_sargb32>(&rbuf_tmp, src);   break;
+                        case pix_format_sabgr32:  convert<pixfmt_sargb32, pixfmt_sabgr32>(&rbuf_tmp, src);   break;
+                        case pix_format_sbgra32:  convert<pixfmt_sargb32, pixfmt_sbgra32>(&rbuf_tmp, src);   break;
+                        case pix_format_rgba32:   convert<pixfmt_sargb32, pixfmt_rgba32>(&rbuf_tmp, src);    break;
+                        case pix_format_argb32:   convert<pixfmt_sargb32, pixfmt_argb32>(&rbuf_tmp, src);    break;
+                        case pix_format_abgr32:   convert<pixfmt_sargb32, pixfmt_abgr32>(&rbuf_tmp, src);    break;
+                        case pix_format_bgra32:   convert<pixfmt_sargb32, pixfmt_bgra32>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb48:    convert<pixfmt_sargb32, pixfmt_rgb48>(&rbuf_tmp, src);     break;
+                        case pix_format_bgr48:    convert<pixfmt_sargb32, pixfmt_bgr48>(&rbuf_tmp, src);     break;
+                        case pix_format_rgba64:   convert<pixfmt_sargb32, pixfmt_rgba64>(&rbuf_tmp, src);    break;
+                        case pix_format_argb64:   convert<pixfmt_sargb32, pixfmt_argb64>(&rbuf_tmp, src);    break;
+                        case pix_format_abgr64:   convert<pixfmt_sargb32, pixfmt_abgr64>(&rbuf_tmp, src);    break;
+                        case pix_format_bgra64:   convert<pixfmt_sargb32, pixfmt_bgra64>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb96:    convert<pixfmt_sargb32, pixfmt_rgb96>(&rbuf_tmp, src);     break;
+                        case pix_format_bgr96:    convert<pixfmt_sargb32, pixfmt_bgr96>(&rbuf_tmp, src);     break;
+                        case pix_format_rgba128:  convert<pixfmt_sargb32, pixfmt_rgba128>(&rbuf_tmp, src);   break;
+                        case pix_format_argb128:  convert<pixfmt_sargb32, pixfmt_argb128>(&rbuf_tmp, src);   break;
+                        case pix_format_abgr128:  convert<pixfmt_sargb32, pixfmt_abgr128>(&rbuf_tmp, src);   break;
+                        case pix_format_bgra128:  convert<pixfmt_sargb32, pixfmt_bgra128>(&rbuf_tmp, src);   break;
+                    }
+                    break;
+                    
+                case pix_format_bgra32:
+                    switch(m_format)
+                    {
+                        default: break;
+                        case pix_format_sgray8:   convert<pixfmt_sbgra32, pixfmt_sgray8>(&rbuf_tmp, src);    break;
+                        case pix_format_gray8:    convert<pixfmt_sbgra32, pixfmt_gray8>(&rbuf_tmp, src);     break;
+                        case pix_format_gray16:   convert<pixfmt_sbgra32, pixfmt_gray16>(&rbuf_tmp, src);    break;
+                        case pix_format_gray32:   convert<pixfmt_sbgra32, pixfmt_gray32>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb555:   color_conv(&rbuf_tmp, src, color_conv_rgb555_to_bgra32()); break;
+                        case pix_format_rgb565:   color_conv(&rbuf_tmp, src, color_conv_rgb565_to_bgra32()); break;
+                        case pix_format_srgb24:   convert<pixfmt_sbgra32, pixfmt_srgb24>(&rbuf_tmp, src);    break;
+                        case pix_format_sbgr24:   convert<pixfmt_sbgra32, pixfmt_sbgr24>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb24:    convert<pixfmt_sbgra32, pixfmt_rgb24>(&rbuf_tmp, src);     break;
+                        case pix_format_bgr24:    convert<pixfmt_sbgra32, pixfmt_bgr24>(&rbuf_tmp, src);     break;
+                        case pix_format_srgba32:  convert<pixfmt_sbgra32, pixfmt_srgba32>(&rbuf_tmp, src);   break;
+                        case pix_format_sargb32:  convert<pixfmt_sbgra32, pixfmt_sargb32>(&rbuf_tmp, src);   break;
+                        case pix_format_sabgr32:  convert<pixfmt_sbgra32, pixfmt_sabgr32>(&rbuf_tmp, src);   break;
+                        case pix_format_sbgra32:  convert<pixfmt_sbgra32, pixfmt_sbgra32>(&rbuf_tmp, src);   break;
+                        case pix_format_rgba32:   convert<pixfmt_sbgra32, pixfmt_rgba32>(&rbuf_tmp, src);    break;
+                        case pix_format_argb32:   convert<pixfmt_sbgra32, pixfmt_argb32>(&rbuf_tmp, src);    break;
+                        case pix_format_abgr32:   convert<pixfmt_sbgra32, pixfmt_abgr32>(&rbuf_tmp, src);    break;
+                        case pix_format_bgra32:   convert<pixfmt_sbgra32, pixfmt_bgra32>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb48:    convert<pixfmt_sbgra32, pixfmt_rgb48>(&rbuf_tmp, src);     break;
+                        case pix_format_bgr48:    convert<pixfmt_sbgra32, pixfmt_bgr48>(&rbuf_tmp, src);     break;
+                        case pix_format_rgba64:   convert<pixfmt_sbgra32, pixfmt_rgba64>(&rbuf_tmp, src);    break;
+                        case pix_format_argb64:   convert<pixfmt_sbgra32, pixfmt_argb64>(&rbuf_tmp, src);    break;
+                        case pix_format_abgr64:   convert<pixfmt_sbgra32, pixfmt_abgr64>(&rbuf_tmp, src);    break;
+                        case pix_format_bgra64:   convert<pixfmt_sbgra32, pixfmt_bgra64>(&rbuf_tmp, src);    break;
+                        case pix_format_rgb96:    convert<pixfmt_sbgra32, pixfmt_rgb96>(&rbuf_tmp, src);     break;
+                        case pix_format_bgr96:    convert<pixfmt_sbgra32, pixfmt_bgr96>(&rbuf_tmp, src);     break;
+                        case pix_format_rgba128:  convert<pixfmt_sbgra32, pixfmt_rgba128>(&rbuf_tmp, src);   break;
+                        case pix_format_argb128:  convert<pixfmt_sbgra32, pixfmt_argb128>(&rbuf_tmp, src);   break;
+                        case pix_format_abgr128:  convert<pixfmt_sbgra32, pixfmt_abgr128>(&rbuf_tmp, src);   break;
+                        case pix_format_bgra128:  convert<pixfmt_sbgra32, pixfmt_bgra128>(&rbuf_tmp, src);   break;
+                    }
+                    break;
+            }
+            
+            m_ximg_window->data = (char*)buf_tmp;
+            XPutImage(m_display, 
+                      m_window, 
+                      m_gc, 
+                      m_ximg_window, 
+                      0, 0, 0, 0,
+                      src->width(), 
+                      src->height());
+            
+            delete [] buf_tmp;
+        }
+    }
+    
+
+    //------------------------------------------------------------------------
+    platform_support::platform_support(pix_format_e format, bool flip_y) :
+        m_specific(new platform_specific(format, flip_y)),
+        m_format(format),
+        m_bpp(m_specific->m_bpp),
+        m_window_flags(0),
+        m_wait_mode(true),
+        m_flip_y(flip_y),
+        m_initial_width(10),
+        m_initial_height(10)
+    {
+        strcpy(m_caption, "AGG Application");
+    }
+
+    //------------------------------------------------------------------------
+    platform_support::~platform_support()
+    {
+        delete m_specific;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    void platform_support::caption(const char* cap)
+    {
+        strcpy(m_caption, cap);
+        if(m_specific->m_initialized)
+        {
+            m_specific->caption(cap);
+        }
+    }
+
+   
+    //------------------------------------------------------------------------
+    enum xevent_mask_e
+    { 
+        xevent_mask =
+            PointerMotionMask|
+            ButtonPressMask|
+            ButtonReleaseMask|
+            ExposureMask|
+            KeyPressMask|
+            StructureNotifyMask
+    };
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::init(unsigned width, unsigned height, unsigned flags)
+    {
+        m_window_flags = flags;
+        
+        m_specific->m_display = XOpenDisplay(NULL);
+        if(m_specific->m_display == 0) 
+        {
+            fprintf(stderr, "Unable to open DISPLAY!\n");
+            return false;
+        }
+        
+        m_specific->m_screen = XDefaultScreen(m_specific->m_display);
+        m_specific->m_depth  = XDefaultDepth(m_specific->m_display, 
+                                             m_specific->m_screen);
+        m_specific->m_visual = XDefaultVisual(m_specific->m_display, 
+                                              m_specific->m_screen);
+        unsigned long r_mask = m_specific->m_visual->red_mask;
+        unsigned long g_mask = m_specific->m_visual->green_mask;
+        unsigned long b_mask = m_specific->m_visual->blue_mask;
+                
+//printf("depth=%d, red=%08x, green=%08x, blue=%08x\n",
+//       m_specific->m_depth,
+//       m_specific->m_visual->red_mask,
+//       m_specific->m_visual->green_mask,
+//       m_specific->m_visual->blue_mask);
+           
+
+//         // NOT COMPLETED YET!
+//         // Try to find an appropriate Visual if the default doesn't fit.
+//         if(m_specific->m_depth < 15 ||
+//            r_mask == 0 || g_mask == 0 || b_mask == 0)
+//         {
+//             
+//             // This is an attempt to find an appropriate Visual if         
+//             // the default one doesn't match the minumum requirements
+//             static int depth[] = { 32, 24, 16, 15 };
+//             int i;
+//             for(int i = 0; i < 4; i++)
+//             {
+//                 XVisualInfo vi;
+//                 if(XMatchVisualInfo(m_specific->m_display, 
+//                                     m_specific->m_screen, 
+//                                     depth[i], 
+//                                     TrueColor, 
+//                                     &vi)) 
+//                 {
+// //                     printf("TrueColor  depth=%d, red=%08x, green=%08x, blue=%08x, bits=%d\n",
+// //                         vi.depth,
+// //                         vi.visual->red_mask,
+// //                         vi.visual->green_mask,
+// //                         vi.visual->blue_mask,
+// //                         vi.bits_per_rgb);
+//                     m_specific->m_depth  = vi.depth;
+//                     m_specific->m_visual = vi.visual;
+//                     r_mask = m_specific->m_visual->red_mask;
+//                     g_mask = m_specific->m_visual->green_mask;
+//                     b_mask = m_specific->m_visual->blue_mask;
+//                     break;
+//                 }
+//                 if(XMatchVisualInfo(m_specific->m_display, 
+//                                     m_specific->m_screen, 
+//                                     depth[i], 
+//                                     DirectColor, 
+//                                     &vi)) 
+//                 {
+// //                     printf("DirectColor depth=%d, red=%08x, green=%08x, blue=%08x, bits=%d\n",
+// //                         vi.depth,
+// //                         vi.visual->red_mask,
+// //                         vi.visual->green_mask,
+// //                         vi.visual->blue_mask,
+// //                         vi.bits_per_rgb);
+//                     m_specific->m_depth  = vi.depth;
+//                     m_specific->m_visual = vi.visual;
+//                     r_mask = m_specific->m_visual->red_mask;
+//                     g_mask = m_specific->m_visual->green_mask;
+//                     b_mask = m_specific->m_visual->blue_mask;
+//                     break;
+//                 }
+//             }
+//         }
+
+        if(m_specific->m_depth < 15 ||
+           r_mask == 0 || g_mask == 0 || b_mask == 0)
+        {
+            fprintf(stderr,
+                   "There's no Visual compatible with minimal AGG requirements:\n"
+                   "At least 15-bit color depth and True- or DirectColor class.\n\n");
+            XCloseDisplay(m_specific->m_display);
+            return false;
+        }
+        
+        int t = 1;
+        int hw_byte_order = LSBFirst;
+        if(*(char*)&t == 0) hw_byte_order = MSBFirst;
+        
+        // Perceive SYS-format by mask
+        switch(m_specific->m_depth)
+        {
+            case 15:
+                m_specific->m_sys_bpp = 16;
+                if(r_mask == 0x7C00 && g_mask == 0x3E0 && b_mask == 0x1F)
+                {
+                    m_specific->m_sys_format = pix_format_rgb555;
+                    m_specific->m_byte_order = hw_byte_order;
+                }
+                break;
+                
+            case 16:
+                m_specific->m_sys_bpp = 16;
+                if(r_mask == 0xF800 && g_mask == 0x7E0 && b_mask == 0x1F)
+                {
+                    m_specific->m_sys_format = pix_format_rgb565;
+                    m_specific->m_byte_order = hw_byte_order;
+                }
+                break;
+                
+            case 24:
+            case 32:
+                m_specific->m_sys_bpp = 32;
+                if(g_mask == 0xFF00)
+                {
+                    if(r_mask == 0xFF && b_mask == 0xFF0000)
+                    {
+                        switch(m_specific->m_format)
+                        {
+                            case pix_format_rgba32:
+                                m_specific->m_sys_format = pix_format_rgba32;
+                                m_specific->m_byte_order = LSBFirst;
+                                break;
+                                
+                            case pix_format_abgr32:
+                                m_specific->m_sys_format = pix_format_abgr32;
+                                m_specific->m_byte_order = MSBFirst;
+                                break;
+
+                            default:                            
+                                m_specific->m_byte_order = hw_byte_order;
+                                m_specific->m_sys_format = 
+                                    (hw_byte_order == LSBFirst) ?
+                                    pix_format_rgba32 :
+                                    pix_format_abgr32;
+                                break;
+                        }
+                    }
+                    
+                    if(r_mask == 0xFF0000 && b_mask == 0xFF)
+                    {
+                        switch(m_specific->m_format)
+                        {
+                            case pix_format_argb32:
+                                m_specific->m_sys_format = pix_format_argb32;
+                                m_specific->m_byte_order = MSBFirst;
+                                break;
+                                
+                            case pix_format_bgra32:
+                                m_specific->m_sys_format = pix_format_bgra32;
+                                m_specific->m_byte_order = LSBFirst;
+                                break;
+
+                            default:                            
+                                m_specific->m_byte_order = hw_byte_order;
+                                m_specific->m_sys_format = 
+                                    (hw_byte_order == MSBFirst) ?
+                                    pix_format_argb32 :
+                                    pix_format_bgra32;
+                                break;
+                        }
+                    }
+                }
+                break;
+        }
+        
+        if(m_specific->m_sys_format == pix_format_undefined)
+        {
+            fprintf(stderr,
+                   "RGB masks are not compatible with AGG pixel formats:\n"
+                   "R=%08x, R=%08x, B=%08x\n", r_mask, g_mask, b_mask);
+            XCloseDisplay(m_specific->m_display);
+            return false;
+        }
+                
+        
+        
+        memset(&m_specific->m_window_attributes, 
+               0, 
+               sizeof(m_specific->m_window_attributes)); 
+        
+        m_specific->m_window_attributes.border_pixel = 
+            XBlackPixel(m_specific->m_display, m_specific->m_screen);
+
+        m_specific->m_window_attributes.background_pixel = 
+            XWhitePixel(m_specific->m_display, m_specific->m_screen);
+
+        m_specific->m_window_attributes.override_redirect = 0;
+
+        unsigned long window_mask = CWBackPixel | CWBorderPixel;
+
+        m_specific->m_window = 
+            XCreateWindow(m_specific->m_display, 
+                          XDefaultRootWindow(m_specific->m_display), 
+                          0, 0,
+                          width,
+                          height,
+                          0, 
+                          m_specific->m_depth, 
+                          InputOutput, 
+                          CopyFromParent,
+                          window_mask,
+                          &m_specific->m_window_attributes);
+
+
+        m_specific->m_gc = XCreateGC(m_specific->m_display, 
+                                     m_specific->m_window, 
+                                     0, 0); 
+        m_specific->m_buf_window = 
+            new unsigned char[width * height * (m_bpp / 8)];
+
+        memset(m_specific->m_buf_window, 255, width * height * (m_bpp / 8));
+        
+        m_rbuf_window.attach(m_specific->m_buf_window,
+                             width,
+                             height,
+                             m_flip_y ? -width * (m_bpp / 8) : width * (m_bpp / 8));
+            
+        m_specific->m_ximg_window = 
+            XCreateImage(m_specific->m_display, 
+                         m_specific->m_visual, //CopyFromParent, 
+                         m_specific->m_depth, 
+                         ZPixmap, 
+                         0,
+                         (char*)m_specific->m_buf_window, 
+                         width,
+                         height, 
+                         m_specific->m_sys_bpp,
+                         width * (m_specific->m_sys_bpp / 8));
+        m_specific->m_ximg_window->byte_order = m_specific->m_byte_order;
+
+        m_specific->caption(m_caption); 
+        m_initial_width = width;
+        m_initial_height = height;
+        
+        if(!m_specific->m_initialized)
+        {
+            on_init();
+            m_specific->m_initialized = true;
+        }
+
+        trans_affine_resizing(width, height);
+        on_resize(width, height);
+        m_specific->m_update_flag = true;
+
+        XSizeHints *hints = XAllocSizeHints();
+        if(hints) 
+        {
+            if(flags & window_resize)
+            {
+                hints->min_width = 32;
+                hints->min_height = 32;
+                hints->max_width = 4096;
+                hints->max_height = 4096;
+            }
+            else
+            {
+                hints->min_width  = width;
+                hints->min_height = height;
+                hints->max_width  = width;
+                hints->max_height = height;
+            }
+            hints->flags = PMaxSize | PMinSize;
+
+            XSetWMNormalHints(m_specific->m_display, 
+                              m_specific->m_window, 
+                              hints);
+
+            XFree(hints);
+        }
+
+
+        XMapWindow(m_specific->m_display, 
+                   m_specific->m_window);
+
+        XSelectInput(m_specific->m_display, 
+                     m_specific->m_window, 
+                     xevent_mask);
+
+        
+        m_specific->m_close_atom = XInternAtom(m_specific->m_display, 
+                                               "WM_DELETE_WINDOW", 
+                                               false);
+
+        XSetWMProtocols(m_specific->m_display, 
+                        m_specific->m_window, 
+                        &m_specific->m_close_atom, 
+                        1);
+
+        return true;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    void platform_support::update_window()
+    {
+        m_specific->put_image(&m_rbuf_window);
+        
+        // When m_wait_mode is true we can discard all the events 
+        // came while the image is being drawn. In this case 
+        // the X server does not accumulate mouse motion events.
+        // When m_wait_mode is false, i.e. we have some idle drawing
+        // we cannot afford to miss any events
+        XSync(m_specific->m_display, m_wait_mode);
+    }
+
+
+    //------------------------------------------------------------------------
+    int platform_support::run()
+    {
+        XFlush(m_specific->m_display);
+        
+        bool quit = false;
+        unsigned flags;
+        int cur_x;
+        int cur_y;
+
+        while(!quit)
+        {
+            if(m_specific->m_update_flag)
+            {
+                on_draw();
+                update_window();
+                m_specific->m_update_flag = false;
+            }
+
+            if(!m_wait_mode)
+            {
+                if(XPending(m_specific->m_display) == 0)
+                {
+                    on_idle();
+                    continue;
+                }
+            }
+
+            XEvent x_event;
+            XNextEvent(m_specific->m_display, &x_event);
+            
+            // In the Idle mode discard all intermediate MotionNotify events
+            if(!m_wait_mode && x_event.type == MotionNotify)
+            {
+                XEvent te = x_event;
+                for(;;)
+                {
+                    if(XPending(m_specific->m_display) == 0) break;
+                    XNextEvent(m_specific->m_display, &te);
+                    if(te.type != MotionNotify) break;
+                }
+                x_event = te;
+            }
+
+            switch(x_event.type) 
+            {
+            case ConfigureNotify: 
+                {
+                    if(x_event.xconfigure.width  != int(m_rbuf_window.width()) ||
+                       x_event.xconfigure.height != int(m_rbuf_window.height()))
+                    {
+                        int width  = x_event.xconfigure.width;
+                        int height = x_event.xconfigure.height;
+
+                        delete [] m_specific->m_buf_window;
+                        m_specific->m_ximg_window->data = 0;
+                        XDestroyImage(m_specific->m_ximg_window);
+
+                        m_specific->m_buf_window = 
+                            new unsigned char[width * height * (m_bpp / 8)];
+
+                        m_rbuf_window.attach(m_specific->m_buf_window,
+                                             width,
+                                             height,
+                                             m_flip_y ? 
+                                             -width * (m_bpp / 8) : 
+                                             width * (m_bpp / 8));
+            
+                        m_specific->m_ximg_window = 
+                            XCreateImage(m_specific->m_display, 
+                                         m_specific->m_visual, //CopyFromParent, 
+                                         m_specific->m_depth, 
+                                         ZPixmap, 
+                                         0,
+                                         (char*)m_specific->m_buf_window, 
+                                         width,
+                                         height, 
+                                         m_specific->m_sys_bpp,
+                                         width * (m_specific->m_sys_bpp / 8));
+                        m_specific->m_ximg_window->byte_order = m_specific->m_byte_order;
+
+                        trans_affine_resizing(width, height);
+                        on_resize(width, height);
+                        on_draw();
+                        update_window();
+                    }
+                }
+                break;
+
+            case Expose:
+                m_specific->put_image(&m_rbuf_window);
+                XFlush(m_specific->m_display);
+                XSync(m_specific->m_display, false);
+                break;
+
+            case KeyPress:
+                {
+                    KeySym key = XLookupKeysym(&x_event.xkey, 0);
+                    flags = 0;
+                    if(x_event.xkey.state & Button1Mask) flags |= mouse_left;
+                    if(x_event.xkey.state & Button3Mask) flags |= mouse_right;
+                    if(x_event.xkey.state & ShiftMask)   flags |= kbd_shift;
+                    if(x_event.xkey.state & ControlMask) flags |= kbd_ctrl;
+
+                    bool left  = false;
+                    bool up    = false;
+                    bool right = false;
+                    bool down  = false;
+
+                    switch(m_specific->m_keymap[key & 0xFF])
+                    {
+                    case key_left:
+                        left = true;
+                        break;
+
+                    case key_up:
+                        up = true;
+                        break;
+
+                    case key_right:
+                        right = true;
+                        break;
+
+                    case key_down:
+                        down = true;
+                        break;
+
+                    case key_f2:                        
+                        copy_window_to_img(max_images - 1);
+                        save_img(max_images - 1, "screenshot");
+                        break;
+                    }
+
+                    if(m_ctrls.on_arrow_keys(left, right, down, up))
+                    {
+                        on_ctrl_change();
+                        force_redraw();
+                    }
+                    else
+                    {
+                        on_key(x_event.xkey.x, 
+                               m_flip_y ? 
+                                   m_rbuf_window.height() - x_event.xkey.y :
+                                   x_event.xkey.y,
+                               m_specific->m_keymap[key & 0xFF],
+                               flags);
+                    }
+                }
+                break;
+
+
+            case ButtonPress:
+                {
+                    flags = 0;
+                    if(x_event.xbutton.state & ShiftMask)   flags |= kbd_shift;
+                    if(x_event.xbutton.state & ControlMask) flags |= kbd_ctrl;
+                    if(x_event.xbutton.button == Button1)   flags |= mouse_left;
+                    if(x_event.xbutton.button == Button3)   flags |= mouse_right;
+
+                    cur_x = x_event.xbutton.x;
+                    cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y :
+                                       x_event.xbutton.y;
+
+                    if(flags & mouse_left)
+                    {
+                        if(m_ctrls.on_mouse_button_down(cur_x, cur_y))
+                        {
+                            m_ctrls.set_cur(cur_x, cur_y);
+                            on_ctrl_change();
+                            force_redraw();
+                        }
+                        else
+                        {
+                            if(m_ctrls.in_rect(cur_x, cur_y))
+                            {
+                                if(m_ctrls.set_cur(cur_x, cur_y))
+                                {
+                                    on_ctrl_change();
+                                    force_redraw();
+                                }
+                            }
+                            else
+                            {
+                                on_mouse_button_down(cur_x, cur_y, flags);
+                            }
+                        }
+                    }
+                    if(flags & mouse_right)
+                    {
+                        on_mouse_button_down(cur_x, cur_y, flags);
+                    }
+                    //m_specific->m_wait_mode = m_wait_mode;
+                    //m_wait_mode = true;
+                }
+                break;
+
+                
+            case MotionNotify:
+                {
+                    flags = 0;
+                    if(x_event.xmotion.state & Button1Mask) flags |= mouse_left;
+                    if(x_event.xmotion.state & Button3Mask) flags |= mouse_right;
+                    if(x_event.xmotion.state & ShiftMask)   flags |= kbd_shift;
+                    if(x_event.xmotion.state & ControlMask) flags |= kbd_ctrl;
+
+                    cur_x = x_event.xbutton.x;
+                    cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y :
+                                       x_event.xbutton.y;
+
+                    if(m_ctrls.on_mouse_move(cur_x, cur_y, (flags & mouse_left) != 0))
+                    {
+                        on_ctrl_change();
+                        force_redraw();
+                    }
+                    else
+                    {
+                        if(!m_ctrls.in_rect(cur_x, cur_y))
+                        {
+                            on_mouse_move(cur_x, cur_y, flags);
+                        }
+                    }
+                }
+                break;
+                
+            case ButtonRelease:
+                {
+                    flags = 0;
+                    if(x_event.xbutton.state & ShiftMask)   flags |= kbd_shift;
+                    if(x_event.xbutton.state & ControlMask) flags |= kbd_ctrl;
+                    if(x_event.xbutton.button == Button1)   flags |= mouse_left;
+                    if(x_event.xbutton.button == Button3)   flags |= mouse_right;
+
+                    cur_x = x_event.xbutton.x;
+                    cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y :
+                                       x_event.xbutton.y;
+
+                    if(flags & mouse_left)
+                    {
+                        if(m_ctrls.on_mouse_button_up(cur_x, cur_y))
+                        {
+                            on_ctrl_change();
+                            force_redraw();
+                        }
+                    }
+                    if(flags & (mouse_left | mouse_right))
+                    {
+                        on_mouse_button_up(cur_x, cur_y, flags);
+                    }
+                }
+                //m_wait_mode = m_specific->m_wait_mode;
+                break;
+
+            case ClientMessage:
+                if((x_event.xclient.format == 32) &&
+                (x_event.xclient.data.l[0] == int(m_specific->m_close_atom)))
+                {
+                    quit = true;
+                }
+                break;
+            }           
+        }
+
+
+        unsigned i = platform_support::max_images;
+        while(i--)
+        {
+            if(m_specific->m_buf_img[i]) 
+            {
+                delete [] m_specific->m_buf_img[i];
+            }
+        }
+
+        delete [] m_specific->m_buf_window;
+        m_specific->m_ximg_window->data = 0;
+        XDestroyImage(m_specific->m_ximg_window);
+        XFreeGC(m_specific->m_display, m_specific->m_gc);
+        XDestroyWindow(m_specific->m_display, m_specific->m_window);
+        XCloseDisplay(m_specific->m_display);
+        
+        return 0;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    const char* platform_support::img_ext() const { return ".ppm"; }
+
+    //------------------------------------------------------------------------
+    const char* platform_support::full_file_name(const char* file_name)
+    {
+        return file_name;
+    }
+
+    //------------------------------------------------------------------------
+    bool platform_support::load_img(unsigned idx, const char* file)
+    {
+        if(idx < max_images)
+        {
+            char buf[1024];
+            strcpy(buf, file);
+            int len = strlen(buf);
+            if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0)
+            {
+                strcat(buf, ".ppm");
+            }
+            
+            FILE* fd = fopen(buf, "rb");
+            if(fd == 0) return false;
+
+            if((len = fread(buf, 1, 1022, fd)) == 0)
+            {
+                fclose(fd);
+                return false;
+            }
+            buf[len] = 0;
+            
+            if(buf[0] != 'P' && buf[1] != '6')
+            {
+                fclose(fd);
+                return false;
+            }
+            
+            char* ptr = buf + 2;
+            
+            while(*ptr && !isdigit(*ptr)) ptr++;
+            if(*ptr == 0)
+            {
+                fclose(fd);
+                return false;
+            }
+            
+            unsigned width = atoi(ptr);
+            if(width == 0 || width > 4096)
+            {
+                fclose(fd);
+                return false;
+            }
+            while(*ptr && isdigit(*ptr)) ptr++;
+            while(*ptr && !isdigit(*ptr)) ptr++;
+            if(*ptr == 0)
+            {
+                fclose(fd);
+                return false;
+            }
+            unsigned height = atoi(ptr);
+            if(height == 0 || height > 4096)
+            {
+                fclose(fd);
+                return false;
+            }
+            while(*ptr && isdigit(*ptr)) ptr++;
+            while(*ptr && !isdigit(*ptr)) ptr++;
+            if(atoi(ptr) != 255)
+            {
+                fclose(fd);
+                return false;
+            }
+            while(*ptr && isdigit(*ptr)) ptr++;
+            if(*ptr == 0)
+            {
+                fclose(fd);
+                return false;
+            }
+            ptr++;
+            fseek(fd, long(ptr - buf), SEEK_SET);
+            
+            create_img(idx, width, height);
+            bool ret = true;
+            
+            if(m_format == pix_format_rgb24)
+            {
+                fread(m_specific->m_buf_img[idx], 1, width * height * 3, fd);
+            }
+            else
+            {
+                unsigned char* buf_img = new unsigned char [width * height * 3];
+                rendering_buffer rbuf_img;
+                rbuf_img.attach(buf_img,
+                                width,
+                                height,
+                                m_flip_y ?
+                                  -width * 3 :
+                                   width * 3);
+                
+                fread(buf_img, 1, width * height * 3, fd);
+                
+                switch(m_format)
+                {
+                    case pix_format_sgray8:
+                        convert<pixfmt_sgray8, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_gray8:
+                        convert<pixfmt_gray8, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_gray16:
+                        convert<pixfmt_gray16, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_gray32:
+                        convert<pixfmt_gray32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_rgb555:
+                        color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgb555());
+                        break;
+                        
+                    case pix_format_rgb565:
+                        color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgb565());
+                        break;
+                        
+                    case pix_format_sbgr24:
+                        convert<pixfmt_sbgr24, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_rgb24:
+                        convert<pixfmt_rgb24, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_bgr24:
+                        convert<pixfmt_bgr24, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_srgba32:
+                        convert<pixfmt_srgba32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_sargb32:
+                        convert<pixfmt_sargb32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_sbgra32:
+                        convert<pixfmt_sbgra32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_sabgr32:
+                        convert<pixfmt_sabgr32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_rgba32:
+                        convert<pixfmt_rgba32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_argb32:
+                        convert<pixfmt_argb32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_bgra32:
+                        convert<pixfmt_bgra32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_abgr32:
+                        convert<pixfmt_abgr32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_rgb48:
+                        convert<pixfmt_rgb48, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_bgr48:
+                        convert<pixfmt_bgr48, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_rgba64:
+                        convert<pixfmt_rgba64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_argb64:
+                        convert<pixfmt_argb64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_bgra64:
+                        convert<pixfmt_bgra64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_abgr64:
+                        convert<pixfmt_abgr64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_rgb96:
+                        convert<pixfmt_rgb96, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_bgr96:
+                        convert<pixfmt_bgr96, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_rgba128:
+                        convert<pixfmt_rgba128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_argb128:
+                        convert<pixfmt_argb128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_bgra128:
+                        convert<pixfmt_bgra128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    case pix_format_abgr128:
+                        convert<pixfmt_abgr128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+                        break;
+                        
+                    default:
+                        ret = false;
+                }
+                delete [] buf_img;
+            }
+                        
+            fclose(fd);
+            return ret;
+        }
+        return false;
+    }
+
+
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::save_img(unsigned idx, const char* file)
+    {
+        if(idx < max_images &&  rbuf_img(idx).buf())
+        {
+            char buf[1024];
+            strcpy(buf, file);
+            int len = strlen(buf);
+            if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0)
+            {
+                strcat(buf, ".ppm");
+            }
+            
+            FILE* fd = fopen(buf, "wb");
+            if(fd == 0) return false;
+            
+            unsigned w = rbuf_img(idx).width();
+            unsigned h = rbuf_img(idx).height();
+            
+            fprintf(fd, "P6\n%d %d\n255\n", w, h);
+                
+            unsigned y; 
+            unsigned char* tmp_buf = new unsigned char [w * 3];
+            for(y = 0; y < rbuf_img(idx).height(); y++)
+            {
+                const unsigned char* src = rbuf_img(idx).row_ptr(m_flip_y ? h - 1 - y : y);
+                switch(m_format)
+                {
+                    case pix_format_sgray8:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sgray8>());
+                        break;
+                        
+                    case pix_format_gray8:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_gray8>());
+                        break;
+                        
+                    case pix_format_gray16:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_gray16>());
+                        break;
+                        
+                    case pix_format_gray32:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_gray32>());
+                        break;
+                        
+                    default: break;
+                    case pix_format_rgb555:
+                        color_conv_row(tmp_buf, src, w, color_conv_rgb555_to_rgb24());
+                        break;
+                        
+                    case pix_format_rgb565:
+                        color_conv_row(tmp_buf, src, w, color_conv_rgb565_to_rgb24());
+                        break;
+                        
+                    case pix_format_sbgr24:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sbgr24>());
+                        break;
+                        
+                    case pix_format_srgb24:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_srgb24>());
+                        break;
+                       
+                    case pix_format_bgr24:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgr24>());
+                        break;
+                        
+                    case pix_format_rgb24:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgb24>());
+                        break;
+                       
+                    case pix_format_srgba32:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_srgba32>());
+                        break;
+                        
+                    case pix_format_sargb32:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sargb32>());
+                        break;
+                        
+                    case pix_format_sbgra32:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sbgra32>());
+                        break;
+                        
+                    case pix_format_sabgr32:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sabgr32>());
+                        break;
+
+                    case pix_format_rgba32:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgba32>());
+                        break;
+                        
+                    case pix_format_argb32:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_argb32>());
+                        break;
+                        
+                    case pix_format_bgra32:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgra32>());
+                        break;
+                        
+                    case pix_format_abgr32:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_abgr32>());
+                        break;
+
+                    case pix_format_bgr48:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgr48>());
+                        break;
+                        
+                    case pix_format_rgb48:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgb48>());
+                        break;
+                       
+                    case pix_format_rgba64:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgba64>());
+                        break;
+                        
+                    case pix_format_argb64:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_argb64>());
+                        break;
+                        
+                    case pix_format_bgra64:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgra64>());
+                        break;
+                        
+                    case pix_format_abgr64:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_abgr64>());
+                        break;
+
+                    case pix_format_bgr96:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgr96>());
+                        break;
+                        
+                    case pix_format_rgb96:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgb96>());
+                        break;
+                       
+                    case pix_format_rgba128:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgba128>());
+                        break;
+                        
+                    case pix_format_argb128:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_argb128>());
+                        break;
+                        
+                    case pix_format_bgra128:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgra128>());
+                        break;
+                        
+                    case pix_format_abgr128:
+                        color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_abgr128>());
+                        break;
+                }
+                fwrite(tmp_buf, 1, w * 3, fd);
+            }
+            delete [] tmp_buf;
+            fclose(fd);
+            return true;
+        }
+        return false;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::create_img(unsigned idx, unsigned width, unsigned height)
+    {
+        if(idx < max_images)
+        {
+            if(width  == 0) width  = rbuf_window().width();
+            if(height == 0) height = rbuf_window().height();
+            delete [] m_specific->m_buf_img[idx];
+            m_specific->m_buf_img[idx] = 
+                new unsigned char[width * height * (m_bpp / 8)];
+
+            m_rbuf_img[idx].attach(m_specific->m_buf_img[idx],
+                                   width,
+                                   height,
+                                   m_flip_y ? 
+                                       -width * (m_bpp / 8) : 
+                                        width * (m_bpp / 8));
+            return true;
+        }
+        return false;
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_support::force_redraw()
+    {
+        m_specific->m_update_flag = true;
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_support::message(const char* msg)
+    {
+        fprintf(stderr, "%s\n", msg);
+    }
+
+    //------------------------------------------------------------------------
+    void platform_support::start_timer()
+    {
+        m_specific->m_sw_start = clock();
+    }
+
+    //------------------------------------------------------------------------
+    double platform_support::elapsed_time() const
+    {
+        clock_t stop = clock();
+        return double(stop - m_specific->m_sw_start) * 1000.0 / CLOCKS_PER_SEC;
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_support::on_init() {}
+    void platform_support::on_resize(int sx, int sy) {}
+    void platform_support::on_idle() {}
+    void platform_support::on_mouse_move(int x, int y, unsigned flags) {}
+    void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {}
+    void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {}
+    void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {}
+    void platform_support::on_ctrl_change() {}
+    void platform_support::on_draw() {}
+    void platform_support::on_post_draw(void* raw_handler) {}
+
+
+
+}
+
+
+int agg_main(int argc, char* argv[]);
+
+
+int main(int argc, char* argv[])
+{
+    return agg_main(argc, argv);
+}
+
+
+
+
+
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp
new file mode 100644
index 0000000000..dc85fd69ff
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp
@@ -0,0 +1,298 @@
+//----------------------------------------------------------------------------
+//
+//----------------------------------------------------------------------------
+// Contact: mcseemagg@yahoo.com
+//          baer@karto.baug.ethz.ch
+//----------------------------------------------------------------------------
+//
+// class pixel_map
+//
+//----------------------------------------------------------------------------
+
+#include <string.h>
+#include <Carbon.h>
+#include <QuickTimeComponents.h>
+#include <ImageCompression.h>
+#include "platform/mac/agg_mac_pmap.h"
+#include "agg_basics.h"
+
+namespace agg
+{
+
+    //------------------------------------------------------------------------
+    pixel_map::~pixel_map()
+    {
+        destroy();
+    }
+
+
+    //------------------------------------------------------------------------
+    pixel_map::pixel_map() :
+        m_pmap(0),
+        m_buf(0),
+        m_bpp(0),
+        m_img_size(0)
+
+    {
+    }
+
+
+    //------------------------------------------------------------------------
+    void pixel_map::destroy()
+    {
+		delete[] m_buf;
+		m_buf = NULL;
+		if (m_pmap != nil)
+		{
+			DisposeGWorld(m_pmap);
+			m_pmap = nil;
+		}
+    }
+
+
+    //------------------------------------------------------------------------
+    void pixel_map::create(unsigned width, 
+                           unsigned height, 
+                           org_e    org,
+                           unsigned clear_val)
+    {
+        destroy();
+        if(width == 0)  width = 1;
+        if(height == 0) height = 1;
+        m_bpp = org;
+        
+        Rect	r;
+    	int		row_bytes = calc_row_len (width, m_bpp);
+    	MacSetRect(&r, 0, 0, width, height);
+    	m_buf = new unsigned char[m_img_size = row_bytes * height];
+ 		// The Quicktime version for creating GWorlds is more flexible than the classical function.
+    	QTNewGWorldFromPtr (&m_pmap, m_bpp, &r, nil, nil, 0, m_buf, row_bytes);
+
+        // create_gray_scale_palette(m_pmap);  I didn't care about gray scale palettes so far.
+        if(clear_val <= 255)
+        {
+            memset(m_buf, clear_val, m_img_size);
+        }
+    }
+
+
+
+    //------------------------------------------------------------------------
+    void pixel_map::clear(unsigned clear_val)
+    {
+        if(m_buf) memset(m_buf, clear_val, m_img_size);
+    }
+
+
+    //static
+    //This function is just copied from the Win32 plattform support.
+    //Is also seems to be appropriate for MacOS as well, but it is not
+    //thouroughly tested so far.
+    //------------------------------------------------------------------------
+
+    unsigned pixel_map::calc_row_len(unsigned width, unsigned bits_per_pixel)
+    {
+        unsigned n = width;
+        unsigned k;
+
+        switch(bits_per_pixel)
+        {
+            case  1: k = n;
+                     n = n >> 3;
+                     if(k & 7) n++; 
+                     break;
+
+            case  4: k = n;
+                     n = n >> 1;
+                     if(k & 3) n++; 
+                     break;
+
+            case  8:
+                     break;
+
+            case 16: n = n << 1;
+                     break;
+
+            case 24: n = (n << 1) + n; 
+                     break;
+
+            case 32: n = n << 2;
+                     break;
+
+            default: n = 0;
+                     break;
+        }
+        return ((n + 3) >> 2) << 2;
+    }
+
+
+
+
+    //------------------------------------------------------------------------
+    void pixel_map::draw(WindowRef window, const Rect *device_rect, const Rect *pmap_rect) const
+    {
+        if(m_pmap == nil || m_buf == NULL) return;
+
+		PixMapHandle	pm = GetGWorldPixMap (m_pmap);
+		CGrafPtr		port = GetWindowPort (window);
+		Rect			dest_rect;
+
+		// Again, I used the Quicktime version.
+		// Good old 'CopyBits' does better interpolation when scaling
+		// but does not support all pixel depths.
+		MacSetRect (&dest_rect, 0, 0, this->width(), this->height());
+		ImageDescriptionHandle		image_description;
+		MakeImageDescriptionForPixMap (pm, &image_description);	   
+		if (image_description != nil)
+		{
+			DecompressImage (GetPixBaseAddr (pm), image_description, GetPortPixMap (port), nil, &dest_rect, ditherCopy, nil);	   
+			DisposeHandle ((Handle) image_description);
+		}
+	}
+
+
+    //------------------------------------------------------------------------
+    void pixel_map::draw(WindowRef window, int x, int y, double scale) const
+    {
+        if(m_pmap == nil || m_buf == NULL) return;
+        unsigned width  = (unsigned)(this->width() * scale);
+        unsigned height = (unsigned)(this->height() * scale);
+        Rect rect;
+        SetRect (&rect, x, y, x + width, y + height);
+        draw(window, &rect);
+    }
+
+
+
+    //------------------------------------------------------------------------
+    void pixel_map::blend(WindowRef window, const Rect *device_rect, const Rect *bmp_rect) const
+    {
+		draw (window, device_rect, bmp_rect);	// currently just mapped to drawing method
+    }
+    
+
+    //------------------------------------------------------------------------
+    void pixel_map::blend(WindowRef window, int x, int y, double scale) const
+    {
+        draw(window, x, y, scale);	// currently just mapped to drawing method
+    }
+
+
+    // I let Quicktime handle image import since it supports most popular
+    // image formats such as:
+    // *.psd, *.bmp, *.tif, *.png, *.jpg, *.gif, *.pct, *.pcx
+    //------------------------------------------------------------------------
+    bool pixel_map::load_from_qt(const char *filename)
+    {
+		FSSpec						fss;
+		OSErr						err;
+		
+		// get file specification to application directory
+		err = HGetVol(nil, &fss.vRefNum, &fss.parID);
+		if (err == noErr)
+		{
+			CopyCStringToPascal(filename, fss.name);
+			GraphicsImportComponent		gi;
+			err = GetGraphicsImporterForFile (&fss, &gi);
+			if (err == noErr)
+			{
+				ImageDescriptionHandle	desc;
+				GraphicsImportGetImageDescription(gi, &desc);
+// For simplicity, all images are currently converted to 32 bit.
+				// create an empty pixelmap
+				short depth = 32;
+				create ((**desc).width, (**desc).height, (org_e)depth, 0xff);
+				DisposeHandle ((Handle)desc);
+				// let Quicktime draw to pixelmap
+				GraphicsImportSetGWorld(gi, m_pmap, nil);
+				GraphicsImportDraw(gi);
+// Well, this is a hack. The graphics importer sets the alpha channel of the pixelmap to 0x00
+// for imported images without alpha channel but this would cause agg to draw an invisible image.
+				// set alpha channel to 0xff
+				unsigned char * buf = m_buf;
+				for (unsigned int size = 0; size < m_img_size; size += 4)
+				{
+					*buf = 0xff;
+					buf += 4;
+				}
+			}
+		}
+        return err == noErr;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool pixel_map::save_as_qt(const char *filename) const
+    {
+		FSSpec						fss;
+ 		OSErr						err;
+		
+		// get file specification to application directory
+		err = HGetVol(nil, &fss.vRefNum, &fss.parID);
+		if (err == noErr)
+		{
+     		GraphicsExportComponent		ge;
+  			CopyCStringToPascal(filename, fss.name);
+  			// I decided to use PNG as output image file type.
+  			// There are a number of other available formats.
+  			// Should I check the file suffix to choose the image file format?
+			err = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypePNG, &ge);
+			if (err == noErr)
+			{
+    			err = GraphicsExportSetInputGWorld(ge, m_pmap);
+	    		if (err == noErr)
+    			{
+    				err = GraphicsExportSetOutputFile (ge, &fss);
+    				if (err == noErr)
+    				{
+    					GraphicsExportDoExport(ge, nil);
+    				}
+    			}
+    			CloseComponent(ge);
+    		}
+    	}
+    	
+        return err == noErr;
+    }
+
+    //------------------------------------------------------------------------
+    unsigned char* pixel_map::buf()
+    {
+        return m_buf;
+    }
+
+    //------------------------------------------------------------------------
+    unsigned pixel_map::width() const
+    {
+        if(m_pmap == nil) return 0;
+		PixMapHandle	pm = GetGWorldPixMap (m_pmap);
+		Rect			bounds;
+		GetPixBounds (pm, &bounds);
+		return bounds.right - bounds.left;
+    }
+
+    //------------------------------------------------------------------------
+    unsigned pixel_map::height() const
+    {
+        if(m_pmap == nil) return 0;
+		PixMapHandle	pm = GetGWorldPixMap (m_pmap);
+		Rect			bounds;
+		GetPixBounds (pm, &bounds);
+		return bounds.bottom - bounds.top;
+    }
+
+    //------------------------------------------------------------------------
+    int pixel_map::row_bytes() const
+    {
+        if(m_pmap == nil) return 0;
+ 		PixMapHandle	pm = GetGWorldPixMap (m_pmap);
+        return calc_row_len(width(), GetPixDepth(pm));
+    }
+
+
+
+}
+
+
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp
new file mode 100644
index 0000000000..f518dbe1f2
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp
@@ -0,0 +1,1053 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4 
+// Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
+// Copyright (C) 2003 Hansruedi Baer (MacOS support)
+//
+// Permission to copy, use, modify, sell and distribute this software 
+// is granted provided this copyright notice appears in all copies. 
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+//          mcseemagg@yahoo.com
+//          http://www.antigrain.com
+//			baer@karto.baug.eth.ch
+//----------------------------------------------------------------------------
+//
+// class platform_support
+//
+//----------------------------------------------------------------------------
+//
+// Note:
+// I tried to retain the original structure for the Win32 platform as far
+// as possible. Currently, not all features are implemented but the examples
+// should work properly.
+// HB
+//----------------------------------------------------------------------------
+
+#include <Carbon.h>
+#if defined(__MWERKS__)
+#include "console.h"
+#endif
+#include <string.h>
+#include <unistd.h>
+#include "platform/agg_platform_support.h"
+#include "platform/mac/agg_mac_pmap.h"
+#include "util/agg_color_conv_rgb8.h"
+
+
+namespace agg
+{
+    
+pascal OSStatus DoWindowClose (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus DoWindowDrawContent (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus DoAppQuit (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus DoMouseDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus DoMouseUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus DoMouseDragged (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus DoKeyDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus DoKeyUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal void DoPeriodicTask (EventLoopTimerRef theTimer, void* userData);
+
+
+    //------------------------------------------------------------------------
+    class platform_specific
+    {
+    public:
+        platform_specific(pix_format_e format, bool flip_y);
+
+        void create_pmap(unsigned width, unsigned height, 
+                         rendering_buffer* wnd);
+
+        void display_pmap(WindowRef window, const rendering_buffer* src);
+        bool load_pmap(const char* fn, unsigned idx, 
+                       rendering_buffer* dst);
+
+        bool save_pmap(const char* fn, unsigned idx, 
+                       const rendering_buffer* src);
+
+        unsigned translate(unsigned keycode);
+
+        pix_format_e     m_format;
+        pix_format_e     m_sys_format;
+        bool             m_flip_y;
+        unsigned         m_bpp;
+        unsigned         m_sys_bpp;
+        WindowRef        m_window;
+        pixel_map   	 m_pmap_window;
+        pixel_map        m_pmap_img[platform_support::max_images];
+        unsigned         m_keymap[256];
+        unsigned         m_last_translated_key;
+        int              m_cur_x;
+        int              m_cur_y;
+        unsigned         m_input_flags;
+        bool             m_redraw_flag;
+        UnsignedWide     m_sw_freq;
+        UnsignedWide     m_sw_start;
+    };
+
+
+    //------------------------------------------------------------------------
+    platform_specific::platform_specific(pix_format_e format, bool flip_y) :
+       	m_format(format),
+        m_sys_format(pix_format_undefined),
+        m_flip_y(flip_y),
+        m_bpp(0),
+        m_sys_bpp(0),
+        m_window(nil),
+        m_last_translated_key(0),
+        m_cur_x(0),
+        m_cur_y(0),
+        m_input_flags(0),
+        m_redraw_flag(true)
+    {
+        memset(m_keymap, 0, sizeof(m_keymap));
+
+        //Keyboard input is not yet fully supported nor tested
+        //m_keymap[VK_PAUSE]       = key_pause;
+        m_keymap[kClearCharCode]      = key_clear;
+
+        //m_keymap[VK_NUMPAD0]    = key_kp0;
+        //m_keymap[VK_NUMPAD1]    = key_kp1;
+        //m_keymap[VK_NUMPAD2]    = key_kp2;
+        //m_keymap[VK_NUMPAD3]    = key_kp3;
+        //m_keymap[VK_NUMPAD4]    = key_kp4;
+        //m_keymap[VK_NUMPAD5]    = key_kp5;
+        //m_keymap[VK_NUMPAD6]    = key_kp6;
+        //m_keymap[VK_NUMPAD7]    = key_kp7;
+        //m_keymap[VK_NUMPAD8]    = key_kp8;
+        //m_keymap[VK_NUMPAD9]    = key_kp9;
+        //m_keymap[VK_DECIMAL]    = key_kp_period;
+        //m_keymap[VK_DIVIDE]     = key_kp_divide;
+        //m_keymap[VK_MULTIPLY]   = key_kp_multiply;
+        //m_keymap[VK_SUBTRACT]   = key_kp_minus;
+        //m_keymap[VK_ADD]        = key_kp_plus;
+
+        m_keymap[kUpArrowCharCode]    = key_up;
+        m_keymap[kDownArrowCharCode]  = key_down;
+        m_keymap[kRightArrowCharCode] = key_right;
+        m_keymap[kLeftArrowCharCode]  = key_left;
+        //m_keymap[VK_INSERT]     = key_insert;
+        m_keymap[kDeleteCharCode]     = key_delete;
+        m_keymap[kHomeCharCode]       = key_home;
+        m_keymap[kEndCharCode]        = key_end;
+        m_keymap[kPageUpCharCode]     = key_page_up;
+        m_keymap[kPageDownCharCode]   = key_page_down;
+
+        //m_keymap[VK_F1]         = key_f1;
+        //m_keymap[VK_F2]         = key_f2;
+        //m_keymap[VK_F3]         = key_f3;
+        //m_keymap[VK_F4]         = key_f4;
+        //m_keymap[VK_F5]         = key_f5;
+        //m_keymap[VK_F6]         = key_f6;
+        //m_keymap[VK_F7]         = key_f7;
+        //m_keymap[VK_F8]         = key_f8;
+        //m_keymap[VK_F9]         = key_f9;
+        //m_keymap[VK_F10]        = key_f10;
+        //m_keymap[VK_F11]        = key_f11;
+        //m_keymap[VK_F12]        = key_f12;
+        //m_keymap[VK_F13]        = key_f13;
+        //m_keymap[VK_F14]        = key_f14;
+        //m_keymap[VK_F15]        = key_f15;
+
+        //m_keymap[VK_NUMLOCK]    = key_numlock;
+        //m_keymap[VK_CAPITAL]    = key_capslock;
+        //m_keymap[VK_SCROLL]     = key_scrollock;
+
+        switch(m_format)
+        {
+        case pix_format_gray8:
+            m_sys_format = pix_format_gray8;
+            m_bpp = 8;
+            m_sys_bpp = 8;
+            break;
+
+        case pix_format_rgb565:
+        case pix_format_rgb555:
+            m_sys_format = pix_format_rgb555;
+            m_bpp = 16;
+            m_sys_bpp = 16;
+            break;
+
+        case pix_format_rgb24:
+        case pix_format_bgr24:
+            m_sys_format = pix_format_rgb24;
+            m_bpp = 24;
+            m_sys_bpp = 24;
+            break;
+
+        case pix_format_bgra32:
+        case pix_format_abgr32:
+        case pix_format_argb32:
+        case pix_format_rgba32:
+            m_sys_format = pix_format_argb32;
+            m_bpp = 32;
+            m_sys_bpp = 32;
+            break;
+        }
+        ::Microseconds(&m_sw_freq);
+        ::Microseconds(&m_sw_start);
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_specific::create_pmap(unsigned width, 
+                                        unsigned height,
+                                        rendering_buffer* wnd)
+    {
+        m_pmap_window.create(width, height, org_e(m_bpp));
+        wnd->attach(m_pmap_window.buf(), 
+                    m_pmap_window.width(),
+                    m_pmap_window.height(),
+                      m_flip_y ?
+                     -m_pmap_window.row_bytes() :
+                      m_pmap_window.row_bytes());
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_specific::display_pmap(WindowRef window, const rendering_buffer* src)
+    {
+        if(m_sys_format == m_format)
+        {
+            m_pmap_window.draw(window);
+        }
+        else
+        {
+            pixel_map pmap_tmp;
+            pmap_tmp.create(m_pmap_window.width(), 
+                            m_pmap_window.height(),
+                            org_e(m_sys_bpp));
+
+            rendering_buffer rbuf_tmp;
+            rbuf_tmp.attach(pmap_tmp.buf(),
+                            pmap_tmp.width(),
+                            pmap_tmp.height(),
+                            m_flip_y ?
+                             -pmap_tmp.row_bytes() :
+                              pmap_tmp.row_bytes());
+
+            switch(m_format)
+            {
+            case pix_format_gray8:
+                return;
+
+            case pix_format_rgb565:
+                color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555());
+                break;
+
+            case pix_format_bgr24:
+                color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb24());
+                break;
+
+            case pix_format_abgr32:
+                color_conv(&rbuf_tmp, src, color_conv_abgr32_to_argb32());
+                break;
+
+            case pix_format_bgra32:
+                color_conv(&rbuf_tmp, src, color_conv_bgra32_to_argb32());
+                break;
+
+            case pix_format_rgba32:
+                color_conv(&rbuf_tmp, src, color_conv_rgba32_to_argb32());
+                break;
+            }
+            pmap_tmp.draw(window);
+        }
+    }
+
+
+    //------------------------------------------------------------------------
+    bool platform_specific::save_pmap(const char* fn, unsigned idx, 
+                                      const rendering_buffer* src)
+    {
+        if(m_sys_format == m_format)
+        {
+            return m_pmap_img[idx].save_as_qt(fn);
+        }
+        else
+        {
+            pixel_map pmap_tmp;
+            pmap_tmp.create(m_pmap_img[idx].width(), 
+                            m_pmap_img[idx].height(),
+                            org_e(m_sys_bpp));
+
+            rendering_buffer rbuf_tmp;
+            rbuf_tmp.attach(pmap_tmp.buf(),
+                            pmap_tmp.width(),
+                            pmap_tmp.height(),
+                            m_flip_y ?
+                             -pmap_tmp.row_bytes() :
+                              pmap_tmp.row_bytes());
+            switch(m_format)
+            {
+            case pix_format_gray8:
+                return false;
+
+            case pix_format_rgb565:
+                color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555());
+                break;
+
+            case pix_format_rgb24:
+                color_conv(&rbuf_tmp, src, color_conv_rgb24_to_bgr24());
+                break;
+
+            case pix_format_abgr32:
+                color_conv(&rbuf_tmp, src, color_conv_abgr32_to_bgra32());
+                break;
+
+            case pix_format_argb32:
+                color_conv(&rbuf_tmp, src, color_conv_argb32_to_bgra32());
+                break;
+
+            case pix_format_rgba32:
+                color_conv(&rbuf_tmp, src, color_conv_rgba32_to_bgra32());
+                break;
+            }
+            return pmap_tmp.save_as_qt(fn);
+        }
+        return true;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool platform_specific::load_pmap(const char* fn, unsigned idx, 
+                                      rendering_buffer* dst)
+    {
+        pixel_map pmap_tmp;
+        if(!pmap_tmp.load_from_qt(fn)) return false;
+
+        rendering_buffer rbuf_tmp;
+        rbuf_tmp.attach(pmap_tmp.buf(),
+                        pmap_tmp.width(),
+                        pmap_tmp.height(),
+                        m_flip_y ?
+                         -pmap_tmp.row_bytes() :
+                          pmap_tmp.row_bytes());
+
+        m_pmap_img[idx].create(pmap_tmp.width(), 
+                               pmap_tmp.height(), 
+                               org_e(m_bpp),
+                               0);
+
+        dst->attach(m_pmap_img[idx].buf(),
+                    m_pmap_img[idx].width(),
+                    m_pmap_img[idx].height(),
+                    m_flip_y ?
+                      -m_pmap_img[idx].row_bytes() :
+                       m_pmap_img[idx].row_bytes());
+
+        switch(m_format)
+        {
+        case pix_format_gray8:
+            return false;
+            break;
+
+        case pix_format_rgb555:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb555()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb555()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb555()); break;
+            }
+            break;
+
+        case pix_format_rgb565:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb565()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb565()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb565()); break;
+            }
+            break;
+
+        case pix_format_rgb24:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb24()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb24()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb24()); break;
+            }
+            break;
+
+        case pix_format_bgr24:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr24()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_bgr24()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_bgr24()); break;
+            }
+            break;
+
+        case pix_format_abgr32:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_abgr32()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_abgr32()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_abgr32()); break;
+            }
+            break;
+
+        case pix_format_argb32:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_argb32()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_argb32()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_argb32()); break;
+            }
+            break;
+
+        case pix_format_bgra32:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgra32()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_bgra32()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_bgra32()); break;
+            }
+            break;
+
+        case pix_format_rgba32:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgba32()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgba32()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgba32()); break;
+            }
+            break;
+        }
+        
+        return true;
+    }
+
+
+
+
+
+
+
+
+    //------------------------------------------------------------------------
+    unsigned platform_specific::translate(unsigned keycode)
+    {
+        return m_last_translated_key = (keycode > 255) ? 0 : m_keymap[keycode];
+    }
+
+
+
+    //------------------------------------------------------------------------
+    platform_support::platform_support(pix_format_e format, bool flip_y) :
+        m_specific(new platform_specific(format, flip_y)),
+        m_format(format),
+        m_bpp(m_specific->m_bpp),
+        m_window_flags(0),
+        m_wait_mode(true),
+        m_flip_y(flip_y),
+        m_initial_width(10),
+        m_initial_height(10)
+    {
+        strcpy(m_caption, "Anti-Grain Geometry Application");
+    }
+
+
+    //------------------------------------------------------------------------
+    platform_support::~platform_support()
+    {
+        delete m_specific;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    void platform_support::caption(const char* cap)
+    {
+        strcpy(m_caption, cap);
+        if(m_specific->m_window)
+        {
+        	SetWindowTitleWithCFString (m_specific->m_window, CFStringCreateWithCStringNoCopy (nil, cap, kCFStringEncodingASCII, nil));
+        }
+    }
+
+
+
+    //------------------------------------------------------------------------
+    static unsigned get_key_flags(UInt32 wflags)
+    {
+        unsigned flags = 0;
+        
+         if(wflags & shiftKey)   flags |= kbd_shift;
+         if(wflags & controlKey) flags |= kbd_ctrl;
+
+        return flags;
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_support::message(const char* msg)
+    {
+		SInt16 item;
+		Str255 p_msg;
+		
+		::CopyCStringToPascal (msg, p_msg);
+		::StandardAlert (kAlertPlainAlert, (const unsigned char*) "\013AGG Message", p_msg, NULL, &item);
+		//::StandardAlert (kAlertPlainAlert, (const unsigned char*) "\pAGG Message", p_msg, NULL, &item);
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_support::start_timer()
+    {
+		::Microseconds (&(m_specific->m_sw_start));
+    }
+
+
+    //------------------------------------------------------------------------
+    double platform_support::elapsed_time() const
+    {
+        UnsignedWide stop;
+        ::Microseconds(&stop);
+        return double(stop.lo - 
+                      m_specific->m_sw_start.lo) * 1e6 / 
+                      double(m_specific->m_sw_freq.lo);
+    }
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::init(unsigned width, unsigned height, unsigned flags)
+    {
+        if(m_specific->m_sys_format == pix_format_undefined)
+        {
+            return false;
+        }
+
+        m_window_flags = flags;
+
+		// application
+		EventTypeSpec		eventType;
+		EventHandlerUPP		handlerUPP;
+
+		eventType.eventClass = kEventClassApplication;
+		eventType.eventKind = kEventAppQuit;
+
+		handlerUPP = NewEventHandlerUPP(DoAppQuit);
+
+		InstallApplicationEventHandler (handlerUPP, 1, &eventType, nil, nil);
+
+		eventType.eventClass = kEventClassMouse;
+		eventType.eventKind = kEventMouseDown;
+		handlerUPP = NewEventHandlerUPP(DoMouseDown);
+		InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil);
+
+		eventType.eventKind = kEventMouseUp;
+		handlerUPP = NewEventHandlerUPP(DoMouseUp);
+		InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil);
+		
+		eventType.eventKind = kEventMouseDragged;
+		handlerUPP = NewEventHandlerUPP(DoMouseDragged);
+		InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil);
+
+		eventType.eventClass = kEventClassKeyboard;
+		eventType.eventKind = kEventRawKeyDown;
+		handlerUPP = NewEventHandlerUPP(DoKeyDown);
+		InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil);
+
+		eventType.eventKind = kEventRawKeyUp;
+		handlerUPP = NewEventHandlerUPP(DoKeyUp);
+		InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil);
+
+		eventType.eventKind = kEventRawKeyRepeat;
+		handlerUPP = NewEventHandlerUPP(DoKeyDown);		// 'key repeat' is translated to 'key down'
+		InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil);
+
+		WindowAttributes	windowAttrs;
+		Rect				bounds;
+
+		// window
+		windowAttrs = kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute;
+		SetRect (&bounds, 0, 0, width, height);
+		OffsetRect (&bounds, 100, 100);
+		CreateNewWindow (kDocumentWindowClass, windowAttrs, &bounds, &m_specific->m_window);
+
+        if(m_specific->m_window == nil)
+        {
+            return false;
+        }
+
+		// I assume the text is ASCII.
+		// Change to kCFStringEncodingMacRoman, kCFStringEncodingISOLatin1, kCFStringEncodingUTF8 or what else you need.
+        SetWindowTitleWithCFString (m_specific->m_window, CFStringCreateWithCStringNoCopy (nil, m_caption, kCFStringEncodingASCII, nil));
+		
+		eventType.eventClass = kEventClassWindow;
+		eventType.eventKind = kEventWindowClose;
+
+		handlerUPP = NewEventHandlerUPP(DoWindowClose);
+		InstallWindowEventHandler (m_specific->m_window, handlerUPP, 1, &eventType, this, NULL);
+
+		eventType.eventKind = kEventWindowDrawContent;
+		handlerUPP = NewEventHandlerUPP(DoWindowDrawContent);
+		InstallWindowEventHandler (m_specific->m_window, handlerUPP, 1, &eventType, this, NULL);
+		
+		// Periodic task
+		// Instead of an idle function I use the Carbon event timer.
+		// You may decide to change the wait value which is currently 50 milliseconds.
+		EventLoopRef		mainLoop;
+		EventLoopTimerUPP	timerUPP;
+		EventLoopTimerRef	theTimer;
+
+		mainLoop = GetMainEventLoop();
+		timerUPP = NewEventLoopTimerUPP (DoPeriodicTask);
+		InstallEventLoopTimer (mainLoop, 0, 50 * kEventDurationMillisecond, timerUPP, this, &theTimer);
+
+        m_specific->create_pmap(width, height, &m_rbuf_window);
+        m_initial_width = width;
+        m_initial_height = height;
+        on_init();
+        on_resize(width, height);
+        m_specific->m_redraw_flag = true;
+		
+  		ShowWindow (m_specific->m_window);
+  		SetPortWindowPort (m_specific->m_window);
+		
+      return true;
+    }
+
+
+    //------------------------------------------------------------------------
+    int platform_support::run()
+    {
+		
+		RunApplicationEventLoop ();
+        return true;
+    }
+
+
+    //------------------------------------------------------------------------
+    const char* platform_support::img_ext() const { return ".bmp"; }
+
+    //------------------------------------------------------------------------
+    const char* platform_support::full_file_name(const char* file_name)
+    {
+        return file_name;
+    }
+
+    //------------------------------------------------------------------------
+    bool platform_support::load_img(unsigned idx, const char* file)
+    {
+        if(idx < max_images)
+        {
+            char fn[1024];
+            strcpy(fn, file);
+            int len = strlen(fn);
+#if defined(__MWERKS__)
+            if(len < 4 || stricmp(fn + len - 4, ".BMP") != 0)
+#else
+	        if(len < 4 || strncasecmp(fn + len - 4, ".BMP", 4) != 0)
+#endif
+            {
+                strcat(fn, ".bmp");
+            }
+            return m_specific->load_pmap(fn, idx, &m_rbuf_img[idx]);
+        }
+        return true;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::save_img(unsigned idx, const char* file)
+    {
+        if(idx < max_images)
+        {
+            char fn[1024];
+            strcpy(fn, file);
+            int len = strlen(fn);
+#if defined(__MWERKS__)
+            if(len < 4 || stricmp(fn + len - 4, ".BMP") != 0)
+#else
+	        if(len < 4 || strncasecmp(fn + len - 4, ".BMP", 4) != 0)
+#endif
+            {
+                strcat(fn, ".bmp");
+            }
+            return m_specific->save_pmap(fn, idx, &m_rbuf_img[idx]);
+        }
+        return true;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::create_img(unsigned idx, unsigned width, unsigned height)
+    {
+        if(idx < max_images)
+        {
+            if(width  == 0) width  = m_specific->m_pmap_window.width();
+            if(height == 0) height = m_specific->m_pmap_window.height();
+            m_specific->m_pmap_img[idx].create(width, height, org_e(m_specific->m_bpp));
+            m_rbuf_img[idx].attach(m_specific->m_pmap_img[idx].buf(), 
+                                   m_specific->m_pmap_img[idx].width(),
+                                   m_specific->m_pmap_img[idx].height(),
+                                   m_flip_y ?
+                                   -m_specific->m_pmap_img[idx].row_bytes() :
+                                    m_specific->m_pmap_img[idx].row_bytes());
+            return true;
+        }
+        return false;
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_support::force_redraw()
+    {
+    	Rect	bounds;
+    	
+        m_specific->m_redraw_flag = true;
+        // on_ctrl_change ();
+		on_draw();
+
+    	SetRect(&bounds, 0, 0, m_rbuf_window.width(), m_rbuf_window.height());
+    	InvalWindowRect(m_specific->m_window, &bounds);
+    }
+
+
+
+    //------------------------------------------------------------------------
+    void platform_support::update_window()
+    {
+        m_specific->display_pmap(m_specific->m_window, &m_rbuf_window);
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_support::on_init() {}
+    void platform_support::on_resize(int sx, int sy) {}
+    void platform_support::on_idle() {}
+    void platform_support::on_mouse_move(int x, int y, unsigned flags) {}
+    void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {}
+    void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {}
+    void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {}
+    void platform_support::on_ctrl_change() {}
+    void platform_support::on_draw() {}
+    void platform_support::on_post_draw(void* raw_handler) {}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoWindowClose (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+	userData;
+	
+	QuitApplicationEventLoop ();
+
+	return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoAppQuit (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+	userData;
+	
+	return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoMouseDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+	Point wheresMyMouse;
+	UInt32 modifier;
+	
+	GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse);
+	GlobalToLocal (&wheresMyMouse);
+	GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier);
+
+    platform_support * app = reinterpret_cast<platform_support*>(userData);
+
+    app->m_specific->m_cur_x = wheresMyMouse.h;
+    if(app->flip_y())
+    {
+        app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v;
+    }
+    else
+    {
+        app->m_specific->m_cur_y = wheresMyMouse.v;
+    }
+    app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier);
+    
+    app->m_ctrls.set_cur(app->m_specific->m_cur_x, 
+                         app->m_specific->m_cur_y);
+    if(app->m_ctrls.on_mouse_button_down(app->m_specific->m_cur_x, 
+                                         app->m_specific->m_cur_y))
+    {
+        app->on_ctrl_change();
+        app->force_redraw();
+    }
+    else
+    {
+        if(app->m_ctrls.in_rect(app->m_specific->m_cur_x, 
+                                app->m_specific->m_cur_y))
+        {
+            if(app->m_ctrls.set_cur(app->m_specific->m_cur_x, 
+                                    app->m_specific->m_cur_y))
+            {
+                app->on_ctrl_change();
+                app->force_redraw();
+            }
+        }
+        else
+        {
+            app->on_mouse_button_down(app->m_specific->m_cur_x, 
+                                      app->m_specific->m_cur_y, 
+                                      app->m_specific->m_input_flags);
+        }
+    }
+
+	return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoMouseUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+	Point wheresMyMouse;
+	UInt32 modifier;
+	
+	GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse);
+	GlobalToLocal (&wheresMyMouse);
+	GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier);
+
+    platform_support * app = reinterpret_cast<platform_support*>(userData);
+
+    app->m_specific->m_cur_x = wheresMyMouse.h;
+    if(app->flip_y())
+    {
+        app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v;
+    }
+    else
+    {
+        app->m_specific->m_cur_y = wheresMyMouse.v;
+    }
+    app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier);
+
+    if(app->m_ctrls.on_mouse_button_up(app->m_specific->m_cur_x, 
+                                       app->m_specific->m_cur_y))
+    {
+        app->on_ctrl_change();
+        app->force_redraw();
+    }
+    app->on_mouse_button_up(app->m_specific->m_cur_x, 
+                            app->m_specific->m_cur_y, 
+                            app->m_specific->m_input_flags);
+
+	return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoMouseDragged (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+	Point wheresMyMouse;
+	UInt32 modifier;
+	
+	GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse);
+	GlobalToLocal (&wheresMyMouse);
+	GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier);
+
+    platform_support * app = reinterpret_cast<platform_support*>(userData);
+
+    app->m_specific->m_cur_x = wheresMyMouse.h;
+    if(app->flip_y())
+    {
+        app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v;
+    }
+    else
+    {
+        app->m_specific->m_cur_y = wheresMyMouse.v;
+    }
+    app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier);
+
+
+    if(app->m_ctrls.on_mouse_move(
+        app->m_specific->m_cur_x, 
+        app->m_specific->m_cur_y,
+        (app->m_specific->m_input_flags & mouse_left) != 0))
+    {
+        app->on_ctrl_change();
+        app->force_redraw();
+    }
+    else
+    {
+        app->on_mouse_move(app->m_specific->m_cur_x, 
+                           app->m_specific->m_cur_y, 
+                           app->m_specific->m_input_flags);
+    }
+
+	return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoKeyDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+	char key_code;
+	UInt32 modifier;
+	
+	GetEventParameter (theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &key_code);
+	GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier);
+
+	platform_support * app = reinterpret_cast<platform_support*>(userData);
+
+	app->m_specific->m_last_translated_key = 0;
+    switch(modifier) 
+    {
+        case controlKey:
+            app->m_specific->m_input_flags |= kbd_ctrl;
+            break;
+
+        case shiftKey:
+            app->m_specific->m_input_flags |= kbd_shift;
+            break;
+
+        default:
+            app->m_specific->translate(key_code);
+            break;
+    }
+
+    if(app->m_specific->m_last_translated_key)
+    {
+        bool left  = false;
+        bool up    = false;
+        bool right = false;
+        bool down  = false;
+
+        switch(app->m_specific->m_last_translated_key)
+        {
+        case key_left:
+            left = true;
+            break;
+
+        case key_up:
+            up = true;
+            break;
+
+        case key_right:
+            right = true;
+            break;
+
+        case key_down:
+            down = true;
+            break;
+
+		//On a Mac, screenshots are handled by the system.
+        case key_f2:                        
+            app->copy_window_to_img(agg::platform_support::max_images - 1);
+            app->save_img(agg::platform_support::max_images - 1, "screenshot");
+            break;
+        }
+
+
+        if(app->m_ctrls.on_arrow_keys(left, right, down, up))
+        {
+            app->on_ctrl_change();
+            app->force_redraw();
+        }
+        else
+        {
+            app->on_key(app->m_specific->m_cur_x,
+                        app->m_specific->m_cur_y,
+                        app->m_specific->m_last_translated_key,
+                        app->m_specific->m_input_flags);
+        }
+    }
+
+	return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoKeyUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+	char key_code;
+	UInt32 modifier;
+	
+	GetEventParameter (theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &key_code);
+	GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier);
+
+	platform_support * app = reinterpret_cast<platform_support*>(userData);
+
+    app->m_specific->m_last_translated_key = 0;
+    switch(modifier) 
+    {
+        case controlKey:
+            app->m_specific->m_input_flags &= ~kbd_ctrl;
+            break;
+
+        case shiftKey:
+            app->m_specific->m_input_flags &= ~kbd_shift;
+            break;
+    }
+    
+	return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoWindowDrawContent (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+    platform_support * app = reinterpret_cast<platform_support*>(userData);
+
+    if(app)
+    {
+        if(app->m_specific->m_redraw_flag)
+        {
+            app->on_draw();
+            app->m_specific->m_redraw_flag = false;
+        }
+        app->m_specific->display_pmap(app->m_specific->m_window, &app->rbuf_window());
+    }
+
+	return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal void DoPeriodicTask (EventLoopTimerRef theTimer, void* userData)
+{
+    platform_support * app = reinterpret_cast<platform_support*>(userData);
+    
+    if(!app->wait_mode())
+		app->on_idle();
+}
+
+
+}
+
+
+
+
+//----------------------------------------------------------------------------
+int agg_main(int argc, char* argv[]);
+
+
+// Hm. Classic MacOS does not know command line input.
+// CodeWarrior provides a way to mimic command line input.
+// The function 'ccommand' can be used to get the command
+// line arguments.
+//----------------------------------------------------------------------------
+int main(int argc, char* argv[])
+{
+#if defined(__MWERKS__)
+	// argc = ccommand (&argv);
+#endif
+    
+    // Check if we are launched by double-clicking under OSX 
+	// Get rid of extra argument, this will confuse the standard argument parsing
+	// calls used in the examples to get the name of the image file to be used
+    if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
+        argc = 1;
+    } 
+
+launch:
+    return agg_main(argc, argv);
+}
\ No newline at end of file
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp
new file mode 100644
index 0000000000..28c6436baa
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp
@@ -0,0 +1,708 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software 
+// is granted provided this copyright notice appears in all copies. 
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+//          mcseemagg@yahoo.com
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// class platform_support. SDL version.
+//
+//----------------------------------------------------------------------------
+
+#include <string.h>
+#include "platform/agg_platform_support.h"
+#include "SDL.h"
+#include "SDL_byteorder.h"
+
+
+namespace agg
+{
+
+    //------------------------------------------------------------------------
+    class platform_specific
+    {
+    public:
+        platform_specific(pix_format_e format, bool flip_y);
+        ~platform_specific();
+
+        pix_format_e  m_format;
+        pix_format_e  m_sys_format;
+        bool          m_flip_y;
+        unsigned      m_bpp;
+        unsigned      m_sys_bpp;
+        unsigned      m_rmask;
+        unsigned      m_gmask;
+        unsigned      m_bmask;
+        unsigned      m_amask;
+        bool          m_update_flag;
+        bool          m_resize_flag;
+        bool          m_initialized;
+        SDL_Surface*  m_surf_screen;
+        SDL_Surface*  m_surf_window;
+        SDL_Surface*  m_surf_img[platform_support::max_images];
+        int           m_cur_x;
+        int           m_cur_y;
+	int          m_sw_start;
+    };
+
+
+
+    //------------------------------------------------------------------------
+    platform_specific::platform_specific(pix_format_e format, bool flip_y) :
+        m_format(format),
+        m_sys_format(pix_format_undefined),
+        m_flip_y(flip_y),
+        m_bpp(0),
+        m_sys_bpp(0),
+        m_update_flag(true), 
+        m_resize_flag(true),
+        m_initialized(false),
+        m_surf_screen(0),
+        m_surf_window(0),
+        m_cur_x(0),
+        m_cur_y(0)
+    {
+        memset(m_surf_img, 0, sizeof(m_surf_img));
+
+        switch(m_format)
+        {
+			case pix_format_gray8:
+            m_bpp = 8;
+            break;
+
+        case pix_format_rgb565:
+            m_rmask = 0xF800;
+            m_gmask = 0x7E0;
+            m_bmask = 0x1F;
+            m_amask = 0;
+            m_bpp = 16;
+            break;
+
+        case pix_format_rgb555:
+            m_rmask = 0x7C00;
+            m_gmask = 0x3E0;
+            m_bmask = 0x1F;
+            m_amask = 0;
+            m_bpp = 16;
+            break;
+			
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+        case pix_format_rgb24:
+			m_rmask = 0xFF;
+            m_gmask = 0xFF00;
+            m_bmask = 0xFF0000;
+            m_amask = 0;
+            m_bpp = 24;
+            break;
+
+        case pix_format_bgr24:
+            m_rmask = 0xFF0000;
+            m_gmask = 0xFF00;
+            m_bmask = 0xFF;
+            m_amask = 0;
+            m_bpp = 24;
+            break;
+
+        case pix_format_bgra32:
+            m_rmask = 0xFF0000;
+            m_gmask = 0xFF00;
+            m_bmask = 0xFF;
+            m_amask = 0xFF000000;
+            m_bpp = 32;
+            break;
+
+        case pix_format_abgr32:
+            m_rmask = 0xFF000000;
+            m_gmask = 0xFF0000;
+            m_bmask = 0xFF00;
+            m_amask = 0xFF;
+            m_bpp = 32;
+            break;
+
+        case pix_format_argb32:
+            m_rmask = 0xFF00;
+            m_gmask = 0xFF0000;
+            m_bmask = 0xFF000000;
+            m_amask = 0xFF;
+            m_bpp = 32;
+            break;
+
+        case pix_format_rgba32:
+            m_rmask = 0xFF;
+            m_gmask = 0xFF00;
+            m_bmask = 0xFF0000;
+            m_amask = 0xFF000000;
+            m_bpp = 32;
+            break;
+#else //SDL_BIG_ENDIAN (PPC)
+        case pix_format_rgb24:
+			m_rmask = 0xFF0000;
+            m_gmask = 0xFF00;
+            m_bmask = 0xFF;
+            m_amask = 0;
+            m_bpp = 24;
+            break;
+
+        case pix_format_bgr24:
+            m_rmask = 0xFF;
+            m_gmask = 0xFF00;
+            m_bmask = 0xFF0000;
+            m_amask = 0;
+            m_bpp = 24;
+            break;
+
+        case pix_format_bgra32:
+            m_rmask = 0xFF00;
+            m_gmask = 0xFF0000;
+            m_bmask = 0xFF000000;
+            m_amask = 0xFF;
+            m_bpp = 32;
+            break;
+
+        case pix_format_abgr32:
+            m_rmask = 0xFF;
+            m_gmask = 0xFF00;
+            m_bmask = 0xFF0000;
+            m_amask = 0xFF000000;
+            m_bpp = 32;
+            break;
+
+        case pix_format_argb32:
+            m_rmask = 0xFF0000;
+            m_gmask = 0xFF00;
+            m_bmask = 0xFF;
+            m_amask = 0xFF000000;
+            m_bpp = 32;
+            break;
+
+        case pix_format_rgba32:
+            m_rmask = 0xFF000000;
+            m_gmask = 0xFF0000;
+            m_bmask = 0xFF00;
+            m_amask = 0xFF;
+            m_bpp = 32;
+            break;
+#endif
+        }
+    }
+
+    //------------------------------------------------------------------------
+    platform_specific::~platform_specific()
+    {
+        int i;
+        for(i = platform_support::max_images - 1; i >= 0; --i)
+        {
+            if(m_surf_img[i]) SDL_FreeSurface(m_surf_img[i]);
+        }
+        if(m_surf_window) SDL_FreeSurface(m_surf_window);
+        if(m_surf_screen) SDL_FreeSurface(m_surf_screen);
+    }
+
+
+
+    //------------------------------------------------------------------------
+    platform_support::platform_support(pix_format_e format, bool flip_y) :
+        m_specific(new platform_specific(format, flip_y)),
+        m_format(format),
+        m_bpp(m_specific->m_bpp),
+        m_window_flags(0),
+        m_wait_mode(true),
+        m_flip_y(flip_y)
+    {
+        SDL_Init(SDL_INIT_VIDEO);
+        strcpy(m_caption, "Anti-Grain Geometry Application");
+    }
+
+
+    //------------------------------------------------------------------------
+    platform_support::~platform_support()
+    {
+        delete m_specific;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    void platform_support::caption(const char* cap)
+    {
+        strcpy(m_caption, cap);
+        if(m_specific->m_initialized)
+        {
+            SDL_WM_SetCaption(cap, 0);
+        }
+    }
+    
+
+
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::init(unsigned width, unsigned height, unsigned flags)
+    {
+        m_window_flags = flags;
+        unsigned wflags = SDL_SWSURFACE;
+
+        if(m_window_flags & window_hw_buffer)
+        {
+            wflags = SDL_HWSURFACE;
+        }
+
+        if(m_window_flags & window_resize)
+        {
+            wflags |= SDL_RESIZABLE;
+        }
+
+        if(m_specific->m_surf_screen) SDL_FreeSurface(m_specific->m_surf_screen);
+
+        m_specific->m_surf_screen = SDL_SetVideoMode(width, height, m_bpp, wflags);
+        if(m_specific->m_surf_screen == 0) 
+        {
+            fprintf(stderr, 
+                    "Unable to set %dx%d %d bpp video: %s\n", 
+                    width, 
+                    height, 
+                    m_bpp, 
+                    ::SDL_GetError());
+            return false;
+        }
+
+        SDL_WM_SetCaption(m_caption, 0);
+
+        if(m_specific->m_surf_window) SDL_FreeSurface(m_specific->m_surf_window);
+
+        m_specific->m_surf_window = 
+            SDL_CreateRGBSurface(SDL_HWSURFACE, 
+                                 m_specific->m_surf_screen->w, 
+                                 m_specific->m_surf_screen->h,
+                                 m_specific->m_surf_screen->format->BitsPerPixel,
+                                 m_specific->m_rmask, 
+                                 m_specific->m_gmask, 
+                                 m_specific->m_bmask, 
+                                 m_specific->m_amask);
+
+        if(m_specific->m_surf_window == 0) 
+        {
+            fprintf(stderr, 
+                    "Unable to create image buffer %dx%d %d bpp: %s\n", 
+                    width, 
+                    height, 
+                    m_bpp, 
+                    SDL_GetError());
+            return false;
+        }
+
+        m_rbuf_window.attach((unsigned char*)m_specific->m_surf_window->pixels, 
+                             m_specific->m_surf_window->w, 
+                             m_specific->m_surf_window->h, 
+                             m_flip_y ? -m_specific->m_surf_window->pitch : 
+                                         m_specific->m_surf_window->pitch);
+
+        if(!m_specific->m_initialized)
+        {
+            m_initial_width = width;
+            m_initial_height = height;
+            on_init();
+            m_specific->m_initialized = true;
+        }
+        on_resize(m_rbuf_window.width(), m_rbuf_window.height());
+        m_specific->m_update_flag = true;
+        return true;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    void platform_support::update_window()
+    {
+        SDL_BlitSurface(m_specific->m_surf_window, 0, m_specific->m_surf_screen, 0);
+        SDL_UpdateRect(m_specific->m_surf_screen, 0, 0, 0, 0);
+    }
+
+
+    //------------------------------------------------------------------------
+    int platform_support::run()
+    {
+        SDL_Event event;
+        bool ev_flag = false;
+
+        for(;;)
+        {
+            if(m_specific->m_update_flag)
+            {
+                on_draw();
+                update_window();
+                m_specific->m_update_flag = false;
+            }
+
+            ev_flag = false;
+            if(m_wait_mode)
+            {
+                SDL_WaitEvent(&event);
+                ev_flag = true;
+            }
+            else
+            {
+                if(SDL_PollEvent(&event))
+                {
+                    ev_flag = true;
+                }
+                else
+                {
+                    on_idle();
+                }
+            }
+
+            if(ev_flag)
+            {
+                if(event.type == SDL_QUIT)
+                {
+                    break;
+                }
+
+                int y;
+                unsigned flags = 0;
+
+                switch (event.type) 
+                {
+                case SDL_VIDEORESIZE:
+                    if(!init(event.resize.w, event.resize.h, m_window_flags)) return false;
+                    on_resize(m_rbuf_window.width(), m_rbuf_window.height());
+                    trans_affine_resizing(event.resize.w, event.resize.h);
+                    m_specific->m_update_flag = true;
+                    break;
+
+                case SDL_KEYDOWN:
+                    {
+                        flags = 0;
+                        if(event.key.keysym.mod & KMOD_SHIFT) flags |= kbd_shift;
+                        if(event.key.keysym.mod & KMOD_CTRL)  flags |= kbd_ctrl;
+
+                        bool left  = false;
+                        bool up    = false;
+                        bool right = false;
+                        bool down  = false;
+
+                        switch(event.key.keysym.sym)
+                        {
+                        case key_left:
+                            left = true;
+                            break;
+
+                        case key_up:
+                            up = true;
+                            break;
+
+                        case key_right:
+                            right = true;
+                            break;
+
+                        case key_down:
+                            down = true;
+                            break;
+                        }
+
+                        if(m_ctrls.on_arrow_keys(left, right, down, up))
+                        {
+                            on_ctrl_change();
+                            force_redraw();
+                        }
+                        else
+                        {
+                            on_key(m_specific->m_cur_x,
+                                   m_specific->m_cur_y,
+                                   event.key.keysym.sym,
+                                   flags);
+                        }
+                    }
+                    break;
+
+                case SDL_MOUSEMOTION:
+                    y = m_flip_y ? 
+                        m_rbuf_window.height() - event.motion.y : 
+                        event.motion.y;
+
+                    m_specific->m_cur_x = event.motion.x;
+                    m_specific->m_cur_y = y;
+                    flags = 0;
+                    if(event.motion.state & SDL_BUTTON_LMASK) flags |= mouse_left;
+                    if(event.motion.state & SDL_BUTTON_RMASK) flags |= mouse_right;
+
+                    if(m_ctrls.on_mouse_move(m_specific->m_cur_x, 
+                                             m_specific->m_cur_y,
+                                             (flags & mouse_left) != 0))
+                    {
+                        on_ctrl_change();
+                        force_redraw();
+                    }
+                    else
+                    {
+                        on_mouse_move(m_specific->m_cur_x, 
+                                      m_specific->m_cur_y, 
+                                      flags);
+                    }
+		    SDL_Event eventtrash;
+		    while (SDL_PeepEvents(&eventtrash, 1, SDL_GETEVENT, SDL_EVENTMASK(SDL_MOUSEMOTION))!=0){;}
+                    break;
+
+		case SDL_MOUSEBUTTONDOWN:
+                    y = m_flip_y
+                        ? m_rbuf_window.height() - event.button.y
+                        : event.button.y;
+
+                    m_specific->m_cur_x = event.button.x;
+                    m_specific->m_cur_y = y;
+                    flags = 0;
+                    switch(event.button.button)
+                    {
+                    case SDL_BUTTON_LEFT:
+                        {
+                            flags = mouse_left;
+
+if(m_ctrls.on_mouse_button_down(m_specific->m_cur_x,
+                                m_specific->m_cur_y))
+                            {
+                                m_ctrls.set_cur(m_specific->m_cur_x, 
+                                    m_specific->m_cur_y);
+                                on_ctrl_change();
+                                force_redraw();
+                            }
+                            else
+                            {
+                                if(m_ctrls.in_rect(m_specific->m_cur_x, 
+                                    m_specific->m_cur_y))
+                                {
+                                    if(m_ctrls.set_cur(m_specific->m_cur_x, 
+                                        m_specific->m_cur_y))
+                                    {
+                                        on_ctrl_change();
+                                        force_redraw();
+                                    }
+                                }
+                                else
+                                {
+                                    on_mouse_button_down(m_specific->m_cur_x, 
+                                        m_specific->m_cur_y, 
+                                        flags);
+                                }
+                            }
+                        }
+                        break;
+                    case SDL_BUTTON_RIGHT:
+                        flags = mouse_right;
+                        on_mouse_button_down(m_specific->m_cur_x, 
+                            m_specific->m_cur_y, 
+                            flags);
+                        break;
+                    } //switch(event.button.button)
+                    break;
+		    
+                case SDL_MOUSEBUTTONUP:
+                    y = m_flip_y
+                        ? m_rbuf_window.height() - event.button.y
+                        : event.button.y;
+
+                    m_specific->m_cur_x = event.button.x;
+                    m_specific->m_cur_y = y;
+                    flags = 0;
+                    if(m_ctrls.on_mouse_button_up(m_specific->m_cur_x, 
+                                                  m_specific->m_cur_y))
+                    {
+                        on_ctrl_change();
+                        force_redraw();
+                    }
+                    on_mouse_button_up(m_specific->m_cur_x, 
+                                       m_specific->m_cur_y, 
+                                       flags);
+                    break;
+                }
+            }
+        }
+        return 0;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    const char* platform_support::img_ext() const { return ".bmp"; }
+
+    //------------------------------------------------------------------------
+    const char* platform_support::full_file_name(const char* file_name)
+    {
+        return file_name;
+    }
+
+    //------------------------------------------------------------------------
+    bool platform_support::load_img(unsigned idx, const char* file)
+    {
+        if(idx < max_images)
+        {
+            if(m_specific->m_surf_img[idx]) SDL_FreeSurface(m_specific->m_surf_img[idx]);
+
+            char fn[1024];
+            strcpy(fn, file);
+            int len = strlen(fn);
+            if(len < 4 || strcmp(fn + len - 4, ".bmp") != 0)
+            {
+                strcat(fn, ".bmp");
+            }
+
+            SDL_Surface* tmp_surf = SDL_LoadBMP(fn);
+            if (tmp_surf == 0) 
+            {
+                fprintf(stderr, "Couldn't load %s: %s\n", fn, SDL_GetError());
+                return false;
+            }
+
+            SDL_PixelFormat format;
+            format.palette = 0;
+            format.BitsPerPixel = m_bpp;
+            format.BytesPerPixel = m_bpp >> 8;
+            format.Rmask = m_specific->m_rmask;
+            format.Gmask = m_specific->m_gmask;
+            format.Bmask = m_specific->m_bmask;
+            format.Amask = m_specific->m_amask;
+            format.Rshift = 0;
+            format.Gshift = 0;
+            format.Bshift = 0;
+            format.Ashift = 0;
+            format.Rloss = 0;
+            format.Gloss = 0;
+            format.Bloss = 0;
+            format.Aloss = 0;
+            format.colorkey = 0;
+            format.alpha = 0;
+
+            m_specific->m_surf_img[idx] = 
+                SDL_ConvertSurface(tmp_surf, 
+                                   &format, 
+                                   SDL_SWSURFACE);
+
+            SDL_FreeSurface(tmp_surf);
+            
+            if(m_specific->m_surf_img[idx] == 0) return false;
+
+            m_rbuf_img[idx].attach((unsigned char*)m_specific->m_surf_img[idx]->pixels, 
+                                   m_specific->m_surf_img[idx]->w, 
+                                   m_specific->m_surf_img[idx]->h, 
+                                   m_flip_y ? -m_specific->m_surf_img[idx]->pitch : 
+                                               m_specific->m_surf_img[idx]->pitch);
+            return true;
+
+        }
+        return false;
+    }
+
+
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::save_img(unsigned idx, const char* file)
+    {
+        if(idx < max_images && m_specific->m_surf_img[idx])
+        {
+            char fn[1024];
+            strcpy(fn, file);
+            int len = strlen(fn);
+            if(len < 4 || strcmp(fn + len - 4, ".bmp") != 0)
+            {
+                strcat(fn, ".bmp");
+            }
+            return SDL_SaveBMP(m_specific->m_surf_img[idx], fn) == 0;
+        }
+        return false;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::create_img(unsigned idx, unsigned width, unsigned height)
+    {
+        if(idx < max_images)
+        {
+
+            if(m_specific->m_surf_img[idx]) SDL_FreeSurface(m_specific->m_surf_img[idx]);
+
+             m_specific->m_surf_img[idx] = 
+                 SDL_CreateRGBSurface(SDL_SWSURFACE, 
+                                      width, 
+                                      height,
+                                      m_specific->m_surf_screen->format->BitsPerPixel,
+                                      m_specific->m_rmask, 
+                                      m_specific->m_gmask, 
+                                      m_specific->m_bmask, 
+                                      m_specific->m_amask);
+            if(m_specific->m_surf_img[idx] == 0) 
+            {
+                fprintf(stderr, "Couldn't create image: %s\n", SDL_GetError());
+                return false;
+            }
+
+            m_rbuf_img[idx].attach((unsigned char*)m_specific->m_surf_img[idx]->pixels, 
+                                   m_specific->m_surf_img[idx]->w, 
+                                   m_specific->m_surf_img[idx]->h, 
+                                   m_flip_y ? -m_specific->m_surf_img[idx]->pitch : 
+                                               m_specific->m_surf_img[idx]->pitch);
+
+            return true;
+        }
+
+        return false;
+    }
+    
+    //------------------------------------------------------------------------
+    void platform_support::start_timer()
+    {
+        m_specific->m_sw_start = SDL_GetTicks();
+    }
+
+    //------------------------------------------------------------------------
+    double platform_support::elapsed_time() const
+    {
+        int stop = SDL_GetTicks();
+        return double(stop - m_specific->m_sw_start);
+    }
+
+    //------------------------------------------------------------------------
+    void platform_support::message(const char* msg)
+    {
+        fprintf(stderr, "%s\n", msg);
+    }
+
+    //------------------------------------------------------------------------
+    void platform_support::force_redraw()
+    {
+        m_specific->m_update_flag = true;
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_support::on_init() {}
+    void platform_support::on_resize(int sx, int sy) {}
+    void platform_support::on_idle() {}
+    void platform_support::on_mouse_move(int x, int y, unsigned flags) {}
+    void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {}
+    void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {}
+    void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {}
+    void platform_support::on_ctrl_change() {}
+    void platform_support::on_draw() {}
+    void platform_support::on_post_draw(void* raw_handler) {}
+
+
+}
+
+
+int agg_main(int argc, char* argv[]);
+
+int main(int argc, char* argv[])
+{
+    return agg_main(argc, argv);
+}
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp
new file mode 100644
index 0000000000..ea9123802f
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp
@@ -0,0 +1,1655 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software 
+// is granted provided this copyright notice appears in all copies. 
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+//          mcseemagg@yahoo.com
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// class platform_support
+//
+//----------------------------------------------------------------------------
+
+#include <windows.h>
+#include <string.h>
+#include "platform/agg_platform_support.h"
+#include "platform/win32/agg_win32_bmp.h"
+#include "util/agg_color_conv.h"
+#include "util/agg_color_conv_rgb8.h"
+#include "util/agg_color_conv_rgb16.h"
+#include "agg_pixfmt_gray.h"
+#include "agg_pixfmt_rgb.h"
+#include "agg_pixfmt_rgba.h"
+
+
+namespace agg
+{
+    
+    //------------------------------------------------------------------------
+    HINSTANCE g_windows_instance = 0;
+    int       g_windows_cmd_show = 0;
+
+
+    //------------------------------------------------------------------------
+    class platform_specific
+    {
+    public:
+        platform_specific(pix_format_e format, bool flip_y);
+
+        void create_pmap(unsigned width, unsigned height, 
+                         rendering_buffer* wnd);
+
+        void display_pmap(HDC dc, const rendering_buffer* src);
+        bool load_pmap(const char* fn, unsigned idx, 
+                       rendering_buffer* dst);
+
+        bool save_pmap(const char* fn, unsigned idx, 
+                       const rendering_buffer* src);
+
+        unsigned translate(unsigned keycode);
+
+        pix_format_e  m_format;
+        pix_format_e  m_sys_format;
+        bool          m_flip_y;
+        unsigned      m_bpp;
+        unsigned      m_sys_bpp;
+        HWND          m_hwnd;
+        pixel_map     m_pmap_window;
+        pixel_map     m_pmap_img[platform_support::max_images];
+        unsigned      m_keymap[256];
+        unsigned      m_last_translated_key;
+        int           m_cur_x;
+        int           m_cur_y;
+        unsigned      m_input_flags;
+        bool          m_redraw_flag;
+        HDC           m_current_dc;
+        LARGE_INTEGER m_sw_freq;
+        LARGE_INTEGER m_sw_start;
+    };
+
+
+    //------------------------------------------------------------------------
+    platform_specific::platform_specific(pix_format_e format, bool flip_y) :
+        m_format(format),
+        m_sys_format(pix_format_undefined),
+        m_flip_y(flip_y),
+        m_bpp(0),
+        m_sys_bpp(0),
+        m_hwnd(0),
+        m_last_translated_key(0),
+        m_cur_x(0),
+        m_cur_y(0),
+        m_input_flags(0),
+        m_redraw_flag(true),
+        m_current_dc(0)
+    {
+        memset(m_keymap, 0, sizeof(m_keymap));
+
+        m_keymap[VK_PAUSE]      = key_pause;
+        m_keymap[VK_CLEAR]      = key_clear;
+
+        m_keymap[VK_NUMPAD0]    = key_kp0;
+        m_keymap[VK_NUMPAD1]    = key_kp1;
+        m_keymap[VK_NUMPAD2]    = key_kp2;
+        m_keymap[VK_NUMPAD3]    = key_kp3;
+        m_keymap[VK_NUMPAD4]    = key_kp4;
+        m_keymap[VK_NUMPAD5]    = key_kp5;
+        m_keymap[VK_NUMPAD6]    = key_kp6;
+        m_keymap[VK_NUMPAD7]    = key_kp7;
+        m_keymap[VK_NUMPAD8]    = key_kp8;
+        m_keymap[VK_NUMPAD9]    = key_kp9;
+        m_keymap[VK_DECIMAL]    = key_kp_period;
+        m_keymap[VK_DIVIDE]     = key_kp_divide;
+        m_keymap[VK_MULTIPLY]   = key_kp_multiply;
+        m_keymap[VK_SUBTRACT]   = key_kp_minus;
+        m_keymap[VK_ADD]        = key_kp_plus;
+
+        m_keymap[VK_UP]         = key_up;
+        m_keymap[VK_DOWN]       = key_down;
+        m_keymap[VK_RIGHT]      = key_right;
+        m_keymap[VK_LEFT]       = key_left;
+        m_keymap[VK_INSERT]     = key_insert;
+        m_keymap[VK_DELETE]     = key_delete;
+        m_keymap[VK_HOME]       = key_home;
+        m_keymap[VK_END]        = key_end;
+        m_keymap[VK_PRIOR]      = key_page_up;
+        m_keymap[VK_NEXT]       = key_page_down;
+
+        m_keymap[VK_F1]         = key_f1;
+        m_keymap[VK_F2]         = key_f2;
+        m_keymap[VK_F3]         = key_f3;
+        m_keymap[VK_F4]         = key_f4;
+        m_keymap[VK_F5]         = key_f5;
+        m_keymap[VK_F6]         = key_f6;
+        m_keymap[VK_F7]         = key_f7;
+        m_keymap[VK_F8]         = key_f8;
+        m_keymap[VK_F9]         = key_f9;
+        m_keymap[VK_F10]        = key_f10;
+        m_keymap[VK_F11]        = key_f11;
+        m_keymap[VK_F12]        = key_f12;
+        m_keymap[VK_F13]        = key_f13;
+        m_keymap[VK_F14]        = key_f14;
+        m_keymap[VK_F15]        = key_f15;
+
+        m_keymap[VK_NUMLOCK]    = key_numlock;
+        m_keymap[VK_CAPITAL]    = key_capslock;
+        m_keymap[VK_SCROLL]     = key_scrollock;
+
+
+        switch(m_format)
+        {
+        case pix_format_bw:
+            m_sys_format = pix_format_bw;
+            m_bpp = 1;
+            m_sys_bpp = 1;
+            break;
+
+        case pix_format_gray8:
+        case pix_format_sgray8:
+            m_sys_format = pix_format_sgray8;
+            m_bpp = 8;
+            m_sys_bpp = 8;
+            break;
+
+        case pix_format_gray16:
+            m_sys_format = pix_format_sgray8;
+            m_bpp = 16;
+            m_sys_bpp = 8;
+            break;
+
+        case pix_format_gray32:
+            m_sys_format = pix_format_sgray8;
+            m_bpp = 32;
+            m_sys_bpp = 8;
+            break;
+
+        case pix_format_rgb565:
+        case pix_format_rgb555:
+            m_sys_format = pix_format_rgb555;
+            m_bpp = 16;
+            m_sys_bpp = 16;
+            break;
+
+        case pix_format_rgbAAA:
+        case pix_format_bgrAAA:
+        case pix_format_rgbBBA:
+        case pix_format_bgrABB:
+            m_sys_format = pix_format_bgr24;
+            m_bpp = 32;
+            m_sys_bpp = 24;
+            break;
+
+        case pix_format_rgb24:
+        case pix_format_bgr24:
+        case pix_format_srgb24:
+        case pix_format_sbgr24:
+            m_sys_format = pix_format_sbgr24;
+            m_bpp = 24;
+            m_sys_bpp = 24;
+            break;
+
+        case pix_format_rgb48:
+        case pix_format_bgr48:
+            m_sys_format = pix_format_sbgr24;
+            m_bpp = 48;
+            m_sys_bpp = 24;
+            break;
+
+        case pix_format_rgb96:
+        case pix_format_bgr96:
+            m_sys_format = pix_format_sbgr24;
+            m_bpp = 96;
+            m_sys_bpp = 24;
+            break;
+
+        case pix_format_bgra32:
+        case pix_format_abgr32:
+        case pix_format_argb32:
+        case pix_format_rgba32:
+        case pix_format_sbgra32:
+        case pix_format_sabgr32:
+        case pix_format_sargb32:
+        case pix_format_srgba32:
+            m_sys_format = pix_format_sbgr24;
+            m_bpp = 32;
+            m_sys_bpp = 24;
+            break;
+
+        case pix_format_bgra64:
+        case pix_format_abgr64:
+        case pix_format_argb64:
+        case pix_format_rgba64:
+            m_sys_format = pix_format_sbgr24;
+            m_bpp = 64;
+            m_sys_bpp = 24;
+            break;
+
+        case pix_format_bgra128:
+        case pix_format_abgr128:
+        case pix_format_argb128:
+        case pix_format_rgba128:
+            m_sys_format = pix_format_sbgr24;
+            m_bpp = 128;
+            m_sys_bpp = 24;
+            break;
+
+        }
+        ::QueryPerformanceFrequency(&m_sw_freq);
+        ::QueryPerformanceCounter(&m_sw_start);
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_specific::create_pmap(unsigned width, 
+                                        unsigned height,
+                                        rendering_buffer* wnd)
+    {
+        m_pmap_window.create(width, height, org_e(m_bpp));
+        wnd->attach(m_pmap_window.buf(), 
+                    m_pmap_window.width(),
+                    m_pmap_window.height(),
+                      m_flip_y ?
+                      m_pmap_window.stride() :
+                     -m_pmap_window.stride());
+    }
+
+
+    //------------------------------------------------------------------------
+    static void convert_pmap(rendering_buffer* dst, 
+                             const rendering_buffer* src, 
+                             pix_format_e format)
+    {
+        switch(format)
+        {
+        case pix_format_gray8:
+            convert<pixfmt_sgray8, pixfmt_gray8>(dst, src);
+            break;
+
+        case pix_format_gray16:
+            convert<pixfmt_sgray8, pixfmt_gray16>(dst, src);
+            break;
+
+        case pix_format_gray32:
+            convert<pixfmt_sgray8, pixfmt_gray32>(dst, src);
+            break;
+
+        case pix_format_rgb565:
+            color_conv(dst, src, color_conv_rgb565_to_rgb555());
+            break;
+
+        case pix_format_rgbAAA:
+            color_conv(dst, src, color_conv_rgbAAA_to_bgr24());
+            break;
+
+        case pix_format_bgrAAA:
+            color_conv(dst, src, color_conv_bgrAAA_to_bgr24());
+            break;
+
+        case pix_format_rgbBBA:
+            color_conv(dst, src, color_conv_rgbBBA_to_bgr24());
+            break;
+
+        case pix_format_bgrABB:
+            color_conv(dst, src, color_conv_bgrABB_to_bgr24());
+            break;
+
+        case pix_format_srgb24:
+            color_conv(dst, src, color_conv_rgb24_to_bgr24());
+            break;
+
+        case pix_format_rgb24:
+            convert<pixfmt_sbgr24, pixfmt_rgb24>(dst, src);
+            break;
+
+        case pix_format_bgr24:
+            convert<pixfmt_sbgr24, pixfmt_bgr24>(dst, src);
+            break;
+
+        case pix_format_rgb48:
+            convert<pixfmt_sbgr24, pixfmt_rgb48>(dst, src);
+            break;
+
+        case pix_format_bgr48:
+            convert<pixfmt_sbgr24, pixfmt_bgr48>(dst, src);
+            break;
+
+        case pix_format_bgra32:
+            convert<pixfmt_sbgr24, pixfmt_bgrx32>(dst, src);
+            break;
+
+        case pix_format_abgr32:
+            convert<pixfmt_sbgr24, pixfmt_xbgr32>(dst, src);
+            break;
+
+        case pix_format_argb32:
+            convert<pixfmt_sbgr24, pixfmt_xrgb32>(dst, src);
+            break;
+
+        case pix_format_rgba32:
+            convert<pixfmt_sbgr24, pixfmt_rgbx32>(dst, src);
+            break;
+
+        case pix_format_sbgra32:
+            convert<pixfmt_sbgr24, pixfmt_sbgrx32>(dst, src);
+            break;
+
+        case pix_format_sabgr32:
+            convert<pixfmt_sbgr24, pixfmt_sxbgr32>(dst, src);
+            break;
+
+        case pix_format_sargb32:
+            convert<pixfmt_sbgr24, pixfmt_sxrgb32>(dst, src);
+            break;
+
+        case pix_format_srgba32:
+            convert<pixfmt_sbgr24, pixfmt_srgbx32>(dst, src);
+            break;
+
+        case pix_format_bgra64:
+            convert<pixfmt_sbgr24, pixfmt_bgrx64>(dst, src);
+            break;
+
+        case pix_format_abgr64:
+            convert<pixfmt_sbgr24, pixfmt_xbgr64>(dst, src);
+            break;
+
+        case pix_format_argb64:
+            convert<pixfmt_sbgr24, pixfmt_xrgb64>(dst, src);
+            break;
+
+        case pix_format_rgba64:
+            convert<pixfmt_sbgr24, pixfmt_rgbx64>(dst, src);
+            break;
+
+        case pix_format_rgb96:
+            convert<pixfmt_sbgr24, pixfmt_rgb96>(dst, src);
+            break;
+
+        case pix_format_bgr96:
+            convert<pixfmt_sbgr24, pixfmt_bgr96>(dst, src);
+            break;
+
+        case pix_format_bgra128:
+            convert<pixfmt_sbgr24, pixfmt_bgrx128>(dst, src);
+            break;
+
+        case pix_format_abgr128:
+            convert<pixfmt_sbgr24, pixfmt_xbgr128>(dst, src);
+            break;
+
+        case pix_format_argb128:
+            convert<pixfmt_sbgr24, pixfmt_xrgb128>(dst, src);
+            break;
+
+        case pix_format_rgba128:
+            convert<pixfmt_sbgr24, pixfmt_rgbx128>(dst, src);
+            break;
+        }
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_specific::display_pmap(HDC dc, const rendering_buffer* src)
+    {
+        if(m_sys_format == m_format)
+        {
+            m_pmap_window.draw(dc);
+        }
+        else
+        {
+            pixel_map pmap_tmp;
+            pmap_tmp.create(m_pmap_window.width(), 
+                            m_pmap_window.height(),
+                            org_e(m_sys_bpp));
+
+            rendering_buffer rbuf_tmp;
+            rbuf_tmp.attach(pmap_tmp.buf(),
+                            pmap_tmp.width(),
+                            pmap_tmp.height(),
+                            m_flip_y ?
+                              pmap_tmp.stride() :
+                             -pmap_tmp.stride());
+
+            convert_pmap(&rbuf_tmp, src, m_format);
+            pmap_tmp.draw(dc);
+        }
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool platform_specific::save_pmap(const char* fn, unsigned idx, 
+                                      const rendering_buffer* src)
+    {
+        if(m_sys_format == m_format)
+        {
+            return m_pmap_img[idx].save_as_bmp(fn);
+        }
+
+        pixel_map pmap_tmp;
+        pmap_tmp.create(m_pmap_img[idx].width(), 
+                          m_pmap_img[idx].height(),
+                          org_e(m_sys_bpp));
+
+        rendering_buffer rbuf_tmp;
+        rbuf_tmp.attach(pmap_tmp.buf(),
+                          pmap_tmp.width(),
+                          pmap_tmp.height(),
+                          m_flip_y ?
+                          pmap_tmp.stride() :
+                          -pmap_tmp.stride());
+
+        convert_pmap(&rbuf_tmp, src, m_format);
+        return pmap_tmp.save_as_bmp(fn);
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool platform_specific::load_pmap(const char* fn, unsigned idx, 
+                                      rendering_buffer* dst)
+    {
+        pixel_map pmap_tmp;
+        if(!pmap_tmp.load_from_bmp(fn)) return false;
+
+        rendering_buffer rbuf_tmp;
+        rbuf_tmp.attach(pmap_tmp.buf(),
+                        pmap_tmp.width(),
+                        pmap_tmp.height(),
+                        m_flip_y ?
+                          pmap_tmp.stride() :
+                         -pmap_tmp.stride());
+
+        m_pmap_img[idx].create(pmap_tmp.width(), 
+                               pmap_tmp.height(), 
+                               org_e(m_bpp),
+                               0);
+
+        dst->attach(m_pmap_img[idx].buf(),
+                    m_pmap_img[idx].width(),
+                    m_pmap_img[idx].height(),
+                    m_flip_y ?
+                       m_pmap_img[idx].stride() :
+                      -m_pmap_img[idx].stride());
+
+        switch(m_format)
+        {
+        case pix_format_sgray8:
+            switch(pmap_tmp.bpp())
+            {
+            //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray8()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_gray8()); break;
+            //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray8()); break;
+            }
+            break;
+
+        case pix_format_gray8:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_gray8, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_gray16:
+            switch(pmap_tmp.bpp())
+            {
+            //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray16()); break;
+            case 24: convert<pixfmt_gray16, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray16()); break;
+            }
+            break;
+
+        case pix_format_gray32:
+            switch(pmap_tmp.bpp())
+            {
+            //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray32()); break;
+            case 24: convert<pixfmt_gray32, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray32()); break;
+            }
+            break;
+
+        case pix_format_rgb555:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb555()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb555()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb555()); break;
+            }
+            break;
+
+        case pix_format_rgb565:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb565()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb565()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb565()); break;
+            }
+            break;
+
+        case pix_format_srgb24:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb24()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb24()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb24()); break;
+            }
+            break;
+
+        case pix_format_sbgr24:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr24()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_bgr24()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr24()); break;
+            }
+            break;
+
+        case pix_format_rgb24:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_rgb24, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_bgr24:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_bgr24, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_rgb48:
+            switch(pmap_tmp.bpp())
+            {
+            //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb48()); break;
+            case 24: convert<pixfmt_rgb48, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb48()); break;
+            }
+            break;
+
+        case pix_format_bgr48:
+            switch(pmap_tmp.bpp())
+            {
+            //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr48()); break;
+            case 24: convert<pixfmt_bgr48, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr48()); break;
+            }
+            break;
+
+        case pix_format_sabgr32:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_abgr32()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_abgr32()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_abgr32()); break;
+            }
+            break;
+
+        case pix_format_sargb32:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_argb32()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_argb32()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_argb32()); break;
+            }
+            break;
+
+        case pix_format_sbgra32:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgra32()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_bgra32()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgra32()); break;
+            }
+            break;
+
+        case pix_format_srgba32:
+            switch(pmap_tmp.bpp())
+            {
+            case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgba32()); break;
+            case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgba32()); break;
+            case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgba32()); break;
+            }
+            break;
+
+        case pix_format_abgr32:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_abgr32, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_argb32:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_argb32, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_bgra32:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_bgra32, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_rgba32:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_rgba32, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_abgr64:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_abgr64, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_argb64:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_argb64, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_bgra64:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_bgra64, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_rgba64:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_rgba64, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_rgb96:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_rgb96, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_bgr96:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_bgr96, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_abgr128:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_abgr128, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_argb128:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_argb128, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_bgra128:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_bgra128, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+
+        case pix_format_rgba128:
+            switch(pmap_tmp.bpp())
+            {
+            case 24: convert<pixfmt_rgba128, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+            }
+            break;
+        }
+
+        return true;
+    }
+
+
+
+
+
+
+
+
+    //------------------------------------------------------------------------
+    unsigned platform_specific::translate(unsigned keycode)
+    {
+        return m_last_translated_key = (keycode > 255) ? 0 : m_keymap[keycode];
+    }
+
+
+
+    //------------------------------------------------------------------------
+    platform_support::platform_support(pix_format_e format, bool flip_y) :
+        m_specific(new platform_specific(format, flip_y)),
+        m_format(format),
+        m_bpp(m_specific->m_bpp),
+        m_window_flags(0),
+        m_wait_mode(true),
+        m_flip_y(flip_y),
+        m_initial_width(10),
+        m_initial_height(10)
+    {
+        strcpy(m_caption, "Anti-Grain Geometry Application");
+    }
+
+
+    //------------------------------------------------------------------------
+    platform_support::~platform_support()
+    {
+        delete m_specific;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    void platform_support::caption(const char* cap)
+    {
+        strcpy(m_caption, cap);
+        if(m_specific->m_hwnd)
+        {
+            SetWindowText(m_specific->m_hwnd, m_caption);
+        }
+    }
+
+    //------------------------------------------------------------------------
+    void platform_support::start_timer()
+    {
+        ::QueryPerformanceCounter(&(m_specific->m_sw_start));
+    }
+
+    //------------------------------------------------------------------------
+    double platform_support::elapsed_time() const
+    {
+        LARGE_INTEGER stop;
+        ::QueryPerformanceCounter(&stop);
+        return double(stop.QuadPart - 
+                      m_specific->m_sw_start.QuadPart) * 1000.0 / 
+                      double(m_specific->m_sw_freq.QuadPart);
+    }
+
+
+
+    //------------------------------------------------------------------------
+    static unsigned get_key_flags(int wflags)
+    {
+        unsigned flags = 0;
+        if(wflags & MK_LBUTTON) flags |= mouse_left;
+        if(wflags & MK_RBUTTON) flags |= mouse_right;
+        if(wflags & MK_SHIFT)   flags |= kbd_shift;
+        if(wflags & MK_CONTROL) flags |= kbd_ctrl;
+        return flags;
+    }
+
+
+    void* platform_support::raw_display_handler()
+    {
+        return m_specific->m_current_dc;
+    }
+
+
+    //------------------------------------------------------------------------
+    LRESULT CALLBACK window_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+    {
+        PAINTSTRUCT ps;
+        HDC paintDC;
+
+
+        void* user_data = reinterpret_cast<void*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
+        platform_support* app = 0;
+
+        if(user_data)
+        {
+            app = reinterpret_cast<platform_support*>(user_data);
+        }
+
+        if(app == 0)
+        {
+            if(msg == WM_DESTROY)
+            {
+                ::PostQuitMessage(0);
+                return 0;
+            }
+            return ::DefWindowProc(hWnd, msg, wParam, lParam);
+        }
+
+        HDC dc = ::GetDC(app->m_specific->m_hwnd);
+        app->m_specific->m_current_dc = dc;
+        LRESULT ret = 0;
+
+        switch(msg) 
+        {
+        //--------------------------------------------------------------------
+        case WM_CREATE:
+            break;
+        
+        //--------------------------------------------------------------------
+        case WM_SIZE:
+            app->m_specific->create_pmap(LOWORD(lParam), 
+                                         HIWORD(lParam),
+                                         &app->rbuf_window());
+
+            app->trans_affine_resizing(LOWORD(lParam), HIWORD(lParam));
+            app->on_resize(LOWORD(lParam), HIWORD(lParam));
+            app->force_redraw();
+            break;
+        
+        //--------------------------------------------------------------------
+        case WM_ERASEBKGND:
+            break;
+        
+        //--------------------------------------------------------------------
+        case WM_LBUTTONDOWN:
+            ::SetCapture(app->m_specific->m_hwnd);
+            app->m_specific->m_cur_x = int16(LOWORD(lParam));
+            if(app->flip_y())
+            {
+                app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam));
+            }
+            else
+            {
+                app->m_specific->m_cur_y = int16(HIWORD(lParam));
+            }
+            app->m_specific->m_input_flags = mouse_left | get_key_flags(wParam);
+            
+            app->m_ctrls.set_cur(app->m_specific->m_cur_x, 
+                                 app->m_specific->m_cur_y);
+            if(app->m_ctrls.on_mouse_button_down(app->m_specific->m_cur_x, 
+                                                 app->m_specific->m_cur_y))
+            {
+                app->on_ctrl_change();
+                app->force_redraw();
+            }
+            else
+            {
+                if(app->m_ctrls.in_rect(app->m_specific->m_cur_x, 
+                                        app->m_specific->m_cur_y))
+                {
+                    if(app->m_ctrls.set_cur(app->m_specific->m_cur_x, 
+                                            app->m_specific->m_cur_y))
+                    {
+                        app->on_ctrl_change();
+                        app->force_redraw();
+                    }
+                }
+                else
+                {
+                    app->on_mouse_button_down(app->m_specific->m_cur_x, 
+                                              app->m_specific->m_cur_y, 
+                                              app->m_specific->m_input_flags);
+                }
+            }
+/*
+            if(!app->wait_mode())
+            {
+                app->on_idle();
+            }
+*/
+            break;
+
+        //--------------------------------------------------------------------
+        case WM_LBUTTONUP:
+            ::ReleaseCapture();
+            app->m_specific->m_cur_x = int16(LOWORD(lParam));
+            if(app->flip_y())
+            {
+                app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam));
+            }
+            else
+            {
+                app->m_specific->m_cur_y = int16(HIWORD(lParam));
+            }
+            app->m_specific->m_input_flags = mouse_left | get_key_flags(wParam);
+
+            if(app->m_ctrls.on_mouse_button_up(app->m_specific->m_cur_x, 
+                                               app->m_specific->m_cur_y))
+            {
+                app->on_ctrl_change();
+                app->force_redraw();
+            }
+            app->on_mouse_button_up(app->m_specific->m_cur_x, 
+                                    app->m_specific->m_cur_y, 
+                                    app->m_specific->m_input_flags);
+/*
+            if(!app->wait_mode())
+            {
+                app->on_idle();
+            }
+*/
+            break;
+
+
+        //--------------------------------------------------------------------
+        case WM_RBUTTONDOWN:
+            ::SetCapture(app->m_specific->m_hwnd);
+            app->m_specific->m_cur_x = int16(LOWORD(lParam));
+            if(app->flip_y())
+            {
+                app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam));
+            }
+            else
+            {
+                app->m_specific->m_cur_y = int16(HIWORD(lParam));
+            }
+            app->m_specific->m_input_flags = mouse_right | get_key_flags(wParam);
+            app->on_mouse_button_down(app->m_specific->m_cur_x, 
+                                      app->m_specific->m_cur_y, 
+                                      app->m_specific->m_input_flags);
+/*
+            if(!app->wait_mode())
+            {
+                app->on_idle();
+            }
+*/
+            break;
+
+        //--------------------------------------------------------------------
+        case WM_RBUTTONUP:
+            ::ReleaseCapture();
+            app->m_specific->m_cur_x = int16(LOWORD(lParam));
+            if(app->flip_y())
+            {
+                app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam));
+            }
+            else
+            {
+                app->m_specific->m_cur_y = int16(HIWORD(lParam));
+            }
+            app->m_specific->m_input_flags = mouse_right | get_key_flags(wParam);
+            app->on_mouse_button_up(app->m_specific->m_cur_x, 
+                                    app->m_specific->m_cur_y, 
+                                    app->m_specific->m_input_flags);
+/*
+            if(!app->wait_mode())
+            {
+                app->on_idle();
+            }
+*/
+            break;
+
+        //--------------------------------------------------------------------
+        case WM_MOUSEMOVE:
+            app->m_specific->m_cur_x = int16(LOWORD(lParam));
+            if(app->flip_y())
+            {
+                app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam));
+            }
+            else
+            {
+                app->m_specific->m_cur_y = int16(HIWORD(lParam));
+            }
+            app->m_specific->m_input_flags = get_key_flags(wParam);
+
+
+            if(app->m_ctrls.on_mouse_move(
+                app->m_specific->m_cur_x, 
+                app->m_specific->m_cur_y,
+                (app->m_specific->m_input_flags & mouse_left) != 0))
+            {
+                app->on_ctrl_change();
+                app->force_redraw();
+            }
+            else
+            {
+                if(!app->m_ctrls.in_rect(app->m_specific->m_cur_x, 
+                                         app->m_specific->m_cur_y))
+                {
+                    app->on_mouse_move(app->m_specific->m_cur_x, 
+                                       app->m_specific->m_cur_y, 
+                                       app->m_specific->m_input_flags);
+                }
+            }
+/*
+            if(!app->wait_mode())
+            {
+                app->on_idle();
+            }
+*/
+            break;
+
+        //--------------------------------------------------------------------
+        case WM_SYSKEYDOWN:
+        case WM_KEYDOWN:
+            app->m_specific->m_last_translated_key = 0;
+            switch(wParam) 
+            {
+                case VK_CONTROL:
+                    app->m_specific->m_input_flags |= kbd_ctrl;
+                    break;
+
+                case VK_SHIFT:
+                    app->m_specific->m_input_flags |= kbd_shift;
+                    break;
+
+                default:
+                    app->m_specific->translate(wParam);
+                    break;
+            }
+        
+            if(app->m_specific->m_last_translated_key)
+            {
+                bool left  = false;
+                bool up    = false;
+                bool right = false;
+                bool down  = false;
+
+                switch(app->m_specific->m_last_translated_key)
+                {
+                case key_left:
+                    left = true;
+                    break;
+
+                case key_up:
+                    up = true;
+                    break;
+
+                case key_right:
+                    right = true;
+                    break;
+
+                case key_down:
+                    down = true;
+                    break;
+
+                case key_f2:                        
+                    app->copy_window_to_img(agg::platform_support::max_images - 1);
+                    app->save_img(agg::platform_support::max_images - 1, "screenshot");
+                    break;
+                }
+
+                if(app->window_flags() & window_process_all_keys)
+                {
+                    app->on_key(app->m_specific->m_cur_x,
+                                app->m_specific->m_cur_y,
+                                app->m_specific->m_last_translated_key,
+                                app->m_specific->m_input_flags);
+                }
+                else
+                {
+                    if(app->m_ctrls.on_arrow_keys(left, right, down, up))
+                    {
+                        app->on_ctrl_change();
+                        app->force_redraw();
+                    }
+                    else
+                    {
+                        app->on_key(app->m_specific->m_cur_x,
+                                    app->m_specific->m_cur_y,
+                                    app->m_specific->m_last_translated_key,
+                                    app->m_specific->m_input_flags);
+                    }
+                }
+            }
+/*
+            if(!app->wait_mode())
+            {
+                app->on_idle();
+            }
+*/
+            break;
+
+        //--------------------------------------------------------------------
+        case WM_SYSKEYUP:
+        case WM_KEYUP:
+            app->m_specific->m_last_translated_key = 0;
+            switch(wParam) 
+            {
+                case VK_CONTROL:
+                    app->m_specific->m_input_flags &= ~kbd_ctrl;
+                    break;
+
+                case VK_SHIFT:
+                    app->m_specific->m_input_flags &= ~kbd_shift;
+                    break;
+            }
+            break;
+
+        //--------------------------------------------------------------------
+        case WM_CHAR:
+        case WM_SYSCHAR:
+            if(app->m_specific->m_last_translated_key == 0)
+            {
+                app->on_key(app->m_specific->m_cur_x,
+                            app->m_specific->m_cur_y,
+                            wParam,
+                            app->m_specific->m_input_flags);
+            }
+            break;
+        
+        //--------------------------------------------------------------------
+        case WM_PAINT:
+            paintDC = ::BeginPaint(hWnd, &ps);
+            app->m_specific->m_current_dc = paintDC;
+            if(app->m_specific->m_redraw_flag)
+            {
+                app->on_draw();
+                app->m_specific->m_redraw_flag = false;
+            }
+            app->m_specific->display_pmap(paintDC, &app->rbuf_window());
+            app->on_post_draw(paintDC);
+            app->m_specific->m_current_dc = 0;
+            ::EndPaint(hWnd, &ps);
+            break;
+        
+        //--------------------------------------------------------------------
+        case WM_COMMAND:
+            break;
+        
+        //--------------------------------------------------------------------
+        case WM_DESTROY:
+            ::PostQuitMessage(0);
+            break;
+        
+        //--------------------------------------------------------------------
+        default:
+            ret = ::DefWindowProc(hWnd, msg, wParam, lParam);
+            break;
+        }
+        app->m_specific->m_current_dc = 0;
+        ::ReleaseDC(app->m_specific->m_hwnd, dc);
+        return ret;
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_support::message(const char* msg)
+    {
+        ::MessageBox(m_specific->m_hwnd, msg, "AGG Message", MB_OK);
+    }
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::init(unsigned width, unsigned height, unsigned flags)
+    {
+        if(m_specific->m_sys_format == pix_format_undefined)
+        {
+            return false;
+        }
+
+        m_window_flags = flags;
+
+        int wflags = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
+
+        WNDCLASS wc;
+        wc.lpszClassName = "AGGAppClass";
+        wc.lpfnWndProc = window_proc;
+        wc.style = wflags;
+        wc.hInstance = g_windows_instance;
+        wc.hIcon = LoadIcon(0, IDI_APPLICATION);
+        wc.hCursor = LoadCursor(0, IDC_ARROW);
+        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+        wc.lpszMenuName = "AGGAppMenu";
+        wc.cbClsExtra = 0;
+        wc.cbWndExtra = 0;
+        ::RegisterClass(&wc);
+
+        wflags = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
+
+        if(m_window_flags & window_resize)
+        {
+            wflags |= WS_THICKFRAME | WS_MAXIMIZEBOX;
+        }
+
+        m_specific->m_hwnd = ::CreateWindow("AGGAppClass",
+                                            m_caption,
+                                            wflags,
+                                            100,
+                                            100,
+                                            width,
+                                            height,
+                                            0,
+                                            0,
+                                            g_windows_instance,
+                                            0);
+
+        if(m_specific->m_hwnd == 0)
+        {
+            return false;
+        }
+
+
+        RECT rct;
+        ::GetClientRect(m_specific->m_hwnd, &rct);
+
+        ::MoveWindow(m_specific->m_hwnd,   // handle to window
+                     100,                  // horizontal position
+                     100,                  // vertical position
+                     width + (width - (rct.right - rct.left)),
+                     height + (height - (rct.bottom - rct.top)),
+                     FALSE);
+   
+        ::SetWindowLongPtr(m_specific->m_hwnd, GWLP_USERDATA, (LONG)this);
+        m_specific->create_pmap(width, height, &m_rbuf_window);
+        m_initial_width = width;
+        m_initial_height = height;
+        on_init();
+        m_specific->m_redraw_flag = true;
+        ::ShowWindow(m_specific->m_hwnd, g_windows_cmd_show);
+        return true;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    int platform_support::run()
+    {
+        MSG msg;
+
+        for(;;)
+        {
+            if(m_wait_mode)
+            {
+                if(!::GetMessage(&msg, 0, 0, 0))
+                {
+                    break;
+                }
+                ::TranslateMessage(&msg);
+                ::DispatchMessage(&msg);
+            }
+            else
+            {
+                if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+                {
+                    ::TranslateMessage(&msg);
+                    if(msg.message == WM_QUIT)
+                    {
+                        break;
+                    }
+                    ::DispatchMessage(&msg);
+                }
+                else
+                {
+                    on_idle();
+                }
+            }
+        }
+        return (int)msg.wParam;
+    }
+
+
+    //------------------------------------------------------------------------
+    const char* platform_support::img_ext() const { return ".bmp"; }
+
+
+    //------------------------------------------------------------------------
+    const char* platform_support::full_file_name(const char* file_name)
+    {
+        return file_name;
+    }
+
+    //------------------------------------------------------------------------
+    bool platform_support::load_img(unsigned idx, const char* file)
+    {
+        if(idx < max_images)
+        {
+            char fn[1024];
+            strcpy(fn, file);
+            int len = strlen(fn);
+            if(len < 4 || _stricmp(fn + len - 4, ".BMP") != 0)
+            {
+                strcat(fn, ".bmp");
+            }
+            return m_specific->load_pmap(fn, idx, &m_rbuf_img[idx]);
+        }
+        return true;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::save_img(unsigned idx, const char* file)
+    {
+        if(idx < max_images)
+        {
+            char fn[1024];
+            strcpy(fn, file);
+            int len = strlen(fn);
+            if(len < 4 || _stricmp(fn + len - 4, ".BMP") != 0)
+            {
+                strcat(fn, ".bmp");
+            }
+            return m_specific->save_pmap(fn, idx, &m_rbuf_img[idx]);
+        }
+        return true;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool platform_support::create_img(unsigned idx, unsigned width, unsigned height)
+    {
+        if(idx < max_images)
+        {
+            if(width  == 0) width  = m_specific->m_pmap_window.width();
+            if(height == 0) height = m_specific->m_pmap_window.height();
+            m_specific->m_pmap_img[idx].create(width, height, org_e(m_specific->m_bpp));
+            m_rbuf_img[idx].attach(m_specific->m_pmap_img[idx].buf(), 
+                                   m_specific->m_pmap_img[idx].width(),
+                                   m_specific->m_pmap_img[idx].height(),
+                                   m_flip_y ?
+                                    m_specific->m_pmap_img[idx].stride() :
+                                   -m_specific->m_pmap_img[idx].stride());
+            return true;
+        }
+        return false;
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_support::force_redraw()
+    {
+        m_specific->m_redraw_flag = true;
+        ::InvalidateRect(m_specific->m_hwnd, 0, FALSE);
+    }
+
+
+
+    //------------------------------------------------------------------------
+    void platform_support::update_window()
+    {
+        HDC dc = ::GetDC(m_specific->m_hwnd);
+        m_specific->display_pmap(dc, &m_rbuf_window);
+        ::ReleaseDC(m_specific->m_hwnd, dc);
+    }
+
+
+    //------------------------------------------------------------------------
+    void platform_support::on_init() {}
+    void platform_support::on_resize(int sx, int sy) {}
+    void platform_support::on_idle() {}
+    void platform_support::on_mouse_move(int x, int y, unsigned flags) {}
+    void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {}
+    void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {}
+    void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {}
+    void platform_support::on_ctrl_change() {}
+    void platform_support::on_draw() {}
+    void platform_support::on_post_draw(void* raw_handler) {}
+}
+
+
+
+
+namespace agg
+{
+    // That's ridiculous. I have to parse the command line by myself
+    // because Windows doesn't provide a method of getting the command
+    // line arguments in a form of argc, argv. Of course, there's 
+    // CommandLineToArgv() but first, it returns Unicode that I don't
+    // need to deal with, but most of all, it's not compatible with Win98.
+    //-----------------------------------------------------------------------
+    class tokenizer
+    {
+    public:
+        enum sep_flag
+        {
+            single,
+            multiple,
+            whole_str
+        };
+
+        struct token
+        {
+            const char* ptr;
+            unsigned    len;
+        };
+
+    public:
+        tokenizer(const char* sep, 
+                  const char* trim=0,
+                  const char* quote="\"",
+                  char mask_chr='\\',
+                  sep_flag sf=multiple);
+
+        void  set_str(const char* str);
+        token next_token();
+
+    private:
+        int  check_chr(const char *str, char chr);
+
+    private:
+        const char* m_src_string;
+        int         m_start;
+        const char* m_sep;
+        const char* m_trim;
+        const char* m_quote;
+        char        m_mask_chr;
+        unsigned    m_sep_len;
+        sep_flag    m_sep_flag;
+    };
+
+
+
+    //-----------------------------------------------------------------------
+    inline void tokenizer::set_str(const char* str) 
+    { 
+        m_src_string = str; 
+        m_start = 0;
+    }
+
+
+    //-----------------------------------------------------------------------
+    inline int tokenizer::check_chr(const char *str, char chr)
+    {
+        return int(strchr(str, chr));
+    }
+
+
+    //-----------------------------------------------------------------------
+    tokenizer::tokenizer(const char* sep, 
+                         const char* trim,
+                         const char* quote,
+                         char mask_chr,
+                         sep_flag sf) :
+        m_src_string(0),
+        m_start(0),
+        m_sep(sep),
+        m_trim(trim),
+        m_quote(quote),
+        m_mask_chr(mask_chr),
+        m_sep_len(sep ? strlen(sep) : 0),
+        m_sep_flag(sep ? sf : single)
+    {
+    }
+
+
+    //-----------------------------------------------------------------------
+    tokenizer::token tokenizer::next_token()
+    {
+        unsigned count = 0;
+        char quote_chr = 0;
+        token tok;
+
+        tok.ptr = 0;
+        tok.len = 0;
+        if(m_src_string == 0 || m_start == -1) return tok;
+
+        const char *pstr = m_src_string + m_start;
+
+        if(*pstr == 0) 
+        {
+            m_start = -1;
+            return tok;
+        }
+
+        int sep_len = 1;
+        if(m_sep_flag == whole_str) sep_len = m_sep_len;
+
+        if(m_sep_flag == multiple)
+        {
+            //Pass all the separator symbols at the begin of the string
+            while(*pstr && check_chr(m_sep, *pstr)) 
+            {
+                ++pstr;
+                ++m_start;
+            }
+        }
+
+        if(*pstr == 0) 
+        {
+            m_start = -1;
+            return tok;
+        }
+
+        for(count = 0;; ++count) 
+        {
+            char c = *pstr;
+            int found = 0;
+
+            //We are outside of qotation: find one of separator symbols
+            if(quote_chr == 0)
+            {
+                if(sep_len == 1)
+                {
+                    found = check_chr(m_sep, c);
+                }
+                else
+                {
+                    found = strncmp(m_sep, pstr, m_sep_len) == 0; 
+                }
+            }
+
+            ++pstr;
+
+            if(c == 0 || found) 
+            {
+                if(m_trim)
+                {
+                    while(count && 
+                          check_chr(m_trim, m_src_string[m_start]))
+                    {
+                        ++m_start;
+                        --count;
+                    }
+
+                    while(count && 
+                          check_chr(m_trim, m_src_string[m_start + count - 1]))
+                    {
+                        --count;
+                    }
+                }
+
+                tok.ptr = m_src_string + m_start;
+                tok.len = count;
+
+                //Next time it will be the next separator character
+                //But we must check, whether it is NOT the end of the string.
+                m_start += count;
+                if(c) 
+                {
+                    m_start += sep_len;
+                    if(m_sep_flag == multiple)
+                    {
+                        //Pass all the separator symbols 
+                        //after the end of the string
+                        while(check_chr(m_sep, m_src_string[m_start])) 
+                        {
+                            ++m_start;
+                        }
+                    }
+                }
+                break;
+            }
+
+            //Switch quote. If it is not a quote yet, try to check any of
+            //quote symbols. Otherwise quote must be finished with quote_symb
+            if(quote_chr == 0)
+            {
+                if(check_chr(m_quote, c)) 
+                {
+                    quote_chr = c;
+                    continue;
+                }
+            }
+            else
+            {
+                //We are inside quote: pass all the mask symbols
+                if(m_mask_chr && c == m_mask_chr)
+                {
+                    if(*pstr) 
+                    {
+                        ++count;
+                        ++pstr;
+                    }
+                    continue; 
+                }
+                if(c == quote_chr) 
+                {
+                    quote_chr = 0;
+                    continue;
+                }
+            }
+        }
+        return tok;
+    }
+
+
+}
+
+
+
+//----------------------------------------------------------------------------
+int agg_main(int argc, char* argv[]);
+
+
+
+//----------------------------------------------------------------------------
+int PASCAL WinMain(HINSTANCE hInstance,
+                   HINSTANCE hPrevInstance,
+                   LPSTR lpszCmdLine,
+                   int nCmdShow)
+{
+    agg::g_windows_instance = hInstance;
+    agg::g_windows_cmd_show = nCmdShow;
+
+    char* argv_str = new char [strlen(lpszCmdLine) + 3];
+    char* argv_ptr = argv_str;
+
+    char* argv[64];
+    memset(argv, 0, sizeof(argv));
+
+    agg::tokenizer cmd_line(" ", "\"' ", "\"'", '\\', agg::tokenizer::multiple);
+    cmd_line.set_str(lpszCmdLine);
+
+    int argc = 0;
+    argv[argc++] = argv_ptr;
+    *argv_ptr++ = 0;
+
+    while(argc < 64)
+    {
+        agg::tokenizer::token tok = cmd_line.next_token();
+        if(tok.ptr == 0) break;
+        if(tok.len)
+        {
+            memcpy(argv_ptr, tok.ptr, tok.len);
+            argv[argc++] = argv_ptr;
+            argv_ptr += tok.len;
+            *argv_ptr++ = 0;
+        }
+    }
+
+    int ret = agg_main(argc, argv);
+    delete [] argv_str;
+
+    return ret;
+}
+
+
+
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp
new file mode 100644
index 0000000000..8c3bdc83fd
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp
@@ -0,0 +1,631 @@
+//----------------------------------------------------------------------------
+//
+//----------------------------------------------------------------------------
+// Contact: mcseemagg@yahoo.com
+//----------------------------------------------------------------------------
+//
+// class pixel_map
+//
+//----------------------------------------------------------------------------
+
+#include "platform/win32/agg_win32_bmp.h"
+#include "agg_basics.h"
+
+namespace agg
+{
+
+    //------------------------------------------------------------------------
+    pixel_map::~pixel_map()
+    {
+        destroy();
+    }
+
+
+    //------------------------------------------------------------------------
+    pixel_map::pixel_map() :
+        m_bmp(0),
+        m_buf(0),
+        m_bpp(0),
+        m_is_internal(false),
+        m_img_size(0),
+        m_full_size(0)
+
+    {
+    }
+
+
+    //------------------------------------------------------------------------
+    void pixel_map::destroy()
+    {
+        if(m_bmp && m_is_internal) delete [] (unsigned char*)m_bmp;
+        m_bmp  = 0;
+        m_is_internal = false;
+        m_buf = 0;
+    }
+
+
+    //------------------------------------------------------------------------
+    void pixel_map::create(unsigned width, 
+                           unsigned height, 
+                           org_e    org,
+                           unsigned clear_val)
+    {
+        destroy();
+        if(width == 0)  width = 1;
+        if(height == 0) height = 1;
+        m_bpp = org;
+        create_from_bmp(create_bitmap_info(width, height, m_bpp));
+        create_gray_scale_palette(m_bmp);
+        m_is_internal = true;
+        if(clear_val <= 255)
+        {
+            memset(m_buf, clear_val, m_img_size);
+        }
+    }
+
+
+    //------------------------------------------------------------------------
+    HBITMAP pixel_map::create_dib_section(HDC h_dc,
+                                          unsigned width, 
+                                          unsigned height, 
+                                          org_e    org,
+                                          unsigned clear_val)
+    {
+        destroy();
+        if(width == 0)  width = 1;
+        if(height == 0) height = 1;
+        m_bpp = org;
+        HBITMAP h_bitmap = create_dib_section_from_args(h_dc, width, height, m_bpp);
+        create_gray_scale_palette(m_bmp);
+        m_is_internal = true;
+        if(clear_val <= 255)
+        {
+            memset(m_buf, clear_val, m_img_size);
+        }
+        return h_bitmap;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    void pixel_map::clear(unsigned clear_val)
+    {
+        if(m_buf) memset(m_buf, clear_val, m_img_size);
+    }
+
+
+    //------------------------------------------------------------------------
+    void pixel_map::attach_to_bmp(BITMAPINFO *bmp)
+    {
+        if(bmp)
+        {
+            destroy();
+            create_from_bmp(bmp);
+            m_is_internal = false;
+        }
+    }
+
+
+
+    //static
+    //------------------------------------------------------------------------
+    unsigned pixel_map::calc_full_size(BITMAPINFO *bmp)
+    {
+        if(bmp == 0) return 0;
+
+        return sizeof(BITMAPINFOHEADER) +
+               sizeof(RGBQUAD) * calc_palette_size(bmp) +
+               bmp->bmiHeader.biSizeImage;
+    }
+
+    //static
+    //------------------------------------------------------------------------
+    unsigned pixel_map::calc_header_size(BITMAPINFO *bmp)
+    {
+        if(bmp == 0) return 0;
+        return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * calc_palette_size(bmp);
+    }
+
+
+    //static
+    //------------------------------------------------------------------------
+    unsigned  pixel_map::calc_palette_size(unsigned  clr_used, unsigned bits_per_pixel)
+    {
+        int palette_size = 0;
+
+        if(bits_per_pixel <= 8)
+        {
+            palette_size = clr_used;
+            if(palette_size == 0)
+            {
+                palette_size = 1 << bits_per_pixel;
+            }
+        }
+        return palette_size;
+    }
+
+    //static
+    //------------------------------------------------------------------------
+    unsigned pixel_map::calc_palette_size(BITMAPINFO *bmp)
+    {
+        if(bmp == 0) return 0;
+        return calc_palette_size(bmp->bmiHeader.biClrUsed, bmp->bmiHeader.biBitCount);
+    }
+
+
+    //static
+    //------------------------------------------------------------------------
+    unsigned char * pixel_map::calc_img_ptr(BITMAPINFO *bmp)
+    {
+        if(bmp == 0) return 0;
+        return ((unsigned char*)bmp) + calc_header_size(bmp);
+    }
+
+    //static
+    //------------------------------------------------------------------------
+    BITMAPINFO* pixel_map::create_bitmap_info(unsigned width, 
+                                              unsigned height, 
+                                              unsigned bits_per_pixel)
+    {
+        unsigned line_len = calc_row_len(width, bits_per_pixel);
+        unsigned img_size = line_len * height;
+        unsigned rgb_size = calc_palette_size(0, bits_per_pixel) * sizeof(RGBQUAD);
+        unsigned full_size = sizeof(BITMAPINFOHEADER) + rgb_size + img_size;
+
+        BITMAPINFO *bmp = (BITMAPINFO *) new unsigned char[full_size];
+
+        bmp->bmiHeader.biSize   = sizeof(BITMAPINFOHEADER);
+        bmp->bmiHeader.biWidth  = width;
+        bmp->bmiHeader.biHeight = height;
+        bmp->bmiHeader.biPlanes = 1;
+        bmp->bmiHeader.biBitCount = (unsigned short)bits_per_pixel;
+        bmp->bmiHeader.biCompression = 0;
+        bmp->bmiHeader.biSizeImage = img_size;
+        bmp->bmiHeader.biXPelsPerMeter = 0;
+        bmp->bmiHeader.biYPelsPerMeter = 0;
+        bmp->bmiHeader.biClrUsed = 0;
+        bmp->bmiHeader.biClrImportant = 0;
+
+        return bmp;
+    }
+
+
+    //static
+    //------------------------------------------------------------------------
+    void pixel_map::create_gray_scale_palette(BITMAPINFO *bmp)
+    {
+        if(bmp == 0) return;
+
+        unsigned rgb_size = calc_palette_size(bmp);
+        RGBQUAD *rgb = (RGBQUAD*)(((unsigned char*)bmp) + sizeof(BITMAPINFOHEADER));
+        unsigned brightness;
+        unsigned i;
+
+        for(i = 0; i < rgb_size; i++)
+        {
+            brightness = (255 * i) / (rgb_size - 1);
+            rgb->rgbBlue =
+            rgb->rgbGreen =  
+            rgb->rgbRed = (unsigned char)brightness; 
+            rgb->rgbReserved = 0;
+            rgb++;
+        }
+    }
+
+
+
+    //static
+    //------------------------------------------------------------------------
+    unsigned pixel_map::calc_row_len(unsigned width, unsigned bits_per_pixel)
+    {
+        unsigned n = width;
+        unsigned k;
+
+        switch(bits_per_pixel)
+        {
+            case  1: k = n;
+                     n = n >> 3;
+                     if(k & 7) n++; 
+                     break;
+
+            case  4: k = n;
+                     n = n >> 1;
+                     if(k & 3) n++; 
+                     break;
+
+            case  8:
+                     break;
+
+            case 16: n *= 2;
+                     break;
+
+            case 24: n *= 3; 
+                     break;
+
+            case 32: n *= 4;
+                     break;
+
+            case 48: n *= 6; 
+                     break;
+
+            case 64: n *= 8; 
+                     break;
+
+            case 96: n *= 12; 
+                     break;
+
+            case 128: n *= 16; 
+                     break;
+
+            default: n = 0;
+                     break;
+        }
+        return ((n + 3) >> 2) << 2;
+    }
+
+
+
+
+
+    //------------------------------------------------------------------------
+    void pixel_map::draw(HDC h_dc, const RECT *device_rect, const RECT *bmp_rect) const
+    {
+        if(m_bmp == 0 || m_buf == 0) return;
+
+        unsigned bmp_x = 0;
+        unsigned bmp_y = 0;
+        unsigned bmp_width  = m_bmp->bmiHeader.biWidth;
+        unsigned bmp_height = m_bmp->bmiHeader.biHeight;
+        unsigned dvc_x = 0;
+        unsigned dvc_y = 0; 
+        unsigned dvc_width  = m_bmp->bmiHeader.biWidth;
+        unsigned dvc_height = m_bmp->bmiHeader.biHeight;
+        
+        if(bmp_rect) 
+        {
+            bmp_x      = bmp_rect->left;
+            bmp_y      = bmp_rect->top;
+            bmp_width  = bmp_rect->right  - bmp_rect->left;
+            bmp_height = bmp_rect->bottom - bmp_rect->top;
+        } 
+
+        dvc_x      = bmp_x;
+        dvc_y      = bmp_y;
+        dvc_width  = bmp_width;
+        dvc_height = bmp_height;
+
+        if(device_rect) 
+        {
+            dvc_x      = device_rect->left;
+            dvc_y      = device_rect->top;
+            dvc_width  = device_rect->right  - device_rect->left;
+            dvc_height = device_rect->bottom - device_rect->top;
+        }
+
+        if(dvc_width != bmp_width || dvc_height != bmp_height)
+        {
+            ::SetStretchBltMode(h_dc, COLORONCOLOR);
+            ::StretchDIBits(
+                h_dc,            // handle of device context 
+                dvc_x,           // x-coordinate of upper-left corner of source rect. 
+                dvc_y,           // y-coordinate of upper-left corner of source rect. 
+                dvc_width,       // width of source rectangle 
+                dvc_height,      // height of source rectangle 
+                bmp_x,
+                bmp_y,           // x, y -coordinates of upper-left corner of dest. rect. 
+                bmp_width,       // width of destination rectangle 
+                bmp_height,      // height of destination rectangle 
+                m_buf,           // address of bitmap bits 
+                m_bmp,           // address of bitmap data 
+                DIB_RGB_COLORS,  // usage 
+                SRCCOPY          // raster operation code 
+            );
+        }
+        else
+        {
+            ::SetDIBitsToDevice(
+                h_dc,            // handle to device context
+                dvc_x,           // x-coordinate of upper-left corner of 
+                dvc_y,           // y-coordinate of upper-left corner of 
+                dvc_width,       // source rectangle width
+                dvc_height,      // source rectangle height
+                bmp_x,           // x-coordinate of lower-left corner of 
+                bmp_y,           // y-coordinate of lower-left corner of 
+                0,               // first scan line in array
+                bmp_height,      // number of scan lines
+                m_buf,           // address of array with DIB bits
+                m_bmp,           // address of structure with bitmap info.
+                DIB_RGB_COLORS   // RGB or palette indexes
+            );
+        }
+    }
+
+
+    //------------------------------------------------------------------------
+    void pixel_map::draw(HDC h_dc, int x, int y, double scale) const
+    {
+        if(m_bmp == 0 || m_buf == 0) return;
+
+        unsigned width  = unsigned(m_bmp->bmiHeader.biWidth * scale);
+        unsigned height = unsigned(m_bmp->bmiHeader.biHeight * scale);
+        RECT rect;
+        rect.left   = x;
+        rect.top    = y;
+        rect.right  = x + width;
+        rect.bottom = y + height;
+        draw(h_dc, &rect);
+    }
+
+
+
+
+    //------------------------------------------------------------------------
+    void pixel_map::blend(HDC h_dc, const RECT *device_rect, const RECT *bmp_rect) const
+    {
+#if !defined(AGG_BMP_ALPHA_BLEND)
+        draw(h_dc, device_rect, bmp_rect);
+        return;
+#else
+        if(m_bpp != 32)
+        {
+            draw(h_dc, device_rect, bmp_rect);
+            return;
+        }
+
+        if(m_bmp == 0 || m_buf == 0) return;
+
+        unsigned bmp_x = 0;
+        unsigned bmp_y = 0;
+        unsigned bmp_width  = m_bmp->bmiHeader.biWidth;
+        unsigned bmp_height = m_bmp->bmiHeader.biHeight;
+        unsigned dvc_x = 0;
+        unsigned dvc_y = 0; 
+        unsigned dvc_width  = m_bmp->bmiHeader.biWidth;
+        unsigned dvc_height = m_bmp->bmiHeader.biHeight;
+        
+        if(bmp_rect) 
+        {
+            bmp_x      = bmp_rect->left;
+            bmp_y      = bmp_rect->top;
+            bmp_width  = bmp_rect->right  - bmp_rect->left;
+            bmp_height = bmp_rect->bottom - bmp_rect->top;
+        } 
+
+        dvc_x      = bmp_x;
+        dvc_y      = bmp_y;
+        dvc_width  = bmp_width;
+        dvc_height = bmp_height;
+
+        if(device_rect) 
+        {
+            dvc_x      = device_rect->left;
+            dvc_y      = device_rect->top;
+            dvc_width  = device_rect->right  - device_rect->left;
+            dvc_height = device_rect->bottom - device_rect->top;
+        }
+
+        HDC mem_dc = ::CreateCompatibleDC(h_dc);
+        void* buf = 0;
+        HBITMAP bmp = ::CreateDIBSection(
+            mem_dc, 
+            m_bmp,  
+            DIB_RGB_COLORS,
+            &buf,
+            0,
+            0
+        );
+        memcpy(buf, m_buf, m_bmp->bmiHeader.biSizeImage);
+
+        HBITMAP temp = (HBITMAP)::SelectObject(mem_dc, bmp);
+
+        BLENDFUNCTION blend;
+        blend.BlendOp = AC_SRC_OVER;
+        blend.BlendFlags = 0;
+
+#if defined(AC_SRC_ALPHA)
+        blend.AlphaFormat = AC_SRC_ALPHA;
+//#elif defined(AC_SRC_NO_PREMULT_ALPHA)
+//        blend.AlphaFormat = AC_SRC_NO_PREMULT_ALPHA;
+#else 
+#error "No appropriate constant for alpha format. Check version of wingdi.h, There must be AC_SRC_ALPHA or AC_SRC_NO_PREMULT_ALPHA"
+#endif
+
+        blend.SourceConstantAlpha = 255;
+        ::AlphaBlend(
+          h_dc,      
+          dvc_x,      
+          dvc_y,      
+          dvc_width,  
+          dvc_height, 
+          mem_dc,
+          bmp_x,
+          bmp_y,     
+          bmp_width, 
+          bmp_height,
+          blend
+        );
+
+        ::SelectObject(mem_dc, temp);
+        ::DeleteObject(bmp);
+        ::DeleteObject(mem_dc);
+#endif //defined(AGG_BMP_ALPHA_BLEND)
+    }
+
+
+    //------------------------------------------------------------------------
+    void pixel_map::blend(HDC h_dc, int x, int y, double scale) const
+    {
+        if(m_bmp == 0 || m_buf == 0) return;
+        unsigned width  = unsigned(m_bmp->bmiHeader.biWidth * scale);
+        unsigned height = unsigned(m_bmp->bmiHeader.biHeight * scale);
+        RECT rect;
+        rect.left   = x;
+        rect.top    = y;
+        rect.right  = x + width;
+        rect.bottom = y + height;
+        blend(h_dc, &rect);
+    }
+
+
+    //------------------------------------------------------------------------
+    bool pixel_map::load_from_bmp(FILE *fd)
+    {
+        BITMAPFILEHEADER  bmf;
+        BITMAPINFO       *bmi = 0;
+        unsigned          bmp_size;
+
+        fread(&bmf, sizeof(bmf), 1, fd);
+        if(bmf.bfType != 0x4D42) goto bmperr;
+
+        bmp_size = bmf.bfSize - sizeof(BITMAPFILEHEADER);
+
+        bmi = (BITMAPINFO*) new unsigned char [bmp_size];
+        if(fread(bmi, 1, bmp_size, fd) != bmp_size) goto bmperr;
+        destroy();
+        m_bpp = bmi->bmiHeader.biBitCount;
+        create_from_bmp(bmi);
+        m_is_internal = 1;
+        return true;
+
+    bmperr:
+        if(bmi) delete [] (unsigned char*) bmi;
+        return false;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool pixel_map::load_from_bmp(const char *filename)
+    {
+        FILE *fd = fopen(filename, "rb");
+        bool ret = false;
+        if(fd)
+        {
+            ret = load_from_bmp(fd);
+            fclose(fd);
+        }
+        return ret;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool pixel_map::save_as_bmp(FILE *fd) const
+    {
+        if(m_bmp == 0) return 0;
+
+        BITMAPFILEHEADER bmf;
+
+        bmf.bfType      = 0x4D42;
+        bmf.bfOffBits   = calc_header_size(m_bmp) + sizeof(bmf);
+        bmf.bfSize      = bmf.bfOffBits + m_img_size;
+        bmf.bfReserved1 = 0;
+        bmf.bfReserved2 = 0;
+
+        fwrite(&bmf, sizeof(bmf), 1, fd);
+        fwrite(m_bmp, m_full_size, 1, fd);
+        return true;
+    }
+
+
+
+    //------------------------------------------------------------------------
+    bool pixel_map::save_as_bmp(const char *filename) const
+    {
+        FILE *fd = fopen(filename, "wb");
+        bool ret = false;
+        if(fd)
+        {
+            ret = save_as_bmp(fd);
+            fclose(fd);
+        }
+        return ret;
+    }
+
+
+    //------------------------------------------------------------------------
+    unsigned char* pixel_map::buf()
+    {
+        return m_buf;
+    }
+
+    //------------------------------------------------------------------------
+    unsigned pixel_map::width() const
+    {
+        return m_bmp->bmiHeader.biWidth;
+    }
+
+    //------------------------------------------------------------------------
+    unsigned pixel_map::height() const
+    {
+        return m_bmp->bmiHeader.biHeight;
+    }
+
+    //------------------------------------------------------------------------
+    int pixel_map::stride() const
+    {
+        return calc_row_len(m_bmp->bmiHeader.biWidth, 
+                            m_bmp->bmiHeader.biBitCount);
+    }
+
+
+    //private
+    //------------------------------------------------------------------------
+    void pixel_map::create_from_bmp(BITMAPINFO *bmp)
+    {
+        if(bmp)
+        {
+            m_img_size  = calc_row_len(bmp->bmiHeader.biWidth, 
+                                       bmp->bmiHeader.biBitCount) * 
+                          bmp->bmiHeader.biHeight;
+
+            m_full_size = calc_full_size(bmp);
+            m_bmp       = bmp;
+            m_buf       = calc_img_ptr(bmp);
+        }
+    }
+
+
+    //private
+    //------------------------------------------------------------------------
+    HBITMAP pixel_map::create_dib_section_from_args(HDC h_dc,
+                                                    unsigned width, 
+                                                    unsigned height, 
+                                                    unsigned bits_per_pixel)
+    {
+        unsigned line_len  = calc_row_len(width, bits_per_pixel);
+        unsigned img_size  = line_len * height;
+        unsigned rgb_size  = calc_palette_size(0, bits_per_pixel) * sizeof(RGBQUAD);
+        unsigned full_size = sizeof(BITMAPINFOHEADER) + rgb_size;
+        
+        BITMAPINFO *bmp = (BITMAPINFO *) new unsigned char[full_size];
+        
+        bmp->bmiHeader.biSize   = sizeof(BITMAPINFOHEADER);
+        bmp->bmiHeader.biWidth  = width;
+        bmp->bmiHeader.biHeight = height;
+        bmp->bmiHeader.biPlanes = 1;
+        bmp->bmiHeader.biBitCount = (unsigned short)bits_per_pixel;
+        bmp->bmiHeader.biCompression = 0;
+        bmp->bmiHeader.biSizeImage = img_size;
+        bmp->bmiHeader.biXPelsPerMeter = 0;
+        bmp->bmiHeader.biYPelsPerMeter = 0;
+        bmp->bmiHeader.biClrUsed = 0;
+        bmp->bmiHeader.biClrImportant = 0;
+        
+        void*   img_ptr  = 0;
+        HBITMAP h_bitmap = ::CreateDIBSection(h_dc, bmp, DIB_RGB_COLORS, &img_ptr, NULL, 0);
+        
+        if(img_ptr)
+        {
+            m_img_size  = calc_row_len(width, bits_per_pixel) * height;
+            m_full_size = 0;
+            m_bmp       = bmp;
+            m_buf       = (unsigned char *) img_ptr;
+        }
+        
+        return h_bitmap;
+    }
+}
+
+
+
-- 
cgit v1.2.3