/*
 * Server-side console management
 *
 * Copyright (C) 1998 Alexandre Julliard
 *               2001 Eric Pouech
 *
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wine/port.h"

#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

#include "handle.h"
#include "process.h"
#include "request.h"
#include "unicode.h"
#include "console.h"


static void console_input_dump( struct object *obj, int verbose );
static void console_input_destroy( struct object *obj );
static int console_input_signaled( struct object *obj, struct thread *thread );

static const struct object_ops console_input_ops =
{
    sizeof(struct console_input),     /* size */
    console_input_dump,               /* dump */
    add_queue,                        /* add_queue */
    remove_queue,                     /* remove_queue */
    console_input_signaled,           /* signaled */
    no_satisfied,                     /* satisfied */
    no_get_fd,                        /* get_fd */
    console_input_destroy             /* destroy */
};

static void console_input_events_dump( struct object *obj, int verbose );
static void console_input_events_destroy( struct object *obj );
static int  console_input_events_signaled( struct object *obj, struct thread *thread );

struct console_input_events
{
    struct object         obj;         /* object header */
    int			  num_alloc;   /* number of allocated events */
    int 		  num_used;    /* number of actually used events */
    struct console_renderer_event*	events;
};

static const struct object_ops console_input_events_ops =
{
    sizeof(struct console_input_events), /* size */
    console_input_events_dump,        /* dump */
    add_queue,                        /* add_queue */
    remove_queue,                     /* remove_queue */
    console_input_events_signaled,    /* signaled */
    no_satisfied,                     /* satisfied */
    no_get_fd,                        /* get_fd */
    console_input_events_destroy      /* destroy */
};

struct screen_buffer
{
    struct object         obj;           /* object header */
    struct screen_buffer *next;          /* linked list of all screen buffers */
    struct screen_buffer *prev;
    struct console_input *input;         /* associated console input */
    int                   mode;          /* output mode */
    int                   cursor_size;   /* size of cursor (percentage filled) */
    int                   cursor_visible;/* cursor visibility flag */
    int                   cursor_x;      /* position of cursor */
    int                   cursor_y;      /* position of cursor */
    int                   width;         /* size (w-h) of the screen buffer */
    int                   height;
    int                   max_width;     /* size (w-h) of the window given font size */
    int                   max_height;
    char_info_t          *data;          /* the data for each cell - a width x height matrix */
    unsigned short        attr;          /* default attribute for screen buffer */
    rectangle_t           win;           /* current visible window on the screen buffer *
					  * as seen in wineconsole */
};

static void screen_buffer_dump( struct object *obj, int verbose );
static void screen_buffer_destroy( struct object *obj );

static const struct object_ops screen_buffer_ops =
{
    sizeof(struct screen_buffer),     /* size */
    screen_buffer_dump,               /* dump */
    no_add_queue,                     /* add_queue */
    NULL,                             /* remove_queue */
    NULL,                             /* signaled */
    NULL,                             /* satisfied */
    no_get_fd,                        /* get_fd */
    screen_buffer_destroy             /* destroy */
};

static struct screen_buffer *screen_buffer_list;

static const char_info_t empty_char_info = { ' ', 0x000f };  /* white on black space */

/* dumps the renderer events of a console */
static void console_input_events_dump( struct object *obj, int verbose )
{
    struct console_input_events *evts = (struct console_input_events *)obj;
    assert( obj->ops == &console_input_events_ops );
    fprintf( stderr, "Console input events: %d/%d events\n",
	     evts->num_used, evts->num_alloc );
}

/* destroys the renderer events of a console */
static void console_input_events_destroy( struct object *obj )
{
    struct console_input_events *evts = (struct console_input_events *)obj;
    assert( obj->ops == &console_input_events_ops );
    free( evts->events );
}

/* the renderer events list is signaled when it's not empty */
static int console_input_events_signaled( struct object *obj, struct thread *thread )
{
    struct console_input_events *evts = (struct console_input_events *)obj;
    assert( obj->ops == &console_input_events_ops );
    return (evts->num_used != 0);
}

/* add an event to the console's renderer events list */
static void console_input_events_append( struct console_input_events* evts,
					 struct console_renderer_event* evt)
{
    int collapsed = FALSE;

    /* to be done even when evt has been generated by the rendere ? */

    /* try to collapse evt into current queue's events */
    if (evts->num_used)
    {
        struct console_renderer_event* last = &evts->events[evts->num_used - 1];

        if (last->event == CONSOLE_RENDERER_UPDATE_EVENT &&
            evt->event == CONSOLE_RENDERER_UPDATE_EVENT)
        {
            /* if two update events overlap, collapse them into a single one */
            if (last->u.update.bottom + 1 >= evt->u.update.top &&
                evt->u.update.bottom + 1 >= last->u.update.top)
            {
                last->u.update.top = min(last->u.update.top, evt->u.update.top);
                last->u.update.bottom = max(last->u.update.bottom, evt->u.update.bottom);
                collapsed = TRUE;
            }
        }
    }
    if (!collapsed)
    {
        if (evts->num_used == evts->num_alloc)
        {
            evts->num_alloc += 16;
            evts->events = realloc( evts->events, evts->num_alloc * sizeof(*evt) );
            assert(evts->events);
        }
        evts->events[evts->num_used++] = *evt;
    }
    wake_up( &evts->obj, 0 );
}

/* retrieves events from the console's renderer events list */
static void console_input_events_get( struct console_input_events* evts )
{
    size_t num = get_reply_max_size() / sizeof(evts->events[0]);

    if (num > evts->num_used) num = evts->num_used;
    set_reply_data( evts->events, num * sizeof(evts->events[0]) );
    if (num < evts->num_used)
    {
        memmove( &evts->events[0], &evts->events[num],
                 (evts->num_used - num) * sizeof(evts->events[0]) );
    }
    evts->num_used -= num;
}

static struct console_input_events *create_console_input_events(void)
{
    struct console_input_events*	evt;

    if (!(evt = alloc_object( &console_input_events_ops ))) return NULL;
    evt->num_alloc = evt->num_used = 0;
    evt->events = NULL;
    return evt;
}

static struct object *create_console_input( struct thread* renderer )
{
    struct console_input *console_input;

    if (!(console_input = alloc_object( &console_input_ops ))) return NULL;
    console_input->renderer      = renderer;
    console_input->mode          = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT |
	                           ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT;
    console_input->num_proc      = 0;
    console_input->active        = NULL;
    console_input->recnum        = 0;
    console_input->records       = NULL;
    console_input->evt           = create_console_input_events();
    console_input->title         = NULL;
    console_input->history_size  = 50;
    console_input->history       = calloc( console_input->history_size, sizeof(WCHAR*) );
    console_input->history_index = 0;
    console_input->history_mode  = 0;
    console_input->edition_mode  = 0;

    if (!console_input->history || !console_input->evt)
    {
	release_object( console_input );
	return NULL;
    }
    return &console_input->obj;
}

static struct screen_buffer *create_console_output( struct console_input *console_input )
{
    struct screen_buffer *screen_buffer;
    struct console_renderer_event evt;
    int	i;

    if (!(screen_buffer = alloc_object( &screen_buffer_ops ))) return NULL;
    screen_buffer->mode           = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
    screen_buffer->input          = console_input;
    screen_buffer->cursor_size    = 100;
    screen_buffer->cursor_visible = 1;
    screen_buffer->width          = 80;
    screen_buffer->height         = 150;
    screen_buffer->max_width      = 80;
    screen_buffer->max_height     = 25;
    screen_buffer->cursor_x       = 0;
    screen_buffer->cursor_y       = 0;
    screen_buffer->attr           = 0x0F;
    screen_buffer->win.left       = 0;
    screen_buffer->win.right      = screen_buffer->max_width - 1;
    screen_buffer->win.top        = 0;
    screen_buffer->win.bottom     = screen_buffer->max_height - 1;

    if ((screen_buffer->next = screen_buffer_list)) screen_buffer->next->prev = screen_buffer;
    screen_buffer->prev = NULL;
    screen_buffer_list = screen_buffer;

    if (!(screen_buffer->data = malloc( screen_buffer->width * screen_buffer->height *
                                        sizeof(*screen_buffer->data) )))
    {
        release_object( screen_buffer );
        return NULL;
    }
    /* clear the first row */
    for (i = 0; i < screen_buffer->width; i++) screen_buffer->data[i] = empty_char_info;
    /* and copy it to all other rows */
    for (i = 1; i < screen_buffer->height; i++)
        memcpy( &screen_buffer->data[i * screen_buffer->width], screen_buffer->data,
                screen_buffer->width * sizeof(char_info_t) );

    if (!console_input->active)
    {
	console_input->active = (struct screen_buffer*)grab_object( screen_buffer );

	/* generate the initial events */
	evt.event = CONSOLE_RENDERER_ACTIVE_SB_EVENT;
	console_input_events_append( console_input->evt, &evt );

	evt.event = CONSOLE_RENDERER_SB_RESIZE_EVENT;
	evt.u.resize.width  = screen_buffer->width;
	evt.u.resize.height = screen_buffer->height;
	console_input_events_append( console_input->evt, &evt );

	evt.event = CONSOLE_RENDERER_DISPLAY_EVENT;
	evt.u.display.left   = screen_buffer->win.left;
	evt.u.display.top    = screen_buffer->win.top;
	evt.u.display.width  = screen_buffer->win.right - screen_buffer->win.left + 1;
	evt.u.display.height = screen_buffer->win.bottom - screen_buffer->win.top + 1;
	console_input_events_append( console_input->evt, &evt );

	evt.event = CONSOLE_RENDERER_UPDATE_EVENT;
	evt.u.update.top    = 0;
	evt.u.update.bottom = screen_buffer->height - 1;
	console_input_events_append( console_input->evt, &evt );

 	evt.event = CONSOLE_RENDERER_CURSOR_GEOM_EVENT;
 	evt.u.cursor_geom.size    = screen_buffer->cursor_size;
 	evt.u.cursor_geom.visible = screen_buffer->cursor_visible;
 	console_input_events_append( console_input->evt, &evt );

	evt.event = CONSOLE_RENDERER_CURSOR_POS_EVENT;
	evt.u.cursor_pos.x = screen_buffer->cursor_x;
	evt.u.cursor_pos.y = screen_buffer->cursor_y;
	console_input_events_append( console_input->evt, &evt );
    }
    return screen_buffer;
}

/* free the console for this process */
int free_console( struct process *process )
{
    struct console_input* console = process->console;

    if (!console || !console->renderer) return 0;

    process->console = NULL;
    if (--console->num_proc == 0)
    {
	/* all processes have terminated... tell the renderer to terminate too */
	struct console_renderer_event evt;
	evt.event = CONSOLE_RENDERER_EXIT_EVENT;
	console_input_events_append( console->evt, &evt );
    }
    release_object( console );

    return 1;
}

/* let process inherit the console from parent... this handle two cases :
 *	1/ generic console inheritance
 *	2/ parent is a renderer which launches process, and process should attach to the console
 *	   renderered by parent
 */
void inherit_console(struct thread *parent_thread, struct process *process, obj_handle_t hconin)
{
    int done = 0;
    struct process* parent = parent_thread->process;

    /* if parent is a renderer, then attach current process to its console
     * a bit hacky....
     */
    if (hconin)
    {
	struct console_input* console;

        if ((console = (struct console_input*)get_handle_obj( parent, hconin, 0, NULL )))
	{
	    if (console->renderer == parent_thread)
	    {
		process->console = (struct console_input*)grab_object( console );
		process->console->num_proc++;
		done = 1;
	    }
	    release_object( console );
	}
    }
    /* otherwise, if parent has a console, attach child to this console */
    if (!done && parent->console)
    {
	assert(parent->console->renderer);
	process->console = (struct console_input*)grab_object( parent->console );
	process->console->num_proc++;
    }
}

int is_console_object( struct object *obj )
{
    return (obj->ops == &console_input_ops || obj->ops == &screen_buffer_ops);
}

static struct console_input* console_input_get( obj_handle_t handle, unsigned access )
{
    struct console_input*	console = 0;

    if (handle)
	console = (struct console_input *)get_handle_obj( current->process, handle,
							  access, &console_input_ops );
    else if (current->process->console)
    {
	assert( current->process->console->renderer );
	console = (struct console_input *)grab_object( current->process->console );
    }

    if (!console && !get_error()) set_error(STATUS_INVALID_PARAMETER);
    return console;
}

/* check if a console input is signaled: yes if non read input records */
static int console_input_signaled( struct object *obj, struct thread *thread )
{
    struct console_input *console = (struct console_input *)obj;
    assert( obj->ops == &console_input_ops );
    return console->recnum ? 1 : 0;
}

struct console_signal_info {
    struct console_input        *console;
    process_id_t                 group;
    int                          signal;
};

static int propagate_console_signal_cb(struct process *process, void *user)
{
    struct console_signal_info* csi = (struct console_signal_info*)user;

    if (process->console == csi->console && process->running_threads &&
        (!csi->group || process->group_id == csi->group))
    {
        struct thread *thread = process->thread_list;

        while (thread)
        {
            struct thread *next = thread->proc_next;
            send_thread_signal( thread, csi->signal );
            thread = next;
        }
    }
    return FALSE;
}

static void propagate_console_signal( struct console_input *console,
                                      int sig, process_id_t group_id )
{
    struct console_signal_info csi;

    if (!console)
    {
        set_error( STATUS_INVALID_PARAMETER );
        return;
    }
    /* FIXME: should support the other events (like CTRL_BREAK) */
    if (sig != CTRL_C_EVENT)
    {
        set_error( STATUS_NOT_IMPLEMENTED );
        return;
    }
    csi.console = console;
    csi.signal  = SIGINT;
    csi.group   = group_id;

    enum_processes(propagate_console_signal_cb, &csi);
}

static int get_console_mode( obj_handle_t handle )
{
    struct object *obj;
    int ret = 0;

    if ((obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL )))
    {
        if (obj->ops == &console_input_ops)
            ret = ((struct console_input *)obj)->mode;
        else if (obj->ops == &screen_buffer_ops)
            ret = ((struct screen_buffer *)obj)->mode;
        else
            set_error( STATUS_OBJECT_TYPE_MISMATCH );
        release_object( obj );
    }
    return ret;
}

/* changes the mode of either a console input or a screen buffer */
static int set_console_mode( obj_handle_t handle, int mode )
{
    struct object *obj;
    int ret = 0;

    if (!(obj = get_handle_obj( current->process, handle, GENERIC_WRITE, NULL )))
        return 0;
    if (obj->ops == &console_input_ops)
    {
	/* FIXME: if we remove the edit mode bits, we need (???) to clean up the history */
        ((struct console_input *)obj)->mode = mode;
        ret = 1;
    }
    else if (obj->ops == &screen_buffer_ops)
    {
        ((struct screen_buffer *)obj)->mode = mode;
        ret = 1;
    }
    else set_error( STATUS_OBJECT_TYPE_MISMATCH );
    release_object( obj );
    return ret;
}

/* add input events to a console input queue */
static int write_console_input( struct console_input* console, int count,
                                const INPUT_RECORD *records )
{
    INPUT_RECORD *new_rec;

    if (!count) return 0;
    if (!(new_rec = realloc( console->records,
                             (console->recnum + count) * sizeof(INPUT_RECORD) )))
    {
        set_error( STATUS_NO_MEMORY );
        release_object( console );
        return -1;
    }
    console->records = new_rec;
    memcpy( new_rec + console->recnum, records, count * sizeof(INPUT_RECORD) );

    if (console->mode & ENABLE_PROCESSED_INPUT)
    {
        int i = 0;
        while (i < count)
        {
            if (records[i].EventType == KEY_EVENT &&
		records[i].Event.KeyEvent.uChar.UnicodeChar == 'C' - 64 &&
		!(records[i].Event.KeyEvent.dwControlKeyState & ENHANCED_KEY))
            {
                if (i != count - 1)
                    memcpy( &console->records[console->recnum + i],
                            &console->records[console->recnum + i + 1],
                            (count - i - 1) * sizeof(INPUT_RECORD) );
                count--;
                if (records[i].Event.KeyEvent.bKeyDown)
                {
                    /* send SIGINT to all processes attached to this console */
                    propagate_console_signal( console, CTRL_C_EVENT, 0 );
                }
            }
            else i++;
        }
    }
    console->recnum += count;
    /* wake up all waiters */
    wake_up( &console->obj, 0 );
    return count;
}

/* retrieve a pointer to the console input records */
static int read_console_input( obj_handle_t handle, int count, int flush )
{
    struct console_input *console;

    if (!(console = (struct console_input *)get_handle_obj( current->process, handle,
                                                            GENERIC_READ, &console_input_ops )))
        return -1;

    if (!count)
    {
        /* special case: do not retrieve anything, but return
         * the total number of records available */
        count = console->recnum;
    }
    else
    {
        if (count > console->recnum) count = console->recnum;
        set_reply_data( console->records, count * sizeof(INPUT_RECORD) );
    }
    if (flush)
    {
        int i;
        for (i = count; i < console->recnum; i++)
            console->records[i-count] = console->records[i];
        if ((console->recnum -= count) > 0)
        {
            INPUT_RECORD *new_rec = realloc( console->records,
                                             console->recnum * sizeof(INPUT_RECORD) );
            if (new_rec) console->records = new_rec;
        }
        else
        {
            free( console->records );
            console->records = NULL;
        }
    }
    release_object( console );
    return count;
}

/* set misc console input information */
static int set_console_input_info( const struct set_console_input_info_request *req,
				   const WCHAR *title, size_t len )
{
    struct console_input *console;
    struct console_renderer_event evt;

    if (!(console = console_input_get( req->handle, GENERIC_WRITE ))) goto error;

    if (req->mask & SET_CONSOLE_INPUT_INFO_ACTIVE_SB)
    {
	struct screen_buffer *screen_buffer;

	screen_buffer = (struct screen_buffer *)get_handle_obj( current->process, req->active_sb,
								GENERIC_READ, &screen_buffer_ops );
	if (!screen_buffer || screen_buffer->input != console)
	{
	    set_error( STATUS_INVALID_PARAMETER );
	    if (screen_buffer) release_object( screen_buffer );
	    goto error;
	}

	if (screen_buffer != console->active)
	{
	    if (console->active) release_object( console->active );
	    console->active = screen_buffer;
	    evt.event = CONSOLE_RENDERER_ACTIVE_SB_EVENT;
	    console_input_events_append( console->evt, &evt );
	}
	else
	    release_object( screen_buffer );
    }
    if (req->mask & SET_CONSOLE_INPUT_INFO_TITLE)
    {
        WCHAR *new_title = mem_alloc( len + sizeof(WCHAR) );
        if (new_title)
        {
            memcpy( new_title, title, len );
            new_title[len / sizeof(WCHAR)] = 0;
            if (console->title) free( console->title );
            console->title = new_title;
	    evt.event = CONSOLE_RENDERER_TITLE_EVENT;
	    console_input_events_append( console->evt, &evt );
        }
    }
    if (req->mask & SET_CONSOLE_INPUT_INFO_HISTORY_MODE)
    {
	console->history_mode = req->history_mode;
    }
    if ((req->mask & SET_CONSOLE_INPUT_INFO_HISTORY_SIZE) &&
	console->history_size != req->history_size)
    {
	WCHAR**	mem = NULL;
	int	i;
	int	delta;

	if (req->history_size)
	{
	    mem = mem_alloc( req->history_size * sizeof(WCHAR*) );
	    if (!mem) goto error;
	    memset( mem, 0, req->history_size * sizeof(WCHAR*) );
	}

	delta = (console->history_index > req->history_size) ?
	    (console->history_index - req->history_size) : 0;

	for (i = delta; i < console->history_index; i++)
	{
	    mem[i - delta] = console->history[i];
	    console->history[i] = NULL;
	}
	console->history_index -= delta;

	for (i = 0; i < console->history_size; i++)
	    if (console->history[i]) free( console->history[i] );
	free( console->history );
	console->history = mem;
	console->history_size = req->history_size;
    }
    if (req->mask & SET_CONSOLE_INPUT_INFO_EDITION_MODE)
    {
        console->edition_mode = req->edition_mode;
    }
    release_object( console );
    return 1;
 error:
    if (console) release_object( console );
    return 0;
}

/* resize a screen buffer */
static int change_screen_buffer_size( struct screen_buffer *screen_buffer,
                                      int new_width, int new_height )
{
    int i, old_width, old_height, copy_width, copy_height;
    char_info_t *new_data;

    if (!(new_data = malloc( new_width * new_height * sizeof(*new_data) )))
    {
        set_error( STATUS_NO_MEMORY );
        return 0;
    }
    old_width = screen_buffer->width;
    old_height = screen_buffer->height;
    copy_width = min( old_width, new_width );
    copy_height = min( old_height, new_height );

    /* copy all the rows */
    for (i = 0; i < copy_height; i++)
    {
        memcpy( &new_data[i * new_width], &screen_buffer->data[i * old_width],
                copy_width * sizeof(char_info_t) );
    }

    /* clear the end of each row */
    if (new_width > old_width)
    {
        /* fill first row */
        for (i = old_width; i < new_width; i++) new_data[i] = empty_char_info;
        /* and blast it to the other rows */
        for (i = 1; i < copy_height; i++)
            memcpy( &new_data[i * new_width + old_width], &new_data[old_width],
                    (new_width - old_width) * sizeof(char_info_t) );
    }

    /* clear remaining rows */
    if (new_height > old_height)
    {
        /* fill first row */
        for (i = 0; i < new_width; i++) new_data[old_height * new_width + i] = empty_char_info;
        /* and blast it to the other rows */
        for (i = old_height+1; i < new_height; i++)
            memcpy( &new_data[i * new_width], &new_data[old_height * new_width],
                    new_width * sizeof(char_info_t) );
    }
    free( screen_buffer->data );
    screen_buffer->data = new_data;
    screen_buffer->width = new_width;
    screen_buffer->height = new_height;
    return 1;
}

/* set misc screen buffer information */
static int set_console_output_info( struct screen_buffer *screen_buffer,
                                    const struct set_console_output_info_request *req )
{
    struct console_renderer_event evt;

    if (req->mask & SET_CONSOLE_OUTPUT_INFO_CURSOR_GEOM)
    {
	if (req->cursor_size < 1 || req->cursor_size > 100)
	{
	    set_error( STATUS_INVALID_PARAMETER );
	    return 0;
	}
        if (screen_buffer->cursor_size != req->cursor_size ||
	    screen_buffer->cursor_visible != req->cursor_visible)
	{
	    screen_buffer->cursor_size    = req->cursor_size;
	    screen_buffer->cursor_visible = req->cursor_visible;
	    evt.event = CONSOLE_RENDERER_CURSOR_GEOM_EVENT;
	    evt.u.cursor_geom.size    = req->cursor_size;
	    evt.u.cursor_geom.visible = req->cursor_visible;
	    console_input_events_append( screen_buffer->input->evt, &evt );
	}
    }
    if (req->mask & SET_CONSOLE_OUTPUT_INFO_CURSOR_POS)
    {
	if (req->cursor_x < 0 || req->cursor_x >= screen_buffer->width ||
	    req->cursor_y < 0 || req->cursor_y >= screen_buffer->height)
	{
	    set_error( STATUS_INVALID_PARAMETER );
	    return 0;
	}
	if (screen_buffer->cursor_x != req->cursor_x || screen_buffer->cursor_y != req->cursor_y)
	{
	    screen_buffer->cursor_x       = req->cursor_x;
	    screen_buffer->cursor_y       = req->cursor_y;
	    evt.event = CONSOLE_RENDERER_CURSOR_POS_EVENT;
	    evt.u.cursor_pos.x = req->cursor_x;
	    evt.u.cursor_pos.y = req->cursor_y;
	    console_input_events_append( screen_buffer->input->evt, &evt );
	}
    }
    if (req->mask & SET_CONSOLE_OUTPUT_INFO_SIZE)
    {
        unsigned cc;

        /* new screen-buffer cannot be smaller than actual window */
	if (req->width < screen_buffer->win.right - screen_buffer->win.left + 1 ||
            req->height < screen_buffer->win.bottom - screen_buffer->win.top + 1)
	{
	    set_error( STATUS_INVALID_PARAMETER );
	    return 0;
	}
        /* FIXME: there are also some basic minimum and max size to deal with */
        if (!change_screen_buffer_size( screen_buffer, req->width, req->height )) return 0;

	evt.event = CONSOLE_RENDERER_SB_RESIZE_EVENT;
	evt.u.resize.width  = req->width;
	evt.u.resize.height = req->height;
	console_input_events_append( screen_buffer->input->evt, &evt );

	evt.event = CONSOLE_RENDERER_UPDATE_EVENT;
	evt.u.update.top    = 0;
	evt.u.update.bottom = screen_buffer->height - 1;
	console_input_events_append( screen_buffer->input->evt, &evt );

        /* scroll window to display sb */
        if (screen_buffer->win.right >= req->width)
        {       
            screen_buffer->win.right -= screen_buffer->win.left;
            screen_buffer->win.left = 0;
        }
        if (screen_buffer->win.bottom >= req->height)
        {       
            screen_buffer->win.bottom -= screen_buffer->win.top;
            screen_buffer->win.top = 0;
        }
        /* reset cursor if needed (normally, if cursor was outside of new sb, the
         * window has been shifted so that the new position of the cursor will be 
         * visible */
        cc = 0;
        if (screen_buffer->cursor_x >= req->width)
        {
            screen_buffer->cursor_x = req->width - 1;
            cc++;
        }
        if (screen_buffer->cursor_y >= req->height)
        {
            screen_buffer->cursor_y = req->height - 1;
            cc++;
        }
        if (cc)
        {
            evt.event = CONSOLE_RENDERER_CURSOR_POS_EVENT;
            evt.u.cursor_pos.x = req->cursor_x;
            evt.u.cursor_pos.y = req->cursor_y;
            console_input_events_append( screen_buffer->input->evt, &evt );
        }

	if (screen_buffer == screen_buffer->input->active &&
	    screen_buffer->input->mode & ENABLE_WINDOW_INPUT)
	{
	    INPUT_RECORD	ir;
	    ir.EventType = WINDOW_BUFFER_SIZE_EVENT;
	    ir.Event.WindowBufferSizeEvent.dwSize.X = req->width;
	    ir.Event.WindowBufferSizeEvent.dwSize.Y = req->height;
	    write_console_input( screen_buffer->input, 1, &ir );
	}
    }
    if (req->mask & SET_CONSOLE_OUTPUT_INFO_ATTR)
    {
	screen_buffer->attr = req->attr;
    }
    if (req->mask & SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW)
    {
	if (req->win_left < 0 || req->win_left > req->win_right ||
	    req->win_right >= screen_buffer->width ||
	    req->win_top < 0  || req->win_top > req->win_bottom ||
	    req->win_bottom >= screen_buffer->height)
	{
	    set_error( STATUS_INVALID_PARAMETER );
	    return 0;
	}
	if (screen_buffer->win.left != req->win_left || screen_buffer->win.top != req->win_top ||
	    screen_buffer->win.right != req->win_right || screen_buffer->win.bottom != req->win_bottom)
	{
	    screen_buffer->win.left   = req->win_left;
	    screen_buffer->win.top    = req->win_top;
	    screen_buffer->win.right  = req->win_right;
	    screen_buffer->win.bottom = req->win_bottom;
	    evt.event = CONSOLE_RENDERER_DISPLAY_EVENT;
	    evt.u.display.left   = req->win_left;
	    evt.u.display.top    = req->win_top;
	    evt.u.display.width  = req->win_right - req->win_left + 1;
	    evt.u.display.height = req->win_bottom - req->win_top + 1;
	    console_input_events_append( screen_buffer->input->evt, &evt );
	}
    }
    if (req->mask & SET_CONSOLE_OUTPUT_INFO_MAX_SIZE)
    {
	/* can only be done by renderer */
	if (current->process->console != screen_buffer->input)
	{
	    set_error( STATUS_INVALID_PARAMETER );
	    return 0;
	}

	screen_buffer->max_width  = req->max_width;
	screen_buffer->max_height = req->max_height;
    }

    return 1;
}

/* appends a new line to history (history is a fixed size array) */
static void console_input_append_hist( struct console_input* console, const WCHAR* buf, size_t len )
{
    WCHAR*	ptr = mem_alloc( (len + 1) * sizeof(WCHAR) );

    if (!ptr)
    {
	set_error( STATUS_NO_MEMORY );
	return;
    }
    if (!console || !console->history_size)
    {
	set_error( STATUS_INVALID_PARAMETER ); /* FIXME */
	return;
    }

    memcpy( ptr, buf, len * sizeof(WCHAR) );
    ptr[len] = 0;

    if (console->history_mode && console->history_index &&
	strncmpW( console->history[console->history_index - 1], ptr, len * sizeof(WCHAR) ) == 0)
    {
	/* ok, mode ask us to not use twice the same string...
	 * so just free mem and returns
	 */
	set_error( STATUS_ALIAS_EXISTS );
	free(ptr);
	return;
    }

    if (console->history_index < console->history_size)
    {
	console->history[console->history_index++] = ptr;
    }
    else
    {
	free( console->history[0]) ;
	memmove( &console->history[0], &console->history[1],
		 (console->history_size - 1) * sizeof(WCHAR*) );
	console->history[console->history_size - 1] = ptr;
    }
}

/* returns a line from the cache */
static size_t console_input_get_hist( struct console_input *console, int index )
{
    size_t ret = 0;

    if (index >= console->history_index) set_error( STATUS_INVALID_PARAMETER );
    else
    {
        ret = strlenW( console->history[index] ) * sizeof(WCHAR);
        set_reply_data( console->history[index], min( ret, get_reply_max_size() ));
    }
    return ret;
}

/* dumb dump */
static void console_input_dump( struct object *obj, int verbose )
{
    struct console_input *console = (struct console_input *)obj;
    assert( obj->ops == &console_input_ops );
    fprintf( stderr, "Console input active=%p evt=%p\n",
	     console->active, console->evt );
}

static void console_input_destroy( struct object *obj )
{
    struct console_input*	console_in = (struct console_input *)obj;
    struct screen_buffer*	curr;
    int				i;

    assert( obj->ops == &console_input_ops );
    if (console_in->title) free( console_in->title );
    if (console_in->records) free( console_in->records );

    if (console_in->active)	release_object( console_in->active );
    console_in->active = NULL;

    for (curr = screen_buffer_list; curr; curr = curr->next)
    {
	if (curr->input == console_in) curr->input = NULL;
    }

    release_object( console_in->evt );
    console_in->evt = NULL;

    for (i = 0; i < console_in->history_size; i++)
	if (console_in->history[i]) free( console_in->history[i] );
    if (console_in->history) free( console_in->history );
}

static void screen_buffer_dump( struct object *obj, int verbose )
{
    struct screen_buffer *screen_buffer = (struct screen_buffer *)obj;
    assert( obj->ops == &screen_buffer_ops );

    fprintf(stderr, "Console screen buffer input=%p\n", screen_buffer->input );
}

static void screen_buffer_destroy( struct object *obj )
{
    struct screen_buffer *screen_buffer = (struct screen_buffer *)obj;

    assert( obj->ops == &screen_buffer_ops );

    if (screen_buffer->next) screen_buffer->next->prev = screen_buffer->prev;
    if (screen_buffer->prev) screen_buffer->prev->next = screen_buffer->next;
    else screen_buffer_list = screen_buffer->next;

    if (screen_buffer->input && screen_buffer->input->active == screen_buffer)
    {
	struct screen_buffer*	sb;
	for (sb = screen_buffer_list; sb && sb->input != screen_buffer->input; sb = sb->next);
	screen_buffer->input->active = sb;
    }
    if (screen_buffer->data) free( screen_buffer->data );
}

/* write data into a screen buffer */
static int write_console_output( struct screen_buffer *screen_buffer, size_t size,
                                 const void* data, enum char_info_mode mode,
                                 int x, int y, int wrap )
{
    int i;
    char_info_t *end, *dest = screen_buffer->data + y * screen_buffer->width + x;

    if (y >= screen_buffer->height) return 0;

    if (wrap)
        end = screen_buffer->data + screen_buffer->height * screen_buffer->width;
    else
        end = screen_buffer->data + (y+1) * screen_buffer->width;

    switch(mode)
    {
    case CHAR_INFO_MODE_TEXT:
        {
            const WCHAR *ptr = data;
            for (i = 0; i < size/sizeof(*ptr) && dest < end; dest++, i++) dest->ch = ptr[i];
        }
        break;
    case CHAR_INFO_MODE_ATTR:
        {
            const unsigned short *ptr = data;
            for (i = 0; i < size/sizeof(*ptr) && dest < end; dest++, i++) dest->attr = ptr[i];
        }
        break;
    case CHAR_INFO_MODE_TEXTATTR:
        {
            const char_info_t *ptr = data;
            for (i = 0; i < size/sizeof(*ptr) && dest < end; dest++, i++) *dest = ptr[i];
        }
        break;
    case CHAR_INFO_MODE_TEXTSTDATTR:
        {
            const WCHAR *ptr = data;
            for (i = 0; i < size/sizeof(*ptr) && dest < end; dest++, i++)
            {
                dest->ch   = ptr[i];
                dest->attr = screen_buffer->attr;
            }
        }
        break;
    default:
        set_error( STATUS_INVALID_PARAMETER );
        return 0;
    }

    if (i && screen_buffer == screen_buffer->input->active)
    {
        struct console_renderer_event evt;
        evt.event = CONSOLE_RENDERER_UPDATE_EVENT;
        evt.u.update.top    = y + x / screen_buffer->width;
        evt.u.update.bottom = y + (x + i - 1) / screen_buffer->width;
        console_input_events_append( screen_buffer->input->evt, &evt );
    }
    return i;
}

/* fill a screen buffer with uniform data */
static int fill_console_output( struct screen_buffer *screen_buffer, char_info_t data,
                                enum char_info_mode mode, int x, int y, int count, int wrap )
{
    int i;
    char_info_t *end, *dest = screen_buffer->data + y * screen_buffer->width + x;

    if (y >= screen_buffer->height) return 0;

    if (wrap)
        end = screen_buffer->data + screen_buffer->height * screen_buffer->width;
    else
        end = screen_buffer->data + (y+1) * screen_buffer->width;

    if (count > end - dest) count = end - dest;

    switch(mode)
    {
    case CHAR_INFO_MODE_TEXT:
        for (i = 0; i < count; i++) dest[i].ch = data.ch;
        break;
    case CHAR_INFO_MODE_ATTR:
        for (i = 0; i < count; i++) dest[i].attr = data.attr;
        break;
    case CHAR_INFO_MODE_TEXTATTR:
        for (i = 0; i < count; i++) dest[i] = data;
        break;
    case CHAR_INFO_MODE_TEXTSTDATTR:
        for (i = 0; i < count; i++)
        {
            dest[i].ch   = data.ch;
            dest[i].attr = screen_buffer->attr;
        }
        break;
    default:
        set_error( STATUS_INVALID_PARAMETER );
        return 0;
    }

    if (count && screen_buffer == screen_buffer->input->active)
    {
        struct console_renderer_event evt;
        evt.event = CONSOLE_RENDERER_UPDATE_EVENT;
        evt.u.update.top    = y;
        evt.u.update.bottom = (y * screen_buffer->width + x + count - 1) / screen_buffer->width;
        console_input_events_append( screen_buffer->input->evt, &evt );
    }
    return i;
}

/* read data from a screen buffer */
static void read_console_output( struct screen_buffer *screen_buffer, int x, int y,
                                 enum char_info_mode mode, int wrap )
{
    int i;
    char_info_t *end, *src = screen_buffer->data + y * screen_buffer->width + x;

    if (y >= screen_buffer->height) return;

    if (wrap)
        end = screen_buffer->data + screen_buffer->height * screen_buffer->width;
    else
        end = screen_buffer->data + (y+1) * screen_buffer->width;

    switch(mode)
    {
    case CHAR_INFO_MODE_TEXT:
        {
            WCHAR *data;
            int count = min( end - src, get_reply_max_size() / sizeof(*data) );
            if ((data = set_reply_data_size( count * sizeof(*data) )))
            {
                for (i = 0; i < count; i++) data[i] = src[i].ch;
            }
        }
        break;
    case CHAR_INFO_MODE_ATTR:
        {
            unsigned short *data;
            int count = min( end - src, get_reply_max_size() / sizeof(*data) );
            if ((data = set_reply_data_size( count * sizeof(*data) )))
            {
                for (i = 0; i < count; i++) data[i] = src[i].attr;
            }
        }
        break;
    case CHAR_INFO_MODE_TEXTATTR:
        {
            char_info_t *data;
            int count = min( end - src, get_reply_max_size() / sizeof(*data) );
            if ((data = set_reply_data_size( count * sizeof(*data) )))
            {
                for (i = 0; i < count; i++) data[i] = src[i];
            }
        }
        break;
    default:
        set_error( STATUS_INVALID_PARAMETER );
        break;
    }
}

/* scroll parts of a screen buffer */
static void scroll_console_output( obj_handle_t handle, int xsrc, int ysrc, int xdst, int ydst,
                                   int w, int h )
{
    struct screen_buffer *screen_buffer;
    int				j;
    char_info_t *psrc, *pdst;
    struct console_renderer_event evt;

    if (!(screen_buffer = (struct screen_buffer *)get_handle_obj( current->process, handle,
								  GENERIC_READ, &screen_buffer_ops )))
	return;
    if (xsrc < 0 || ysrc < 0 || xdst < 0 || ydst < 0 ||
	xsrc + w > screen_buffer->width  ||
	xdst + w > screen_buffer->width  ||
	ysrc + h > screen_buffer->height ||
	ydst + h > screen_buffer->height ||
	w == 0 || h == 0)
    {
	set_error( STATUS_INVALID_PARAMETER );
	release_object( screen_buffer );
	return;
    }

    if (ysrc < ydst)
    {
	psrc = &screen_buffer->data[(ysrc + h - 1) * screen_buffer->width + xsrc];
	pdst = &screen_buffer->data[(ydst + h - 1) * screen_buffer->width + xdst];

	for (j = h; j > 0; j--)
	{
	    memcpy(pdst, psrc, w * sizeof(*pdst) );
	    pdst -= screen_buffer->width;
	    psrc -= screen_buffer->width;
	}
    }
    else
    {
	psrc = &screen_buffer->data[ysrc * screen_buffer->width + xsrc];
	pdst = &screen_buffer->data[ydst * screen_buffer->width + xdst];

	for (j = 0; j < h; j++)
	{
	    /* we use memmove here because when psrc and pdst are the same,
	     * copies are done on the same row, so the dst and src blocks
	     * can overlap */
	    memmove( pdst, psrc, w * sizeof(*pdst) );
	    pdst += screen_buffer->width;
	    psrc += screen_buffer->width;
	}
    }

    /* FIXME: this could be enhanced, by signalling scroll */
    evt.event = CONSOLE_RENDERER_UPDATE_EVENT;
    evt.u.update.top    = min(ysrc, ydst);
    evt.u.update.bottom = max(ysrc, ydst) + h - 1;
    console_input_events_append( screen_buffer->input->evt, &evt );

    release_object( screen_buffer );
}

/* allocate a console for the renderer */
DECL_HANDLER(alloc_console)
{
    obj_handle_t in = 0;
    obj_handle_t evt = 0;
    struct process *process;
    struct process *renderer = current->process;
    struct console_input *console;

    process = (req->pid) ? get_process_from_id( req->pid ) :
              (struct process *)grab_object( renderer->parent );

    reply->handle_in = 0;
    reply->event = 0;
    if (!process) return;
    if (process != renderer && process->console)
    {
        set_error( STATUS_ACCESS_DENIED );
        goto the_end;
    }

    if ((console = (struct console_input*)create_console_input( current )))
    {
        if ((in = alloc_handle( renderer, console, req->access, req->inherit )))
        {
            if ((evt = alloc_handle( renderer, console->evt,
                                     SYNCHRONIZE|GENERIC_READ|GENERIC_WRITE, FALSE )))
            {
                if (process != renderer)
                {
                    process->console = (struct console_input*)grab_object( console );
                    console->num_proc++;
                }
                reply->handle_in = in;
                reply->event = evt;
                release_object( console );
                goto the_end;
            }
            close_handle( renderer, in, NULL );
        }
        free_console( process );
    }
 the_end:
    release_object( process );
}

/* free the console of the current process */
DECL_HANDLER(free_console)
{
    free_console( current->process );
}

/* let the renderer peek the events it's waiting on */
DECL_HANDLER(get_console_renderer_events)
{
    struct console_input_events *evt;

    evt = (struct console_input_events *)get_handle_obj( current->process, req->handle,
                                                         GENERIC_WRITE, &console_input_events_ops );
    if (!evt) return;
    console_input_events_get( evt );
    release_object( evt );
}

/* open a handle to the process console */
DECL_HANDLER(open_console)
{
    struct object      *obj = NULL;

    reply->handle = 0;
    switch (req->from)
    {
    case 0:
        if (current->process->console && current->process->console->renderer)
            obj = grab_object( (struct object*)current->process->console );
        break;
    case 1:
         if (current->process->console && current->process->console->renderer &&
             current->process->console->active)
             obj = grab_object( (struct object*)current->process->console->active );
        break;
    default:
        if ((obj = get_handle_obj( current->process, (obj_handle_t)req->from,
                                   GENERIC_READ|GENERIC_WRITE, &console_input_ops )))
        {
            struct console_input* console = (struct console_input*)obj;
            obj = (console->active) ? grab_object( console->active ) : NULL;
            release_object( console );
        }
        break;
    }

    /* FIXME: req->share is not used (as in screen buffer creation)  */
    if (obj)
    {
        reply->handle = alloc_handle( current->process, obj, req->access, req->inherit );
        release_object( obj );
    }
    else if (!get_error()) set_error( STATUS_ACCESS_DENIED );
}

/* set info about a console input */
DECL_HANDLER(set_console_input_info)
{
    set_console_input_info( req, get_req_data(), get_req_data_size() );
}

/* get info about a console (output only) */
DECL_HANDLER(get_console_input_info)
{
    struct console_input *console;

    if (!(console = console_input_get( req->handle, GENERIC_READ ))) return;
    if (console->title)
    {
        size_t len = strlenW( console->title ) * sizeof(WCHAR);
        if (len > get_reply_max_size()) len = get_reply_max_size();
        set_reply_data( console->title, len );
    }
    reply->history_mode  = console->history_mode;
    reply->history_size  = console->history_size;
    reply->history_index = console->history_index;
    reply->edition_mode  = console->edition_mode;

    release_object( console );
}

/* get a console mode (input or output) */
DECL_HANDLER(get_console_mode)
{
    reply->mode = get_console_mode( req->handle );
}

/* set a console mode (input or output) */
DECL_HANDLER(set_console_mode)
{
    set_console_mode( req->handle, req->mode );
}

/* add input records to a console input queue */
DECL_HANDLER(write_console_input)
{
    struct console_input *console;

    reply->written = 0;
    if (!(console = (struct console_input *)get_handle_obj( current->process, req->handle,
                                                            GENERIC_WRITE, &console_input_ops )))
        return;
    reply->written = write_console_input( console, get_req_data_size() / sizeof(INPUT_RECORD),
                                          get_req_data() );
    release_object( console );
}

/* fetch input records from a console input queue */
DECL_HANDLER(read_console_input)
{
    int count = get_reply_max_size() / sizeof(INPUT_RECORD);
    reply->read = read_console_input( req->handle, count, req->flush );
}

/* appends a string to console's history */
DECL_HANDLER(append_console_input_history)
{
    struct console_input *console;

    if (!(console = console_input_get( req->handle, GENERIC_WRITE ))) return;
    console_input_append_hist( console, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
    release_object( console );
}

/* appends a string to console's history */
DECL_HANDLER(get_console_input_history)
{
    struct console_input *console;

    if (!(console = console_input_get( req->handle, GENERIC_WRITE ))) return;
    reply->total = console_input_get_hist( console, req->index );
    release_object( console );
}

/* creates a screen buffer */
DECL_HANDLER(create_console_output)
{
    struct console_input*	console;
    struct screen_buffer*	screen_buffer;

    if (!(console = console_input_get( req->handle_in, GENERIC_WRITE))) return;

    screen_buffer = create_console_output( console );
    if (screen_buffer)
    {
        /* FIXME: should store sharing and test it when opening the CONOUT$ device
         * see file.c on how this could be done */
        reply->handle_out = alloc_handle( current->process, screen_buffer,
                                          req->access, req->inherit );
        release_object( screen_buffer );
    }
    release_object( console );
}

/* set info about a console screen buffer */
DECL_HANDLER(set_console_output_info)
{
    struct screen_buffer *screen_buffer;

    if ((screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle,
                                                                GENERIC_WRITE, &screen_buffer_ops)))
    {
        set_console_output_info( screen_buffer, req );
        release_object( screen_buffer );
    }
}

/* get info about a console screen buffer */
DECL_HANDLER(get_console_output_info)
{
    struct screen_buffer *screen_buffer;

    if ((screen_buffer = (struct screen_buffer *)get_handle_obj( current->process, req->handle,
                                                                 GENERIC_READ, &screen_buffer_ops)))
    {
        reply->cursor_size    = screen_buffer->cursor_size;
        reply->cursor_visible = screen_buffer->cursor_visible;
        reply->cursor_x       = screen_buffer->cursor_x;
        reply->cursor_y       = screen_buffer->cursor_y;
        reply->width          = screen_buffer->width;
        reply->height         = screen_buffer->height;
        reply->attr           = screen_buffer->attr;
        reply->win_left       = screen_buffer->win.left;
        reply->win_top        = screen_buffer->win.top;
        reply->win_right      = screen_buffer->win.right;
        reply->win_bottom     = screen_buffer->win.bottom;
        reply->max_width      = screen_buffer->max_width;
        reply->max_height     = screen_buffer->max_height;
        release_object( screen_buffer );
    }
}

/* read data (chars & attrs) from a screen buffer */
DECL_HANDLER(read_console_output)
{
    struct screen_buffer *screen_buffer;

    if ((screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle,
                                                                GENERIC_READ, &screen_buffer_ops )))
    {
        read_console_output( screen_buffer, req->x, req->y, req->mode, req->wrap );
        reply->width  = screen_buffer->width;
        reply->height = screen_buffer->height;
        release_object( screen_buffer );
    }
}

/* write data (char and/or attrs) to a screen buffer */
DECL_HANDLER(write_console_output)
{
    struct screen_buffer *screen_buffer;

    if ((screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle,
                                                                GENERIC_WRITE, &screen_buffer_ops)))
    {
        reply->written = write_console_output( screen_buffer, get_req_data_size(), get_req_data(),
                                               req->mode, req->x, req->y, req->wrap );
        reply->width  = screen_buffer->width;
        reply->height = screen_buffer->height;
        release_object( screen_buffer );
    }
}

/* fill a screen buffer with constant data (chars and/or attributes) */
DECL_HANDLER(fill_console_output)
{
    struct screen_buffer *screen_buffer;

    if ((screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle,
                                                                GENERIC_WRITE, &screen_buffer_ops)))
    {
        reply->written = fill_console_output( screen_buffer, req->data, req->mode,
                                              req->x, req->y, req->count, req->wrap );
        release_object( screen_buffer );
    }
}

/* move a rect of data in a screen buffer */
DECL_HANDLER(move_console_output)
{
    scroll_console_output( req->handle, req->x_src, req->y_src, req->x_dst, req->y_dst,
			   req->w, req->h );
}

/* sends a signal to a console (process, group...) */
DECL_HANDLER(send_console_signal)
{
    process_id_t group;

    group = req->group_id ? req->group_id : current->process->group_id;

    if (!group)
        set_error( STATUS_INVALID_PARAMETER);
    else
        propagate_console_signal( current->process->console, req->signal, group );
}
