[comp.sources.amiga] mouseclock.sh

jrh@duncan.UUCP (John Hoffman) (07/10/87)

    Here is a nifty little clock program sent to me in the days when this
newsgroup wasn't getting out too well.  This will be a repost for some
of you...
    Enjoy!
	Doc

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	mouseclock.c
# This archive created: Fri Jul 10 13:47:27 1987
# By:	Craig Norborg (Purdue University Computing Center)
cat << \SHAR_EOF > mouseclock.c
/*
 * MouseClock - Turn your mouse pointer into a digital clock which
 *              updates once a minute.  
 *
 * NOTE: This program directly modifies the preferences data structure.
 *       Using this program while trying to modify your preferences may
 *       have bad results.
 *
 * Copyright (c) 1986, 1987 John R. Hoffman
 *
 * To use MouseClock, just Run it from your Startup-Sequence.  To stop
 * it just delete the window and the previous pointer will be restored.
 *
 * This program is placed in the public domain as long as the above
 * copyright is included.  Sale of this program except for REASONABLE 
 * media costs is prohibited.
 *
 * To create with MANX: cc MouseClock.c
 *                      ln MouseClock.o -lc
 *
 * Error codes:
 *
 *      0 - Normal exit.
 *    101 - Can't get intuition.
 *    102 - Can't create a timer port.
 *    103 - Can't open a timer device.
 *    104 - Can't open a window.
 *
 * Modification History:
 *
 *   11/03/86 John Hoffman - Original version.
 *   01/02/87 John Hoffman - Added call to set task priority to -5,
 *                           fixed hot point location,
 *                           fixed to work with 16 bit integers,
 *                           added code to adjust update time to 
 *                           five seconds after the minute.
 *
 */

static char *Copyright = "Copyright (c) 1986, 1987 John R. Hoffman";

/* #define PRINT_ERRORS */

#ifdef PRINT_ERRORS
#include <stdio.h>
#endif

#include <exec/types.h>
#include <libraries/dos.h>
#include <intuition/intuitionbase.h>
#include <intuition/intuition.h>

    /* The pointer image. */

static USHORT Clock[] = {
    0x0000, 0x0000, 0xf800, 0xf800, 0xe000, 0xe000, 0xb000, 0xb000,
    0x9800, 0x9800, 0x0c00, 0x0c00, 0xfffe, 0xfffe, 0x0000, 0xfffe,
    0xb8ee, 0xfffe, 0xa8aa, 0xfffe, 0xaaaa, 0xfffe, 0xb8ee, 0xfffe,
    0xaaaa, 0xfffe, 0xa8aa, 0xfffe, 0xb8ee, 0xfffe, 0x0000, 0xfffe,
    0xfffe, 0xfffe, 0x0000, 0x0000
};

    /* The hot point offset for the pointer. */

#define CLOCK_HOT_X -1
#define CLOCK_HOT_Y  0

    /* The positions in the pointer image which are replaced. */

static USHORT positions[] = { 16, 18, 20, 22, 24, 26, 28 };

    /* The number of positions. */

#define NUMPOS (sizeof(positions)/sizeof(USHORT))

    /* The bitmap for each of the digits. */

static USHORT digits[10][7] = {
    0x7, 0x5, 0x5, 0x5, 0x5, 0x5, 0x7,    /* 0 */
    0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2,    /* 1 */
    0x7, 0x1, 0x1, 0x7, 0x4, 0x4, 0x7,    /* 2 */
    0x7, 0x1, 0x1, 0x7, 0x1, 0x1, 0x7,    /* 3 */
    0x5, 0x5, 0x5, 0x7, 0x1, 0x1, 0x1,    /* 4 */
    0x7, 0x4, 0x4, 0x7, 0x1, 0x1, 0x7,    /* 5 */
    0x7, 0x4, 0x4, 0x7, 0x5, 0x5, 0x7,    /* 6 */
    0x7, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,    /* 7 */
    0x7, 0x5, 0x5, 0x7, 0x5, 0x5, 0x7,    /* 8 */
    0x7, 0x5, 0x5, 0x7, 0x1, 0x1, 0x7     /* 9 */
};

static struct NewWindow New_Window = {
    426, 0, 164, 10,
    -1, -1,
    CLOSEWINDOW,
    WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG | SIMPLE_REFRESH | NOCAREREFRESH,
    NULL, NULL,
    (UBYTE *) "MouseClock ",
    NULL, NULL, 0, 0, 0, 0,
    WBENCHSCREEN
    };

struct IntuitionBase *IntuitionBase = NULL;
extern struct IntuitionBase *OpenLibrary();

static struct Window *Window = NULL;
extern struct Window *OpenWindow();

static struct MsgPort *Msg_Port = NULL;
extern struct MsgPort *CreatePort();

static struct timerequest Timer_Request;

extern struct Task *FindTask();
extern struct IntuiMessage *GetMsg();

USHORT SetTime();

main()
{
    BYTE old_hotX, old_hotY;
    USHORT second, old_pointer[POINTERSIZE];
    struct Preferences pref;
    struct IntuiMessage *Msg;

	SetTaskPri(FindTask(0L), -5L);

    if ( (IntuitionBase = OpenLibrary("intuition.library", 0L)) == NULL )
        finish(101, "Can't get intuition.\n");

    if ( (Msg_Port = CreatePort("timer.port", 0L)) == NULL )
        finish(102, "Can't create a timer port.\n");

    if ( OpenDevice(TIMERNAME, (long) UNIT_VBLANK, &Timer_Request, 0L) != 0 )
        finish(103, "Can't open a timer device.\n");

    Timer_Request.tr_node.io_Message.mn_ReplyPort    = Msg_Port;
    Timer_Request.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
    Timer_Request.tr_node.io_Message.mn_Node.ln_Pri  = 0;

    Timer_Request.tr_node.io_Command = TR_ADDREQUEST;

    if ( (Window = (struct Window *) OpenWindow(&New_Window)) == NULL )
        finish(104, "Can't open a window.\n");

    GetMouse(&old_pointer, &old_hotX, &old_hotY);

    second = SetTime(&Clock, NUMPOS, &positions);

    SetMouse(&Clock, CLOCK_HOT_X, CLOCK_HOT_Y);

    for ( ; ; ) {

        Timer_Request.tr_time.tv_secs  = 60 - second + 5;
        Timer_Request.tr_time.tv_micro = 0;

        SendIO(&Timer_Request.tr_node);

        Wait(1L << Window->UserPort->mp_SigBit | 
             1L << Msg_Port->mp_SigBit);

        while ( (Msg = GetMsg(Window->UserPort)) != 0 ) {
            if ( Msg->Class == CLOSEWINDOW ) {
                ReplyMsg(Msg);
                SetMouse(&old_pointer, old_hotX, old_hotY);
                finish(0, "");
            }
            ReplyMsg(Msg);
        }

        GetMsg(Msg_Port);

        second = SetTime(&Clock, NUMPOS, &positions);

        SetClock(&Clock, NUMPOS, &positions);

    }
}

finish(code, msg)
int code;
char *msg;
{
    AbortIO(&Timer_Request.tr_node);

    if ( Window != NULL )
        CloseWindow(Window);

    if ( Timer_Request.tr_node.io_Message.mn_ReplyPort != NULL )
        CloseDevice(&Timer_Request);

    if ( Msg_Port != NULL )
        DeletePort(Msg_Port);

    if ( IntuitionBase != NULL )
        CloseLibrary(IntuitionBase);

#ifdef PRINT_ERRORS
    if ( msg[0] != '\0' )
        fputs(msg, stderr);
#endif

    exit(code);
}

/* Get the whole pointer matrix and the hot point offset. */

GetMouse(pointer, hotX, hotY)
register USHORT *pointer;
BYTE *hotX;
BYTE *hotY;
{
    register int i;
    struct Preferences pref;

    Forbid();

        GetPrefs(&pref, (long)sizeof(struct Preferences));

            for ( i = 0; i < POINTERSIZE; i++ )
                pointer[i] = pref.PointerMatrix[i];

            *hotX = pref.XOffset;
            *hotY = pref.YOffset;

    Permit();
}

/* Set the current time in the pointer matrix. */

USHORT SetTime(pointer, numpos, pos)
register USHORT *pointer;
register USHORT numpos;
register USHORT *pos;
{
    register int i;
    struct DateStamp tnow;
    USHORT hour10, hour1, min10, min1;
    static USHORT hour10_old = 99;
    static USHORT hour1_old = 99;
    static USHORT min10_old = 99;

    DateStamp(&tnow);

    hour1  = (tnow.ds_Minute / 60) % 12;
    hour1  = (hour1 == 0) ? 12 : hour1;
    hour10 = hour1 / 10;
    hour1  = hour1 % 10;

    min1  = tnow.ds_Minute % 60;
    min10 = min1 / 10;
    min1  = min1 % 10;

    if ( hour10_old != hour10 ) {
        for ( i=0; i < numpos; i++ ) {
            if ( hour10 == 1 )
                pointer[pos[i]] |= 0x8000;
            else
                pointer[pos[i]] &= 0x7fff;
        }
        hour10_old = hour10;
    }

    if ( hour1_old != hour1 ) {
        for ( i=0; i < numpos; i++ ) {
            pointer[pos[i]] &= 0xc7ff;
            pointer[pos[i]] |= (digits[hour1][i] << 11);
        }
        hour1_old = hour1;
    }

    if ( min10_old != min10 ) {
        for ( i=0; i < numpos; i++ ) {
            pointer[pos[i]] &= 0xff1f;
            pointer[pos[i]] |= (digits[min10][i] << 5);
        }
        min10_old = min10;
    }

    for ( i=0; i < numpos; i++ ) {
        pointer[pos[i]] &= 0xfff1;
        pointer[pos[i]] |= (digits[min1][i] << 1);
    }

	return((USHORT)(tnow.ds_Tick/TICKS_PER_SECOND));
}

/* Set certain positions in the pointer matrix. */

SetClock(pointer, numpos, pos)
register USHORT *pointer;
register USHORT numpos;
register USHORT *pos;
{
    register int i;
    struct Preferences pref;

    Forbid();

        GetPrefs(&pref, (long)sizeof(struct Preferences));

        for ( i = 0; i < numpos; i++ )
            pref.PointerMatrix[pos[i]] = pointer[pos[i]];

        SetPrefs(&pref, (long)sizeof(struct Preferences), FALSE);

    Permit();
}

/* Set the whole pointer matrix and the hot point offset. */

SetMouse(pointer, hotX, hotY)
register USHORT *pointer;
BYTE hotX;
BYTE hotY;
{
    register int i;
    struct Preferences pref;

    Forbid();

        GetPrefs(&pref, (long)sizeof(struct Preferences));

            for ( i = 0; i < POINTERSIZE; i++ )
                pref.PointerMatrix[i] = pointer[i];

            pref.XOffset = hotX;
            pref.YOffset = hotY;

        SetPrefs(&pref, (long)sizeof(struct Preferences), FALSE);

    Permit();
}

SHAR_EOF
#	End of shell archive
exit 0