diff --git a/cleanup-code.sh b/cleanup-code.sh index f7cb1ba2..a34fbe93 100755 --- a/cleanup-code.sh +++ b/cleanup-code.sh @@ -103,6 +103,11 @@ tab2space() { # sed -i 's/\/mg_GetMsgQueueForThisThread/g' `grep GetMsgQueueThisThread -rl src/` -sed -i 's/\/getMsgQueue/g' `grep kernel_GetMsgQueue -rl src/` +# sed -i 's/\/getMsgQueue/g' `grep kernel_GetMsgQueue -rl src/` + +# sed -i 's/\/isWindowInThisThread/g' `grep BE_THIS_THREAD -rl src/` + +sed -i 's/\/setMsgQueueTimerFlag/g' `grep SetMsgQueueTimerFlag -rl src/` +sed -i 's/\/removeMsgQueueTimerFlag/g' `grep RemoveMsgQueueTimerFlag -rl src/` exit 0 diff --git a/src/include/internals.h b/src/include/internals.h index 2e3df0f7..17943edc 100644 --- a/src/include/internals.h +++ b/src/include/internals.h @@ -109,6 +109,9 @@ struct GAL_Surface; struct _MAINWIN; typedef struct _MAINWIN* PMAINWIN; +struct _TIMER; +typedef struct _TIMER TIMER; + typedef struct _SCROLLWINDOWINFO { int iOffx; @@ -202,13 +205,17 @@ struct _MSGQUEUE #endif int nrWindows; // the number of main/virtual windows. - MSG* msg; // post message buffer + /* buffer for post message */ int len; // buffer length + MSG* msg; // post message buffer int readpos, writepos; // positions for reading and writing int loop_depth; // message loop depth, for dialog boxes + /* Since 4.2.0, MiniGUI provides support for timers per message thread */ int FirstTimerSlot; // the first timer slot to be checked + TIMER* timer_slots [DEF_NR_TIMERS]; + // slots for timer DWORD TimerMask; // timer slots mask }; @@ -604,20 +611,6 @@ static inline PMSGQUEUE getMsgQueue (HWND hWnd) #ifdef _MGHAVE_VIRTUAL_WINDOW -/* Be careful: does not check validity of hWnd */ -static inline BOOL BE_THIS_THREAD (HWND hWnd) -{ - PMAINWIN pMainWin = getMainWindowPtr(hWnd); -#ifdef WIN32 - if (pMainWin && pMainWin->pMsgQueue->th.p == pthread_self().p) -#else - if (pMainWin && pMainWin->pMsgQueue->th == pthread_self()) -#endif - return TRUE; - - return FALSE; -} - MSGQUEUE* mg_AllocMsgQueueForThisThread (void); void mg_FreeMsgQueueForThisThread (void); MSGQUEUE* mg_GetMsgQueueForThisThread (BOOL alloc); @@ -636,6 +629,67 @@ static inline void deleteThreadInfoKey (void) pthread_key_delete (__mg_threadinfo_key); } +static inline MSGQUEUE* getMsgQueueForThisThread (void) +{ + MSGQUEUE* pMsgQueue; + + pMsgQueue = (MSGQUEUE*)pthread_getspecific (__mg_threadinfo_key); +#ifdef __VXWORKS__ + if (pMsgQueue == (void *)-1) { + pMsgQueue = NULL; + } +#endif + + return pMsgQueue; +} + +static inline TIMER** getTimerSlotsForThisThread (void) +{ + MSGQUEUE* pMsgQueue; + + pMsgQueue = (MSGQUEUE*)pthread_getspecific (__mg_threadinfo_key); +#ifdef __VXWORKS__ + if (pMsgQueue == (void *)-1) { + pMsgQueue = NULL; + } +#endif + + if (pMsgQueue) + return pMsgQueue->timer_slots; + return NULL; +} + +/* Be careful: does not check validity of hWnd */ +static inline BOOL isWindowInThisThread (HWND hWnd) +{ + PMAINWIN pMainWin = getMainWindowPtr(hWnd); +#ifdef WIN32 + if (pMainWin && pMainWin->pMsgQueue->th.p == pthread_self().p) +#else + if (pMainWin && pMainWin->pMsgQueue->th == pthread_self()) +#endif + return TRUE; + + return FALSE; +} + +#else /* define _MGHAVE_VIRTUAL_WINDOW */ + +static inline MSGQUEUE* getMsgQueueForThisThread (void) +{ + return __mg_dsk_msg_queue; +} + +static inline TIMER** getTimerSlotsForThisThread (void) +{ + return __mg_dsk_msg_queue->timer_slots; +} + +static inline BOOL isWindowInThisThread (HWND hWnd) +{ + return TRUE; +} + #endif /* defined _MGHAVE_VIRTUAL_WINDOW */ #ifndef _MGRM_THREADS @@ -653,13 +707,13 @@ static inline void AlertDesktopTimerEvent (void) } #endif /* defined _MGRM_THREADS */ -static inline void SetMsgQueueTimerFlag (PMSGQUEUE pMsgQueue, int slot) +static inline void setMsgQueueTimerFlag (PMSGQUEUE pMsgQueue, int slot) { pMsgQueue->TimerMask |= (0x01 << slot); POST_MSGQ (pMsgQueue); } -static inline void RemoveMsgQueueTimerFlag (PMSGQUEUE pMsgQueue, int slot) +static inline void removeMsgQueueTimerFlag (PMSGQUEUE pMsgQueue, int slot) { pMsgQueue->TimerMask &= ~(0x01 << slot); } diff --git a/src/include/timer.h b/src/include/timer.h index 3f449cfc..2a970c48 100644 --- a/src/include/timer.h +++ b/src/include/timer.h @@ -52,14 +52,10 @@ #ifndef GUI_TIMER_H #define GUI_TIMER_H -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - #define USEC_1S 1000000 #define USEC_10MS 10000 -typedef struct _timer { +typedef struct _TIMER { HWND hWnd; LINT id; DWORD speed; @@ -67,26 +63,36 @@ typedef struct _timer { TIMERPROC proc; UINT_PTR tick_count; - PMSGQUEUE msg_queue; + + // removed since 4.2.0 + // PMSGQUEUE msg_queue; } TIMER; typedef TIMER* PTIMER; +struct _MSGQUEUE; +typedef struct _MSGQUEUE MSGQUEUE; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + BOOL mg_InitTimer (void); void mg_TerminateTimer (void); void __mg_dispatch_timer_message (DWORD inter); -void __mg_remove_timers_by_msg_queue (const MSGQUEUE* msg_que); +void __mg_remove_timers_by_msg_queue (MSGQUEUE* msg_queue); +void __mg_remove_timer (MSGQUEUE* msg_queue, int slot); +#if 0 TIMER* __mg_get_timer (int slot); -void __mg_remove_timer (TIMER* timer, int slot); - static inline HWND __mg_get_timer_hwnd (int slot) { - TIMER* ptimer = __mg_get_timer (slot); - if (ptimer) - return ptimer->hWnd; + TIMER* timer = __mg_get_timer (slot); + if (timer) + return timer->hWnd; return HWND_NULL; } +#endif /* deprecated code since 4.2.0 */ #ifdef __cplusplus } diff --git a/src/kernel/message.c b/src/kernel/message.c index 37099042..334f4b39 100644 --- a/src/kernel/message.c +++ b/src/kernel/message.c @@ -199,11 +199,6 @@ MSGQUEUE* mg_GetMsgQueueForThisThread (BOOL alloc) if (pMsgQueue == NULL && alloc) { pMsgQueue = mg_AllocMsgQueueForThisThread (); -#if 0 - if (pMsgQueue) { - pthread_cleanup_push (mg_FreeMsgQueueForThisThread, (void*)pMsgQueue); - } -#endif } return pMsgQueue; @@ -352,7 +347,7 @@ ret: UNLOCK_MSGQ (msg_que); #ifdef _MGHAVE_VIRTUAL_WINDOW - if (!BE_THIS_THREAD (msg->hwnd)) + if (!isWindowInThisThread (msg->hwnd)) POST_MSGQ (msg_que); #endif @@ -764,7 +759,7 @@ checkagain: pMsgQueue->FirstTimerSlot ++; pMsgQueue->FirstTimerSlot %= DEF_NR_TIMERS; - if ((timer = __mg_get_timer (slot))) { + if ((timer = pMsgQueue->timer_slots[slot])) { pMsgQueue->TimerMask &= ~(0x01UL << slot); if (timer->proc) { @@ -782,7 +777,7 @@ checkagain: if (!ret_timer_proc) { /* remove the timer */ - __mg_remove_timer (timer, slot); + __mg_remove_timer (pMsgQueue, slot); } UNLOCK_MSGQ (pMsgQueue); goto checkagain; @@ -967,7 +962,7 @@ LRESULT GUIAPI SendMessage (HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) MG_CHECK_RET (MG_IS_WINDOW(hWnd), -1); #ifdef _MGHAVE_VIRTUAL_WINDOW - if (!BE_THIS_THREAD(hWnd)) + if (!isWindowInThisThread(hWnd)) return SendSyncMessage (hWnd, nMsg, wParam, lParam); #endif @@ -1012,7 +1007,7 @@ LRESULT SendTopNotifyMessage (HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam UNLOCK_MSGQ (pMsgQueue); #ifdef _MGHAVE_VIRTUAL_WINDOW - if ( !BE_THIS_THREAD(hWnd) ) + if ( !isWindowInThisThread(hWnd) ) POST_MSGQ(pMsgQueue); #endif @@ -1052,7 +1047,7 @@ int GUIAPI SendNotifyMessage (HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam UNLOCK_MSGQ (pMsgQueue); #ifdef _MGHAVE_VIRTUAL_WINDOW - if ( !BE_THIS_THREAD(hWnd) ) + if ( !isWindowInThisThread(hWnd) ) POST_MSGQ(pMsgQueue); #endif @@ -1072,7 +1067,7 @@ int GUIAPI PostMessage (HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) pMsgQueue->dwState |= QS_PAINT; UNLOCK_MSGQ (pMsgQueue); #ifdef _MGHAVE_VIRTUAL_WINDOW - if ( !BE_THIS_THREAD(hWnd) ) + if ( !isWindowInThisThread(hWnd) ) POST_MSGQ(pMsgQueue); #endif return ERR_OK; @@ -1111,7 +1106,7 @@ int GUIAPI PostQuitMessage (HWND hWnd) UNLOCK_MSGQ (pMsgQueue); #ifdef _MGHAVE_VIRTUAL_WINDOW - if (!BE_THIS_THREAD (hWnd)) + if (!isWindowInThisThread (hWnd)) POST_MSGQ (pMsgQueue); #endif @@ -1298,11 +1293,11 @@ int GUIAPI ThrowAwayMessages (HWND hWnd) /* clear timer message flags of this window */ for (slot = 0; slot < DEF_NR_TIMERS; slot++) { if (pMsgQueue->TimerMask & (0x01UL << slot)) { - HWND timer_wnd = __mg_get_timer_hwnd (slot); + HWND timer_wnd = pMsgQueue->timer_slots [slot]->hWnd; if (timer_wnd == hWnd || (MG_IS_MAIN_WINDOW (hWnd) && gui_GetMainWindowPtrOfControl (timer_wnd) == (PMAINWIN)hWnd)) { - RemoveMsgQueueTimerFlag (pMsgQueue, slot); + removeMsgQueueTimerFlag (pMsgQueue, slot); } } } @@ -1450,7 +1445,7 @@ LRESULT SendSyncMessage (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) LRESULT GUIAPI PostSyncMessage (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { MG_CHECK_RET (MG_IS_WINDOW(hWnd), -1); - if (BE_THIS_THREAD(hWnd)) + if (isWindowInThisThread(hWnd)) return -1; return SendSyncMessage (hWnd, msg, wParam, lParam); diff --git a/src/kernel/timer.c b/src/kernel/timer.c index 17ba2b3e..c6a9c769 100644 --- a/src/kernel/timer.c +++ b/src/kernel/timer.c @@ -78,17 +78,6 @@ #endif DWORD __mg_timer_counter = 0; -static TIMER *timerstr[DEF_NR_TIMERS]; - -#ifdef _MGHAVE_VIRTUAL_WINDOW -/* lock for protecting timerstr */ -static pthread_mutex_t timerLock; -#define TIMER_LOCK() pthread_mutex_lock(&timerLock) -#define TIMER_UNLOCK() pthread_mutex_unlock(&timerLock) -#else -#define TIMER_LOCK() -#define TIMER_UNLOCK() -#endif /* timer action for minigui timers */ static void __mg_timer_action (void *data) @@ -229,10 +218,6 @@ BOOL mg_InitTimer (void) { __mg_os_start_time_ms(); -#ifdef _MGHAVE_VIRTUAL_WINDOW - pthread_mutex_init (&timerLock, NULL); -#endif - #ifdef _MGRM_THREADS __mg_timer_counter = 0; #else @@ -244,8 +229,6 @@ BOOL mg_InitTimer (void) void mg_TerminateTimer (void) { - int i; - #ifdef __AOS__ tp_os_timer_delete (__mg_os_timer); #endif @@ -260,6 +243,9 @@ void mg_TerminateTimer (void) # endif /* __WINBOND_SWLINUX__ */ #endif + /* Since 4.2.0, we allocate timer slots per thread, and manage the time slots + in message queue */ +#if 0 for (i = 0; i < DEF_NR_TIMERS; i++) { if (timerstr[i] != NULL) free ( timerstr[i] ); @@ -269,48 +255,306 @@ void mg_TerminateTimer (void) #ifdef _MGHAVE_VIRTUAL_WINDOW pthread_mutex_destroy (&timerLock); #endif + +#endif /* deprecated code */ } /************************* Functions run in desktop thread *******************/ +#ifdef _MGHAVE_VIRTUAL_WINDOW +#else +#endif + void __mg_dispatch_timer_message (DWORD inter) { int i; + MSGQUEUE* msg_queue; if (inter == 0) return; - TIMER_LOCK (); - - for (i=0; imsg_queue) { - timerstr[i]->count += inter; - if (timerstr[i]->count >= timerstr[i]->speed) { + msg_queue = getMsgQueueForThisThread (); + if (msg_queue) { + TIMER** timer_slots = msg_queue->timer_slots; + for (i = 0; i < DEF_NR_TIMERS; i++) { + if (timer_slots[i]) { + timer_slots[i]->count += inter; + if (timer_slots[i]->count >= timer_slots[i]->speed) { #ifdef _MGRM_PROCESSES - timerstr[i]->tick_count = SHAREDRES_TIMER_COUNTER; + timer_slots[i]->tick_count = SHAREDRES_TIMER_COUNTER; #else - timerstr[i]->tick_count = __mg_timer_counter; + timer_slots[i]->tick_count = __mg_timer_counter; #endif - /* setting timer flag is simple, we do not need to lock msgq, - or else we may encounter dead lock here */ - SetMsgQueueTimerFlag (timerstr[i]->msg_queue, i); - timerstr[i]->count -= timerstr[i]->speed; + /* setting timer flag is simple, we do not need to lock msgq, + or else we may encounter dead lock here */ + setMsgQueueTimerFlag (msg_queue, i); + timer_slots[i]->count -= timer_slots[i]->speed; + } } } } - - TIMER_UNLOCK (); + else { + _WRN_PRINTF ("called for non message thread\n"); + } } -/* thread safe, no mutex */ -TIMER* __mg_get_timer (int slot) +BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD speed, + TIMERPROC timer_proc) { - if (slot < 0 || slot >= DEF_NR_TIMERS) - return NULL; + int i; + int slot = -1; + TIMER** timer_slots; - return timerstr[slot]; + if (id == 0) { + _WRN_PRINTF ("bad identifier (%ld).\n", id); + return FALSE; + } + + if (speed == 0) { + speed = 1; + } + + timer_slots = getTimerSlotsForThisThread(); + if (MG_UNLIKELY (timer_slots == NULL)) { + _WRN_PRINTF ("called for non message thread\n"); + goto badret; + } + + if (MG_UNLIKELY (!isWindowInThisThread (hWnd))) { + _WRN_PRINTF ("called for a window not in current thread\n"); + goto badret; + } + + /* Is there an empty timer slot? */ + for (i = 0; i < DEF_NR_TIMERS; i++) { + if (timer_slots[i] == NULL) { + if (slot < 0) + slot = i; + } + else if (timer_slots[i]->hWnd == hWnd && timer_slots[i]->id == id) { + _WRN_PRINTF ("duplicated call to SetTimerEx (%p, %ld).\n", hWnd, id); + goto badret; + } + } + + if (slot < 0 || slot == DEF_NR_TIMERS) { + _WRN_PRINTF ("no more slot for new timer (total: %d)\n", DEF_NR_TIMERS); + goto badret; + } + + timer_slots[slot] = mg_slice_new (TIMER); + + timer_slots[slot]->speed = speed; + timer_slots[slot]->hWnd = hWnd; + timer_slots[slot]->id = id; + timer_slots[slot]->count = 0; + timer_slots[slot]->proc = timer_proc; + timer_slots[slot]->tick_count = 0; + +#ifdef _MGRM_PROCESSES + if (!mgIsServer) + __mg_set_select_timeout (USEC_10MS * speed); +#endif + + return TRUE; + +badret: + return FALSE; +} + +#ifdef _MGRM_PROCESSES +static void reset_select_timeout (TIMER** timer_slots) +{ + int i; + + unsigned int speed = 0; + for (i = 0; i < DEF_NR_TIMERS; i++) { + if (timer_slots[i]) { + if (speed == 0 || timer_slots[i]->speed < speed) + speed = timer_slots[i]->speed; + } + } + __mg_set_select_timeout (USEC_10MS * speed); +} +#endif + +void __mg_remove_timer (MSGQUEUE* msg_queue, int slot) +{ + TIMER** timer_slots; + + if (slot < 0 || slot >= DEF_NR_TIMERS) + return; + + timer_slots = msg_queue->timer_slots; + if (MG_LIKELY (timer_slots[slot])) { + /* The following code is already moved to message.c... + * timer->msg_queue->TimerMask &= ~(0x01 << slot); + */ + mg_slice_delete (TIMER, timer_slots[slot]); + timer_slots [slot] = NULL; + +#ifdef _MGRM_PROCESSES + if (!mgIsServer) + reset_select_timeout (timer_slots); +#endif + } +} + +void __mg_remove_timers_by_msg_queue (MSGQUEUE* msg_queue) +{ + int i; + TIMER** timer_slots = msg_queue->timer_slots; + + for (i = 0; i < DEF_NR_TIMERS; i++) { + if (timer_slots [i]) { + mg_slice_delete (TIMER, timer_slots[i]); + timer_slots [i] = NULL; + } + } +} + +/* If id == 0, clear all timers of the window */ +int GUIAPI KillTimer (HWND hWnd, LINT id) +{ + int i; + int killed = 0; + MSGQUEUE* msg_queue; + + msg_queue = getMsgQueueForThisThread (); + if (msg_queue) { + + TIMER** timer_slots = msg_queue->timer_slots; + for (i = 0; i < DEF_NR_TIMERS; i++) { + if ((timer_slots [i] && timer_slots [i]->hWnd == hWnd) && + (id == 0 || timer_slots [i]->id == id)) { + removeMsgQueueTimerFlag (msg_queue, i); + mg_slice_delete (TIMER, timer_slots[i]); + timer_slots [i] = NULL; + killed ++; + + if (id) + break; + } + } + +#ifdef _MGRM_PROCESSES + if (!mgIsServer && killed) + reset_select_timeout (msg_queue->timer_slots); +#endif + } + else { + _WRN_PRINTF ("called for non message thread\n"); + } + + + return killed; +} + +BOOL GUIAPI ResetTimerEx (HWND hWnd, LINT id, DWORD speed, + TIMERPROC timer_proc) +{ + int i; + MSGQUEUE* msg_queue; + + if (id == 0) + return FALSE; + + msg_queue = getMsgQueueForThisThread (); + if (MG_LIKELY (msg_queue)) { + TIMER** timer_slots = msg_queue->timer_slots; + + for (i = 0; i < DEF_NR_TIMERS; i++) { + if (timer_slots[i] && + timer_slots[i]->hWnd == hWnd && timer_slots[i]->id == id) { + + /* Should clear old timer flags */ + removeMsgQueueTimerFlag (msg_queue, i); + timer_slots[i]->speed = speed; + timer_slots[i]->count = 0; + if (timer_proc != (TIMERPROC)INV_PTR) + timer_slots[i]->proc = timer_proc; + timer_slots[i]->tick_count = 0; + + return TRUE; + } + } + } + else { + _WRN_PRINTF ("called for non message thread\n"); + } + + return FALSE; +} + +BOOL GUIAPI IsTimerInstalled (HWND hWnd, LINT id) +{ + int i; + TIMER** timer_slots; + + if (id == 0) + return FALSE; + + timer_slots = getTimerSlotsForThisThread (); + if (timer_slots) { + for (i = 0; i < DEF_NR_TIMERS; i++) { + if (timer_slots[i] && + timer_slots[i]->hWnd == hWnd && timer_slots[i]->id == id) { + return TRUE; + } + } + } + else { + _WRN_PRINTF ("called for non message thread\n"); + } + + return FALSE; +} + +BOOL GUIAPI HaveFreeTimer (void) +{ + int i; + TIMER** timer_slots; + + timer_slots = getTimerSlotsForThisThread (); + if (timer_slots) { + for (i = 0; i < DEF_NR_TIMERS; i++) { + if (timer_slots[i] == NULL) + return TRUE; + } + } + else { + _WRN_PRINTF ("called for non message thread\n"); + } + + return FALSE; +} + +DWORD GUIAPI GetTickCount (void) +{ +#ifdef _MGRM_PROCESSES + return SHAREDRES_TIMER_COUNTER; +#elif defined(_MGRM_STANDALONE) + __mg_timer_counter = __mg_os_get_time_ms()/10; + return __mg_timer_counter; +#else + return __mg_timer_counter; +#endif } #if 0 +/* Since 4.2.0, we use timer slots per thread, and manage the time slots + in message queue */ +static TIMER *timerstr[DEF_NR_TIMERS]; + +#ifdef _MGHAVE_VIRTUAL_WINDOW +/* lock for protecting timerstr */ +static pthread_mutex_t timerLock; +#define TIMER_LOCK() pthread_mutex_lock(&timerLock) +#define TIMER_UNLOCK() pthread_mutex_unlock(&timerLock) +#else +#define TIMER_LOCK() +#define TIMER_UNLOCK() +#endif + int __mg_get_timer_slot (HWND hWnd, int id) { int i; @@ -360,250 +604,22 @@ void __mg_move_timer_last (TIMER* timer, int slot) TIMER_UNLOCK (); return; } -#endif -BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD speed, - TIMERPROC timer_proc) +TIMER* __mg_get_timer (int slot) { - int i; - int slot = -1; - PMSGQUEUE pMsgQueue; + TIMER** timer_slots; - if (id == 0) { - _WRN_PRINTF ("KERNEL>Timer: bad identifier (%ld).\n", id); - return FALSE; - } - - if (speed == 0) { - speed = 1; - } - -#ifdef _MGHAVE_VIRTUAL_WINDOW - if (!(pMsgQueue = mg_GetMsgQueueForThisThread (FALSE))) { - _WRN_PRINTF ("KERNEL>Timer: Not a GUI thread.\n"); - return FALSE; - } -#else - pMsgQueue = __mg_dsk_msg_queue; -#endif - - TIMER_LOCK (); - - /* Is there an empty timer slot? */ - for (i=0; ihWnd == hWnd && timerstr[i]->id == id) { - _WRN_PRINTF ("KERNEL>Timer: duplicated call to SetTimerEx (%p, %ld).\n", hWnd, id); - goto badret; - } - } - - if (slot < 0 || slot == DEF_NR_TIMERS) { - _WRN_PRINTF ("KERNEL>Timer: No more slot for new timer (total: %d)\n", DEF_NR_TIMERS); - goto badret; - } - - timerstr[slot] = malloc (sizeof (TIMER)); - - timerstr[slot]->speed = speed; - timerstr[slot]->hWnd = hWnd; - timerstr[slot]->id = id; - timerstr[slot]->count = 0; - timerstr[slot]->proc = timer_proc; - timerstr[slot]->tick_count = 0; - timerstr[slot]->msg_queue = pMsgQueue; - -#ifdef _MGRM_PROCESSES - if (!mgIsServer) - __mg_set_select_timeout (USEC_10MS * speed); -#endif - - TIMER_UNLOCK (); - return TRUE; - -badret: - TIMER_UNLOCK (); - return FALSE; -} - -#ifdef _MGRM_PROCESSES -static void reset_select_timeout (void) -{ - int i; - - unsigned int speed = 0; - for (i=0; ispeed < speed) - speed = timerstr[i]->speed; - } - } - __mg_set_select_timeout (USEC_10MS * speed); -} -#endif - -void __mg_remove_timer (TIMER* timer, int slot) -{ if (slot < 0 || slot >= DEF_NR_TIMERS) - return; + return NULL; - TIMER_LOCK (); - - if (timer && timer->msg_queue && timerstr[slot] == timer) { - /* The following code is already moved to message.c... - * timer->msg_queue->TimerMask &= ~(0x01 << slot); - */ - free (timerstr[slot]); - timerstr [slot] = NULL; - -#ifdef _MGRM_PROCESSES - if (!mgIsServer) - reset_select_timeout (); -#endif + timer_slots = getTimerSlotsForThisThread (); + if (timer_slots) { + return timer_slots[slot]; } - - TIMER_UNLOCK (); - return; + _WRN_PRINTF ("called for non message thread\n"); + return NULL; } -void __mg_remove_timers_by_msg_queue (const MSGQUEUE* msg_que) -{ - int i; - - TIMER_LOCK (); - - for (i=0; imsg_queue == msg_que) { - free (timerstr[i]); - timerstr [i] = NULL; - } - } - - TIMER_UNLOCK (); -} - -/* If id == 0, clear all timers of the window */ -int GUIAPI KillTimer (HWND hWnd, LINT id) -{ - int i; - PMSGQUEUE pMsgQueue; - int killed = 0; - -#ifdef _MGHAVE_VIRTUAL_WINDOW - if (!(pMsgQueue = mg_GetMsgQueueForThisThread (FALSE))) - return 0; -#else - pMsgQueue = __mg_dsk_msg_queue; -#endif - - TIMER_LOCK (); - - for (i = 0; i < DEF_NR_TIMERS; i++) { - if ((timerstr [i] && timerstr [i]->hWnd == hWnd) && - (id == 0 || timerstr [i]->id == id)) { - RemoveMsgQueueTimerFlag (pMsgQueue, i); - free (timerstr[i]); - timerstr [i] = NULL; - killed ++; - - if (id) break; - } - } - -#ifdef _MGRM_PROCESSES - if (!mgIsServer && killed) - reset_select_timeout (); -#endif - - TIMER_UNLOCK (); - return killed; -} - -BOOL GUIAPI ResetTimerEx (HWND hWnd, LINT id, DWORD speed, - TIMERPROC timer_proc) -{ - int i; - PMSGQUEUE pMsgQueue; - - if (id == 0) - return FALSE; - -#ifdef _MGHAVE_VIRTUAL_WINDOW - if (!(pMsgQueue = mg_GetMsgQueueForThisThread (FALSE))) - return FALSE; -#else - pMsgQueue = __mg_dsk_msg_queue; -#endif - - TIMER_LOCK (); - - for (i = 0; i < DEF_NR_TIMERS; i++) { - if (timerstr[i] && timerstr[i]->hWnd == hWnd && timerstr[i]->id == id) { - /* Should clear old timer flags */ - RemoveMsgQueueTimerFlag (pMsgQueue, i); - timerstr[i]->speed = speed; - timerstr[i]->count = 0; - if (timer_proc != (TIMERPROC)INV_PTR) - timerstr[i]->proc = timer_proc; - timerstr[i]->tick_count = 0; - - TIMER_UNLOCK (); - return TRUE; - } - } - - TIMER_UNLOCK (); - return FALSE; -} - -BOOL GUIAPI IsTimerInstalled (HWND hWnd, LINT id) -{ - int i; - - if (id == 0) - return FALSE; - - TIMER_LOCK (); - - for (i = 0; i < DEF_NR_TIMERS; i++) { - if ( timerstr[i] != NULL ) { - if ( timerstr[i]->hWnd == hWnd && timerstr[i]->id == id) { - TIMER_UNLOCK (); - return TRUE; - } - } - } - - TIMER_UNLOCK (); - return FALSE; -} - -/* no lock is ok */ -BOOL GUIAPI HaveFreeTimer (void) -{ - int i; - - for (i=0; i