- make sure to send a joy removed event even if the joystick wasn't opened under OSX
authorVALVE\alfred@alfredlinux.valvesoftware.com
Mon, 22 Apr 2013 15:24:35 -0700
changeset 7086 141ffce8bb59
parent 7085 152cc7ddfa57
child 7087 5639ac726076
- make sure to send a joy removed event even if the joystick wasn't opened under OSX
src/joystick/SDL_joystick.c
src/joystick/darwin/SDL_sysjoystick.c
--- a/src/joystick/SDL_joystick.c	Mon Apr 22 12:07:16 2013 -0700
+++ b/src/joystick/SDL_joystick.c	Mon Apr 22 15:24:35 2013 -0700
@@ -629,6 +629,8 @@
 		joystick = joysticknext;
 	}
 
+	// this needs to happen AFTER walking the joystick list above, so that any
+	// dangling hardware data from removed devices can be free'd
 	SDL_SYS_JoystickDetect();
 }
 
--- a/src/joystick/darwin/SDL_sysjoystick.c	Mon Apr 22 12:07:16 2013 -0700
+++ b/src/joystick/darwin/SDL_sysjoystick.c	Mon Apr 22 15:24:35 2013 -0700
@@ -64,6 +64,7 @@
 IONotificationPortRef notificationPort = 0;
 /* if 1 then a device was added since the last update call */
 static SDL_bool s_bDeviceAdded = SDL_FALSE;
+static SDL_bool s_bDeviceRemoved = SDL_FALSE;
 
 /* static incrementing counter for new joystick devices seen on the system. Devices should start with index 0 */
 static int s_joystick_instance_id = -1;
@@ -126,6 +127,7 @@
 {
     recDevice *device = (recDevice *) refcon;
     device->removed = 1;
+	s_bDeviceRemoved = SDL_TRUE;
 }
 
 
@@ -137,6 +139,7 @@
     {
 		recDevice *device = (recDevice *) refcon;
 		device->removed = 1;
+		s_bDeviceRemoved = SDL_TRUE;
 	}
 }
 
@@ -804,7 +807,8 @@
 	
 	while ( device )
 	{
-		nJoySticks++;
+		if ( !device->removed )
+			nJoySticks++;
         device = device->pNext;
 	}
 
@@ -816,10 +820,11 @@
 void
 SDL_SYS_JoystickDetect()
 {
-	if ( s_bDeviceAdded )
+	if ( s_bDeviceAdded || s_bDeviceRemoved )
 	{
 		recDevice *device = gpDeviceList;
 		s_bDeviceAdded = SDL_FALSE;
+		s_bDeviceRemoved = SDL_FALSE;
 		int device_index = 0;
 		// send notifications
 		while ( device )
@@ -839,9 +844,49 @@
 					}
 				}
 #endif /* !SDL_EVENTS_DISABLED */
+				
 			}
-			device_index++;
-			device = device->pNext;
+			
+			if ( device->removed )
+			{
+				recDevice *removeDevice = device;
+				if ( gpDeviceList == removeDevice )
+				{
+					device = device->pNext;
+					gpDeviceList = device;
+				}
+				else
+				{
+					device = gpDeviceList;
+					while ( device->pNext != removeDevice )
+					{
+						device = device->pNext;
+					}
+					
+					device->pNext = removeDevice->pNext;
+				}
+								
+#if !SDL_EVENTS_DISABLED
+				SDL_Event event;
+				event.type = SDL_JOYDEVICEREMOVED;
+				
+				if (SDL_GetEventState(event.type) == SDL_ENABLE) {
+					event.jdevice.which = removeDevice->instance_id;
+					if ((SDL_EventOK == NULL)
+						|| (*SDL_EventOK) (SDL_EventOKParam, &event)) {
+						SDL_PushEvent(&event);
+					}
+				}
+
+				DisposePtr((Ptr) removeDevice);
+#endif /* !SDL_EVENTS_DISABLED */	
+				
+			}
+			else
+			{
+				device = device->pNext;
+				device_index++;
+			}
 		}
 	}
 }
@@ -849,7 +894,7 @@
 SDL_bool
 SDL_SYS_JoystickNeedsPolling()
 {
-	return s_bDeviceAdded;
+	return s_bDeviceAdded || s_bDeviceRemoved;
 }
 
 /* Function to get the device-dependent name of a joystick */