/*
 * Server-side clipboard management
 *
 * Copyright (C) 2002 Ulrich Czekalla
 *
 * 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 <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "request.h"
#include "object.h"
#include "user.h"
#include "winuser.h"
#include "winternl.h"

struct clipboard
{
    struct object  obj;              /* object header */
    struct thread *open_thread;      /* thread id that has clipboard open */
    user_handle_t  open_win;         /* window that has clipboard open */
    struct thread *owner_thread;     /* thread id that owns the clipboard */
    user_handle_t  owner_win;        /* window that owns the clipboard data */
    user_handle_t  viewer;           /* first window in clipboard viewer list */
    unsigned int   seqno;            /* clipboard change sequence number */
    time_t         seqno_timestamp;  /* time stamp of last seqno increment */
};

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

static const struct object_ops clipboard_ops =
{
    sizeof(struct clipboard),     /* size */
    clipboard_dump,               /* dump */
    no_add_queue,                 /* add_queue */
    NULL,                         /* remove_queue */
    NULL,                         /* signaled */
    NULL,                         /* satisfied */
    no_signal,                    /* signal */
    no_get_fd,                    /* get_fd */
    no_map_access,                /* map_access */
    no_lookup_name,               /* lookup_name */
    no_close_handle,              /* close_handle */
    no_destroy                    /* destroy */
};


#define MINUPDATELAPSE 2

/* dump a clipboard object */
static void clipboard_dump( struct object *obj, int verbose )
{
    struct clipboard *clipboard = (struct clipboard *)obj;

    fprintf( stderr, "Clipboard open_thread=%p open_win=%p owner_thread=%p owner_win=%p viewer=%p seq=%u\n",
             clipboard->open_thread, clipboard->open_win, clipboard->owner_thread,
             clipboard->owner_win, clipboard->viewer, clipboard->seqno );
}

/* retrieve the clipboard info for the current process, allocating it if needed */
static struct clipboard *get_process_clipboard(void)
{
    struct clipboard *clipboard;
    struct winstation *winstation = get_process_winstation( current->process, WINSTA_ACCESSCLIPBOARD );

    if (!winstation) return NULL;

    if (!(clipboard = winstation->clipboard))
    {
        if ((clipboard = alloc_object( &clipboard_ops )))
        {
            clipboard->open_thread = NULL;
            clipboard->open_win = 0;
            clipboard->owner_thread = NULL;
            clipboard->owner_win = 0;
            clipboard->viewer = 0;
            clipboard->seqno = 0;
            clipboard->seqno_timestamp = 0;
            winstation->clipboard = clipboard;
        }
    }
    release_object( winstation );
    return clipboard;
}


/* Called when thread terminates to allow release of clipboard */
void cleanup_clipboard_thread(struct thread *thread)
{
    struct clipboard *clipboard;
    struct winstation *winstation = get_process_winstation( thread->process, WINSTA_ACCESSCLIPBOARD );

    if (!winstation) return;

    if ((clipboard = winstation->clipboard))
    {
        if (thread == clipboard->open_thread)
        {
            clipboard->open_win = 0;
            clipboard->open_thread = NULL;
        }
        if (thread == clipboard->owner_thread)
        {
            clipboard->owner_win = 0;
            clipboard->owner_thread = NULL;
        }
    }
    release_object( winstation );
}

static int set_clipboard_window( struct clipboard *clipboard, user_handle_t win, int clear )
{
    if (clipboard->open_thread && clipboard->open_thread != current)
    {
        set_error(STATUS_WAS_LOCKED);
        return 0;
    }
    else if (!clear)
    {
        clipboard->open_win = win;
        clipboard->open_thread = current;
    }
    else
    {
        clipboard->open_thread = NULL;
        clipboard->open_win = 0;
    }
    return 1;
}


static int set_clipboard_owner( struct clipboard *clipboard, user_handle_t win, int clear )
{
    if (clipboard->open_thread && clipboard->open_thread->process != current->process)
    {
        set_error(STATUS_WAS_LOCKED);
        return 0;
    }
    else if (!clear)
    {
        clipboard->owner_win = win;
        clipboard->owner_thread = current;
    }
    else
    {
        clipboard->owner_win = 0;
        clipboard->owner_thread = NULL;
    }
    return 1;
}


static int get_seqno( struct clipboard *clipboard )
{
    time_t tm = time(NULL);

    if (!clipboard->owner_thread && (tm > (clipboard->seqno_timestamp + MINUPDATELAPSE)))
    {
        clipboard->seqno_timestamp = tm;
        clipboard->seqno++;
    }
    return clipboard->seqno;
}


DECL_HANDLER(set_clipboard_info)
{
    struct clipboard *clipboard = get_process_clipboard();

    if (!clipboard) return;

    reply->old_clipboard = clipboard->open_win;
    reply->old_owner     = clipboard->owner_win;
    reply->old_viewer    = clipboard->viewer;

    if (req->flags & SET_CB_OPEN)
    {
        if (clipboard->open_thread)
        {
            /* clipboard already opened */
            set_error(STATUS_WAS_LOCKED);
            return;
        }

        if (!set_clipboard_window( clipboard, req->clipboard, 0 )) return;
    }
    else if (req->flags & SET_CB_CLOSE)
    {
        if (clipboard->open_thread != current)
        {
            set_win32_error(ERROR_CLIPBOARD_NOT_OPEN);
            return;
        }

        if (!set_clipboard_window( clipboard, 0, 1 )) return;
    }

    if (req->flags & SET_CB_OWNER)
    {
        if (!set_clipboard_owner( clipboard, req->owner, 0 )) return;
    }
    else if (req->flags & SET_CB_RELOWNER)
    {
        if (!set_clipboard_owner( clipboard, 0, 1 )) return;
    }

    if (req->flags & SET_CB_VIEWER) clipboard->viewer = req->viewer;

    if (req->flags & SET_CB_SEQNO) clipboard->seqno++;

    reply->seqno = get_seqno( clipboard );

    if (clipboard->open_thread == current) reply->flags |= CB_OPEN;
    if (clipboard->owner_thread == current) reply->flags |= CB_OWNER;
    if (clipboard->owner_thread && clipboard->owner_thread->process == current->process)
        reply->flags |= CB_PROCESS;
}
