/*
 * 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 "request.h"
#include "object.h"
#include "user.h"

static struct thread *cbthread; /* thread id that has clipboard open */
static user_handle_t clipboard; /* window that has clipboard open */

static struct thread *cbowner;  /* thread id that owns the clipboard */
static user_handle_t owner;     /* window that owns the clipboard data */

static user_handle_t viewer;    /* first window in clipboard viewer list */
static unsigned int seqno;      /* clipboard change sequence number */
static time_t seqnots;          /* time stamp of last seqno increment */

#define MINUPDATELAPSE 2

/* Called when thread terminates to allow release of clipboard */
void cleanup_clipboard_thread(struct thread *thread)
{
    if (thread == cbthread)
    {
        clipboard = 0;
        cbthread = NULL;
    }
    if (thread == cbowner)
    {
        owner = 0;
        cbowner = NULL;
    }
}

static int set_clipboard_window(user_handle_t win, int clear)
{
    if (cbthread && cbthread != current)
    {
        set_error(STATUS_WAS_LOCKED);
        return 0;
    }
    else if (!clear)
    {
        clipboard = win;
        cbthread = current;
    }
    else
    {
        cbthread = NULL;
        clipboard = 0;
    }
    return 1;
}


static int set_clipboard_owner(user_handle_t win, int clear)
{
    if (cbthread && cbthread != current)
    {
        set_error(STATUS_WAS_LOCKED);
        return 0;
    }
    else if (!clear)
    {
        owner = win;
        cbowner = current;
    }
    else
    {
        owner = 0;
        cbowner = NULL;
    }
    return 1;
}


static int get_seqno(void)
{
    time_t tm = time(NULL);

    if (!cbowner && (tm > (seqnots + MINUPDATELAPSE)))
    {
        seqnots = tm;
        seqno++;
    }
    return seqno;
}


DECL_HANDLER(set_clipboard_info)
{
    reply->old_clipboard = clipboard;
    reply->old_owner = owner;
    reply->old_viewer = viewer;

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

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

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

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

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

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

    reply->seqno = get_seqno();

    if (cbthread == current)
        reply->flags |= CB_OPEN;

    if (cbowner == current)
        reply->flags |= CB_OWNER;
}
