Changeset 101897 in vbox
- Timestamp:
- Nov 6, 2023 7:36:01 PM (15 months ago)
- Location:
- trunk/src/libs/xpcom18a4/xpcom/threads
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/xpcom/threads/plevent.c
r33044 r101897 36 36 * ***** END LICENSE BLOCK ***** */ 37 37 38 #if defined(_WIN32)39 #include <windows.h>40 #endif41 42 #if defined(XP_OS2)43 #define INCL_DOS44 #define INCL_DOSERRORS45 #define INCL_WIN46 #include <os2.h>47 #define DefWindowProc WinDefWindowProc48 #endif /* XP_OS2 */49 50 38 #include "nspr.h" 51 39 #include "plevent.h" 52 40 53 #if !defined(WIN32)54 41 #include <errno.h> 55 42 #include <stddef.h> 56 #if !defined(XP_OS2)57 43 #include <unistd.h> 58 #endif /* !XP_OS2 */59 #endif /* !Win32 */60 61 #if defined(XP_UNIX)62 44 /* for fcntl */ 63 45 #include <sys/types.h> 64 46 #include <fcntl.h> 65 #endif66 67 #if defined(XP_BEOS)68 #include <kernel/OS.h>69 #endif70 47 71 48 #if defined(XP_MACOSX) 72 #if defined(MOZ_WIDGET_COCOA) 73 #include <CoreFoundation/CoreFoundation.h> 74 #define MAC_USE_CFRUNLOOPSOURCE 75 #elif defined(TARGET_CARBON) 76 /* #include <CarbonEvents.h> */ 77 /* #define MAC_USE_CARBON_EVENT */ 78 #include <CoreFoundation/CoreFoundation.h> 79 #define MAC_USE_CFRUNLOOPSOURCE 80 #endif 49 # include <CoreFoundation/CoreFoundation.h> 81 50 #endif 82 51 83 52 #include "private/pprthred.h" 84 85 #if defined(VMS)86 /*87 ** On OpenVMS, XtAppAddInput doesn't want a regular fd, instead it88 ** wants an event flag. So, we don't create and use a pipe for89 ** notification of when an event queue has something ready, instead90 ** we use an event flag. Shouldn't be a problem if we only have91 ** a few event queues.92 */93 #include <lib$routines.h>94 #include <starlet.h>95 #include <stsdef.h>96 #endif /* VMS */97 98 #if defined(_WIN32)99 /* Comment out the following USE_TIMER define to prevent100 * WIN32 from using a WIN32 native timer for PLEvent notification.101 * With USE_TIMER defined we will use a timer when pending input102 * or paint events are starved, otherwise it will use a posted103 * WM_APP msg for PLEvent notification.104 */105 #define USE_TIMER106 107 /* Threshold defined in milliseconds for determining when the input108 * and paint events have been held in the WIN32 msg queue too long109 */110 #define INPUT_STARVATION_LIMIT 50111 /* The paint starvation limit is set to the smallest value which112 * does not cause performance degradation while running page load tests113 */114 #define PAINT_STARVATION_LIMIT 750115 /* The WIN9X paint starvation limit is larger because it was116 * determined that the following value was required to prevent performance117 * degradation on page load tests for WIN98/95 only.118 */119 #define WIN9X_PAINT_STARVATION_LIMIT 3000120 121 #define TIMER_ID 0122 /* If _md_PerformanceSetting <=0 then no event starvation otherwise events will be starved */123 static PRInt32 _md_PerformanceSetting = 0;124 static PRUint32 _md_StarvationDelay = 0;125 static PRUint32 _md_SwitchTime = 0;126 #endif127 53 128 54 static PRLogModuleInfo *event_lm = NULL; … … 150 76 PRPackedBool processingEvents; 151 77 PRPackedBool notified; 152 #if defined(_WIN32)153 PRPackedBool timerSet;154 #endif155 78 156 79 #if defined(XP_UNIX) && !defined(XP_MACOSX) 157 #if defined(VMS)158 int efn;159 #else160 80 PRInt32 eventPipe[2]; 161 #endif162 81 PLGetEventIDFunc idFunc; 163 82 void* idFuncClosure; 164 #elif defined(_WIN32) || defined(XP_OS2)165 HWND eventReceiverWindow;166 PRBool removeMsg;167 #elif defined(XP_BEOS)168 port_id eventport;169 83 #elif defined(XP_MACOSX) 170 #if defined(MAC_USE_CFRUNLOOPSOURCE)171 84 CFRunLoopSourceRef mRunLoopSource; 172 85 CFRunLoopRef mMainRunLoop; 173 86 CFStringRef mRunLoopModeStr; /* vbox */ 174 #elif defined(MAC_USE_CARBON_EVENT)175 EventHandlerUPP eventHandlerUPP;176 EventHandlerRef eventHandlerRef;177 #endif178 87 #endif 179 88 }; … … 189 98 static PRInt32 _pl_GetEventCount(PLEventQueue* self); 190 99 191 192 #if defined(_WIN32) || defined(XP_OS2)193 #if defined(XP_OS2)194 ULONG _pr_PostEventMsgId;195 #else196 UINT _pr_PostEventMsgId;197 #endif /* OS2 */198 static char *_pr_eventWindowClass = "XPCOM:EventWindow";199 #endif /* Win32, OS2 */200 201 #if defined(_WIN32)202 203 static LPCTSTR _md_GetEventQueuePropName() {204 static ATOM atom = 0;205 if (!atom) {206 atom = GlobalAddAtom("XPCOM_EventQueue");207 }208 return MAKEINTATOM(atom);209 }210 #endif211 212 #if defined(MAC_USE_CARBON_EVENT)213 enum {214 kEventClassPL = FOUR_CHAR_CODE('PLEC'),215 216 kEventProcessPLEvents = 1,217 218 kEventParamPLEventQueue = FOUR_CHAR_CODE('OWNQ')219 };220 221 static pascal Boolean _md_CarbonEventComparator(EventRef inEvent, void *inCompareData);222 #endif223 100 224 101 /******************************************************************************* … … 253 130 self->processingEvents = PR_FALSE; 254 131 self->type = qtype; 255 #if defined(_WIN32)256 self->timerSet = PR_FALSE;257 #endif258 #if defined(_WIN32) || defined(XP_OS2)259 self->removeMsg = PR_TRUE;260 #endif261 262 132 self->notified = PR_FALSE; 263 133 … … 761 631 PRUint32 starvationDelay) 762 632 { 763 #if defined(_WIN32)764 765 _md_StarvationDelay = starvationDelay;766 767 if (favorPerformanceOverEventStarvation) {768 _md_PerformanceSetting++;769 return;770 }771 772 _md_PerformanceSetting--;773 774 if (_md_PerformanceSetting == 0) {775 /* Switched from allowing event starvation to no event starvation so grab776 the current time to determine when to actually switch to using timers777 instead of posted WM_APP messages. */778 _md_SwitchTime = PR_IntervalToMilliseconds(PR_IntervalNow());779 }780 781 #endif782 633 } 783 634 … … 842 693 _pl_SetupNativeNotifier(PLEventQueue* self) 843 694 { 844 #if defined(VMS) 845 unsigned int status; 846 self->idFunc = 0; 847 self->idFuncClosure = 0; 848 status = LIB$GET_EF(&self->efn); 849 if (!$VMS_STATUS_SUCCESS(status)) 850 return PR_FAILURE; 851 PR_LOG(event_lm, PR_LOG_DEBUG, 852 ("$$$ Allocated event flag %d", self->efn)); 853 return PR_SUCCESS; 854 #elif defined(XP_UNIX) && !defined(XP_MACOSX) 695 #if defined(XP_UNIX) && !defined(XP_MACOSX) 855 696 int err; 856 697 int flags; … … 891 732 close(self->eventPipe[1]); 892 733 return PR_FAILURE; 893 #elif defined(XP_BEOS)894 /* hook up to the nsToolkit queue, however the appshell895 * isn't necessairly started, so we might have to create896 * the queue ourselves897 */898 char portname[64];899 char semname[64];900 PR_snprintf(portname, sizeof(portname), "event%lx",901 (long unsigned) self->handlerThread);902 PR_snprintf(semname, sizeof(semname), "sync%lx",903 (long unsigned) self->handlerThread);904 905 if((self->eventport = find_port(portname)) < 0)906 {907 /* create port908 */909 self->eventport = create_port(500, portname);910 911 /* We don't use the sem, but it has to be there912 */913 create_sem(0, semname);914 }915 916 return PR_SUCCESS;917 734 #else 918 735 return PR_SUCCESS; … … 923 740 _pl_CleanupNativeNotifier(PLEventQueue* self) 924 741 { 925 #if defined(VMS) 926 { 927 unsigned int status; 928 PR_LOG(event_lm, PR_LOG_DEBUG, 929 ("$$$ Freeing event flag %d", self->efn)); 930 status = LIB$FREE_EF(&self->efn); 931 } 932 #elif defined(XP_UNIX) && !defined(XP_MACOSX) 742 #if defined(XP_UNIX) && !defined(XP_MACOSX) 933 743 close(self->eventPipe[0]); 934 744 close(self->eventPipe[1]); 935 #elif defined(_WIN32)936 if (self->timerSet) {937 KillTimer(self->eventReceiverWindow, TIMER_ID);938 self->timerSet = PR_FALSE;939 }940 RemoveProp(self->eventReceiverWindow, _md_GetEventQueuePropName());941 942 /* DestroyWindow doesn't do anything when called from a non ui thread. Since943 * self->eventReceiverWindow was created on the ui thread, it must be destroyed944 * on the ui thread.945 */946 SendMessage(self->eventReceiverWindow, WM_CLOSE, 0, 0);947 948 #elif defined(XP_OS2)949 WinDestroyWindow(self->eventReceiverWindow);950 745 #elif defined(MAC_USE_CFRUNLOOPSOURCE) 951 746 … … 955 750 CFRelease(self->mMainRunLoop); 956 751 CFRelease(self->mRunLoopModeStr); /* vbox */ 957 958 #elif defined(MAC_USE_CARBON_EVENT) 959 EventComparatorUPP comparator = NewEventComparatorUPP(_md_CarbonEventComparator); 960 PR_ASSERT(comparator != NULL); 961 if (comparator) { 962 FlushSpecificEventsFromQueue(GetMainEventQueue(), comparator, self); 963 DisposeEventComparatorUPP(comparator); 964 } 965 DisposeEventHandlerUPP(self->eventHandlerUPP); 966 RemoveEventHandler(self->eventHandlerRef); 967 #endif 968 } 969 970 #if defined(_WIN32) 971 972 static PRBool _md_WasInputPending = PR_FALSE; 973 static PRUint32 _md_InputTime = 0; 974 static PRBool _md_WasPaintPending = PR_FALSE; 975 static PRUint32 _md_PaintTime = 0; 976 /* last mouse location */ 977 static POINT _md_LastMousePos; 978 979 /******************************************************************************* 980 * Timer callback function. Timers are used on WIN32 instead of APP events 981 * when there are pending UI events because APP events can cause the GUI to lockup 982 * because posted messages are processed before other messages. 983 ******************************************************************************/ 984 985 static void CALLBACK _md_TimerProc( HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime ) 986 { 987 PREventQueue* queue = (PREventQueue *) GetProp(hwnd, _md_GetEventQueuePropName()); 988 PR_ASSERT(queue != NULL); 989 990 KillTimer(hwnd, TIMER_ID); 991 queue->timerSet = PR_FALSE; 992 queue->removeMsg = PR_FALSE; 993 PL_ProcessPendingEvents( queue ); 994 queue->removeMsg = PR_TRUE; 995 } 996 997 static PRBool _md_IsWIN9X = PR_FALSE; 998 static PRBool _md_IsOSSet = PR_FALSE; 999 1000 static void _md_DetermineOSType() 1001 { 1002 OSVERSIONINFO os; 1003 os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 1004 GetVersionEx(&os); 1005 if (VER_PLATFORM_WIN32_WINDOWS == os.dwPlatformId) { 1006 _md_IsWIN9X = PR_TRUE; 1007 } 1008 } 1009 1010 static PRUint32 _md_GetPaintStarvationLimit() 1011 { 1012 if (! _md_IsOSSet) { 1013 _md_DetermineOSType(); 1014 _md_IsOSSet = PR_TRUE; 1015 } 1016 1017 if (_md_IsWIN9X) { 1018 return WIN9X_PAINT_STARVATION_LIMIT; 1019 } 1020 1021 return PAINT_STARVATION_LIMIT; 1022 } 1023 1024 1025 /* 1026 * Determine if an event is being starved (i.e the starvation limit has 1027 * been exceeded. 1028 * Note: this function uses the current setting and updates the contents 1029 * of the wasPending and lastTime arguments 1030 * 1031 * ispending: PR_TRUE if the event is currently pending 1032 * starvationLimit: Threshold defined in milliseconds for determining when 1033 * the event has been held in the queue too long 1034 * wasPending: PR_TRUE if the last time _md_EventIsStarved was called 1035 * the event was pending. This value is updated within 1036 * this function. 1037 * lastTime: Holds the last time the event was in the queue. 1038 * This value is updated within this function 1039 * returns: PR_TRUE if the event is starved, PR_FALSE otherwise 1040 */ 1041 1042 static PRBool _md_EventIsStarved(PRBool isPending, PRUint32 starvationLimit, 1043 PRBool *wasPending, PRUint32 *lastTime, 1044 PRUint32 currentTime) 1045 { 1046 if (*wasPending && isPending) { 1047 /* 1048 * It was pending previously and the event is still 1049 * pending so check to see if the elapsed time is 1050 * over the limit which indicates the event was starved 1051 */ 1052 if ((currentTime - *lastTime) > starvationLimit) { 1053 return PR_TRUE; /* pending and over the limit */ 1054 } 1055 1056 return PR_FALSE; /* pending but within the limit */ 1057 } 1058 1059 if (isPending) { 1060 /* 1061 * was_pending must be false so record the current time 1062 * so the elapsed time can be computed the next time this 1063 * function is called 1064 */ 1065 *lastTime = currentTime; 1066 *wasPending = PR_TRUE; 1067 return PR_FALSE; 1068 } 1069 1070 /* Event is no longer pending */ 1071 *wasPending = PR_FALSE; 1072 return PR_FALSE; 1073 } 1074 1075 /* Determines if the there is a pending Mouse or input event */ 1076 1077 static PRBool _md_IsInputPending(WORD qstatus) 1078 { 1079 /* Return immediately there aren't any pending input or paints. */ 1080 if (qstatus == 0) { 1081 return PR_FALSE; 1082 } 1083 1084 /* Is there anything other than a QS_MOUSEMOVE pending? */ 1085 if ((qstatus & QS_MOUSEBUTTON) || 1086 (qstatus & QS_KEY) || 1087 (qstatus & QS_HOTKEY)) { 1088 return PR_TRUE; 1089 } 1090 1091 /* 1092 * Mouse moves need extra processing to determine if the mouse 1093 * pointer actually changed location because Windows automatically 1094 * generates WM_MOVEMOVE events when a new window is created which 1095 * we need to filter out. 1096 */ 1097 if (qstatus & QS_MOUSEMOVE) { 1098 POINT cursorPos; 1099 GetCursorPos(&cursorPos); 1100 if ((_md_LastMousePos.x == cursorPos.x) && 1101 (_md_LastMousePos.y == cursorPos.y)) { 1102 return PR_FALSE; /* This is a fake mouse move */ 1103 } 1104 1105 /* Real mouse move */ 1106 _md_LastMousePos.x = cursorPos.x; 1107 _md_LastMousePos.y = cursorPos.y; 1108 return PR_TRUE; 1109 } 1110 1111 return PR_FALSE; 1112 } 1113 1114 static PRStatus 1115 _pl_NativeNotify(PLEventQueue* self) 1116 { 1117 #ifdef USE_TIMER 1118 WORD qstatus; 1119 1120 PRUint32 now = PR_IntervalToMilliseconds(PR_IntervalNow()); 1121 1122 /* Since calls to set the _md_PerformanceSetting can be nested 1123 * only performance setting values <= 0 will potentially trigger 1124 * the use of a timer. 1125 */ 1126 if ((_md_PerformanceSetting <= 0) && 1127 ((now - _md_SwitchTime) > _md_StarvationDelay)) { 1128 SetTimer(self->eventReceiverWindow, TIMER_ID, 0 ,_md_TimerProc); 1129 self->timerSet = PR_TRUE; 1130 _md_WasInputPending = PR_FALSE; 1131 _md_WasPaintPending = PR_FALSE; 1132 return PR_SUCCESS; 1133 } 1134 1135 qstatus = HIWORD(GetQueueStatus(QS_INPUT | QS_PAINT)); 1136 1137 /* Check for starved input */ 1138 if (_md_EventIsStarved( _md_IsInputPending(qstatus), 1139 INPUT_STARVATION_LIMIT, 1140 &_md_WasInputPending, 1141 &_md_InputTime, 1142 now )) { 1143 /* 1144 * Use a timer for notification. Timers have the lowest priority. 1145 * They are not processed until all other events have been processed. 1146 * This allows any starved paints and input to be processed. 1147 */ 1148 SetTimer(self->eventReceiverWindow, TIMER_ID, 0 ,_md_TimerProc); 1149 self->timerSet = PR_TRUE; 1150 1151 /* 1152 * Clear any pending paint. _md_WasInputPending was cleared in 1153 * _md_EventIsStarved. 1154 */ 1155 _md_WasPaintPending = PR_FALSE; 1156 return PR_SUCCESS; 1157 } 1158 1159 if (_md_EventIsStarved( (qstatus & QS_PAINT), 1160 _md_GetPaintStarvationLimit(), 1161 &_md_WasPaintPending, 1162 &_md_PaintTime, 1163 now) ) { 1164 /* 1165 * Use a timer for notification. Timers have the lowest priority. 1166 * They are not processed until all other events have been processed. 1167 * This allows any starved paints and input to be processed 1168 */ 1169 SetTimer(self->eventReceiverWindow, TIMER_ID, 0 ,_md_TimerProc); 1170 self->timerSet = PR_TRUE; 1171 1172 /* 1173 * Clear any pending input. _md_WasPaintPending was cleared in 1174 * _md_EventIsStarved. 1175 */ 1176 _md_WasInputPending = PR_FALSE; 1177 return PR_SUCCESS; 1178 } 1179 1180 /* 1181 * Nothing is being starved so post a message instead of using a timer. 1182 * Posted messages are processed before other messages so they have the 1183 * highest priority. 1184 */ 1185 #endif 1186 PostMessage( self->eventReceiverWindow, _pr_PostEventMsgId, 1187 (WPARAM)0, (LPARAM)self ); 1188 1189 return PR_SUCCESS; 1190 }/* --- end _pl_NativeNotify() --- */ 1191 #endif 1192 1193 1194 #if defined(XP_OS2) 1195 static PRStatus 1196 _pl_NativeNotify(PLEventQueue* self) 1197 { 1198 BOOL rc = WinPostMsg( self->eventReceiverWindow, _pr_PostEventMsgId, 1199 0, MPFROMP(self)); 1200 return (rc == TRUE) ? PR_SUCCESS : PR_FAILURE; 1201 }/* --- end _pl_NativeNotify() --- */ 1202 #endif /* XP_OS2 */ 1203 1204 #if defined(VMS) 1205 /* Just set the event flag */ 1206 static PRStatus 1207 _pl_NativeNotify(PLEventQueue* self) 1208 { 1209 unsigned int status; 1210 PR_LOG(event_lm, PR_LOG_DEBUG, 1211 ("_pl_NativeNotify: self=%p efn=%d", 1212 self, self->efn)); 1213 status = SYS$SETEF(self->efn); 1214 return ($VMS_STATUS_SUCCESS(status)) ? PR_SUCCESS : PR_FAILURE; 1215 }/* --- end _pl_NativeNotify() --- */ 1216 #elif defined(XP_UNIX) && !defined(XP_MACOSX) 752 #endif 753 } 754 755 #if defined(XP_UNIX) && !defined(XP_MACOSX) 1217 756 1218 757 static PRStatus … … 1242 781 #endif /* defined(XP_UNIX) && !defined(XP_MACOSX) */ 1243 782 1244 #if defined(XP_BEOS)1245 struct ThreadInterfaceData1246 {1247 void *data;1248 int32 sync;1249 };1250 1251 static PRStatus1252 _pl_NativeNotify(PLEventQueue* self)1253 {1254 struct ThreadInterfaceData id;1255 id.data = self;1256 id.sync = false;1257 write_port(self->eventport, 'natv', &id, sizeof(id));1258 1259 return PR_SUCCESS; /* Is this correct? */1260 }1261 #endif /* XP_BEOS */1262 1263 783 #if defined(XP_MACOSX) 1264 784 static PRStatus 1265 785 _pl_NativeNotify(PLEventQueue* self) 1266 786 { 1267 #if defined(MAC_USE_CFRUNLOOPSOURCE)1268 787 CFRunLoopSourceSignal(self->mRunLoopSource); 1269 788 CFRunLoopWakeUp(self->mMainRunLoop); 1270 #elif defined(MAC_USE_CARBON_EVENT)1271 OSErr err;1272 EventRef newEvent;1273 if (CreateEvent(NULL, kEventClassPL, kEventProcessPLEvents,1274 0, kEventAttributeNone, &newEvent) != noErr)1275 return PR_FAILURE;1276 err = SetEventParameter(newEvent, kEventParamPLEventQueue,1277 typeUInt32, sizeof(PREventQueue*), &self);1278 if (err == noErr) {1279 err = PostEventToQueue(GetMainEventQueue(), newEvent, kEventPriorityLow);1280 ReleaseEvent(newEvent);1281 }1282 if (err != noErr)1283 return PR_FAILURE;1284 #endif1285 789 return PR_SUCCESS; 1286 790 } … … 1290 794 _pl_AcknowledgeNativeNotify(PLEventQueue* self) 1291 795 { 1292 #if defined(_WIN32) || defined(XP_OS2) 1293 #ifdef XP_OS2 1294 QMSG aMsg; 1295 #else 1296 MSG aMsg; 1297 #endif 1298 /* 1299 * only remove msg when we've been called directly by 1300 * PL_ProcessPendingEvents, not when we've been called by 1301 * the window proc because the window proc will remove the 1302 * msg for us. 1303 */ 1304 if (self->removeMsg) { 1305 PR_LOG(event_lm, PR_LOG_DEBUG, 1306 ("_pl_AcknowledgeNativeNotify: self=%p", self)); 1307 #ifdef XP_OS2 1308 WinPeekMsg((HAB)0, &aMsg, self->eventReceiverWindow, 1309 _pr_PostEventMsgId, _pr_PostEventMsgId, PM_REMOVE); 1310 #else 1311 PeekMessage(&aMsg, self->eventReceiverWindow, 1312 _pr_PostEventMsgId, _pr_PostEventMsgId, PM_REMOVE); 1313 if (self->timerSet) { 1314 KillTimer(self->eventReceiverWindow, TIMER_ID); 1315 self->timerSet = PR_FALSE; 1316 } 1317 #endif 1318 } 1319 return PR_SUCCESS; 1320 #elif defined(VMS) 1321 PR_LOG(event_lm, PR_LOG_DEBUG, 1322 ("_pl_AcknowledgeNativeNotify: self=%p efn=%d", 1323 self, self->efn)); 1324 /* 1325 ** If this is the last entry, then clear the event flag. Also make sure 1326 ** the flag is cleared on any spurious wakeups. 1327 */ 1328 sys$clref(self->efn); 1329 return PR_SUCCESS; 1330 #elif defined(XP_UNIX) && !defined(XP_MACOSX) 796 #if defined(XP_UNIX) && !defined(XP_MACOSX) 1331 797 1332 798 PRInt32 count; … … 1342 808 return PR_SUCCESS; 1343 809 return PR_FAILURE; 1344 #elif defined( MAC_USE_CFRUNLOOPSOURCE)/* vbox */810 #elif defined(XP_MACOSX) /* vbox */ 1345 811 /* vbox */ 1346 812 CFRunLoopRunInMode(self->mRunLoopModeStr, 0.0, 1); /* vbox */ 1347 813 return PR_SUCCESS; /* vbox */ 1348 814 #else 1349 1350 815 /* nothing to do on the other platforms */ 1351 816 return PR_SUCCESS; … … 1359 824 return -1; 1360 825 1361 #if defined(VMS) 1362 return -(self->efn); 1363 #elif defined(XP_UNIX) && !defined(XP_MACOSX) 826 #if defined(XP_UNIX) && !defined(XP_MACOSX) 1364 827 return self->eventPipe[0]; 1365 828 #else … … 1381 844 } 1382 845 1383 #if defined(_WIN32) 1384 /* 1385 ** Global Instance handle... 1386 ** In Win32 this is the module handle of the DLL. 1387 ** 1388 */ 1389 static HINSTANCE _pr_hInstance; 1390 #endif 1391 1392 1393 #if defined(_WIN32) 1394 1395 /* 1396 ** Initialization routine for the DLL... 1397 */ 1398 1399 BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved) 1400 { 1401 switch (dwReason) 1402 { 1403 case DLL_PROCESS_ATTACH: 1404 _pr_hInstance = hDLL; 1405 break; 1406 1407 case DLL_THREAD_ATTACH: 1408 break; 1409 1410 case DLL_THREAD_DETACH: 1411 break; 1412 1413 case DLL_PROCESS_DETACH: 1414 _pr_hInstance = NULL; 1415 break; 1416 } 1417 1418 return TRUE; 1419 } 1420 #endif 1421 1422 1423 #if defined(_WIN32) || defined(XP_OS2) 1424 #ifdef XP_OS2 1425 MRESULT EXPENTRY 1426 _md_EventReceiverProc(HWND hwnd, ULONG uMsg, MPARAM wParam, MPARAM lParam) 1427 #else 1428 LRESULT CALLBACK 1429 _md_EventReceiverProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 1430 #endif 1431 { 1432 if (_pr_PostEventMsgId == uMsg ) 1433 { 1434 PREventQueue *queue = (PREventQueue *)lParam; 1435 queue->removeMsg = PR_FALSE; 1436 PL_ProcessPendingEvents(queue); 1437 queue->removeMsg = PR_TRUE; 1438 #ifdef XP_OS2 1439 return MRFROMLONG(TRUE); 1440 #else 1441 return TRUE; 1442 #endif 1443 } 1444 return DefWindowProc(hwnd, uMsg, wParam, lParam); 1445 } 1446 1447 static PRBool isInitialized; 1448 static PRCallOnceType once; 1449 static PRLock *initLock; 1450 1451 /* 1452 ** InitWinEventLib() -- Create the Windows initialization lock 1453 ** 1454 */ 1455 static PRStatus InitEventLib( void ) 1456 { 1457 PR_ASSERT( initLock == NULL ); 1458 1459 initLock = PR_NewLock(); 1460 return initLock ? PR_SUCCESS : PR_FAILURE; 1461 } 1462 1463 #endif /* Win32, OS2 */ 1464 1465 #if defined(_WIN32) 1466 1467 /* 1468 ** _md_CreateEventQueue() -- ModelDependent initializer 1469 */ 1470 static void _md_CreateEventQueue( PLEventQueue *eventQueue ) 1471 { 1472 WNDCLASS wc; 1473 1474 /* 1475 ** If this is the first call to PL_InitializeEventsLib(), 1476 ** make the call to InitWinEventLib() to create the initLock. 1477 ** 1478 ** Then lock the initializer lock to insure that 1479 ** we have exclusive control over the initialization sequence. 1480 ** 1481 */ 1482 1483 1484 /* Register the windows message for XPCOM Event notification */ 1485 _pr_PostEventMsgId = RegisterWindowMessage("XPCOM_PostEvent"); 1486 1487 /* Register the class for the event receiver window */ 1488 if (!GetClassInfo(_pr_hInstance, _pr_eventWindowClass, &wc)) { 1489 wc.style = 0; 1490 wc.lpfnWndProc = _md_EventReceiverProc; 1491 wc.cbClsExtra = 0; 1492 wc.cbWndExtra = 0; 1493 wc.hInstance = _pr_hInstance; 1494 wc.hIcon = NULL; 1495 wc.hCursor = NULL; 1496 wc.hbrBackground = (HBRUSH) NULL; 1497 wc.lpszMenuName = (LPCSTR) NULL; 1498 wc.lpszClassName = _pr_eventWindowClass; 1499 RegisterClass(&wc); 1500 } 1501 1502 /* Create the event receiver window */ 1503 eventQueue->eventReceiverWindow = CreateWindow(_pr_eventWindowClass, 1504 "XPCOM:EventReceiver", 1505 0, 0, 0, 10, 10, 1506 NULL, NULL, _pr_hInstance, 1507 NULL); 1508 PR_ASSERT(eventQueue->eventReceiverWindow); 1509 /* Set a property which can be used to retrieve the event queue 1510 * within the _md_TimerProc callback 1511 */ 1512 SetProp(eventQueue->eventReceiverWindow, 1513 _md_GetEventQueuePropName(), (HANDLE)eventQueue); 1514 1515 return; 1516 } /* end _md_CreateEventQueue() */ 1517 #endif /* Winxx */ 1518 1519 #if defined(XP_OS2) 1520 /* 1521 ** _md_CreateEventQueue() -- ModelDependent initializer 1522 */ 1523 static void _md_CreateEventQueue( PLEventQueue *eventQueue ) 1524 { 1525 /* Must have HMQ for this & can't assume we already have appshell */ 1526 if( FALSE == WinQueryQueueInfo( HMQ_CURRENT, NULL, 0)) 1527 { 1528 PPIB ppib; 1529 PTIB ptib; 1530 HAB hab; 1531 HMQ hmq; 1532 1533 /* Set our app to be a PM app before attempting Win calls */ 1534 DosGetInfoBlocks(&ptib, &ppib); 1535 ppib->pib_ultype = 3; 1536 1537 hab = WinInitialize(0); 1538 hmq = WinCreateMsgQueue(hab, 0); 1539 PR_ASSERT(hmq); 1540 } 1541 1542 if( !_pr_PostEventMsgId) 1543 { 1544 WinRegisterClass( 0 /* hab_current */, 1545 _pr_eventWindowClass, 1546 _md_EventReceiverProc, 1547 0, 0); 1548 1549 _pr_PostEventMsgId = WinAddAtom( WinQuerySystemAtomTable(), 1550 "XPCOM_PostEvent"); 1551 } 1552 1553 eventQueue->eventReceiverWindow = WinCreateWindow( HWND_DESKTOP, 1554 _pr_eventWindowClass, 1555 "", 0, 1556 0, 0, 0, 0, 1557 HWND_DESKTOP, 1558 HWND_TOP, 1559 0, 1560 NULL, 1561 NULL); 1562 PR_ASSERT(eventQueue->eventReceiverWindow); 1563 1564 return; 1565 } /* end _md_CreateEventQueue() */ 1566 #endif /* XP_OS2 */ 1567 1568 #if (defined(XP_UNIX) && !defined(XP_MACOSX)) || defined(XP_BEOS) 846 #if defined(XP_UNIX) && !defined(XP_MACOSX) 1569 847 /* 1570 848 ** _md_CreateEventQueue() -- ModelDependent initializer … … 1578 856 return; 1579 857 } /* end _md_CreateEventQueue() */ 1580 #endif /* (defined(XP_UNIX) && !defined(XP_MACOSX)) || defined(XP_BEOS) */ 1581 1582 #if defined(MAC_USE_CFRUNLOOPSOURCE) 858 #endif /* defined(XP_UNIX) && !defined(XP_MACOSX) */ 859 1583 860 static void _md_EventReceiverProc(void *info) 1584 861 { … … 1587 864 } 1588 865 1589 #elif defined(MAC_USE_CARBON_EVENT)1590 /*1591 ** _md_CreateEventQueue() -- ModelDependent initializer1592 */1593 1594 static pascal OSStatus _md_EventReceiverProc(EventHandlerCallRef nextHandler,1595 EventRef inEvent,1596 void* userData)1597 {1598 if (GetEventClass(inEvent) == kEventClassPL &&1599 GetEventKind(inEvent) == kEventProcessPLEvents)1600 {1601 PREventQueue *queue;1602 if (GetEventParameter(inEvent, kEventParamPLEventQueue,1603 typeUInt32, NULL, sizeof(PREventQueue*), NULL,1604 &queue) == noErr)1605 {1606 PL_ProcessPendingEvents(queue);1607 return noErr;1608 }1609 }1610 return eventNotHandledErr;1611 }1612 1613 static pascal Boolean _md_CarbonEventComparator(EventRef inEvent,1614 void *inCompareData)1615 {1616 Boolean match = false;1617 1618 if (GetEventClass(inEvent) == kEventClassPL &&1619 GetEventKind(inEvent) == kEventProcessPLEvents)1620 {1621 PREventQueue *queue;1622 match = ((GetEventParameter(inEvent, kEventParamPLEventQueue,1623 typeUInt32, NULL, sizeof(PREventQueue*), NULL,1624 &queue) == noErr) && (queue == inCompareData));1625 }1626 return match;1627 }1628 1629 #endif /* defined(MAC_USE_CARBON_EVENT) */1630 1631 866 #if defined(XP_MACOSX) 1632 867 static void _md_CreateEventQueue( PLEventQueue *eventQueue ) 1633 868 { 1634 #if defined(MAC_USE_CFRUNLOOPSOURCE)1635 869 CFRunLoopSourceContext sourceContext = { 0 }; 1636 870 sourceContext.version = 0; … … 1658 892 eventQueue->mRunLoopSource, eventQueue->mRunLoopModeStr); /* vbox */ 1659 893 } /* vbox */ 1660 1661 #elif defined(MAC_USE_CARBON_EVENT)1662 eventQueue->eventHandlerUPP = NewEventHandlerUPP(_md_EventReceiverProc);1663 PR_ASSERT(eventQueue->eventHandlerUPP);1664 if (eventQueue->eventHandlerUPP)1665 {1666 EventTypeSpec eventType;1667 1668 eventType.eventClass = kEventClassPL;1669 eventType.eventKind = kEventProcessPLEvents;1670 1671 InstallApplicationEventHandler(eventQueue->eventHandlerUPP, 1, &eventType,1672 eventQueue, &eventQueue->eventHandlerRef);1673 PR_ASSERT(eventQueue->eventHandlerRef);1674 }1675 #endif1676 894 } /* end _md_CreateEventQueue() */ 1677 895 #endif /* defined(XP_MACOSX) */ -
trunk/src/libs/xpcom18a4/xpcom/threads/plevent.h
r11551 r101897 191 191 #include "prcvar.h" 192 192 #include "prmon.h" 193 194 /* For HWND */195 #if defined(XP_WIN32)196 #include <windef.h>197 #elif defined(XP_OS2)198 #define INCL_DOSMISC199 #define INCL_DOSPROCESS200 #define INCL_DOSERRORS201 #include <os2.h>202 #endif203 193 204 194 #ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP … … 550 540 /******************************************************************************/ 551 541 552 /*553 ** Returns the event queue associated with the main thread.554 **555 */556 #if defined(XP_WIN) || defined(XP_OS2)557 /* -----------------------------------------------------------------------558 ** FUNCTION: PL_GetNativeEventReceiverWindow()559 **560 ** DESCRIPTION:561 ** PL_GetNativeEventReceiverWindow() returns the windows562 ** handle of the event receiver window associated with the563 ** referenced PLEventQueue argument.564 **565 ** INPUTS:566 ** PLEventQueue pointer567 **568 ** RETURNS:569 ** event receiver window handle.570 **571 ** RESTRICTIONS: MS-Windows ONLY.572 **573 */574 PR_EXTERN(HWND)575 PL_GetNativeEventReceiverWindow(576 PLEventQueue *eqp577 );578 #endif /* XP_WIN || XP_OS2 */579 580 542 #ifdef XP_UNIX 581 543 /* ----------------------------------------------------------------------- … … 650 612 /* ----------------------------------------------------------------------- */ 651 613 652 #if defined(NO_NSPR_10_SUPPORT)653 #else654 /********* ???????????????? FIX ME ??????????????????????????? *****/655 /********************** Some old definitions *****************************/656 657 /* Re: prevent.h->plevent.h */658 #define PREvent PLEvent659 #define PREventQueue PLEventQueue660 #define PR_CreateEventQueue PL_CreateEventQueue661 #define PR_DestroyEventQueue PL_DestroyEventQueue662 #define PR_GetEventQueueMonitor PL_GetEventQueueMonitor663 #define PR_ENTER_EVENT_QUEUE_MONITOR PL_ENTER_EVENT_QUEUE_MONITOR664 #define PR_EXIT_EVENT_QUEUE_MONITOR PL_EXIT_EVENT_QUEUE_MONITOR665 #define PR_PostEvent PL_PostEvent666 #define PR_PostSynchronousEvent PL_PostSynchronousEvent667 #define PR_GetEvent PL_GetEvent668 #define PR_EventAvailable PL_EventAvailable669 #define PREventFunProc PLEventFunProc670 #define PR_MapEvents PL_MapEvents671 #define PR_RevokeEvents PL_RevokeEvents672 #define PR_ProcessPendingEvents PL_ProcessPendingEvents673 #define PR_WaitForEvent PL_WaitForEvent674 #define PR_EventLoop PL_EventLoop675 #define PR_GetEventQueueSelectFD PL_GetEventQueueSelectFD676 #define PRHandleEventProc PLHandleEventProc677 #define PRDestroyEventProc PLDestroyEventProc678 #define PR_InitEvent PL_InitEvent679 #define PR_GetEventOwner PL_GetEventOwner680 #define PR_HandleEvent PL_HandleEvent681 #define PR_DestroyEvent PL_DestroyEvent682 #define PR_DequeueEvent PL_DequeueEvent683 #define PR_GetMainEventQueue PL_GetMainEventQueue684 685 /********* ????????????? End Fix me ?????????????????????????????? *****/686 #endif /* NO_NSPR_10_SUPPORT */687 688 614 PR_END_EXTERN_C 689 615
Note:
See TracChangeset
for help on using the changeset viewer.