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 26277 2004-03-20 07:43:01Z SC $ 7 * ------------------------------------------------------------------------- 8 */ 9 10#include "wx/wx.h" 11 12#include "wx/mac/private.h" 13 14#include "wx/mac/macnotfy.h" 15 16const short kMaxEvents = 1000 ; 17 18struct wxMacNotificationEvents 19{ 20 short top ; 21 short bottom ; 22 23 wxMacNotificationProcPtr proc[kMaxEvents] ; 24 unsigned long events[kMaxEvents] ; 25 void* data[kMaxEvents] ; 26} ; 27 28typedef struct wxMacNotificationEvents wxMacNotificationEvents ; 29static wxMacNotificationEvents gMacNotificationEvents ; 30 31static ProcessSerialNumber gAppProcess ; 32 33void wxMacWakeUp() 34{ 35 ProcessSerialNumber psn ; 36 Boolean isSame ; 37 psn.highLongOfPSN = 0 ; 38 psn.lowLongOfPSN = kCurrentProcess ; 39 SameProcess( &gAppProcess , &psn , &isSame ) ; 40 if ( isSame ) 41 { 42#if TARGET_CARBON 43 EventRef dummyEvent ; 44 OSStatus err = MacCreateEvent(nil, 'WXMC', 'WXMC', GetCurrentEventTime(), 45 kEventAttributeNone, &dummyEvent); 46 if (err == noErr) 47 { 48 err = PostEventToQueue(GetMainEventQueue(), dummyEvent, 49 kEventPriorityHigh); 50 } 51#else 52 PostEvent( nullEvent , 0 ) ; 53#endif 54 } 55 else 56 { 57 WakeUpProcess( &gAppProcess ) ; 58 } 59} 60 61void wxMacCreateNotifierTable() 62{ 63 GetCurrentProcess(&gAppProcess); 64 gMacNotificationEvents.top = 0 ; 65 gMacNotificationEvents.bottom = 0 ; 66 for ( int i = 0 ; i < kMaxEvents ; ++i ) 67 { 68 gMacNotificationEvents.proc[i] = NULL ; 69 gMacNotificationEvents.events[i] = NULL ; 70 gMacNotificationEvents.data[i] = NULL ; 71 } 72} 73 74void wxMacDestroyNotifierTable() 75{ 76} 77 78wxMacNotifierTableRef wxMacGetNotifierTable() 79{ 80 return (wxMacNotifierTableRef) &gMacNotificationEvents ; 81} 82 83void wxMacAddEvent( 84 wxMacNotifierTableRef table , 85 wxMacNotificationProcPtr handler , 86 unsigned long event , 87 void* data , 88 short wakeUp ) 89{ 90 wxMacNotificationEvents *e = (wxMacNotificationEvents *) table ; 91 wxASSERT_MSG( handler != NULL , wxT("illegal notification proc ptr") ) ; 92 /* this should be protected eventually */ 93 short index = e->top++ ; 94 95 if ( e->top == kMaxEvents ) 96 e->top = 0 ; 97 98 e->proc[index] = handler ; 99 e->events[index] = event ; 100 e->data[index] = data ; 101 if ( wakeUp ) 102 wxMacWakeUp() ; 103} 104 105bool gInProcessing = false ; 106 107void wxMacRemoveAllNotifiersForData( wxMacNotifierTableRef table , void* data ) 108{ 109 wxMacNotificationEvents *e = (wxMacNotificationEvents *) table ; 110 /* this should be protected eventually */ 111 short index = e->bottom ; 112 113 while ( e->top != index ) 114 { 115 if ( e->data[index] == data ) 116 e->data[index] = NULL ; 117 index++ ; 118 if ( index == kMaxEvents ) 119 index = 0 ; 120 } 121} 122 123void wxMacProcessNotifierEvents() 124{ 125 // if ( gInProcessing ) 126 // return ; 127 128 gInProcessing = true ; 129 if ( gMacNotificationEvents.top != gMacNotificationEvents.bottom ) 130 { 131 // we only should process the notifiers that were here when we entered it 132 // otherwise we might never get out... 133 short count = gMacNotificationEvents.top - gMacNotificationEvents.bottom ; 134 if ( count < 0 ) 135 count += kMaxEvents ; 136 137 while ( count-- ) 138 { 139 // consume event at bottom 140 short index = gMacNotificationEvents.bottom++ ; 141 if ( gMacNotificationEvents.bottom == kMaxEvents ) 142 gMacNotificationEvents.bottom = 0 ; 143 void* data = gMacNotificationEvents.data[index] ; 144 unsigned long event = gMacNotificationEvents.events[index] ; 145 wxMacNotificationProcPtr handler = gMacNotificationEvents.proc[index] ; 146 147 gMacNotificationEvents.data[index] = NULL ; 148 gMacNotificationEvents.events[index] = NULL ; 149 gMacNotificationEvents.proc[index] = NULL ; 150 151 if ( handler ) 152 handler( event , data ) ; 153 } 154 } 155 gInProcessing = false ; 156} 157 158void wxMacProcessNotifierAndPendingEvents() 159{ 160 wxMacProcessNotifierEvents() ; 161 wxTheApp->ProcessPendingEvents() ; 162} 163