/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "Licence").
 * You may not use this file except in compliance with the Licence.
 *
 * You can obtain a copy of the licence at RISC OS path @.^.LICENCE
 * or  http://www.riscosdev.com/lanman98/LICENCE.CDDL
 * See the Licence for the specific language governing permissions
 * and limitations under the Licence.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the Licence file. If applicable, add the
 * following below this CDDL HEADER, with the fields enclosed by
 * brackets "[]" replaced with your own identifying information:
 * Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
 
/*
 *   Portions Copyright 1996 Warm Silence Software Ltd.
 */

/******************************************************/
/*                                                    */
/* Name: PGdev.c                                      */
/* Author: Paul Gardiner.                             */
/* Function:                                          */
/*   Provides a library of functions for claiming     */
/* one-user-at-a-time devices.                        */
/*                                                    */ 
/******************************************************/

#include "kernel.h"
#include "swis.h"
#include <stdio.h>
#include <string.h>
#include "PGwin.h"
#include "PGerr.h"
#include "PGdev.h"
#include "PGdevH.h"


static _kernel_swi_regs regs;

static int known_free[7] = {0};

static int my_ref = 0;

static int claimed_devices[7] = {0};

static int messagep[64];

void xyzDEVxyz(int reason, int *poll)
{
    int dev;
    
    switch(poll[4])
    {
        case 11:
            dev = poll[5];
            if(dev >= 1 && dev <= 6 && poll[2] != my_ref)
            {
                if(claimed_devices[dev])
                {
                    messagep[0] = 256;
                    messagep[3] = poll[2];
                    messagep[4] = 12;
                    messagep[5] = dev;
                    messagep[6] = 0;
                    sprintf((char *)(messagep + 7), "%s: device in use", WinTaskName());
                    regs.r[0] = 17;
                    regs.r[1] = (int) messagep;
                    regs.r[2] = poll[1];
                    _kernel_swi(Wimp_SendMessage, &regs, &regs);
                }
                else
                {
                    known_free[dev] = 0;
                }
            }
            break;
        case 12:
            dev = poll[5];
            if(dev >= 1 && dev <= 6)
            {
                if(my_ref != 0)
                    claimed_devices[dev] = 0;
                else
                    Error("Device refused without my asking: %s", poll + 7);
            }
            break;
    }
}

static int messagem[64];

int DevClaim(int dev)
{    
    if(dev < 1 || dev > 6)
        return 0;
    if(known_free[dev])
    {
        claimed_devices[dev] = 1;
    }
    else
    {
        claimed_devices[dev] = 1;
        messagem[0] = 256;
        messagem[3] = 0;
        messagem[4] = 11;
        messagem[5] = dev;
        messagem[6] = 0;
        strcpy((char *)(messagem + 7), WinTaskName());
        regs.r[0] = 17;
        regs.r[1] = (int) messagem;
        regs.r[2] = 0;
        _kernel_swi(Wimp_SendMessage, &regs, &regs);
        my_ref = messagem[2];
        WinCoOp();
        my_ref = 0;
        known_free[dev] = claimed_devices[dev];
    }
    return claimed_devices[dev];
}

void DevRelease(int dev)
{
    claimed_devices[dev] = 0;
}
