/* * BlinkCursor * A nice blinky caret routine for your progs * * v. 1.00 (23 July 1993) * * © 1993-1998 Straylight */ /*----- Licensing note ----------------------------------------------------* * * This file is part of Straylight's Steel library. * * Steel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * Steel 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Steel. If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "wimp.h" #include "wimpt.h" #include "os.h" #include "blinkC.h" #include "alarm.h" #include "swiv.h" #include #include "dll.h" #ifndef _dll_NODLL extern void _dllEntry(blink__exit)(void); extern void _dllEntry(blink__doBlink)(int at,void *handle); #endif /* * A handle thing for alarm. It's not used by the routine, but it helps * identify the alarm routine to be removed. */ #define blink__MYHANDLE (void *)&blink__onAlready /* * The SWI number for Wimp_SendMessage. */ #define Wimp_SendMessage 0x600E7 /* * Due to circular definitions, I am forced to add in a prototype for this * function. */ static void blink__setupAlarm(void); /* * A flag to say whether we are on already or not. */ static BOOL blink__onAlready; /* * A flag to say whether the caret is visible or not. */ static BOOL blink__caretVisible; /* * void blink__onCaret(void) * * Use * Makes the caret visible. */ static void blink__onCaret(void) { wimp_caretstr c; wimpt_noerr(wimp_get_caret_pos(&c)); c.height &= ~(1<<25); wimpt_noerr(wimp_set_caret_pos(&c)); blink__caretVisible=TRUE; } /* * void blink__offCaret(void) * * Use * Makes the caret invisible. */ static void blink__offCaret(void) { wimp_caretstr c; wimpt_noerr(wimp_get_caret_pos(&c)); c.height |= 1<<25; wimpt_noerr(wimp_set_caret_pos(&c)); blink__caretVisible=FALSE; } /* * BOOL blink__ownCaret(void) * * Use * Returns whether the task owns the caret or not! * * Returns * TRUE if it does. */ static BOOL blink__ownCaret(void) { wimp_caretstr c; wimp_msgstr m; int task; wimpt_noerr(wimp_get_caret_pos(&c)); if (c.w<=0) return (FALSE); m.hdr.size=20; m.hdr.your_ref=0; _swix(Wimp_SendMessage, _inr(0,2)+_out(2), 19,&m,c.w, &task); return (task==wimpt_task()); } _dll_static void blink__doBlink(int at,void *handle) { handle=handle; at=at; if (blink__ownCaret()) { switch (blink__caretVisible) { case TRUE: blink__offCaret(); break; case FALSE: blink__onCaret(); break; } } blink__setupAlarm(); } /* * void blink__setupAlarm(void) * * Use * Sets up next alarm ready. */ static void blink__setupAlarm(void) { int nextTime=((alarm_timenow()/25)*25)+25; alarm_set(nextTime,_dllEntry(blink__doBlink),blink__MYHANDLE); } /* * void blinkCursor(BOOL onOrOff) * * Use * Turns the blinkingness of the cursor on or off. You must call * alarm_init() before this function, or all hell breaks loose. * * Parameters * BOOL onOrOff == whether you want to turn blinking cursor on or off */ void blinkCursor(BOOL onOrOff) { if (onOrOff==blink__onAlready) return; switch (onOrOff) { case TRUE: blink__setupAlarm(); blink__onAlready=TRUE; break; case FALSE: if (blink__ownCaret()) blink__onCaret(); alarm_removeall(blink__MYHANDLE); blink__onAlready=FALSE; break; } } /* * void blink__exit(void) * * Use * Turns off the caret blinking. */ _dll_static void blink__exit(void) { blinkCursor(FALSE); } /* * void blink_init(void) * * Use * Sets everything up nicely. */ void blink_init(void) { atexit(_dllEntry(blink__exit)); }