[Scummvm-cvs-logs] SF.net SVN: scummvm:[38852] scummvm/trunk/engines/sci

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Tue Feb 24 21:39:34 CET 2009


Revision: 38852
          http://scummvm.svn.sourceforge.net/scummvm/?rev=38852&view=rev
Author:   fingolfin
Date:     2009-02-24 20:39:34 +0000 (Tue, 24 Feb 2009)

Log Message:
-----------
SCI: Renamed gfx/gfx_operations.h to gfx/operations.h (matching the source file); moved include/sci_widgets.h to gfx/ (matching location of source file); renamed gfx/widgets.cpp to gfx/gfx_widgets.cpp (matching the header)

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/kernel.cpp
    scummvm/trunk/engines/sci/engine/kgraphics.cpp
    scummvm/trunk/engines/sci/engine/kmenu.cpp
    scummvm/trunk/engines/sci/engine/savegame.cfsml
    scummvm/trunk/engines/sci/engine/savegame.cpp
    scummvm/trunk/engines/sci/engine/scriptdebug.cpp
    scummvm/trunk/engines/sci/gfx/gfx_state_internal.h
    scummvm/trunk/engines/sci/gfx/menubar.h
    scummvm/trunk/engines/sci/gfx/operations.cpp
    scummvm/trunk/engines/sci/gfx/sci_widgets.cpp
    scummvm/trunk/engines/sci/module.mk
    scummvm/trunk/engines/sci/scicore/sciconsole.h

Added Paths:
-----------
    scummvm/trunk/engines/sci/gfx/gfx_widgets.cpp
    scummvm/trunk/engines/sci/gfx/operations.h
    scummvm/trunk/engines/sci/gfx/sci_widgets.h

Removed Paths:
-------------
    scummvm/trunk/engines/sci/gfx/gfx_operations.h
    scummvm/trunk/engines/sci/gfx/widgets.cpp
    scummvm/trunk/engines/sci/include/sci_widgets.h

Modified: scummvm/trunk/engines/sci/engine/kernel.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.cpp	2009-02-24 20:33:31 UTC (rev 38851)
+++ scummvm/trunk/engines/sci/engine/kernel.cpp	2009-02-24 20:39:34 UTC (rev 38852)
@@ -39,7 +39,7 @@
 #include "sci/engine/kernel.h"
 #include "sci/include/sciresource.h"
 #include "sci/include/engine.h"
-#include "sci/gfx/gfx_operations.h"
+#include "sci/gfx/operations.h"
 #include "sci/engine/kernel_types.h"
 
 namespace Sci {

Modified: scummvm/trunk/engines/sci/engine/kgraphics.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kgraphics.cpp	2009-02-24 20:33:31 UTC (rev 38851)
+++ scummvm/trunk/engines/sci/engine/kgraphics.cpp	2009-02-24 20:39:34 UTC (rev 38852)
@@ -27,7 +27,7 @@
 
 #include "sci/include/sciresource.h"
 #include "sci/include/engine.h"
-#include "sci/include/sci_widgets.h"
+#include "sci/gfx/sci_widgets.h"
 #include "sci/gfx/gfx_widgets.h"
 #include "sci/engine/sci_graphics.h"
 #include "sci/engine/kernel.h"

Modified: scummvm/trunk/engines/sci/engine/kmenu.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kmenu.cpp	2009-02-24 20:33:31 UTC (rev 38851)
+++ scummvm/trunk/engines/sci/engine/kmenu.cpp	2009-02-24 20:39:34 UTC (rev 38852)
@@ -25,7 +25,7 @@
 
 #include "sci/include/sciresource.h"
 #include "sci/include/engine.h"
-#include "sci/include/sci_widgets.h"
+#include "sci/gfx/sci_widgets.h"
 #include "sci/gfx/menubar.h"
 #include "sci/engine/kernel.h"
 

Modified: scummvm/trunk/engines/sci/engine/savegame.cfsml
===================================================================
--- scummvm/trunk/engines/sci/engine/savegame.cfsml	2009-02-24 20:33:31 UTC (rev 38851)
+++ scummvm/trunk/engines/sci/engine/savegame.cfsml	2009-02-24 20:39:34 UTC (rev 38852)
@@ -33,7 +33,7 @@
 #include "common/stream.h"
 #include "common/system.h"
 #include "sci/sci_memory.h"
-#include "sci/gfx/gfx_operations.h"
+#include "sci/gfx/operations.h"
 #include "sci/gfx/menubar.h"
 #include "sci/sfx/sfx_engine.h"
 #include "sci/include/engine.h"

Modified: scummvm/trunk/engines/sci/engine/savegame.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/savegame.cpp	2009-02-24 20:33:31 UTC (rev 38851)
+++ scummvm/trunk/engines/sci/engine/savegame.cpp	2009-02-24 20:39:34 UTC (rev 38852)
@@ -33,7 +33,7 @@
 #include "common/stream.h"
 #include "common/system.h"
 #include "sci/sci_memory.h"
-#include "sci/gfx/gfx_operations.h"
+#include "sci/gfx/operations.h"
 #include "sci/gfx/menubar.h"
 #include "sci/sfx/sfx_engine.h"
 #include "sci/include/engine.h"

Modified: scummvm/trunk/engines/sci/engine/scriptdebug.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/scriptdebug.cpp	2009-02-24 20:33:31 UTC (rev 38851)
+++ scummvm/trunk/engines/sci/engine/scriptdebug.cpp	2009-02-24 20:39:34 UTC (rev 38852)
@@ -34,7 +34,7 @@
 #include "sci/engine/kernel.h"
 #include "sci/engine/kernel_types.h"
 #include "sci/include/sci_midi.h"
-#include "sci/include/sci_widgets.h"
+#include "sci/gfx/sci_widgets.h"
 #include "sci/sci.h"
 #include "sci/gfx/gfx_widgets.h"
 

Deleted: scummvm/trunk/engines/sci/gfx/gfx_operations.h
===================================================================
--- scummvm/trunk/engines/sci/gfx/gfx_operations.h	2009-02-24 20:33:31 UTC (rev 38851)
+++ scummvm/trunk/engines/sci/gfx/gfx_operations.h	2009-02-24 20:39:34 UTC (rev 38852)
@@ -1,682 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-/* Graphical operations, called from the widget state manager */
-
-#ifndef SCI_GFX_GFX_OPERATIONS_H
-#define SCI_GFX_GFX_OPERATIONS_H
-
-#include "sci/gfx/gfx_resmgr.h"
-#include "sci/gfx/gfx_tools.h"
-#include "sci/gfx/gfx_options.h"
-#include "sci/gfx/gfx_system.h"
-#include "sci/include/uinput.h"
-
-namespace Sci {
-
-#define GFXOP_NO_POINTER -1
-
-/* Threshold in color index mode to differentiate between visible and non-visible stuff.
-** GFXOP_ALPHA_THRESHOLD itself should be treated as non-visible.
-*/
-#define GFXOP_ALPHA_THRESHOLD 0xff
-
-struct gfx_text_handle_t {
-	char *text; /* Copy of the actual text */
-
-	int lines_nr;
-	int line_height;
-	text_fragment_t *lines; /* Text offsets */
-	gfx_bitmap_font_t *font;
-	gfx_pixmap_t **text_pixmaps;
-
-	int width, height;
-
-	int priority, control;
-	gfx_alignment_t halign, valign;
-};
-
-/* Unless individually stated otherwise, the following applies:
-** All operations herein apply to the standard 320x200 coordinate system.
-** All operations perform clipping relative to state->clip_zone.
-*/
-
-typedef enum {
-	GFX_BOX_SHADE_FLAT,
-	GFX_BOX_SHADE_RIGHT,
-	GFX_BOX_SHADE_LEFT,
-	GFX_BOX_SHADE_DOWN,
-	GFX_BOX_SHADE_UP
-#if 0
-	/* possible with alphaing, but there is no way to check for
-	** alpha capability of gfx_driver->draw_filled_rect() yet
-	*/
-	, GFX_BOX_SHADE_RIGHT_DOWN,
-	GFX_BOX_SHADE_LEFT_DOWN,
-	GFX_BOX_SHADE_RIGHT_UP,
-	GFX_BOX_SHADE_LEFT_UP
-#endif
-} gfx_box_shade_t;
-
-
-struct gfx_dirty_rect_t {
-	rect_t rect;
-	gfx_dirty_rect_t *next;
-};
-
-
-struct gfx_input_event_t {
-	sci_event_t event;
-	gfx_input_event_t *next;
-};
-
-struct gfx_state_t {
-	int version; /* Interpreter version */
-
-	gfx_options_t *options;
-
-	Common::Point pointer_pos; /* Mouse pointer coordinates */
-
-	rect_t clip_zone_unscaled; /* The current UNSCALED clipping zone */
-	rect_t clip_zone; /* The current SCALED clipping zone; a cached scaled version of clip_zone_unscaled */
-
-	gfx_driver_t *driver;
-	gfx_pixmap_color_t *static_palette; /* Null for dynamic palettes */
-	int static_palette_entries;
-
-	int visible_map;
-
-	gfx_resstate_t *resstate; /* Resource state */
-
-	gfx_pixmap_t *priority_map; /* back buffer priority map (unscaled) */
-	gfx_pixmap_t *static_priority_map; /* static buffer priority map (unscaled) */
-	gfx_pixmap_t *control_map; /* back buffer control map (only exists unscaled in the first place) */
-
-
-	int mouse_pointer_visible; /* Whether the pointer is drawn right now */
-	Common::Point old_pointer_draw_pos; /* Mouse pointer draw coordinates */
-	rect_t pointer_bg_zone; /* old-pointer-draw-pos relative zone inside the pointer
-				** pixmap that was drawn  */
-
-	int mouse_pointer_in_hw; /* Current pointer is being handled in hardware */
-
-	gfx_pixmap_t *mouse_pointer; /* Only set when drawing the mouse manually */
-	gfx_pixmap_t *mouse_pointer_bg; /* Background under the pointer */
-
-	int tag_mode; /* Set to 1 after a new pic is drawn and the resource manager
-		      ** has tagged all resources. Reset after the next front buffer
-		      ** update is done, when all resources that are still tagged are
-		      ** flushed.  */
-
-	int disable_dirty; /* Set to 1 to disable dirty rect accounting */
-
-	int pic_nr; /* Number of the current pic */
-	int palette_nr; /* Palette number of the current pic */
-
-	gfx_input_event_t *events;
-
-	gfx_pixmap_t *fullscreen_override; /* An optional override picture which must have unscaled
-					   ** full-screen size, which overrides all other visibility, and
-					   ** which is generally slow */
-
-	gfxr_pic_t *pic, *pic_unscaled; /* The background picture and its unscaled equivalent */
-
-	gfx_dirty_rect_t *dirty_rects; /* Dirty rectangles */
-
-	void *internal_state; /* Internal interpreter information */
-
-};
-
-
-/**************************/
-/* Fundamental operations */
-/**************************/
-
-int gfxop_init_default(gfx_state_t *state, gfx_options_t *options, void *misc_info);
-/* Initializes a graphics mode suggested by the graphics driver
-** Parameters: (gfx_state_ t *) state: The state to initialize in that mode
-**             (gfx_options_t *) options: Rendering options
-**             (void *) misc_info: Additional information for the interpreter
-**                      part of the resource loader
-** Returns   : (int) GFX_OK on success, GFX_FATAL otherwise
-*/
-
-int gfxop_init(gfx_state_t *state, int xfact, int yfact, gfx_color_mode_t bpp,
-	gfx_options_t *options, void *misc_info);
-/* Initializes a custom graphics mode
-** Parameters: (gfx_state_t *) state: The state to initialize
-**             (int x int) xfact, yfact: Horizontal and vertical scale factors
-**             (gfx_color_mode_t) bpp: Bytes per pixel to initialize with, or
-**                                     0 (GFX_COLOR_MODE_AUTO) to auto-detect
-**             (gfx_options_t *) options: Rendering options
-**             (void *) misc_info: Additional information for the interpreter
-**                      part of the resource loader
-** Returns   : (int) GFX_OK on success, GFX_ERROR if that particular mode is
-**                   unavailable, or GFX_FATAL if the graphics driver is unable
-**                   to provide any useful graphics support
-*/
-
-int gfxop_set_parameter(gfx_state_t *state, char *attribute, char *value);
-/* Sets a driver-specific parameter
-** Parameters: (gfx_state_t *) state: The state, encapsulating the driver object to manipulate
-**             (char *) attribute: The attribute to set
-**             (char *) value: The value the attribute should be set to
-** Returns   : (int) GFX_OK on success, GFX_FATAL on fatal error conditions triggered
-**                   by the command
-*/
-
-int gfxop_exit(gfx_state_t *state);
-/* Deinitializes a currently active driver
-** Parameters: (gfx_state_t *) state: The state encapsulating the driver in question
-** Returns   : (int) GFX_OK
-*/
-
-int gfxop_scan_bitmask(gfx_state_t *state, rect_t area, gfx_map_mask_t map);
-/* Calculates a bit mask calculated from some pixels on the specified map
-** Parameters: (gfx_state_t *) state: The state containing the pixels to scan
-**             (rect_t) area: The area to check
-**             (gfx_map_mask_t) map: The GFX_MASKed map(s) to test
-** Returns   : (int) An integer value where, for each 0<=i<=15, bit #i is set
-**             iff there exists a map for which the corresponding bit was set
-**             in the 'map' parameter and for which there exists a pixel within
-**             the specified area so that the pixel's lower 4 bits, interpreted
-**             as an integer value, equal i.
-** (Short version: This is an implementation of "on_control()").
-*/
-
-int gfxop_set_visible_map(gfx_state_t *state, gfx_map_mask_t map);
-/* Sets the currently visible map
-** Parameters: (gfx_state_t *) state: The state to modify
-**             (gfx_map_mask_t) map: The GFX_MASK to set
-** Returns   : (int) GFX_OK, or GFX_ERROR if map was invalid
-** 'visible_map' can be any of GFX_MASK_VISUAL, GFX_MASK_PRIORITY and GFX_MASK_CONTROL; the appropriate
-** map (as far as its contents are known to the graphics subsystem) is then subsequently drawn to the
-** screen at each update. If this is set to anything other than GFX_MASK_VISUAL, slow full-screen updates
-** are performed. Mostly useful for debugging.
-** The screen needs to be updated for the changes to take effect.
-*/
-
-int gfxop_set_clip_zone(gfx_state_t *state, rect_t zone);
-/* Sets a new clipping zone
-** Parameters: (gfx_state_t *) state: The affected state
-**             (rect_t) zone: The new clipping zone
-** Returns   : (int) GFX_OK
-*/
-
-/******************************/
-/* Generic drawing operations */
-/******************************/
-
-int gfxop_draw_line(gfx_state_t *state,
-	Common::Point start, Common::Point end, gfx_color_t color,
-	gfx_line_mode_t line_mode, gfx_line_style_t line_style);
-/* Renders a clipped line to the back buffer
-** Parameters: (gfx_state_t *) state: The state affected
-**             (Common::Point) start: Starting point of the line
-**	       (Common::Point) end: End point of the line
-**             (gfx_color_t) color: The color to use for drawing
-**             (gfx_line_mode_t) line_mode: Any valid line mode to use
-**             (gfx_line_style_t) line_style: The line style to use
-** Returns   : (int) GFX_OK or GFX_FATAL
-*/
-
-int gfxop_draw_rectangle(gfx_state_t *state, rect_t rect, gfx_color_t color, gfx_line_mode_t line_mode,
-	gfx_line_style_t line_style);
-/* Draws a non-filled rectangular box to the back buffer
-** Parameters: (gfx_state_t *) state: The affected state
-**             (rect_t) rect: The rectangular area the box is drawn to
-**             (gfx_color_t) color: The color the box is to be drawn in
-**             (gfx_line_mode_t) line_mode: The line mode to use
-**             (gfx_line_style_t) line_style: The line style to use for the box
-** Returns   : (int) GFX_OK or GFX_FATAL
-** Boxes drawn in thin lines will surround the minimal area described by rect.
-*/
-
-int gfxop_draw_box(gfx_state_t *state, rect_t box, gfx_color_t color1, gfx_color_t color2,
-	gfx_box_shade_t shade_type);
-/* Draws a filled box to the back buffer
-** Parameters: (gfx_state_t *) state: The affected state
-**             (rect_t) box: The area to draw to
-**             (gfx_color_t) color1: The primary color to use for drawing
-**             (gfx_color_t) color2: The secondary color to draw in
-**             (gfx_box_shade_t) shade_type: The shading system to use
-**                               (e.g. GFX_BOX_SHADE_FLAT)
-** Returns   : (int) GFX_OK or GFX_FATAL
-** The draw mask, control, and priority values are derived from color1.
-*/
-
-int gfxop_fill_box(gfx_state_t *state, rect_t box, gfx_color_t color);
-/* Fills a box in the back buffer with a specific color
-** Parameters: (gfx_state_t *) state: The state to draw to
-**             (rect_t) box: The box to fill
-**             (gfx_color_t) color: The color to use for filling
-** Returns   : (int) GFX_OK or GFX_FATAL
-** This is a simple wrapper function for gfxop_draw_box
-*/
-
-int gfxop_clear_box(gfx_state_t *state, rect_t box);
-/* Copies a box from the static buffer to the back buffer
-** Parameters: (gfx_state_t *) state: The affected state
-**             (rect_t) box: The box to propagate from the static buffer
-** Returns   : (int) GFX_OK or GFX_FATAL
-*/
-
-
-int gfxop_update(gfx_state_t *state);
-/* Updates all dirty rectangles
-** Parameters: (gfx_state_t) *state: The relevant state
-** Returns   : (int) GFX_OK or GFX_FATAL if reported by the driver
-** In order to track dirty rectangles, they must be enabled in the options.
-** This function instructs the resource manager to free all tagged data
-** on certain occasions (see gfxop_new_pic).
-*/
-
-
-int gfxop_update_box(gfx_state_t *state, rect_t box);
-/* Propagates a box from the back buffer to the front (visible) buffer
-** Parameters: (gfx_state_t *) state: The affected state
-**             (rect_t) box: The box to propagate to the front buffer
-** Returns   : (int) GFX_OK or GFX_FATAL
-** This function instructs the resource manager to free all tagged data
-** on certain occasions (see gfxop_new_pic).
-** When called with dirty rectangle management enabled, it will automatically
-** propagate all dirty rectangles as well, UNLESS dirty frame accounting has
-** been disabled explicitly.
-*/
-
-int gfxop_enable_dirty_frames(gfx_state_t *state);
-/* Enables dirty frame accounting
-** Parameters: (gfx_state_t *) state: The state dirty frame accounting is to be enabled in
-** Returns   : (int) GFX_OK or GFX_ERROR if state was invalid
-** Dirty frame accounting is enabled by default.
-*/
-
-int gfxop_disable_dirty_frames(gfx_state_t *state);
-/* Disables dirty frame accounting
-** Parameters: (gfx_state_t *) state: The state dirty frame accounting is to be disabled in
-** Returns   : (int) GFX_OK or GFX_ERROR if state was invalid
-*/
-
-
-/********************/
-/* Color operations */
-/********************/
-
-int gfxop_set_color(gfx_state_t *state, gfx_color_t *color, int r, int g, int b, int a,
-	int priority, int control);
-/* Maps an r/g/b value to a color and sets a gfx_color_t structure
-** Parameters: (gfx_state_t *) state: The current state
-**             (gfx_color_t *) color: Pointer to the structure to write to
-**             (int x int x int) r,g,b: The red/green/blue color intensity values
-**                               of the result color (0x00 (minimum) to 0xff (max))
-**                               If any of these values is less than zero, the
-**                               resulting color will not affect the visual map when
-**                               used for drawing
-**             (int) a: The alpha (transparency) value, with 0x00 meaning absolutely
-**                      opaque and 0xff meaning fully transparent. Alpha blending support
-**                      is optional for drivers, so these are the only two values that
-**                      are guaranteed to work as intended. Any value in between them
-**                      must guarantee the following opaqueness:
-**                      opaqueness(x-1) >= opaqueness(x) >= opaqueness (x+1)
-**                      (i.e. ([0,255], less-transparent-than) must define a partial order)
-**             (int) priority: The priority to use for drawing, or -1 for none
-**             (int) control: The control to use for drawing, or -1 to disable drawing to the
-**                            control map
-** Returns   : (int) GFX_OK or GFX_ERROR if state is invalid
-** In palette mode, this may allocate a new color. Use gfxop_free_color() described below to
-** free that color.
-*/
-
-int gfxop_set_system_color(gfx_state_t *state, gfx_color_t *color);
-/* Designates a color as a 'system color'
-** Parameters: (gfx_state_t *) state: The affected state
-**             (gfx_color_t *) color: The color to designate as a system color
-** Returns   : (int) GFX_OK or GFX_ERROR if state is invalid
-** System colors are permanent colors that cannot be deallocated. As such, they must be used
-** with caution.
-*/
-
-int gfxop_free_color(gfx_state_t *state, gfx_color_t *color);
-/* Frees a color allocated by gfxop_set_color()
-** Parmaeters: (gfx_state_t *) state: The state affected
-**             (gfx_color_t *) color: The color to de-allocate
-** Returns   : (int) GFX_OK or GFX_ERROR if state is invalid
-** This function is a no-op in non-index mode, or if color is a system color.
-*/
-
-
-/**********************/
-/* Pointer and IO ops */
-/**********************/
-
-int gfxop_usleep(gfx_state_t *state, long usecs);
-/* Suspends program execution for the specified amount of microseconds
-** Parameters: (gfx_state_t *) state: The state affected
-**             (long) usecs: The amount of microseconds to wait
-** Returns   : (int) GFX_OK or GFX_ERROR
-** The mouse pointer will be redrawn continually, if applicable
-*/
-
-int gfxop_set_pointer_cursor(gfx_state_t *state, int nr);
-/* Sets the mouse pointer to a cursor resource
-** Parameters: (gfx_state_t *) state: The affected state
-**             (int) nr: Number of the cursor resource to use
-** Returns   : (int) GFX_OK, GFX_ERROR if the resource did not
-**                   exist and was not GFXOP_NO_POINTER, or GFX_FATAL on
-**                   fatal error conditions.
-** Use nr = GFX_NO_POINTER to disable the mouse pointer (default).
-*/
-
-int gfxop_set_pointer_view(gfx_state_t *state, int nr, int loop, int cel, Common::Point *hotspot);
-/* Sets the mouse pointer to a view resource
-** Parameters: (gfx_state_t *) state: The affected state
-**             (int) nr: Number of the view resource to use
-**             (int) loop: View loop to use
-**             (int) cel: View cel to use
-**             (Common::Point *) hotspot: Manually set hotspot to use, or NULL for default.
-** Returns   : (int) GFX_OK or GFX_FATAL
-** Use gfxop_set_pointer_cursor(state, GFXOP_NO_POINTER) to disable the
-** pointer.
-*/
-
-int gfxop_set_pointer_position(gfx_state_t *state, Common::Point pos);
-/* Teleports the mouse pointer to a specific position
-** Parameters: (gfx_state_t *) state: The state the pointer is in
-**             (Common::Point) pos: The position to teleport it to
-** Returns   : (int) Any error code or GFX_OK
-** Depending on the graphics driver, this operation may be without
-** any effect
-*/
-
-sci_event_t gfxop_get_event(gfx_state_t *state, unsigned int mask);
-/* Retreives the next input event from the driver
-** Parameters: (gfx_state_t *) state: The affected state
-**             (int) mask: The event mask to poll from (see uinput.h)
-** Returns   : (sci_event_t) The next event in the driver's event queue, or
-**             a NONE event if no event matching the mask was found.
-*/
-
-
-/*******************/
-/* View operations */
-/*******************/
-
-int gfxop_lookup_view_get_loops(gfx_state_t *state, int nr);
-/* Determines the number of loops associated with a view
-** Parameters: (gfx_state_t *) state: The state to use
-**             (int) nr: Number of the view to investigate
-** Returns   : (int) The number of loops, or GFX_ERROR if the view didn't exist
-*/
-
-int gfxop_lookup_view_get_cels(gfx_state_t *state, int nr, int loop);
-/* Determines the number of cels associated stored in a loop
-** Parameters: (gfx_state_t *) state: The state to look up in
-**             (int) nr: Number of the view to look up in
-**             (int) loop: Number of the loop the number of cels of
-**                         are to  be investigated
-** Returns   : (int) The number of cels in that loop, or GFX_ERROR if either
-**                   the view or the loop didn't exist
-*/
-
-int gfxop_check_cel(gfx_state_t *state, int nr, int *loop, int *cel);
-/* Clips the view/loop/cel position of a cel
-** Parameters: (gfx_state_t *) state: The state to use
-**             (int) nr: Number of the view to use
-**             (int *) loop: Pointer to the variable storing the loop
-**                           number to verify
-**             (int *) cel: Pointer to the variable storing the cel
-**                          number to check
-** Returns   : (int) GFX_OK or GFX_ERROR if the view didn't exist
-** *loop is clipped first, then *cel. The resulting setup will be a valid
-** view configuration.
-*/
-
-int gfxop_overflow_cel(gfx_state_t *state, int nr, int *loop, int *cel);
-/* Resets loop/cel values to zero if they have become invalid
-** Parameters: (gfx_state_t *) state: The state to use
-**             (int) nr: Number of the view to use
-**             (int *) loop: Pointer to the variable storing the loop
-**                           number to verify
-**             (int *) cel: Pointer to the variable storing the cel
-**                          number to check
-** Returns   : (int) GFX_OK or GFX_ERROR if the view didn't exist
-** *loop is clipped first, then *cel. The resulting setup will be a valid
-** view configuration.
-*/
-
-int gfxop_get_cel_parameters(gfx_state_t *state, int nr, int loop, int cel,
-	int *width, int *height, Common::Point *offset);
-/* Retreives the width and height of a cel
-** Parameters: (gfx_state_t *) state: The state to use
-**             (int) nr: Number of the view
-**             (int) loop: Loop number to examine
-**             (int) cel: The cel (inside the loop) to look up
-**             (int *) width: The variable the width will be stored in
-**             (int *) height: The variable the height will be stored in
-**             (Common::Point *) offset: The variable the cel's x/y offset will be stored in
-** Returns   : (int) GFX_OK if the lookup succeeded, GFX_ERROR if the nr/loop/cel
-**             combination was invalid
-*/
-
-int gfxop_draw_cel(gfx_state_t *state, int nr, int loop, int cel, Common::Point pos,
-	gfx_color_t color, int palette);
-/* Draws (part of) a cel to the back buffer
-** Parameters: (gfx_state_t *) state: The state encapsulating the driver to draw with
-**             (int) nr: Number of the view to draw
-**             (int) loop: Loop of the cel to draw
-**             (int) cel: The cel number of the cel to draw
-**             (Common::Point) pos: The positino the cel is to be drawn to
-**             (gfx_color_t color): The priority and control values to use for drawing
-**	       (int) palette: The palette to use
-** Returns   : (int) GFX_OK or GFX_FATAL
-*/
-
-
-int gfxop_draw_cel_static(gfx_state_t *state, int nr, int loop, int cel, Common::Point pos,
-	gfx_color_t color, int palette);
-/* Draws a cel to the static buffer; no clipping is performed
-** Parameters: (gfx_state_t *) state: The state encapsulating the driver to draw with
-**             (int) nr: Number of the view to draw
-**             (int) loop: Loop of the cel to draw
-**             (int) cel: The cel number of the cel to draw
-**             (Common::Point) pos: The positino the cel is to be drawn to
-**             (gfx_color_t color): The priority and control values to use for drawing
-**	       (int) palette: The palette to use
-** Returns   : (int) GFX_OK or GFX_FATAL
-** Let me repeat, no clipping (except for the display borders) is performed.
-*/
-
-
-int gfxop_draw_cel_static_clipped(gfx_state_t *state, int nr, int loop, int cel, Common::Point pos,
-	gfx_color_t color, int palette);
-/* Draws (part of) a clipped cel to the static buffer
-** Parameters: (gfx_state_t *) state: The state encapsulating the driver to draw with
-**             (int) nr: Number of the view to draw
-**             (int) loop: Loop of the cel to draw
-**             (int) cel: The cel number of the cel to draw
-**             (Common::Point) pos: The positino the cel is to be drawn to
-**             (gfx_color_t color): The priority and control values to use for drawing
-**	       (int) palette: The palette to use
-** Returns   : (int) GFX_OK or GFX_FATAL
-** This function does clip.
-*/
-
-
-/******************/
-/* Pic operations */
-/******************/
-/* These operations are exempt from clipping */
-
-int gfxop_new_pic(gfx_state_t *state, int nr, int flags, int default_palette);
-/* Draws a pic and writes it over the static buffer
-** Parameters: (gfx_state_t *) state: The state affected
-**             (int) nr: Number of the pic to draw
-**             (int) flags: Interpreter-dependant flags to use for drawing
-**             (int) default_palette: The default palette for drawing
-** Returns   : (int) GFX_OK or GFX_FATAL
-** This function instructs the resource manager to tag all data as "unused".
-** See the resource manager tag functions for a full description.
-*/
-
-void *gfxop_get_pic_metainfo(gfx_state_t *state);
-/* Retreives all meta-information assigned to the current pic
-** Parameters: (gfx_state_t *) state: The state affected
-** Returns   : (void *) NULL if the pic doesn't exist or has no meta-information,
-**             the meta-info otherwise
-** This meta-information is referred to as 'internal data' in the pic code
-*/
-
-int gfxop_add_to_pic(gfx_state_t *state, int nr, int flags, int default_palette);
-/* Adds a pic to the static buffer
-** Parameters: (gfx_state_t *) state: The state affected
-**             (int) nr: Number of the pic to add
-**             (int) flags: Interpreter-dependant flags to use for drawing
-**             (int) default_palette: The default palette for drawing
-** Returns   : (int) GFX_OK or GFX_FATAL
-*/
-
-
-
-
-/*******************/
-/* Text operations */
-/*******************/
-
-
-int gfxop_get_font_height(gfx_state_t *state, int font_nr);
-/* Returns the fixed line height for one specified font
-** Parameters: (gfx_state_t *) state: The state to work on
-**             (int) font_nr: Number of the font to inspect
-** Returns   : (int) GFX_ERROR, GFX_FATAL, or the font line height
-*/
-
-int gfxop_get_text_params(gfx_state_t *state, int font_nr, const char *text,
-	int maxwidth, int *width, int *height, int flags,
-	int *lines_nr, int *lineheight, int *lastline_width);
-/* Calculates the width and height of a specified text in a specified font
-** Parameters: (gfx_state_t *) state: The state to use
-**             (int) font_nr: Font number to use for the calculation
-**             (const char *) text: The text to examine
-**             (int) flags: ORred GFXR_FONT_FLAGs
-**             (int) maxwidth: The maximum pixel width to allow for the text
-** Returns   : (int) GFX_OK or GFX_ERROR if the font didn't exist
-**             (int) *width: The resulting width
-**             (int) *height: The resulting height
-**             (int) *lines_nr: Number of lines used in the text
-**             (int) *lineheight: Pixel height (SCI scale) of each text line
-**             (int) *lastline_wdith: Pixel offset (SCI scale) of the space
-**                   after the last character in the last line
-*/
-
-gfx_text_handle_t *gfxop_new_text(gfx_state_t *state, int font_nr, char *text, int maxwidth,
-	gfx_alignment_t halign, gfx_alignment_t valign, gfx_color_t color1,
-	gfx_color_t color2, gfx_color_t bg_color, int flags);
-/* Generates a new text handle that can be used to draw any text
-** Parameters: (gfx_state_t *) state: The state to use
-**             (int) font_nr: Font number to use for the calculation
-**             (char *) text: The text to examine
-**             (int) maxwidth: The maximum pixel width to allow for the text
-**             (gfx_alignment_t) halign: The horizontal text alignment
-**             (gfx_alignment_t) valign: The vertical text alignment
-**             (gfx_color_t x gfx_color_t) color1, color2: The text's foreground colors
-**                                         (the function will dither between those two)
-**             (gfx_color_t) bg_color: The background color
-**             (int) flags: ORred GFXR_FONT_FLAGs
-** Returns   : (gfx_text_handle_t *) A newly allocated gfx_text_handle_t, or
-**             NULL if font_nr was invalid
-** The control and priority values for the text will be extracted from color1.
-** Note that the colors must have been allocated properly, or the text may display in
-** incorrect colors.
-*/
-
-int gfxop_free_text(gfx_state_t *state, gfx_text_handle_t *handle);
-/* Frees a previously allocated text handle and all related resources
-** Parameters: (gfx_state_t *) state: The state to use
-**             (gfx_text_handle_t *) handle: The handle to free
-** Returns   : (int) GFX_OK
-*/
-
-int gfxop_draw_text(gfx_state_t *state, gfx_text_handle_t *handle, rect_t zone);
-/* Draws text stored in a text handle
-** Parameters: (gfx_state_t *) state: The target state
-**             (gfx_text_handle_t *) handle: The text handle to use for drawing
-**             (rect_t) zone: The rectangular box to draw to. In combination with
-**                            halign and valign, this defines where the text is
-**                            drawn to.
-** Returns   : (int) GFX_OK or GFX_FATAL
-*/
-
-
-/****************************/
-/* Manual pixmap operations */
-/****************************/
-
-gfx_pixmap_t *gfxop_grab_pixmap(gfx_state_t *state, rect_t area);
-/* Grabs a screen section from the back buffer and stores it in a pixmap
-** Parameters: (gfx_state_t *) state: The affected state
-**             (rect_t) area: The area to grab
-** Returns   : (gfx_pixmap_t *) A result pixmap, or NULL on error
-** Obviously, this only affects the visual map
-*/
-
-int gfxop_draw_pixmap(gfx_state_t *state, gfx_pixmap_t *pxm, rect_t zone, Common::Point pos);
-/* Draws part of a pixmap to the screen
-** Parameters: (gfx_state_t *) state: The affected state
-**             (gfx_pixmap_t *) pxm: The pixmap to draw
-**             (rect_t) zone: The segment of the pixmap to draw
-**             (Common::Point) pos: The position the pixmap should be drawn to
-** Returns   : (int) GFX_OK or any error code
-*/
-
-int gfxop_free_pixmap(gfx_state_t *state, gfx_pixmap_t *pxm);
-/* Frees a pixmap returned by gfxop_grab_pixmap()
-** Parameters: (gfx_state_t *) state: The affected state
-**             (gfx_pixmap_t *) pxm: The pixmap to free
-** Returns   : (int) GFX_OK, or GFX_ERROR if the state was invalid
-*/
-
-/******************************/
-/* Dirty rectangle operations */
-/******************************/
-
-gfx_dirty_rect_t *gfxdr_add_dirty(gfx_dirty_rect_t *base, rect_t box, int strategy);
-/* Adds a dirty rectangle to 'base' according to a strategy
-** Parameters: (gfx_dirty_rect_t *) base: The base rectangle to add to, or NULL
-**             (rect_t) box: The dirty frame to add
-**             (int) strategy: The dirty frame heuristic to use (see gfx_options.h)
-** Returns   : (gfx_dirty_rect_t *) an appropriate singly-linked dirty rectangle
-**                                  result cluster
-*/
-
-int _gfxop_clip(rect_t *rect, rect_t clipzone);
-/* Clips a rectangle against another one
-** Parameters: (rect_t *) rect: The rectangle to clip
-**             (rect_t) clipzone: The outer bounds rect must be in
-** Reuturns  : (int) 1 if rect is empty now, 0 otherwise
-*/
-
-} // End of namespace Sci
-
-#endif // SCI_GFX_GFX_OPERATIONS_H

Modified: scummvm/trunk/engines/sci/gfx/gfx_state_internal.h
===================================================================
--- scummvm/trunk/engines/sci/gfx/gfx_state_internal.h	2009-02-24 20:33:31 UTC (rev 38851)
+++ scummvm/trunk/engines/sci/gfx/gfx_state_internal.h	2009-02-24 20:39:34 UTC (rev 38852)
@@ -28,7 +28,7 @@
 
 #include "sci/gfx/gfx_tools.h"
 #include "sci/gfx/gfx_options.h"
-#include "sci/gfx/gfx_operations.h"
+#include "sci/gfx/operations.h"
 #include "sci/gfx/gfx_resmgr.h"
 #include "sci/gfx/gfx_system.h"
 

Copied: scummvm/trunk/engines/sci/gfx/gfx_widgets.cpp (from rev 38850, scummvm/trunk/engines/sci/gfx/widgets.cpp)
===================================================================
--- scummvm/trunk/engines/sci/gfx/gfx_widgets.cpp	                        (rev 0)
+++ scummvm/trunk/engines/sci/gfx/gfx_widgets.cpp	2009-02-24 20:39:34 UTC (rev 38852)
@@ -0,0 +1,2154 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "sci/sci_memory.h"
+#include "sci/gfx/gfx_widgets.h"
+
+namespace Sci {
+
+#undef GFXW_DEBUG_DIRTY // Enable to debug dirty rectangle propagation (writes to stderr)
+
+#ifdef GFXW_DEBUG_DIRTY
+#  define DDIRTY fprintf(stderr, "%s:%5d| ", __FILE__, __LINE__); fprintf
+#else
+#  define DDIRTY if (0) fprintf
+#endif
+
+Common::Point gfxw_point_zero(0, 0);
+
+#define MAX_SERIAL_NUMBER 0x7fffffff
+static int widget_serial_number_counter = 0x10000; // Avoid confusion with IDs
+
+#ifdef GFXW_DEBUG_WIDGETS
+
+gfxw_widget_t *debug_widgets[GFXW_DEBUG_WIDGETS];
+int debug_widget_pos = 0;
+
+static void _gfxw_debug_add_widget(gfxw_widget_t *widget) {
+	if (debug_widget_pos == GFXW_DEBUG_WIDGETS) {
+		GFXERROR("WIDGET DEBUG: Allocated the maximum number of %d widgets- Aborting!\n", GFXW_DEBUG_WIDGETS);
+		BREAKPOINT();
+	}
+	debug_widgets[debug_widget_pos++] = widget;
+}
+
+static void _gfxw_debug_remove_widget(gfxw_widget_t *widget) {
+	int i;
+	int found = 0;
+	for (i = 0; i < debug_widget_pos; i++) {
+		if (debug_widgets[i] == widget) {
+			memmove(debug_widgets + i, debug_widgets + i + 1, (sizeof(gfxw_widget_t *)) * (debug_widget_pos - i - 1));
+			debug_widgets[debug_widget_pos--] = NULL;
+			found++;
+		}
+	}
+
+	if (found > 1) {
+		GFXERROR("While removing widget: Found it %d times!\n", found);
+		BREAKPOINT();
+	}
+
+	if (found == 0) {
+		GFXERROR("Attempted removal of unregistered widget!\n");
+		BREAKPOINT();
+	}
+}
+#else // !GFXW_DEBUG_WIDGETS
+#define _gfxw_debug_add_widget(a)
+#define _gfxw_debug_remove_widget(a)
+#endif
+
+
+static inline void indent(int indentation) {
+	int i;
+	for (i = 0; i < indentation; i++)
+		sciprintf("    ");
+}
+
+static void _gfxw_print_widget(gfxw_widget_t *widget, int indentation) {
+	unsigned int i;
+	char flags_list[] = "VOCDTMI";
+
+	indent(indentation);
+
+	if (widget->magic == GFXW_MAGIC_VALID) {
+		if (widget->visual)
+			sciprintf("v ");
+		else
+			sciprintf("NoVis ");
+	} else if (widget->magic == GFXW_MAGIC_INVALID)
+		sciprintf("INVALID ");
+
+	sciprintf("S%08x", widget->serial);
+
+	if (widget->ID != GFXW_NO_ID) {
+		sciprintf("#%x", widget->ID);
+
+		if (widget->subID != GFXW_NO_ID)
+			sciprintf(":%x ", widget->subID);
+		else
+			sciprintf(" ");
+	}
+
+	sciprintf("[(%d,%d)(%dx%d)]", widget->bounds.x, widget->bounds.y, widget->bounds.xl, widget->bounds.yl);
+
+	for (i = 0; i < strlen(flags_list); i++)
+		if (widget->flags & (1 << i))
+			sciprintf("%c", flags_list[i]);
+
+	sciprintf(" ");
+}
+
+static int _gfxwop_print_empty(gfxw_widget_t *widget, int indentation) {
+	_gfxw_print_widget(widget, indentation);
+	sciprintf("<untyped #%d>", widget->type);
+
+	return 0;
+}
+
+gfxw_widget_t * _gfxw_new_widget(int size, gfxw_widget_type_t type) {
+	gfxw_widget_t *widget = (gfxw_widget_t*)sci_malloc(size);
+#ifdef SATISFY_PURIFY
+	memset(widget, 0, size);
+#endif
+
+	widget->magic = GFXW_MAGIC_VALID;
+	widget->parent = NULL;
+	widget->visual = NULL;
+	widget->next = NULL;
+	widget->type = type;
+	widget->bounds = gfx_rect(0, 0, 0, 0);
+	widget->flags = GFXW_FLAG_DIRTY;
+	widget->ID = GFXW_NO_ID;
+	widget->subID = GFXW_NO_ID;
+	widget->serial = widget_serial_number_counter++;
+	widget->widget_priority = -1;
+
+	widget_serial_number_counter &= MAX_SERIAL_NUMBER;
+
+	widget->draw = NULL;
+	widget->widfree = NULL;
+	widget->tag = NULL;
+	widget->print = _gfxwop_print_empty;
+	widget->should_replace = NULL;
+	widget->compare_to = widget->equals = widget->superarea_of = NULL;
+
+	_gfxw_debug_add_widget(widget);
+
+	return widget;
+}
+
+static inline int verify_widget(gfxw_widget_t *widget) {
+	if (!widget) {
+		GFXERROR("Attempt to use NULL widget\n");
+#ifdef GFXW_DEBUG_WIDGETS
+		BREAKPOINT();
+#endif
+		return 1;
+	} else if (widget->magic != GFXW_MAGIC_VALID) {
+		if (widget->magic == GFXW_MAGIC_INVALID) {
+			GFXERROR("Attempt to use invalidated widget\n");
+		} else {
+			GFXERROR("Attempt to use non-widget\n");
+		}
+#ifdef GFXW_DEBUG_WIDGETS
+		BREAKPOINT();
+#endif
+		return 1;
+	}
+	return 0;
+}
+
+#define VERIFY_WIDGET(w) \
+	if (verify_widget((gfxw_widget_t *)(w))) { GFXERROR("Error occured while validating widget\n"); }
+
+static void _gfxw_unallocate_widget(gfx_state_t *state, gfxw_widget_t *widget) {
+	if (GFXW_IS_TEXT(widget)) {
+		gfxw_text_t *text = (gfxw_text_t *) widget;
+
+		if (text->text_handle) {
+			if (!state) {
+				GFXERROR("Attempt to free text without supplying mode to free it from!\n");
+				BREAKPOINT();
+			} else {
+				gfxop_free_text(state, text->text_handle);
+				text->text_handle = NULL;
+			}
+		}
+	}
+
+	widget->magic = GFXW_MAGIC_INVALID;
+	free(widget);
+	_gfxw_debug_remove_widget(widget);
+}
+
+#define GFX_ASSERT(_x) \
+{ \
+	int retval = (_x); \
+	if (retval == GFX_ERROR) { \
+		GFXERROR("Error occured while drawing widget!\n"); \
+		return 1; \
+	} else if (retval == GFX_FATAL) { \
+		error("Fatal error occured while drawing widget!\nGraphics state invalid; aborting program..."); \
+	} \
+}
+
+//********** Widgets *************
+
+// Base class operations and common stuff
+
+// Assertion for drawing
+#define DRAW_ASSERT(widget, exp_type) \
+	if (!(widget)) { \
+		sciprintf("L%d: NULL widget", __LINE__); \
+		return 1; \
+	} \
+	if (!(widget)->print) { \
+		sciprintf("L%d: Widget of type %d does not have print function", __LINE__, (widget)->type); \
+	} \
+	if ((widget)->type != (exp_type)) { \
+		sciprintf("L%d: Error in widget: Expected type " # exp_type "(%d) but got %d\n", __LINE__, exp_type, (widget)->type); \
+		sciprintf("Erroneous widget: "); \
+		widget->print(widget, 4); \
+		sciprintf("\n"); \
+		return 1; \
+	} \
+	if (!(widget->flags & GFXW_FLAG_VISIBLE)) \
+		return 0; \
+	if (!(widget->type == GFXW_VISUAL || widget->visual)) { \
+		sciprintf("L%d: Error while drawing widget: Widget has no visual\n", __LINE__); \
+		sciprintf("Erroneous widget: "); \
+		widget->print(widget, 1); \
+		sciprintf("\n"); \
+		return 1; \
+	}
+
+static inline int _color_equals(gfx_color_t a, gfx_color_t b) {
+	if (a.mask != b.mask)
+		return 0;
+
+	if (a.mask & GFX_MASK_VISUAL) {
+		if (a.visual.r != b.visual.r || a.visual.g != b.visual.g || a.visual.b != b.visual.b || a.alpha != b.alpha)
+			return 0;
+	}
+
+	if (a.mask & GFX_MASK_PRIORITY)
+		if (a.priority != b.priority)
+			return 0;
+
+	if (a.mask & GFX_MASK_CONTROL)
+		if (a.control != b.control)
+			return 0;
+
+	return 1;
+}
+
+static int _gfxwop_basic_set_visual(gfxw_widget_t *widget, gfxw_visual_t *visual) {
+	widget->visual = visual;
+
+	if (widget->parent) {
+		DDIRTY(stderr, "basic_set_visual: DOWNWARDS rel(%d,%d,%d,%d, 1)\n", GFX_PRINT_RECT(widget->bounds));
+		widget->parent->add_dirty_rel(widget->parent, widget->bounds, 1);
+	}
+
+	return 0;
+}
+
+static int _gfxwop_basic_should_replace(gfxw_widget_t *widget, gfxw_widget_t *other) {
+	return 0;
+}
+
+static inline void _gfxw_set_ops(gfxw_widget_t *widget, gfxw_point_op *draw, gfxw_op *free, gfxw_op *tag, gfxw_op_int *print,
+	gfxw_bin_op *compare_to, gfxw_bin_op *equals, gfxw_bin_op *superarea_of) {
+	widget->draw = draw;
+	widget->widfree = free;
+	widget->tag = tag;
+	widget->print = print;
+	widget->compare_to = compare_to;
+	widget->equals = equals;
+	widget->superarea_of = superarea_of;
+
+	widget->should_replace = _gfxwop_basic_should_replace;
+	widget->set_visual = _gfxwop_basic_set_visual;
+}
+
+void gfxw_remove_widget_from_container(gfxw_container_t *container, gfxw_widget_t *widget) {
+	gfxw_widget_t **seekerp;
+
+	if (!container) {
+		GFXERROR("Attempt to remove widget from NULL container!\n");
+		BREAKPOINT();
+	}
+
+	seekerp = &(container->contents);
+
+	if (GFXW_IS_LIST(widget) && GFXW_IS_PORT(container)) {
+		gfxw_port_t *port = (gfxw_port_t *) container;
+		if (port->decorations == (gfxw_list_t *) widget) {
+			port->decorations = NULL;
+			return;
+		}
+	}
+
+	while (*seekerp && *seekerp != widget)
+		seekerp = &((*seekerp)->next);
+
+	if (!*seekerp) {
+		GFXERROR("Internal error: Attempt to remove widget from container it was not contained in!\n");
+		sciprintf("Widget:");
+		widget->print(GFXW(widget), 1);
+		sciprintf("Container:");
+		widget->print(GFXW(container), 1);
+		BREAKPOINT();
+		return;
+	}
+
+	if (container->nextpp == &(widget->next))
+		container->nextpp = seekerp;
+
+	*seekerp = widget->next; // Remove it
+	widget->parent = NULL;
+	widget->next = NULL;
+}
+
+static int _gfxwop_basic_free(gfxw_widget_t *widget) {
+	gfxw_visual_t *visual = widget->visual;
+	gfx_state_t *state = (visual) ? visual->gfx_state : NULL;
+
+	DDIRTY(stderr, "BASIC-FREE: SomeAddDirty\n");
+
+	if (widget->parent) {
+		if (GFXW_IS_CONTAINER(widget))
+			widget->parent->add_dirty_abs(widget->parent, widget->bounds, 1);
+		else
+			widget->parent->add_dirty_rel(widget->parent, widget->bounds, 1);
+
+		gfxw_remove_widget_from_container(widget->parent, widget);
+	}
+
+	_gfxw_unallocate_widget(state, widget);
+
+	return 0;
+}
+
+static int _gfxwop_basic_tag(gfxw_widget_t *widget) {
+	widget->flags |= GFXW_FLAG_TAGGED;
+
+	return 0;
+}
+
+static int _gfxwop_basic_compare_to(gfxw_widget_t *widget, gfxw_widget_t *other) {
+	return 1;
+}
+
+static int _gfxwop_basic_equals(gfxw_widget_t *widget, gfxw_widget_t *other) {
+	return 0;
+}
+
+static int _gfxwop_basic_superarea_of(gfxw_widget_t *widget, gfxw_widget_t *other) {
+	return (widget == other);
+}
+
+//*** Boxes ***
+
+static inline rect_t _move_rect(rect_t rect, Common::Point point) {
+	return gfx_rect(rect.x + point.x, rect.y + point.y, rect.xl, rect.yl);
+}
+
+static inline void _split_rect(rect_t rect, Common::Point *p1, Common::Point *p2) {
+	p1->x = rect.x;
+	p1->y = rect.y;
+	p2->x = rect.x + rect.xl;
+	p2->y = rect.y + rect.yl;
+}
+
+static inline Common::Point _move_point(rect_t rect, Common::Point point) {
+	return Common::Point(rect.x + point.x, rect.y + point.y);
+}
+
+static int _gfxwop_box_draw(gfxw_widget_t *widget, Common::Point pos) {
+	gfxw_box_t *box = (gfxw_box_t *) widget;
+	DRAW_ASSERT(widget, GFXW_BOX);
+	GFX_ASSERT(gfxop_draw_box(box->visual->gfx_state, _move_rect(box->bounds, pos), box->color1, box->color2, box->shade_type));
+
+	return 0;
+}
+
+static int _gfxwop_box_print(gfxw_widget_t *widget, int indentation) {
+	_gfxw_print_widget(widget, indentation);
+	sciprintf("BOX");
+	return 0;
+}
+
+static int _gfxwop_box_superarea_of(gfxw_widget_t *widget, gfxw_widget_t *other) {
+	gfxw_box_t *box = (gfxw_box_t *) widget;
+
+	if (box->color1.alpha)
+		return 0;
+
+	if (box->shade_type != GFX_BOX_SHADE_FLAT && box->color2.alpha)
+		return 0;
+
+	if (!gfx_rect_subset(other->bounds, box->bounds))
+		return 0;
+
+	return 1;
+}
+
+static int _gfxwop_box_equals(gfxw_widget_t *widget, gfxw_widget_t *other) {
+	gfxw_box_t *wbox = (gfxw_box_t *)widget, *obox;
+	if (other->type != GFXW_BOX)
+		return 0;
+
+	obox = (gfxw_box_t *) other;
+
+	if (!gfx_rect_equals(wbox->bounds, obox->bounds))
+		return 0;
+
+	if (!_color_equals(wbox->color1, obox->color1))
+		return 0;
+
+	if (wbox->shade_type != obox->shade_type)
+		return 0;
+
+	if (wbox->shade_type != GFX_BOX_SHADE_FLAT
+	        && _color_equals(wbox->color2, obox->color2))
+		return 0;
+
+	return 1;
+}
+
+void _gfxw_set_ops_BOX(gfxw_widget_t *widget) {
+	_gfxw_set_ops(GFXW(widget), _gfxwop_box_draw, _gfxwop_basic_free, _gfxwop_basic_tag, _gfxwop_box_print,
+	              _gfxwop_basic_compare_to, _gfxwop_box_equals, _gfxwop_box_superarea_of);
+}
+
+static inline int _gfxw_color_get_priority(gfx_color_t color) {
+	return (color.mask & GFX_MASK_PRIORITY) ? color.priority : -1;
+}
+
+gfxw_box_t *gfxw_new_box(gfx_state_t *state, rect_t area, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type) {
+	gfxw_box_t *widget = (gfxw_box_t *)_gfxw_new_widget(sizeof(gfxw_box_t), GFXW_BOX);
+
+	widget->widget_priority = _gfxw_color_get_priority(color1);
+	widget->bounds = area;
+	widget->color1 = color1;
+	widget->color2 = color2;
+	widget->shade_type = shade_type;
+
+	widget->flags |= GFXW_FLAG_VISIBLE;
+
+	if ((color1.mask & GFX_MASK_VISUAL) && ((state && (state->driver->mode->palette)) || (!color1.alpha && !color2.alpha)))
+		widget->flags |= GFXW_FLAG_OPAQUE;
+
+	_gfxw_set_ops_BOX(GFXW(widget));
+
+	return widget;
+}
+
+static inline gfxw_primitive_t *_gfxw_new_primitive(rect_t area, gfx_color_t color, gfx_line_mode_t mode,
+													gfx_line_style_t style, gfxw_widget_type_t type) {
+	gfxw_primitive_t *widget = (gfxw_primitive_t *)_gfxw_new_widget(sizeof(gfxw_primitive_t), type);
+
+	widget->widget_priority = _gfxw_color_get_priority(color);
+	widget->bounds = area;
+	widget->color = color;
+	widget->line_mode = mode;
+	widget->line_style = style;
+
+	widget->flags |= GFXW_FLAG_VISIBLE;
+	return widget;
+}
+
+//*** Rectangles ***
+
+static int _gfxwop_primitive_equals(gfxw_widget_t *widget, gfxw_widget_t *other) {
+	gfxw_primitive_t *wprim = (gfxw_primitive_t *) widget, *oprim;
+	if (widget->type != other->type)
+		return 0;
+
+	oprim = (gfxw_primitive_t *) other;
+
+	if (!gfx_rect_equals(wprim->bounds, oprim->bounds))
+		return 0;
+
+	if (!_color_equals(wprim->color, oprim->color))
+		return 0;
+
+	if (wprim->line_mode != oprim->line_mode)
+		return 0;
+
+	if (wprim->line_style != oprim->line_style)
+		return 0;
+
+	return 1;
+}
+
+static int _gfxwop_rect_draw(gfxw_widget_t *widget, Common::Point pos) {
+	gfxw_primitive_t *rect = (gfxw_primitive_t *) widget;
+	DRAW_ASSERT(widget, GFXW_RECT);
+
+	GFX_ASSERT(gfxop_draw_rectangle(rect->visual->gfx_state, gfx_rect(rect->bounds.x + pos.x, rect->bounds.y + pos.y,
+	                                         rect->bounds.xl - 1, rect->bounds.yl - 1), rect->color, rect->line_mode, rect->line_style));
+	return 0;
+}
+
+static int _gfxwop_rect_print(gfxw_widget_t *rect, int indentation) {
+	_gfxw_print_widget(GFXW(rect), indentation);
+	sciprintf("RECT");
+
+	return 0;
+}
+
+void _gfxw_set_ops_RECT(gfxw_widget_t *prim) {
+	_gfxw_set_ops(GFXW(prim), _gfxwop_rect_draw, _gfxwop_basic_free, _gfxwop_basic_tag, _gfxwop_rect_print,
+	              _gfxwop_basic_compare_to, _gfxwop_primitive_equals, _gfxwop_basic_superarea_of);
+}
+
+gfxw_primitive_t *gfxw_new_rect(rect_t rect, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style) {
+	gfxw_primitive_t *prim = _gfxw_new_primitive(rect, color, line_mode, line_style, GFXW_RECT);
+	prim->bounds.xl++;
+	prim->bounds.yl++; // Since it is actually one pixel bigger in each direction
+
+	_gfxw_set_ops_RECT(GFXW(prim));
+
+	return prim;
+}
+
+//*** Lines ***
+
+static int _gfxwop_line_draw(gfxw_widget_t *widget, Common::Point pos) {
+	gfxw_primitive_t *line = (gfxw_primitive_t *)widget;
+	rect_t linepos = widget->bounds;
+	Common::Point p1, p2;
+
+	linepos.xl--;
+	linepos.yl--;
+
+	if (widget->type == GFXW_INVERSE_LINE) {
+		linepos.x += linepos.xl;
+		linepos.xl = -linepos.xl;
+	} else {
+		DRAW_ASSERT(widget, GFXW_LINE);
+	}
+
+	_split_rect(_move_rect(linepos, pos), &p1, &p2);
+	GFX_ASSERT(gfxop_draw_line(line->visual->gfx_state, p1, p2, line->color, line->line_mode, line->line_style));
+	return 0;
+}
+
+static int _gfxwop_line_print(gfxw_widget_t *widget, int indentation) {
+	_gfxw_print_widget(widget, indentation);
+	if (widget->type == GFXW_INVERSE_LINE)
+		sciprintf("INVERSE-LINE");
+	else
+		sciprintf("LINE");
+
+	return 0;
+}
+
+void _gfxw_set_ops_LINE(gfxw_widget_t *prim) {
+	_gfxw_set_ops(GFXW(prim), _gfxwop_line_draw, _gfxwop_basic_free, _gfxwop_basic_tag, _gfxwop_line_print,
+	              _gfxwop_basic_compare_to, _gfxwop_primitive_equals, _gfxwop_basic_superarea_of);
+}
+
+gfxw_primitive_t *gfxw_new_line(Common::Point start, Common::Point end, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style) {
+	gfxw_primitive_t *prim;
+	// Encode into internal representation
+	rect_t line = gfx_rect(start.x, start.y, end.x - start.x, end.y - start.y);
+
+	byte inverse = 0;
+
+	if (line.xl < 0) {
+		line.x += line.xl;
+		line.y += line.yl;
+		line.xl = -line.xl;
+		line.yl = -line.yl;
+	}
+
+	if (line.yl < 0) {
+		inverse = 1;
+		line.x += line.xl;
+		line.xl = -line.xl;
+	}
+
+	line.xl++;
+	line.yl++;
+
+	prim = _gfxw_new_primitive(line, color, line_mode, line_style, inverse ? GFXW_INVERSE_LINE : GFXW_LINE);
+
+	_gfxw_set_ops_LINE(GFXW(prim));
+
+	return prim;
+}
+
+//*** Views and static views ***
+
+gfxw_view_t *_gfxw_new_simple_view(gfx_state_t *state, Common::Point pos, int view, int loop, int cel, int palette, int priority, int control,
+								   gfx_alignment_t halign, gfx_alignment_t valign, int size, gfxw_widget_type_t type) {
+	gfxw_view_t *widget;
+	int width, height;
+	Common::Point offset;
+
+	if (!state) {
+		GFXERROR("Attempt to create view widget with NULL state!\n");
+		return NULL;
+	}
+
+	if (gfxop_get_cel_parameters(state, view, loop, cel, &width, &height, &offset)) {
+		GFXERROR("Attempt to retrieve cel parameters for (%d/%d/%d) failed (Maybe the values weren't checked beforehand?)\n",
+		         view, cel, loop);
+		return NULL;
+	}
+
+	widget = (gfxw_view_t *)_gfxw_new_widget(size, type);
+
+	widget->widget_priority = priority;
+	widget->pos = pos;
+	widget->color.mask = ((priority < 0) ? 0 : GFX_MASK_PRIORITY) | ((control < 0) ? 0 : GFX_MASK_CONTROL);
+	widget->color.priority = priority;
+	widget->color.control = control;
+	widget->view = view;
+	widget->loop = loop;
+	widget->cel = cel;
+	widget->palette = palette;
+
+	if (halign == ALIGN_CENTER)
+		widget->pos.x -= width >> 1;
+	else if (halign == ALIGN_RIGHT)
+		widget->pos.x -= width;
+
+	if (valign == ALIGN_CENTER)
+		widget->pos.y -= height >> 1;
+	else if (valign == ALIGN_BOTTOM)
+		widget->pos.y -= height;
+
+	widget->bounds = gfx_rect(widget->pos.x - offset.x, widget->pos.y - offset.y, width, height);
+
+	widget->flags |= GFXW_FLAG_VISIBLE;
+
+	return widget;
+}
+
+int _gfxwop_view_draw(gfxw_widget_t *widget, Common::Point pos) {
+	gfxw_view_t *view = (gfxw_view_t *)widget;
+	DRAW_ASSERT(widget, GFXW_VIEW);
+
+	GFX_ASSERT(gfxop_draw_cel(view->visual->gfx_state, view->view, view->loop, view->cel,
+				Common::Point(view->pos.x + pos.x, view->pos.y + pos.y), view->color, view->palette));
+
+	return 0;
+}
+
+static int _gfxwop_static_view_draw(gfxw_widget_t *widget, Common::Point pos) {
+	gfxw_view_t *view = (gfxw_view_t *)widget;
+	DRAW_ASSERT(widget, GFXW_VIEW);
+
+	GFX_ASSERT(gfxop_draw_cel_static(view->visual->gfx_state, view->view, view->loop,
+	                                 view->cel, _move_point(view->bounds, pos), view->color, view->palette));
+
+	return 0;
+}
+
+static int _w_gfxwop_view_print(gfxw_widget_t *widget, const char *name, int indentation) {
+	gfxw_view_t *view = (gfxw_view_t *)widget;
+	_gfxw_print_widget(widget, indentation);
+
+	sciprintf(name);
+	sciprintf("(%d/%d/%d)@(%d,%d)[p:%d,c:%d]", view->view, view->loop, view->cel, view->pos.x, view->pos.y,
+	          (view->color.mask & GFX_MASK_PRIORITY) ? view->color.priority : -1,
+	          (view->color.mask & GFX_MASK_CONTROL) ? view->color.control : -1);
+
+	return 0;
+}
+
+static int _gfxwop_view_print(gfxw_widget_t *widget, int indentation) {
+	return _w_gfxwop_view_print(widget, "VIEW", indentation);
+}
+
+static int _gfxwop_static_view_print(gfxw_widget_t *widget, int indentation) {
+	return _w_gfxwop_view_print(widget, "PICVIEW", indentation);
+}
+
+void _gfxw_set_ops_VIEW(gfxw_widget_t *view, char stat) {
+	_gfxw_set_ops(GFXW(view), (stat) ? _gfxwop_static_view_draw : _gfxwop_view_draw, _gfxwop_basic_free,
+	              _gfxwop_basic_tag, (stat) ? _gfxwop_static_view_print : _gfxwop_view_print,
+	              _gfxwop_basic_compare_to, _gfxwop_basic_equals, _gfxwop_basic_superarea_of);
+}
+
+gfxw_view_t *gfxw_new_view(gfx_state_t *state, Common::Point pos, int view_nr, int loop, int cel, int palette, int priority, int control,
+	gfx_alignment_t halign, gfx_alignment_t valign, int flags) {
+	gfxw_view_t *view;
+
+	if (flags & GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET) {
+		int foo;
+		Common::Point offset;
+		gfxop_get_cel_parameters(state, view_nr, loop, cel, &foo, &foo, &offset);
+		pos.x += offset.x;
+		pos.y += offset.y;
+	}
+
+	view = _gfxw_new_simple_view(state, pos, view_nr, loop, cel, palette, priority, control, halign, valign,
+	                             sizeof(gfxw_view_t), (flags & GFXW_VIEW_FLAG_STATIC) ? GFXW_STATIC_VIEW : GFXW_VIEW);
+
+	_gfxw_set_ops_VIEW(GFXW(view), (char)(flags & GFXW_VIEW_FLAG_STATIC));
+
+	return view;
+}
+
+//*** Dynamic Views ***
+
+static int _gfxwop_dyn_view_draw(gfxw_widget_t *widget, Common::Point pos) {
+	gfxw_dyn_view_t *view = (gfxw_dyn_view_t *) widget;
+	DRAW_ASSERT(widget, GFXW_DYN_VIEW);
+
+	GFX_ASSERT(gfxop_draw_cel(view->visual->gfx_state, view->view, view->loop,
+	                          view->cel, _move_point(view->draw_bounds, pos), view->color, view->palette));
+
+	/*
+	  gfx_color_t red;
+	  red.visual.r = 0xff;
+	  red.visual.g = red.visual.b = 0;
+	  red.mask = GFX_MASK_VISUAL;
+	  GFX_ASSERT(gfxop_draw_rectangle(view->visual->gfx_state,
+	  gfx_rect(view->bounds.x + pos.x, view->bounds.y + pos.y, view->bounds.xl - 1, view->bounds.yl - 1), red, 0, 0));
+	*/
+
+	return 0;
+
+}
+
+static int _gfxwop_draw_nop(gfxw_widget_t *widget, Common::Point pos) {
+	return 0;
+}
+
+static int _gfxwop_pic_view_draw(gfxw_widget_t *widget, Common::Point pos) {
+	gfxw_dyn_view_t *view = (gfxw_dyn_view_t *) widget;
+	DRAW_ASSERT(widget, GFXW_PIC_VIEW);
+
+	GFX_ASSERT(gfxop_set_clip_zone(view->visual->gfx_state, view->parent->zone));
+	GFX_ASSERT(gfxop_draw_cel_static_clipped(view->visual->gfx_state, view->view, view->loop,
+	           view->cel, _move_point(view->draw_bounds, pos), view->color, view->palette));
+
+	// Draw again on the back buffer
+	GFX_ASSERT(gfxop_draw_cel(view->visual->gfx_state, view->view, view->loop, view->cel,
+	                          _move_point(view->draw_bounds, pos), view->color, view->palette));
+
+
+	widget->draw = _gfxwop_draw_nop; // No more drawing needs to be done
+
+	return 0;
+}
+
+static int _gfxwop_some_view_print(gfxw_widget_t *widget, int indentation, const char *type_string) {
+	gfxw_dyn_view_t *view = (gfxw_dyn_view_t *)widget;
+
+	_gfxw_print_widget(widget, indentation);
+
+	sciprintf(type_string);
+	sciprintf(" SORT=%d z=%d seq=%d (%d/%d/%d)@(%d,%d)[p:%d,c:%d]; sig[%04x@%p]", view->force_precedence, view->z,
+	          view->sequence, view->view, view->loop, view->cel, view->pos.x, view->pos.y,
+	          (view->color.mask & GFX_MASK_PRIORITY) ? view->color.priority : -1,
+	          (view->color.mask & GFX_MASK_CONTROL) ? view->color.control : -1, view->signal, view->signalp);
+
+	return 0;
+}
+
+static int _gfxwop_dyn_view_print(gfxw_widget_t *widget, int indentation) {
+	return _gfxwop_some_view_print(widget, indentation, "DYNVIEW");
+}
+
+static int _gfxwop_pic_view_print(gfxw_widget_t *widget, int indentation) {
+	return _gfxwop_some_view_print(widget, indentation, "PICVIEW");
+}
+
+static int _gfxwop_dyn_view_equals(gfxw_widget_t *widget, gfxw_widget_t *other) {
+	gfxw_dyn_view_t *wview = (gfxw_dyn_view_t *)widget, *oview;
+	if (!GFXW_IS_DYN_VIEW(other))
+		return 0;
+
+	oview = (gfxw_dyn_view_t *)other;
+
+	if (wview->pos.x != oview->pos.x || wview->pos.y != oview->pos.y || wview->z != oview->z)
+		return 0;
+
+	if (wview->view != oview->view || wview->loop != oview->loop || wview->cel != oview->cel)
+		return 0;
+
+	if (!_color_equals(wview->color, oview->color))
+		return 0;
+
+	if (wview->flags != oview->flags)
+		return 0;
+
+	return 1;
+}
+
+static int _gfxwop_dyn_view_compare_to(gfxw_widget_t *widget, gfxw_widget_t *other) {
+	int retval;
+	gfxw_dyn_view_t *wview = (gfxw_dyn_view_t *) widget, *oview;
+	if (!GFXW_IS_DYN_VIEW(other))
+		return 1;
+
+	oview = (gfxw_dyn_view_t *) other;
+
+	retval = wview->force_precedence - oview->force_precedence;
+	if (retval)
+		return retval;
+
+	retval = wview->pos.y - oview->pos.y;
+	if (retval)
+		return retval;
+
+	retval = (wview->z - oview->z);
+	if (retval)
+		return retval;
+
+	return -(wview->sequence - oview->sequence);
+}
+
+void _gfxw_set_ops_DYNVIEW(gfxw_widget_t *widget) {
+	_gfxw_set_ops(GFXW(widget), _gfxwop_dyn_view_draw, _gfxwop_basic_free, _gfxwop_basic_tag,
+	              _gfxwop_dyn_view_print, _gfxwop_dyn_view_compare_to, _gfxwop_dyn_view_equals, _gfxwop_basic_superarea_of);
+}
+
+void _gfxw_set_ops_PICVIEW(gfxw_widget_t *widget) {
+	_gfxw_set_ops_DYNVIEW(widget);
+	widget->draw = _gfxwop_pic_view_draw;
+	widget->print = _gfxwop_pic_view_print;
+}
+
+gfxw_dyn_view_t *gfxw_new_dyn_view(gfx_state_t *state, Common::Point pos, int z, int view, int loop, int cel, int palette, int priority, int control,
+	gfx_alignment_t halign, gfx_alignment_t valign, int sequence) {
+	gfxw_dyn_view_t *widget;
+	int width, height;
+	int xalignmod, yalignmod;
+	Common::Point offset;
+
+	if (!state) {
+		GFXERROR("Attempt to create view widget with NULL state!\n");
+		return NULL;
+	}
+
+	if (gfxop_get_cel_parameters(state, view, loop, cel, &width, &height, &offset)) {
+		GFXERROR("Attempt to retrieve cel parameters for (%d/%d/%d) failed (Maybe the values weren't checked beforehand?)\n",
+		         view, cel, loop);
+		return NULL;
+	}
+
+	widget = (gfxw_dyn_view_t *)_gfxw_new_widget(sizeof(gfxw_dyn_view_t), GFXW_DYN_VIEW);
+
+	widget->pos = pos;
+	widget->color.mask = ((priority < 0) ? 0 : GFX_MASK_PRIORITY) | ((control < 0) ? 0 : GFX_MASK_CONTROL);
+	widget->widget_priority = priority;
+	widget->color.priority = priority;
+	widget->color.control = control;
+	widget->color.alpha = 0;
+	widget->color.visual.global_index = 0;
+	widget->color.visual.r = 0;
+	widget->color.visual.g = 0;
+	widget->color.visual.b = 0;
+	widget->view = view;
+	widget->loop = loop;
+	widget->cel = cel;
+	widget->sequence = sequence;
+	widget->force_precedence = 0;
+	widget->palette = palette;
+
+	if (halign == ALIGN_CENTER)
+		xalignmod = width >> 1;
+	else if (halign == ALIGN_RIGHT)
+		xalignmod = width;
+	else
+		xalignmod = 0;
+
+	if (valign == ALIGN_CENTER)
+		yalignmod = height >> 1;
+	else if (valign == ALIGN_BOTTOM)
+		yalignmod = height;
+	else
+		yalignmod = 0;
+
+	widget->z = z;
+
+	widget->draw_bounds = gfx_rect(widget->pos.x - xalignmod, widget->pos.y - yalignmod - z, width, height);
+	widget->bounds = gfx_rect(widget->pos.x - offset.x - xalignmod, widget->pos.y - offset.y - yalignmod - z, width, height);
+
+	widget->flags |= GFXW_FLAG_VISIBLE;
+
+	_gfxw_set_ops_DYNVIEW(GFXW(widget));
+
+	widget->signalp = NULL;
+	widget->signal = 0;
+
+	return widget;
+}
+
+//*** Text ***
+
+static int _gfxwop_text_free(gfxw_widget_t *widget) {
+	gfxw_text_t *text = (gfxw_text_t *)widget;
+	free(text->text);
+
+	return _gfxwop_basic_free(widget);
+}
+
+static int _gfxwop_text_draw(gfxw_widget_t *widget, Common::Point pos) {
+	gfxw_text_t *text = (gfxw_text_t *)widget;
+	DRAW_ASSERT(widget, GFXW_TEXT);
+
+	GFX_ASSERT(gfxop_draw_text(text->visual->gfx_state, text->text_handle, _move_rect(text->bounds, pos)));
+
+	return 0;
+}
+
+static int _gfxwop_text_alloc_and_draw(gfxw_widget_t *widget, Common::Point pos) {
+	gfxw_text_t *text = (gfxw_text_t *)widget;
+	DRAW_ASSERT(widget, GFXW_TEXT);
+
+	text->text_handle = gfxop_new_text(widget->visual->gfx_state, text->font_nr, text->text, text->bounds.xl,
+	                   text->halign, text->valign, text->color1, text->color2, text->bgcolor, text->text_flags);
+
+	text->draw = _gfxwop_text_draw;
+
+	return _gfxwop_text_draw(widget, pos);
+}
+
+static int _gfxwop_text_print(gfxw_widget_t *widget, int indentation) {
+	_gfxw_print_widget(widget, indentation);
+	sciprintf("TEXT:'%s'", ((gfxw_text_t *)widget)->text);
+
+	return 0;
+}
+
+static int _gfxwop_text_equals(gfxw_widget_t *widget, gfxw_widget_t *other) {
+	gfxw_text_t *wtext = (gfxw_text_t *)widget, *otext;
+	if (other->type != GFXW_TEXT)
+		return 0;
+
+	otext = (gfxw_text_t *)other;
+
+	if ((wtext->bounds.x != otext->bounds.x) || (wtext->bounds.y != otext->bounds.y))
+		return 0;
+
+	if (wtext->halign != otext->halign || wtext->valign != otext->valign)
+		return 0;
+
+	if (wtext->text_flags != otext->text_flags)
+		return 0;
+
+	if (wtext->font_nr != otext->font_nr)
+		return 0;
+
+	/* if (!(_color_equals(wtext->color1, otext->color1) && _color_equals(wtext->color2, otext->color2)
+			&& _color_equals(wtext->bgcolor, otext->bgcolor)))
+		return 0; */
+
+	return 1;
+}
+
+static int _gfxwop_text_should_replace(gfxw_widget_t *widget, gfxw_widget_t *other) {
+	gfxw_text_t *wtext = (gfxw_text_t *)widget, *otext;
+
+	if (other->type != GFXW_TEXT)
+		return 0;
+
+	otext = (gfxw_text_t *)other;
+
+	return strcmp(wtext->text, otext->text);
+}
+
+static int _gfxwop_text_compare_to(gfxw_widget_t *widget, gfxw_widget_t *other) {
+	return 1;
+}
+
+void _gfxw_set_ops_TEXT(gfxw_widget_t *widget) {
+	_gfxw_set_ops(GFXW(widget), _gfxwop_text_alloc_and_draw, _gfxwop_text_free, _gfxwop_basic_tag,
+	              _gfxwop_text_print, _gfxwop_text_compare_to, _gfxwop_text_equals,
+	              _gfxwop_basic_superarea_of);
+	widget->should_replace = _gfxwop_text_should_replace;
+}
+
+gfxw_text_t *gfxw_new_text(gfx_state_t *state, rect_t area, int font, const char *text, gfx_alignment_t halign,
+	gfx_alignment_t valign, gfx_color_t color1, gfx_color_t color2, gfx_color_t bgcolor, int text_flags) {
+	gfxw_text_t *widget = (gfxw_text_t *)_gfxw_new_widget(sizeof(gfxw_text_t), GFXW_TEXT);
+
+	widget->widget_priority = _gfxw_color_get_priority(color1);
+	widget->font_nr = font;
+	widget->text = (char *)sci_malloc(strlen(text) + 1);
+	widget->halign = halign;
+	widget->valign = valign;
+	widget->color1 = color1;
+	widget->color2 = color2;
+	widget->bgcolor = bgcolor;
+	widget->text_flags = text_flags;
+	widget->text_handle = NULL;
+
+	strcpy(widget->text, text);
+
+	gfxop_get_text_params(state, font, text, area.xl, &(widget->width), &(widget->height), text_flags,
+	                      &(widget->lines_nr), &(widget->lineheight), &(widget->lastline_width));
+
+	/* FIXME: Window is too big
+	area.x += _calc_needmove(halign, area.xl, widget->width);
+	area.y += _calc_needmove(valign, area.yl, widget->height);
+	*/
+
+	if (halign == ALIGN_LEFT)
+		area.xl = widget->width;
+	if (valign == ALIGN_TOP)
+		area.yl = widget->height;
+
+	widget->bounds = area;
+
+	widget->flags |= GFXW_FLAG_VISIBLE;
+
+	_gfxw_set_ops_TEXT(GFXW(widget));
+
+	return widget;
+}
+
+void gfxw_text_info(gfx_state_t *state, gfxw_text_t *text, int *lines, int *lineheight, int *offset) {
+	if (lines)
+		*lines = text->lines_nr;
+	if (lineheight)
+		*lineheight = text->lineheight;
+	if (offset)
+		*offset = text->lastline_width;
+}
+
+//-- Container types --
+
+static int _gfxwop_container_add_dirty_rel(gfxw_container_t *cont, rect_t rect, int propagate) {
+	DDIRTY(stderr, "->container_add_dirty_rel(%d,%d,%d,%d, %d)\n", GFX_PRINT_RECT(rect), propagate);
+	return cont->add_dirty_abs(cont, _move_rect(rect, Common::Point(cont->zone.x, cont->zone.y)), propagate);
+}
+
+static inline void _gfxw_set_container_ops(gfxw_container_t *container, gfxw_point_op *draw, gfxw_op *free, gfxw_op *tag,
+	gfxw_op_int *print, gfxw_bin_op *compare_to, gfxw_bin_op *equals,
+	gfxw_bin_op *superarea_of, gfxw_visual_op *set_visual,
+	gfxw_unary_container_op *free_tagged, gfxw_unary_container_op *free_contents,
+	gfxw_rect_op *add_dirty, gfxw_container_op *add) {
+	_gfxw_set_ops(GFXW(container), draw, free, tag, print, compare_to, equals, superarea_of);
+
+	container->free_tagged = free_tagged;
+	container->free_contents = free_contents;
+	container->add_dirty_abs = add_dirty;
+	container->add_dirty_rel = _gfxwop_container_add_dirty_rel;
+	container->add = add;
+	container->set_visual = set_visual;
+}
+
+static int _w_gfxwop_container_print_contents(const char *name, gfxw_widget_t *widget, int indentation) {
+	gfxw_widget_t *seeker = widget;
+
+	indent(indentation);
+
+	sciprintf("--%s:\n", name);
+
+	while (seeker) {
+		seeker->print(seeker, indentation + 1);
+		sciprintf("\n");
+		seeker = seeker->next;
+	}
+
+	return 0;
+}
+
+static int _w_gfxwop_container_print(gfxw_widget_t *widget, int indentation) {
+	gfx_dirty_rect_t *dirty;
+	gfxw_container_t *container = (gfxw_container_t *)widget;
+	if (!GFXW_IS_CONTAINER(widget)) {
+		GFXERROR("_w_gfxwop_container_print() called on type %d widget\n", widget->type);
+		return 1;
+	}
+
+	sciprintf(" viszone=((%d,%d),(%dx%d))\n", container->zone.x, container->zone.y,
+	          container->zone.xl, container->zone.yl);
+
+	indent(indentation);
+	sciprintf("--dirty:\n");
+
+	dirty = container->dirty;
+	while (dirty) {
+		indent(indentation + 1);
+		sciprintf("dirty(%d,%d, (%dx%d))\n", dirty->rect.x, dirty->rect.y, dirty->rect.xl, dirty->rect.yl);
+		dirty = dirty->next;
+	}
+
+	_w_gfxwop_container_print_contents("contents", container->contents, indentation);
+
+	return 0;
+}
+
+gfxw_container_t *_gfxw_new_container_widget(rect_t area, int size, gfxw_widget_type_t type) {
+	gfxw_container_t *widget = (gfxw_container_t *)_gfxw_new_widget(size, type);
+
+	widget->bounds = widget->zone = area;
+	widget->contents = NULL;
+	widget->nextpp = &(widget->contents);
+	widget->dirty = NULL;
+
+	widget->flags |= GFXW_FLAG_VISIBLE | GFXW_FLAG_CONTAINER;
+
+	return widget;
+}
+
+static void recursively_free_dirty_rects(gfx_dirty_rect_t *dirty) {
+	if (dirty) {
+		recursively_free_dirty_rects(dirty->next);
+		free(dirty);
+	}
+}
+
+int ti = 0;
+
+static inline int _gfxw_dirty_rect_overlaps_normal_rect(rect_t port_zone, rect_t bounds, rect_t dirty) {
+	bounds.x += port_zone.x;
+	bounds.y += port_zone.y;
+
+	return gfx_rects_overlap(bounds, dirty);
+}
+
+static int _gfxwop_container_draw_contents(gfxw_widget_t *widget, gfxw_widget_t *contents) {
+	gfxw_container_t *container = (gfxw_container_t *)widget;
+	gfx_dirty_rect_t *dirty = container->dirty;
+	gfx_state_t *gfx_state = (widget->visual) ? widget->visual->gfx_state : ((gfxw_visual_t *) widget)->gfx_state;
+	int draw_ports;
+	rect_t nullzone = {0, 0, 0, 0};
+
+	if (!contents)
+		return 0;
+
+	while (dirty) {
+		gfxw_widget_t *seeker = contents;
+
+		while (seeker) {
+			if (_gfxw_dirty_rect_overlaps_normal_rect(GFXW_IS_CONTAINER(seeker) ? nullzone : container->zone,
+			        // Containers have absolute coordinates, reflect this.
+			        seeker->bounds, dirty->rect)) {
+
+				if (GFXW_IS_CONTAINER(seeker)) {// Propagate dirty rectangles /upwards/
+					DDIRTY(stderr, "container_draw_contents: propagate upwards (%d,%d,%d,%d ,0)\n", GFX_PRINT_RECT(dirty->rect));
+					((gfxw_container_t *)seeker)->add_dirty_abs((gfxw_container_t *)seeker, dirty->rect, 0);
+				}
+
+				seeker->flags |= GFXW_FLAG_DIRTY;
+			}
+
+			seeker = seeker->next;
+		}
+
+		dirty = dirty->next;
+	}
+
+	// The draw loop is executed twice: Once for normal data, and once for ports.
+	for (draw_ports = 0; draw_ports < 2; draw_ports++) {
+		dirty = container->dirty;
+
+		while (dirty) {
+			gfxw_widget_t *seeker = contents;
+			while (seeker && (draw_ports || !GFXW_IS_PORT(seeker))) {
+				rect_t small_rect;
+				byte draw_noncontainers;
+
+				memcpy(&small_rect, &(dirty->rect), sizeof(rect_t));
+				draw_noncontainers = !_gfxop_clip(&small_rect, container->bounds);
+
+				if (seeker->flags & GFXW_FLAG_DIRTY) {
+
+					if (!GFXW_IS_CONTAINER(seeker) && draw_noncontainers) {
+						GFX_ASSERT(gfxop_set_clip_zone(gfx_state, small_rect));
+					}
+					/* Clip zone must be reset after each element, because we might
+					** descend into containers.
+					** Doing this is relatively cheap, though. */
+					if (draw_noncontainers || GFXW_IS_CONTAINER(seeker))
+						seeker->draw(seeker, Common::Point(container->zone.x, container->zone.y));
+
+					if (!dirty->next)
+						seeker->flags &= ~GFXW_FLAG_DIRTY;
+				}
+
+				seeker = seeker->next;
+			}
+			dirty = dirty->next;
+		}
+	}
+	// Remember that the dirty rects should be freed afterwards!
+
+	return 0;
+}
+
+static int _gfxwop_container_free(gfxw_widget_t *widget) {
+	gfxw_container_t *container = (gfxw_container_t *)widget;
+	gfxw_widget_t *seeker = container->contents;
+
+	while (seeker) {
+		gfxw_widget_t *next = seeker->next;
+		seeker->widfree(seeker);
+		seeker = next;
+	}
+
+	recursively_free_dirty_rects(container->dirty);
+	container->dirty = NULL;
+
+	return _gfxwop_basic_free(widget);
+}
+
+static int _gfxwop_container_tag(gfxw_widget_t *widget) {
+	gfxw_container_t *container = (gfxw_container_t *) widget;
+	gfxw_widget_t *seeker = container->contents;
+
+	while (seeker) {
+		seeker->tag(seeker);
+		seeker = seeker->next;
+	}
+
+	return 0;
+}
+
+static int _w_gfxwop_container_set_visual_contents(gfxw_widget_t *contents, gfxw_visual_t *visual) {
+	while (contents) {
+		contents->set_visual(contents, visual);
+		contents = contents->next;
+	}
+	return 0;
+}
+
+static int _gfxwop_container_set_visual(gfxw_widget_t *widget, gfxw_visual_t *visual) {
+	gfxw_container_t *container = (gfxw_container_t *) widget;
+
+	container->visual = visual;
+	if (widget->parent) {
+		if (!(GFXW_IS_LIST(widget) && !GFXWC(widget)->contents)) {
+			DDIRTY(stderr, "set_visual::DOWNWARDS abs(%d,%d,%d,%d, 1)\n", GFX_PRINT_RECT(widget->bounds));
+			widget->parent->add_dirty_abs(widget->parent, widget->bounds, 1);
+		}
+	}
+
+	return _w_gfxwop_container_set_visual_contents(container->contents, visual);
+}
+
+static int _gfxwop_container_free_tagged(gfxw_container_t *container) {
+	gfxw_widget_t *seekerp = (container->contents);
+
+	while (seekerp) {
+		gfxw_widget_t *redshirt = seekerp;
+
+		if (redshirt->flags & GFXW_FLAG_TAGGED) {
+			seekerp = (redshirt->next);
+			redshirt->widfree(redshirt);
+		} else
+			seekerp = (seekerp)->next;
+	}
+
+	return 0;
+}
+
+static int _gfxwop_container_free_contents(gfxw_container_t *container) {
+	gfxw_widget_t *seeker = container->contents;
+
+	while (seeker) {
+		gfxw_widget_t *next = seeker->next;
+		seeker->widfree(seeker);
+		seeker = next;
+	}
+	return 0;
+}
+
+static void _gfxw_dirtify_container(gfxw_container_t *container, gfxw_widget_t *widget) {
+	if (GFXW_IS_CONTAINER(widget))
+		container->add_dirty_abs(GFXWC(container), widget->bounds, 1);
+	else
+		container->add_dirty_rel(GFXWC(container), widget->bounds, 1);
+}
+
+static int _parentize_widget(gfxw_container_t *container, gfxw_widget_t *widget) {
+	if (widget->parent) {
+		GFXERROR("_gfxwop_container_add(): Attempt to give second parent node to widget!\nWidget:");
+		widget->print(GFXW(widget), 3);
+		sciprintf("\nContainer:");
+		container->print(GFXW(container), 3);
+
+		return 1;
+	}
+
+	widget->parent = GFXWC(container);
+
+	if (GFXW_IS_VISUAL(container))
+		widget->set_visual(widget, (gfxw_visual_t *) container);
+	else if (container->visual)
+		widget->set_visual(widget, container->visual);
+
+	return 0;
+}
+
+static int _gfxw_container_id_equals(gfxw_container_t *container, gfxw_widget_t *widget) {
+	gfxw_widget_t **seekerp = &(container->contents);
+
+	if (GFXW_IS_PORT(widget))
+		return 0;
+
+	if (widget->ID == GFXW_NO_ID)
+		return 0;
+
+	while (*seekerp && ((*seekerp)->ID != widget->ID || (*seekerp)->subID != widget->subID))
+		seekerp = &((*seekerp)->next);
+
+	if (!*seekerp)
+		return 0;
+
+	if ((*seekerp)->equals(*seekerp, widget) && !(*seekerp)->should_replace(*seekerp, widget)) {
+		widget->widfree(widget);
+		(*seekerp)->flags &= ~GFXW_FLAG_TAGGED;
+		return 1;
+	} else {
+		if (!(widget->flags & GFXW_FLAG_MULTI_ID))
+			(*seekerp)->widfree(*seekerp);
+		return 0;
+	}
+}
+
+static int _gfxwop_container_add_dirty(gfxw_container_t *container, rect_t dirty, int propagate) {
+#if 0
+	// This code has been disabled because containers may contain sub-containers with
+	// bounds greater than their own.
+	if (_gfxop_clip(&dirty, container->bounds))
+		return 0;
+#endif
+
+	DDIRTY(stderr, "Effectively adding dirty %d,%d,%d,%d %d to ID %d\n", GFX_PRINT_RECT(dirty), propagate, container->ID);
+	container->dirty = gfxdr_add_dirty(container->dirty, dirty, GFXW_DIRTY_STRATEGY);
+	return 0;
+}
+
+static int _gfxwop_container_add(gfxw_container_t *container, gfxw_widget_t *widget) {
+	if (_gfxw_container_id_equals(container, widget))
+		return 0;
+
+	if (_parentize_widget(container, widget))
+		return 1;
+
+	if (!(GFXW_IS_LIST(widget) && (!GFXWC(widget)->contents))) { // Don't dirtify self on empty lists
+		DDIRTY(stderr, "container_add: dirtify DOWNWARDS (%d,%d,%d,%d, 1)\n", GFX_PRINT_RECT(widget->bounds));
+		_gfxw_dirtify_container(container, widget);
+	}
+
+	*(container->nextpp) = widget;
+	container->nextpp = &(widget->next);
+
+	return 0;
+}
+
+//*** Lists and sorted lists ***
+
+static int _gfxwop_list_draw(gfxw_widget_t *list, Common::Point pos) {
+	DRAW_ASSERT(list, GFXW_LIST);
+
+	_gfxwop_container_draw_contents(list, ((gfxw_list_t *)list)->contents);
+	recursively_free_dirty_rects(GFXWC(list)->dirty);
+	GFXWC(list)->dirty = NULL;
+	list->flags &= ~GFXW_FLAG_DIRTY;
+
+	return 0;
+}
+
+static int _gfxwop_sorted_list_draw(gfxw_widget_t *list, Common::Point pos) {
+	DRAW_ASSERT(list, GFXW_SORTED_LIST);
+
+	_gfxwop_container_draw_contents(list, ((gfxw_list_t *)list)->contents);
+	recursively_free_dirty_rects(GFXWC(list)->dirty);
+	GFXWC(list)->dirty = NULL;
+
+	return 0;
+}
+
+static inline int _w_gfxwop_list_print(gfxw_widget_t *list, const char *name, int indentation) {
+	_gfxw_print_widget(list, indentation);
+	sciprintf(name);
+
+	return _w_gfxwop_container_print(list, indentation);
+}
+
+static int _gfxwop_list_print(gfxw_widget_t *list, int indentation) {
+	return _w_gfxwop_list_print(list, "LIST", indentation);
+}
+
+static int _gfxwop_sorted_list_print(gfxw_widget_t *list, int indentation) {
+	return _w_gfxwop_list_print(list, "SORTED_LIST", indentation);
+}
+
+#if 0
+struct gfxw_widget_list {
+	gfxw_widget_t *widget;
+	struct gfxw_widget_list *next;
+};
+
+static struct gfxw_widtet_list *_gfxw_make_widget_list_recursive(gfxw_widget_t *widget) {
+	gfxw_widget_list *node;
+
+	if (!widget)
+		return NULL;
+
+	node = sci_malloc(sizeof(struct gfxw_widget_list));
+	node->widget = widget;
+	node->next = _gfxw_make_widget_list_recursive(widget->next);
+
+	return node;
+}
+
+static struct gfxw_widget_list *_gfxw_make_widget_list(gfxw_container_t *container) {
+	return _gfxw_make_widget_list_recursive(container->contents);
+}
+#endif
+
+static int _gfxwop_list_equals(gfxw_widget_t *widget, gfxw_widget_t *other) {
+	// Requires identical order of list elements.
+	gfxw_list_t *wlist, *olist;
+
+	if (widget->type != other->type)
+		return 0;
+
+	if (!GFXW_IS_LIST(widget)) {
+		GFXWARN("_gfxwop_list_equals(): Method called on non-list!\n");
+		widget->print(widget, 0);
+		sciprintf("\n");
+		return 0;
+	}
+
+	wlist = (gfxw_list_t *)widget;
+	olist = (gfxw_list_t *)other;
+
+	if (memcmp(&(wlist->bounds), &(olist->bounds), sizeof(rect_t)))
+		return 0;
+
+	widget = wlist->contents;
+	other = olist->contents;
+
+	while (widget && other) {
+		if (!(widget->equals(widget, other) && !widget->should_replace(widget, other)))
+			return 0;
+
+		widget = widget->next;
+		other = other->next;
+	}
+
+	return (!widget && !other); // True if both are finished now
+}
+
+static int _gfxwop_list_add_dirty(gfxw_container_t *container, rect_t dirty, int propagate) {
+	// Lists add dirty boxes to both themselves and their parenting port/visual
+
+	container->flags |= GFXW_FLAG_DIRTY;
+
+	DDIRTY(stderr, "list_add_dirty %d,%d,%d,%d %d\n", GFX_PRINT_RECT(dirty), propagate);
+	if (propagate)
+		if (container->parent) {
+			DDIRTY(stderr, "->PROPAGATING\n");
+			container->parent->add_dirty_abs(container->parent, dirty, 1);
+		}
+
+	return _gfxwop_container_add_dirty(container, dirty, propagate);
+}
+
+int _gfxwop_ordered_add(gfxw_container_t *container, gfxw_widget_t *widget, int compare_all) {
+	// O(n)
+	gfxw_widget_t **seekerp = &(container->contents);
+
+	if (widget->next) {
+		GFXERROR("_gfxwop_sorted_list_add(): Attempt to add widget to two lists!\nWidget:");
+		widget->print(GFXW(widget), 3);
+		sciprintf("\nList:");
+		container->print(GFXW(container), 3);
+		BREAKPOINT();
+
+		return 1;
+	}
+
+	if (_gfxw_container_id_equals(container, widget))
+		return 0;
+
+	while (*seekerp && (compare_all || (widget->compare_to(widget, *seekerp) >= 0))) {
+
+		if (widget->equals(GFXW(widget), GFXW(*seekerp))) {
+			if (compare_all) {
+				if ((*seekerp)->visual)
+					(*seekerp)->widfree(GFXW(*seekerp)); // If it's a fresh widget
+				else
+					gfxw_annihilate(GFXW(*seekerp));
+
+				return _gfxwop_ordered_add(container, widget, compare_all); // We might have destroyed the container's contents
+			} else {
+				widget->next = (*seekerp)->next;
+				(*seekerp)->widfree(GFXW(*seekerp));
+				*seekerp = widget;
+				return (_parentize_widget(container, widget));
+			}
+		}
+
+		if (*seekerp)
+			seekerp = &((*seekerp)->next);
+	}
+
+	widget->next = *seekerp;
+	*seekerp = widget;
+
+	return _parentize_widget(container, widget);
+}
+
+static int _gfxwop_sorted_list_add(gfxw_container_t *container, gfxw_widget_t *widget) {
+	// O(n)
+	return _gfxwop_ordered_add(container, widget, 0);
+}
+
+void _gfxw_set_ops_LIST(gfxw_container_t *list, char sorted) {
+	_gfxw_set_container_ops((gfxw_container_t *)list, sorted ? _gfxwop_sorted_list_draw : _gfxwop_list_draw,
+	                        _gfxwop_container_free, _gfxwop_container_tag,
+	                        sorted ? _gfxwop_sorted_list_print : _gfxwop_list_print,
+	                        _gfxwop_basic_compare_to, sorted ? _gfxwop_basic_equals : _gfxwop_list_equals,
+	                        _gfxwop_basic_superarea_of, _gfxwop_container_set_visual,
+	                        _gfxwop_container_free_tagged, _gfxwop_container_free_contents,
+	                        _gfxwop_list_add_dirty, sorted ? _gfxwop_sorted_list_add : _gfxwop_container_add);
+}
+
+gfxw_list_t *gfxw_new_list(rect_t area, int sorted) {
+	gfxw_list_t *list = (gfxw_list_t *) _gfxw_new_container_widget(area, sizeof(gfxw_list_t),
+	                    sorted ? GFXW_SORTED_LIST : GFXW_LIST);
+
+	_gfxw_set_ops_LIST(GFXWC(list), (char)sorted);
+
+	return list;
+}
+
+//*** Visuals ***
+
+static int _gfxwop_visual_draw(gfxw_widget_t *widget, Common::Point pos) {
+	gfxw_visual_t *visual = (gfxw_visual_t *) widget;
+	gfx_dirty_rect_t *dirty = visual->dirty;
+	DRAW_ASSERT(widget, GFXW_VISUAL);
+
+	while (dirty) {
+		int err = gfxop_clear_box(visual->gfx_state, dirty->rect);
+
+		if (err) {
+			GFXERROR("Error while clearing dirty rect (%d,%d,(%dx%d))\n", dirty->rect.x,
+			         dirty->rect.y, dirty->rect.xl, dirty->rect.yl);
+			if (err == GFX_FATAL)
+				return err;
+		}
+
+		dirty = dirty->next;
+	}
+
+	_gfxwop_container_draw_contents(widget, visual->contents);
+
+	recursively_free_dirty_rects(visual->dirty);
+	visual->dirty = NULL;
+	widget->flags &= ~GFXW_FLAG_DIRTY;
+
+	return 0;
+}
+
+static int _gfxwop_visual_free(gfxw_widget_t *widget) {
+	gfxw_visual_t *visual = (gfxw_visual_t *) widget;
+	gfxw_port_t **portrefs;
+	int retval;
+
+	if (!GFXW_IS_VISUAL(visual)) {
+		GFXERROR("_gfxwop_visual_free() called on non-visual!Widget was: ");
+		widget->print(widget, 3);
+		return 1;
+	}
+
+	portrefs = visual->port_refs;
+
+	retval = _gfxwop_container_free(widget);
+
+	free(portrefs);
+
+	return 0;
+}
+
+static int _gfxwop_visual_print(gfxw_widget_t *widget, int indentation) {
+	int i;
+	int comma = 0;
+	gfxw_visual_t *visual = (gfxw_visual_t *) widget;
+
+	if (!GFXW_IS_VISUAL(visual)) {
+		GFXERROR("_gfxwop_visual_free() called on non-visual!Widget was: ");
+		widget->print(widget, 3);
+		return 1;
+	}
+
+	_gfxw_print_widget(widget, indentation);
+	sciprintf("VISUAL; ports={");
+	for (i = 0; i < visual->port_refs_nr; i++)
+		if (visual->port_refs[i]) {
+			if (comma)
+				sciprintf(",");
+			else
+				comma = 1;
+
+			sciprintf("%d", i);
+		}
+	sciprintf("}\n");
+
+	return _w_gfxwop_container_print(widget, indentation);
+}
+
+static int _gfxwop_visual_set_visual(gfxw_widget_t *self, gfxw_visual_t *visual) {
+	if (self != GFXW(visual)) {
+		GFXWARN("Attempt to set a visual's parent visual to something else!\n");
+	} else {
+		GFXWARN("Attempt to set a visual's parent visual!\n");
+	}
+
+	return 1;
+}
+
+void _gfxw_set_ops_VISUAL(gfxw_container_t *visual) {
+	_gfxw_set_container_ops((gfxw_container_t *)visual, _gfxwop_visual_draw, _gfxwop_visual_free,
+	                        _gfxwop_container_tag, _gfxwop_visual_print, _gfxwop_basic_compare_to,
+	                        _gfxwop_basic_equals, _gfxwop_basic_superarea_of, _gfxwop_visual_set_visual,
+	                        _gfxwop_container_free_tagged, _gfxwop_container_free_contents,
+	                        _gfxwop_container_add_dirty, _gfxwop_container_add);
+}
+
+gfxw_visual_t *gfxw_new_visual(gfx_state_t *state, int font) {
+	gfxw_visual_t *visual = (gfxw_visual_t *) _gfxw_new_container_widget(gfx_rect(0, 0, 320, 200), sizeof(gfxw_visual_t), GFXW_VISUAL);
+
+	visual->font_nr = font;
+	visual->gfx_state = state;
+
+	visual->port_refs_nr = 16;
+	visual->port_refs = (gfxw_port_t **)sci_calloc(sizeof(gfxw_port_t), visual->port_refs_nr);
+
+	_gfxw_set_ops_VISUAL(GFXWC(visual));
+
+	return visual;
+}
+
+static int _visual_find_free_ID(gfxw_visual_t *visual) {
+	int id = 0;
+	int newports = 16;
+
+	while (visual->port_refs[id] && id < visual->port_refs_nr)
+		id++;
+
+	if (id == visual->port_refs_nr) { // Out of ports?
+		visual->port_refs_nr += newports;
+		visual->port_refs = (gfxw_port_t**)sci_realloc(visual->port_refs, visual->port_refs_nr);
+		memset(visual->port_refs + id, 0, newports * sizeof(gfxw_port_t *)); // Clear new port refs
+	}
+
+	return id;
+}
+
+static int _gfxwop_add_dirty_rects(gfxw_container_t *dest, gfx_dirty_rect_t *src) {
+	DDIRTY(stderr, "Adding multiple dirty to #%d\n", dest->ID);
+	if (src) {
+		dest->dirty = gfxdr_add_dirty(dest->dirty, src->rect, GFXW_DIRTY_STRATEGY);
+		_gfxwop_add_dirty_rects(dest, src->next);
+	}
+
+	return 0;
+}
+
+//*** Ports ***
+
+static int _gfxwop_port_draw(gfxw_widget_t *widget, Common::Point pos) {
+	gfxw_port_t *port = (gfxw_port_t *) widget;
+	DRAW_ASSERT(widget, GFXW_PORT);
+
+	if (port->decorations) {
+		DDIRTY(stderr, "Getting/applying deco dirty (multi)\n");
+		_gfxwop_add_dirty_rects(GFXWC(port->decorations), port->dirty);
+		if (port->decorations->draw(GFXW(port->decorations), gfxw_point_zero)) {
+			port->decorations->dirty = NULL;
+			return 1;
+		}
+		port->decorations->dirty = NULL;
+	}
+
+	_gfxwop_container_draw_contents(widget, port->contents);
+
+	recursively_free_dirty_rects(port->dirty);
+	port->dirty = NULL;
+	widget->flags &= ~GFXW_FLAG_DIRTY;
+
+	return 0;
+}
+
+static int _gfxwop_port_free(gfxw_widget_t *widget) {
+	gfxw_port_t *port = (gfxw_port_t *) widget;
+
+	if (port->visual) {
+		gfxw_visual_t *visual = port->visual;
+		int ID = port->ID;
+
+		if (ID < 0 || ID >= visual->port_refs_nr) {
+			GFXWARN("Attempt to free port #%d; allowed: [0..%d]!\n", ID, visual->port_refs_nr);
+			return GFX_ERROR;
+		}
+
+		if (visual->port_refs[ID] != port) {
+			GFXWARN("While freeing port %d: Port is at %p, but port list indicates %p", ID, (void *)port, (void *)visual->port_refs[ID]);
+		} else
+			visual->port_refs[ID] = NULL;
+
+	}
+
+	if (port->decorations)
+		port->decorations->widfree(GFXW(port->decorations));
+
+	return _gfxwop_container_free(widget);
+}
+
+static int _gfxwop_port_print(gfxw_widget_t *widget, int indentation) {
+	gfxw_port_t *port = (gfxw_port_t *)widget;
+
+	_gfxw_print_widget(widget, indentation);
+	sciprintf("PORT");
+	sciprintf(" font=%d drawpos=(%d,%d)", port->font_nr, port->draw_pos.x, port->draw_pos.y);
+	if (port->gray_text)
+		sciprintf(" (gray)");
+	_w_gfxwop_container_print(GFXW(port), indentation);
+
+	return _w_gfxwop_container_print_contents("decorations", GFXW(port->decorations), indentation);
+}
+
+static int _gfxwop_port_superarea_of(gfxw_widget_t *self, gfxw_widget_t *other) {
+	gfxw_port_t *port = (gfxw_port_t *) self;
+
+	if (!port->port_bg)
+		return _gfxwop_basic_superarea_of(self, other);
+
+	return port->port_bg->superarea_of(port->port_bg, other);
+}
+
+static int _gfxwop_port_set_visual(gfxw_widget_t *widget, gfxw_visual_t *visual) {
+	gfxw_list_t *decorations = ((gfxw_port_t *) widget)->decorations;
+	widget->visual = visual;
+
+	if (decorations)
+		if (decorations->set_visual(GFXW(decorations), visual)) {
+			GFXWARN("Setting the visual for decorations failed for port ");
+			widget->print(widget, 1);
+			return 1;
+		}
+
+	return _gfxwop_container_set_visual(widget, visual);
+}
+
+static int _gfxwop_port_add_dirty(gfxw_container_t *widget, rect_t dirty, int propagate) {
+	gfxw_port_t *self = (gfxw_port_t *) widget;
+
+	self->flags |= GFXW_FLAG_DIRTY;
+
+	_gfxwop_container_add_dirty(widget, dirty, propagate);
+
+	DDIRTY(stderr, "Added dirty to ID %d\n", widget->ID);
+	DDIRTY(stderr, "dirty= (%d,%d,%d,%d) bounds (%d,%d,%d,%d)\n", dirty.x, dirty.x, dirty.xl, dirty.yl,
+	       widget->bounds.x, widget->bounds.y, widget->bounds.xl, widget->bounds.yl);
+#if 0
+	// FIXME: This is a worthwhile optimization
+	if (self->port_bg) {
+		gfxw_widget_t foo;
+
+		foo.bounds = dirty; // Yeah, sub-elegant, I know
+		foo.bounds.x -= self->zone.x;
+		foo.bounds.y -= self->zone.y;
+		if (self->port_bg->superarea_of(self->port_bg, &foo)) {
+			gfxw_container_t *parent = self->parent;
+			while (parent) {
+				fprintf(stderr, "Dirtifying parent id %d\n", parent->ID);
+				parent->flags |= GFXW_FLAG_DIRTY;
+				parent = parent->parent;
+			}
+			return 0;
+		}
+	} // else propagate to the parent, since we're not 'catching' the dirty rect
+#endif
+
+	if (propagate)
+		if (self->parent) {
+			DDIRTY(stderr, "PROPAGATE\n");
+			return self->parent->add_dirty_abs(self->parent, dirty, 1);
+		}
+
+	return 0;
+}
+
+static int _gfxwop_port_add(gfxw_container_t *container, gfxw_widget_t *widget) {
+	// O(n)
+	return _gfxwop_ordered_add(container, widget, 1);
+}
+
+void _gfxw_set_ops_PORT(gfxw_container_t *widget) {
+	_gfxw_set_container_ops((gfxw_container_t *)widget, _gfxwop_port_draw, _gfxwop_port_free, _gfxwop_container_tag,
+	                        _gfxwop_port_print, _gfxwop_basic_compare_to, _gfxwop_basic_equals, _gfxwop_port_superarea_of,
+	                        _gfxwop_port_set_visual, _gfxwop_container_free_tagged, _gfxwop_container_free_contents,
+	                        _gfxwop_port_add_dirty, _gfxwop_port_add);
+}
+
+gfxw_port_t *gfxw_new_port(gfxw_visual_t *visual, gfxw_port_t *predecessor, rect_t area, gfx_color_t fgcolor, gfx_color_t bgcolor) {
+	gfxw_port_t *widget = (gfxw_port_t *)_gfxw_new_container_widget(area, sizeof(gfxw_port_t), GFXW_PORT);
+
+	VERIFY_WIDGET(visual);
+
+	widget->port_bg = NULL;
+	widget->parent = NULL;
+	widget->decorations = NULL;
+	widget->title_text = NULL;
+	widget->draw_pos = Common::Point(0, 0);
+	widget->gray_text = 0;
+	widget->color = fgcolor;
+	widget->bgcolor = bgcolor;
+	widget->font_nr = visual->font_nr;
+	widget->ID = _visual_find_free_ID(visual);
+	widget->chrono_port = 0;
+	visual->port_refs[widget->ID] = widget;
+
+	_gfxw_set_ops_PORT(GFXWC(widget));
+
+	return widget;
+}
+
+void gfxw_port_auto_restore_background(gfxw_visual_t *visual, gfxw_port_t *window, rect_t auto_rect) {
+	window->port_flags |= WINDOW_FLAG_AUTO_RESTORE;
+	window->restore_snap = gfxw_make_snapshot(visual, auto_rect);
+}
+
+gfxw_port_t *gfxw_remove_port(gfxw_visual_t *visual, gfxw_port_t *port) {
+	gfxw_port_t *parent;
+	VERIFY_WIDGET(visual);
+	VERIFY_WIDGET(port);
+
+	if (!visual->contents) {
+		GFXWARN("Attempt to remove port from empty visual\n");
+		return NULL;
+	}
+
+	parent = (gfxw_port_t *)port->parent;
+	if (port->port_flags & WINDOW_FLAG_AUTO_RESTORE)
+		gfxw_restore_snapshot(visual, port->restore_snap);
+
+	if (port->widfree(GFXW(port)))
+		return parent;
+
+	while (parent && !GFXW_IS_PORT(parent))
+		parent = (gfxw_port_t *)parent->parent; // Ascend through ancestors
+
+	return parent;
+}
+
+gfxw_port_t *gfxw_find_port(gfxw_visual_t *visual, int ID) {
+	if (ID < 0 || ID >= visual->port_refs_nr)
+		return NULL;
+
+	return visual->port_refs[ID];
+}
+
+gfxw_port_t *gfxw_find_default_port(gfxw_visual_t *visual) {
+	int id = visual->port_refs_nr;
+
+	while (id--) {
+		gfxw_port_t *port = visual->port_refs[id];
+
+		if (port)
+			return port;
+	}
+
+	return NULL;
+}
+
+// - other functions -
+
+gfxw_widget_t *gfxw_set_id(gfxw_widget_t *widget, int ID, int subID) {
+	if (widget) {
+		widget->ID = ID;
+		widget->subID = subID;
+	}
+
+	return widget;
+}
+
+gfxw_dyn_view_t *gfxw_dyn_view_set_params(gfxw_dyn_view_t *widget, int under_bits, void *under_bitsp, int signal, void *signalp) {
+	if (!widget)
+		return NULL;
+
+	widget->under_bits = under_bits;
+	widget->under_bitsp = under_bitsp;
+	widget->signal = signal;
+	widget->signalp = signalp;
+
+	return widget;
+}
+
+gfxw_widget_t *gfxw_remove_id(gfxw_container_t *container, int ID, int subID) {
+	gfxw_widget_t **wp = &(container->contents);
+
+	while (*wp) {
+		if ((*wp)->ID == ID && (subID == GFXW_NO_ID || (*wp)->subID == subID)) {
+			gfxw_widget_t *widget = *wp;
+
+			*wp = (*wp)->next;
+			widget->next = NULL;
+			widget->parent = NULL;
+			widget->visual = NULL;
+
+			return widget;
+		}
+
+		wp = &((*wp)->next);
+	}
+
+	return NULL;
+}
+
+gfxw_widget_t *gfxw_hide_widget(gfxw_widget_t *widget) {
+	if (widget->flags & GFXW_FLAG_VISIBLE) {
+		widget->flags &= ~GFXW_FLAG_VISIBLE;
+
+		if (widget->parent)
+			widget->parent->add_dirty_rel(widget->parent, widget->bounds, 1);
+	}
+
+	return widget;
+}
+
+gfxw_widget_t *gfxw_show_widget(gfxw_widget_t *widget) {
+	if (!(widget->flags & GFXW_FLAG_VISIBLE)) {
+		widget->flags |= GFXW_FLAG_VISIBLE;
+
+		if (widget->parent)
+			widget->parent->add_dirty_rel(widget->parent, widget->bounds, 1);
+	}
+
+	return widget;
+}
+
+gfxw_snapshot_t *gfxw_make_snapshot(gfxw_visual_t *visual, rect_t area) {
+	gfxw_snapshot_t *retval = (gfxw_snapshot_t*)sci_malloc(sizeof(gfxw_snapshot_t));
+
+	retval->serial = widget_serial_number_counter++;
+
+	retval->area = area;
+
+	// Work around subset semantics in gfx_rect_subset.
+	// This fixes the help icon in LSL5. */
+	if (retval->area.xl == 320) retval->area.xl = 321;
+
+	return retval;
+}
+
+int gfxw_widget_matches_snapshot(gfxw_snapshot_t *snapshot, gfxw_widget_t *widget) {
+	int free_below = (snapshot->serial < widget_serial_number_counter) ? 0 : widget_serial_number_counter;
+	int free_above_eq = snapshot->serial;
+	rect_t bounds = widget->bounds;
+
+	if (!GFXW_IS_CONTAINER(widget) && widget->parent) {
+		bounds.x += widget->parent->bounds.x;
+		bounds.y += widget->parent->bounds.y;
+	}
+
+	return ((widget->serial >= free_above_eq || widget->serial < free_below) && gfx_rect_subset(bounds, snapshot->area));
+}
+
+#define MAGIC_FREE_NUMBER -42
+
+void _gfxw_free_contents_appropriately(gfxw_container_t *container, gfxw_snapshot_t *snapshot, int priority) {
+	gfxw_widget_t *widget = container->contents;
+
+	while (widget) {
+		gfxw_widget_t *next = widget->next;
+
+		if (gfxw_widget_matches_snapshot(snapshot, widget) && !(widget->flags & GFXW_FLAG_IMMUNE_TO_SNAPSHOTS)
+		        && (priority == MAGIC_FREE_NUMBER || priority <= widget->widget_priority || widget->widget_priority == -1)) {
+			widget->widfree(widget);
+		} else {
+			if (GFXW_IS_CONTAINER(widget))
+				_gfxw_free_contents_appropriately(GFXWC(widget), snapshot, priority);
+		}
+
+		widget = next;
+	}
+}
+
+gfxw_snapshot_t *gfxw_restore_snapshot(gfxw_visual_t *visual, gfxw_snapshot_t *snapshot) {
+	_gfxw_free_contents_appropriately(GFXWC(visual), snapshot, MAGIC_FREE_NUMBER);
+
+	return snapshot;
+}
+
+void gfxw_annihilate(gfxw_widget_t *widget) {
+	gfxw_visual_t *visual = widget->visual;
+	int widget_priority = 0;
+	int free_overdrawn = 0;
+
+	gfxw_snapshot_t snapshot;
+	if (!GFXW_IS_CONTAINER(widget) && widget->parent && visual && (widget->flags & GFXW_FLAG_VISIBLE)) {
+		snapshot.serial = 0;
+		snapshot.area = widget->bounds;
+		snapshot.area.x += widget->parent->zone.x;
+		snapshot.area.y += widget->parent->zone.y;
+		free_overdrawn = 1;
+		widget_priority = widget->widget_priority;
+	}
+
+	widget->widfree(GFXW(widget));
+
+	if (free_overdrawn)
+		_gfxw_free_contents_appropriately(GFXWC(visual), &snapshot, widget_priority);
+}
+
+gfxw_dyn_view_t *gfxw_picviewize_dynview(gfxw_dyn_view_t *dynview) {
+	dynview->type = GFXW_PIC_VIEW;
+	dynview->flags |= GFXW_FLAG_DIRTY;
+
+	_gfxw_set_ops_PICVIEW(GFXW(dynview));
+
+	if (dynview->parent)
+		_gfxw_dirtify_container(dynview->parent, GFXW(dynview));
+
+	return dynview;
+}
+
+// Chrono-Ports (tm)
+
+gfxw_port_t * gfxw_get_chrono_port(gfxw_visual_t *visual, gfxw_list_t **temp_widgets_list, int flags) {
+	gfxw_port_t *result = NULL;
+	gfx_color_t transparent = {{0, 0, 0, 0}, 0, 0, 0, 0};
+	int id = 0;
+
+	if (!(flags & GFXW_CHRONO_NON_TOPMOST)) {
+		result = gfxw_find_default_port(visual);
+	} else {
+		id = visual->port_refs_nr;
+		while (id >= 0 && (!visual->port_refs[id] || !visual->port_refs[id]->chrono_port))
+			id--;
+
+		if (id >= 0)
+			result = visual->port_refs[id];
+	}
+
+	if (!result || !result->chrono_port) {
+		if (flags & GFXW_CHRONO_NO_CREATE)
+			return NULL;
+		result = gfxw_new_port(visual, NULL, gfx_rect(0, 0, 320, 200), transparent, transparent);
+		*temp_widgets_list = gfxw_new_list(gfx_rect(0, 0, 320, 200), 1);
+		result->add(GFXWC(result), GFXW(*temp_widgets_list));
+		result->chrono_port = 1;
+		if (temp_widgets_list)
+			*temp_widgets_list = GFXWC(result->contents);
+		return result;
+	};
+
+	if (temp_widgets_list)
+		*temp_widgets_list = GFXWC(result->contents);
+
+	return result;
+}
+
+static int gfxw_check_chrono_overlaps(gfxw_port_t *chrono, gfxw_widget_t *widget) {
+	gfxw_widget_t *seeker = GFXWC(chrono->contents)->contents;
+
+	while (seeker) {
+		if (gfx_rect_equals(seeker->bounds, widget->bounds)) {
+			gfxw_annihilate(GFXW(seeker));
+			return 1;
+		}
+
+		seeker = seeker->next;
+	}
+
+	return 0;
+}
+
+void gfxw_add_to_chrono(gfxw_visual_t *visual, gfxw_widget_t *widget) {
+	gfxw_list_t *tw;
+	gfxw_port_t *chrono = gfxw_get_chrono_port(visual, &tw, 0);
+
+	gfxw_check_chrono_overlaps(chrono, widget);
+	chrono->add(GFXWC(chrono), widget);
+}
+
+static gfxw_widget_t *gfxw_widget_intersects_chrono(gfxw_list_t *tw, gfxw_widget_t *widget) {
+	gfxw_widget_t *seeker;
+
+	assert(tw->type == GFXW_SORTED_LIST);
+
+	seeker = tw->contents;
+	while (seeker) {
+		Common::Point origin;
+		rect_t bounds = widget->bounds;
+
+		bounds = widget->bounds;
+		origin.x = seeker->parent->zone.x;
+		origin.y = seeker->parent->zone.y;
+		gfx_rect_translate(bounds, origin);
+
+		if (gfx_rects_overlap(bounds, seeker->bounds))
+			return seeker;
+
+		seeker = seeker->next;
+	}
+
+	return 0;
+}
+
+void gfxw_widget_reparent_chrono(gfxw_visual_t *visual, gfxw_widget_t *view, gfxw_list_t *target) {
+	gfxw_list_t *tw;
+	gfxw_port_t *chrono;
+	gfxw_widget_t *intersector;
+
+	chrono = gfxw_get_chrono_port(visual, &tw, GFXW_CHRONO_NO_CREATE);
+	if (chrono == NULL)
+		return;
+
+	intersector = gfxw_widget_intersects_chrono(tw, view);
+	if (intersector) {
+		Common::Point origin = Common::Point(intersector->parent->zone.x, intersector->parent->zone.y);
+
+		gfxw_remove_widget_from_container(GFXWC(chrono), GFXW(tw));
+		gfxw_remove_widget_from_container(GFXWC(chrono->parent), GFXW(chrono));
+		gfxw_annihilate(GFXW(chrono));
+
+		gfx_rect_translate(tw->zone, origin);
+		target->add(GFXWC(target), GFXW(tw));
+	}
+}
+
+void gfxw_widget_kill_chrono(gfxw_visual_t *visual, int window) {
+	int i;
+
+	for (i = window; i < visual->port_refs_nr ; i++) {
+		if (visual->port_refs[i] && visual->port_refs[i]->chrono_port)
+			gfxw_annihilate(GFXW(visual->port_refs[i]));
+	}
+}
+
+} // End of namespace Sci

Modified: scummvm/trunk/engines/sci/gfx/menubar.h
===================================================================
--- scummvm/trunk/engines/sci/gfx/menubar.h	2009-02-24 20:33:31 UTC (rev 38851)
+++ scummvm/trunk/engines/sci/gfx/menubar.h	2009-02-24 20:39:34 UTC (rev 38852)
@@ -29,7 +29,7 @@
 #define SCI_GFX_SCI_MENUBAR_H
 
 #include "sci/include/vm_types.h"
-#include "sci/gfx/gfx_operations.h"
+#include "sci/gfx/operations.h"
 #include "sci/gfx/gfx_widgets.h"
 
 namespace Sci {

Modified: scummvm/trunk/engines/sci/gfx/operations.cpp
===================================================================
--- scummvm/trunk/engines/sci/gfx/operations.cpp	2009-02-24 20:33:31 UTC (rev 38851)
+++ scummvm/trunk/engines/sci/gfx/operations.cpp	2009-02-24 20:39:34 UTC (rev 38852)
@@ -26,7 +26,7 @@
 // Graphical operations, called from the widget state manager
 
 #include "sci/sci_memory.h"
-#include "sci/gfx/gfx_operations.h"
+#include "sci/gfx/operations.h"
 
 #include "common/system.h"
 

Copied: scummvm/trunk/engines/sci/gfx/operations.h (from rev 38850, scummvm/trunk/engines/sci/gfx/gfx_operations.h)
===================================================================
--- scummvm/trunk/engines/sci/gfx/operations.h	                        (rev 0)
+++ scummvm/trunk/engines/sci/gfx/operations.h	2009-02-24 20:39:34 UTC (rev 38852)
@@ -0,0 +1,682 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/* Graphical operations, called from the widget state manager */
+
+#ifndef SCI_GFX_GFX_OPERATIONS_H
+#define SCI_GFX_GFX_OPERATIONS_H
+
+#include "sci/gfx/gfx_resmgr.h"
+#include "sci/gfx/gfx_tools.h"
+#include "sci/gfx/gfx_options.h"
+#include "sci/gfx/gfx_system.h"
+#include "sci/include/uinput.h"
+
+namespace Sci {
+
+#define GFXOP_NO_POINTER -1
+
+/* Threshold in color index mode to differentiate between visible and non-visible stuff.
+** GFXOP_ALPHA_THRESHOLD itself should be treated as non-visible.
+*/
+#define GFXOP_ALPHA_THRESHOLD 0xff
+
+struct gfx_text_handle_t {
+	char *text; /* Copy of the actual text */
+
+	int lines_nr;
+	int line_height;
+	text_fragment_t *lines; /* Text offsets */
+	gfx_bitmap_font_t *font;
+	gfx_pixmap_t **text_pixmaps;
+
+	int width, height;
+
+	int priority, control;
+	gfx_alignment_t halign, valign;
+};
+
+/* Unless individually stated otherwise, the following applies:
+** All operations herein apply to the standard 320x200 coordinate system.
+** All operations perform clipping relative to state->clip_zone.
+*/
+
+typedef enum {
+	GFX_BOX_SHADE_FLAT,
+	GFX_BOX_SHADE_RIGHT,
+	GFX_BOX_SHADE_LEFT,
+	GFX_BOX_SHADE_DOWN,
+	GFX_BOX_SHADE_UP
+#if 0
+	/* possible with alphaing, but there is no way to check for
+	** alpha capability of gfx_driver->draw_filled_rect() yet
+	*/
+	, GFX_BOX_SHADE_RIGHT_DOWN,
+	GFX_BOX_SHADE_LEFT_DOWN,
+	GFX_BOX_SHADE_RIGHT_UP,
+	GFX_BOX_SHADE_LEFT_UP
+#endif
+} gfx_box_shade_t;
+
+
+struct gfx_dirty_rect_t {
+	rect_t rect;
+	gfx_dirty_rect_t *next;
+};
+
+
+struct gfx_input_event_t {

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list