1/* -------------------------------------------------------------------------
2 * Project: Mac Notifier Support
3 * Name:    macnotfy.c
4 * Author:  Stefan CSomor
5 * Purpose: Mac Notifier main file
6 * CVSID:   $Id: macnotfy.cpp 31794 2005-02-06 16:02:39Z SC $
7 * -------------------------------------------------------------------------
8 */
9
10#include "wx/wxprec.h"
11
12#include "wx/wx.h"
13
14#include "wx/mac/private.h"
15
16#include "wx/mac/macnotfy.h"
17
18const short kMaxEvents = 1000 ;
19
20struct wxMacNotificationEvents
21{
22    short top ;
23    short bottom ;
24
25    wxMacNotificationProcPtr proc[kMaxEvents] ;
26    unsigned long events[kMaxEvents] ;
27    void* data[kMaxEvents] ;
28} ;
29
30typedef struct wxMacNotificationEvents wxMacNotificationEvents ;
31static wxMacNotificationEvents gMacNotificationEvents ;
32
33ProcessSerialNumber gAppProcess ;
34
35void wxMacCreateNotifierTable()
36{
37      GetCurrentProcess(&gAppProcess);
38    gMacNotificationEvents.top = 0 ;
39    gMacNotificationEvents.bottom = 0 ;
40    for ( int i = 0 ; i < kMaxEvents ; ++i )
41    {
42        gMacNotificationEvents.proc[i] = NULL ;
43        gMacNotificationEvents.events[i] = 0 ;
44        gMacNotificationEvents.data[i] = NULL ;
45    }
46}
47
48void wxMacDestroyNotifierTable()
49{
50}
51
52wxMacNotifierTableRef wxMacGetNotifierTable()
53{
54    return (wxMacNotifierTableRef) &gMacNotificationEvents ;
55}
56
57void wxMacAddEvent(
58    wxMacNotifierTableRef table ,
59    wxMacNotificationProcPtr handler ,
60    unsigned long event ,
61    void* data ,
62    short wakeUp )
63{
64    wxMacNotificationEvents *e = (wxMacNotificationEvents *) table ;
65    wxASSERT_MSG( handler != NULL , wxT("illegal notification proc ptr") ) ;
66    /* this should be protected eventually */
67    short index = e->top++ ;
68
69    if ( e->top == kMaxEvents )
70        e->top = 0 ;
71
72    e->proc[index] = handler ;
73    e->events[index] = event ;
74    e->data[index] = data ;
75    if ( wakeUp )
76        wxMacWakeUp() ;
77}
78
79bool gInProcessing = false ;
80
81void wxMacRemoveAllNotifiersForData( wxMacNotifierTableRef table , void* data )
82{
83    wxMacNotificationEvents *e = (wxMacNotificationEvents *) table ;
84    /* this should be protected eventually */
85    short index = e->bottom ;
86
87    while ( e->top != index )
88    {
89        if ( e->data[index] == data )
90            e->data[index] = NULL ;
91        index++ ;
92        if ( index == kMaxEvents )
93            index = 0 ;
94    }
95}
96
97void wxMacProcessNotifierEvents()
98{
99    //  if ( gInProcessing )
100    //      return ;
101
102    gInProcessing = true ;
103    if ( gMacNotificationEvents.top != gMacNotificationEvents.bottom )
104    {
105        // we only should process the notifiers that were here when we entered it
106        // otherwise we might never get out...
107        short count = gMacNotificationEvents.top - gMacNotificationEvents.bottom ;
108        if ( count < 0 )
109            count += kMaxEvents ;
110
111        while ( count-- )
112        {
113            // consume event at bottom
114            short index = gMacNotificationEvents.bottom++ ;
115            if ( gMacNotificationEvents.bottom == kMaxEvents )
116                gMacNotificationEvents.bottom = 0 ;
117            void* data = gMacNotificationEvents.data[index] ;
118            unsigned long event = gMacNotificationEvents.events[index] ;
119            wxMacNotificationProcPtr handler =  gMacNotificationEvents.proc[index] ;
120
121            gMacNotificationEvents.data[index] = NULL ;
122            gMacNotificationEvents.events[index] = 0 ;
123            gMacNotificationEvents.proc[index]  = NULL ;
124
125            if ( handler )
126                handler( event , data  ) ;
127        }
128    }
129    gInProcessing = false ;
130}
131
132void wxMacProcessNotifierAndPendingEvents()
133{
134    wxMacProcessNotifierEvents() ;
135    wxTheApp->ProcessPendingEvents() ;
136}
137