wine/windows/timer.c
Alexandre Julliard 234bc24db1 Release 941210
Wed Dec  7 14:52:25 1994  Alexandre Julliard  (julliard@lamisun.epfl.ch)

	* [controls/listbox.c]
	Fixed problems due to new scroll-bar code.

	* [loader/signal.c] [miscemu/ioports.c]
	Handle I/O opcodes that use an absolute address.

	* [objects/text.c]
	Implemented TabbedTextOut().

Sat Dec  3 18:53:08 1994  Kenneth MacDonald  <K.MacDonald@ed.ac.uk>

	* [objects/metafile.c]
	Implemented GetMetafile().
	Fixed bug in PlayMetaFile() when reading disc based metafile records.
	Added META_POLYPOLYGON, META_DELETEOBJECT and META_EOF to 
	PlayMetaFileRecord().
	
Wed Nov 30 06:32:25 1994  Martin von Loewis  (martin@cs.csufresno.edu)

	* [Imakefile]
	wine.sym: Remove gcc2_compiled and friends

	* [controls/listbox.c][if1632/relay.c][if1632/relay.c]
	  [loader/resource.c][memory/heap.c][objects/dib.c][windows/dialog.c]
	Replace #ifdef DEBUG_XXX with if(debugging_xxx){

	* [if1632/call.S]
	CallToLibMain: New function

	* [if1632/relay.c][include/options.h][misc/main.c]
	  [miscemu/int1a.c][miscemu/int21.c][miscemu/kernel.c]
	removed Options.relay_debug

	* [include/heap.h]
	HEAP_OWNER: Use ds instead of cs:ip

	* [loader/ne_image.c]
	LoadNEImage: Remember current exe, handle nodata dlls
	InitNEDLL: handle nodata dlls, call CallToLibMain

	* [loader/selector.c]
	CreateSelectors: Initialize auto_data_sel with 0

	* [memory/heap.c]
	HEAP_CheckHeap: Check prev
	HEAP_CheckLocalHeaps: new function

	* [misc/profile]
	Remember and dump only changed profiles

	* [tools/makedebug]
	Introduce debugging_xxx flags

Sun Nov 27 23:13:22 MET 1994	<erik@xs4all.nl>

	* [clipboard.h color.h dc.h dos_fs.h event.h font.h graphics.h
	if1632.h kernel.h library.h miscemu.h ne_image.h nonclient.h 
	pe_image.h selectors.h wintypes.h]
	Added.

	* [*/*]
	- Commented all 'static char copyright statements', see misc/main.c
	- moved prototypes to headers files, fixed wrong prototypes.
	- *please* add a header file for each .c if you need to export
	  things.

	* [misc/main.c]
	Added one static string which list the names of the contributors.

Fri Nov 25 16:24:27 MET 1994		  Dag Asheim (dash@ifi.uio.no)

	* [Configure]
	Made the support for multiple languages more automatic.  Added
	a [fonts] section to the wine.conf file.  Made the defaults
	better.  Generally cleaned it up.

	* [rc/sysres_No.rc] [rc/sysres_De.rc] [rc/sysres.c]
	Norwegian resources and small fixes to the german resources.

Wed Nov 23 20:28:59 1994  Martin von Loewis  (martin@cs.csufresno.edu)

	* [debugger/break.c]
	bark(), toggle_next(), should_continue(): New functions
	insert_break(): Fixed, adds write access to page before writing
	wine_bp.next_addr: new structure field

	* [debugger/dbg.y]
	Changed symbol's value to be it's value instead of the value
	pointed to by the symbol.
	Changed SIGTRAP handling to allow continuation after break point

	* [misc/shell.c]
	ShellAbout(): Load resource from memory
1994-12-10 13:02:28 +00:00

252 lines
6.8 KiB
C

/*
* Timer functions
*
* Copyright 1993 Alexandre Julliard
*/
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
#include "windows.h"
#include "message.h"
#include "stddebug.h"
/* #define DEBUG_TIMER */
#include "debug.h"
typedef struct tagTIMER
{
HWND hwnd;
WORD msg; /* WM_TIMER or WM_SYSTIMER */
WORD id;
WORD timeout;
struct tagTIMER *next;
DWORD expires;
FARPROC proc;
} TIMER;
#define NB_TIMERS 34
#define NB_RESERVED_TIMERS 2 /* for SetSystemTimer */
static TIMER TimersArray[NB_TIMERS];
static TIMER * pNextTimer = NULL; /* Next timer to expire */
/* Duration from 'time' until expiration of the timer */
#define EXPIRE_TIME(pTimer,time) \
(((pTimer)->expires <= (time)) ? 0 : (pTimer)->expires - (time))
/***********************************************************************
* TIMER_InsertTimer
*
* Insert the timer at its place in the chain.
*/
static void TIMER_InsertTimer( TIMER * pTimer )
{
if (!pNextTimer || (pTimer->expires < pNextTimer->expires))
{
pTimer->next = pNextTimer;
pNextTimer = pTimer;
}
else
{
TIMER * ptr = pNextTimer;
while (ptr->next && (pTimer->expires >= ptr->next->expires))
ptr = ptr->next;
pTimer->next = ptr->next;
ptr->next = pTimer;
}
}
/***********************************************************************
* TIMER_RemoveTimer
*
* Remove the timer from the chain.
*/
static void TIMER_RemoveTimer( TIMER * pTimer )
{
if (pTimer == pNextTimer) pNextTimer = pTimer->next;
else
{
TIMER * ptr = pNextTimer;
while (ptr && (ptr->next != pTimer)) ptr = ptr->next;
if (ptr) ptr->next = pTimer->next;
}
pTimer->next = NULL;
}
/***********************************************************************
* TIMER_RestartTimers
*
* Restart an expired timer.
*/
static void TIMER_RestartTimer( TIMER * pTimer, DWORD curTime )
{
TIMER_RemoveTimer( pTimer );
pTimer->expires = curTime + pTimer->timeout;
TIMER_InsertTimer( pTimer );
}
/***********************************************************************
* TIMER_CheckTimer
*
* Check whether a timer has expired, and create a message if necessary.
* Otherwise, return time until next timer expiration in 'next'.
* If 'hwnd' is not NULL, only consider timers for this window.
* If 'remove' is TRUE, remove all expired timers up to the returned one.
*/
BOOL TIMER_CheckTimer( LONG *next, MSG *msg, HWND hwnd, BOOL remove )
{
TIMER * pTimer = pNextTimer;
DWORD curTime = GetTickCount();
if (hwnd) /* Find first timer for this window */
while (pTimer && (pTimer->hwnd != hwnd)) pTimer = pTimer->next;
if (!pTimer) *next = -1;
else *next = EXPIRE_TIME( pTimer, curTime );
if (*next != 0) return FALSE; /* No timer expired */
if (remove) /* Restart all timers before pTimer, and then pTimer itself */
{
while (pNextTimer != pTimer) TIMER_RestartTimer( pNextTimer, curTime );
TIMER_RestartTimer( pTimer, curTime );
}
/* Build the message */
msg->hwnd = pTimer->hwnd;
msg->message = pTimer->msg;
msg->wParam = pTimer->id;
msg->lParam = (LONG)pTimer->proc;
msg->time = curTime;
return TRUE;
}
/***********************************************************************
* TIMER_SetTimer
*/
static WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout,
FARPROC proc, BOOL sys )
{
int i;
TIMER * pTimer;
if (!timeout) return 0;
/* if (!hwnd && !proc) return 0; */
/* Check if there's already a timer with the same hwnd and id */
for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
(pTimer->timeout != 0))
{
/* Got one: set new values and return */
pTimer->timeout = timeout;
pTimer->expires = GetTickCount() + timeout;
pTimer->proc = proc;
TIMER_RemoveTimer( pTimer );
TIMER_InsertTimer( pTimer );
return id;
}
/* Find a free timer */
for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
if (!pTimer->timeout) break;
if (i >= NB_TIMERS) return 0;
if (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) return 0;
if (!hwnd) id = i + 1;
/* Add the timer */
pTimer->hwnd = hwnd;
pTimer->msg = sys ? WM_SYSTIMER : WM_TIMER;
pTimer->id = id;
pTimer->timeout = timeout;
pTimer->expires = GetTickCount() + timeout;
pTimer->proc = proc;
TIMER_InsertTimer( pTimer );
MSG_IncTimerCount( GetTaskQueue(0) );
if (!id)
return TRUE;
else
return id;
}
/***********************************************************************
* TIMER_KillTimer
*/
static BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys )
{
int i;
TIMER * pTimer;
/* Find the timer */
for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
(pTimer->timeout != 0)) break;
if (i >= NB_TIMERS) return FALSE;
if (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) return FALSE;
if (!sys && (pTimer->msg != WM_TIMER)) return FALSE;
else if (sys && (pTimer->msg != WM_SYSTIMER)) return FALSE;
/* Delete the timer */
pTimer->hwnd = 0;
pTimer->msg = 0;
pTimer->id = 0;
pTimer->timeout = 0;
pTimer->proc = 0;
TIMER_RemoveTimer( pTimer );
MSG_DecTimerCount( GetTaskQueue(0) );
return TRUE;
}
/***********************************************************************
* SetTimer (USER.10)
*/
WORD SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc )
{
dprintf_timer(stddeb, "SetTimer: %d %d %d %p\n", hwnd, id, timeout, proc );
return TIMER_SetTimer( hwnd, id, timeout, proc, FALSE );
}
/***********************************************************************
* SetSystemTimer (USER.11)
*/
WORD SetSystemTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc )
{
dprintf_timer(stddeb, "SetSystemTimer: %d %d %d %p\n",
hwnd, id, timeout, proc );
return TIMER_SetTimer( hwnd, id, timeout, proc, TRUE );
}
/***********************************************************************
* KillTimer (USER.12)
*/
BOOL KillTimer( HWND hwnd, WORD id )
{
dprintf_timer(stddeb, "KillTimer: %d %d\n", hwnd, id );
return TIMER_KillTimer( hwnd, id, FALSE );
}
/***********************************************************************
* KillSystemTimer (USER.182)
*/
BOOL KillSystemTimer( HWND hwnd, WORD id )
{
dprintf_timer(stddeb, "KillSystemTimer: %d %d\n", hwnd, id );
return TIMER_KillTimer( hwnd, id, TRUE );
}