Bugs in SDL 1.3 with code that fixes it

Add this just before WM_INPUT in SDL_win32events.c

It gives you relative movement with the mouse with proper Windows Mouse Ballistics. Unfortunately for whoever designed this section of SDL you should not be using RAW INPUT to drive a mouse cursor, which means you can only support one pointer device to move the cursor (in theory windows lets multiple devices move the cursor so it’s not a big issue). However RAWINPUT should be used for any other movement (game/3d movement), so a two pronged approach is needed. I haven’t coded this yet however it should give whoever is in charge of SDL 1.3 an idea about how to tackle this issue.

We need a CURSOR movement AND a mouse movement type event. There is no way you can combine them if you want to use RAWINPUT as it removes the Windows filtering, and the cursor should be maintained at the OS speed not something random.

Code:
case WM_MOUSEMOVE:
{
int x,y,i;
/* mouse has entered the window */
if ( ! in_window )
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hwnd;
TrackMouseEvent(&tme);
in_window = TRUE;
SDL_SetMouseFocus(0, data->window);
}

		/* mouse has moved within the window */
		x = LOWORD(lParam);
		y = HIWORD(lParam);
		if ( 1 )	//relative motion
		{
			POINT center;
			RECT rect;
			GetClientRect(hwnd,&rect);
			center.x = (rect.right/2);
			center.y = (rect.bottom/2);
			x -= (Sint16)center.x;
			y -= (Sint16)center.y;
			if ( x || y )
			{
				ClientToScreen(hwnd, &center);
				SetCursorPos(center.x, center.y);
				SDL_SendMouseMotion(0, 1, x, y, 0);
			}
		} else 
		{
			//posted = SDL_PrivateMouseMotion(0, 0, x, y); //do non relative motion here
		}
	}
	break;

There is a bug in SDL_Memset() in sdl_string.c . It doesn’t always clear memory, frankly this code is convoluted and looks like it was written by a high school student. A simple for loop at least wouldn’t be a buggy mess. It won’t take anyone experienced long to see why there is an error in this rather important function.

Another thing, someone changed SDLK_DELETE to a literal character, which then messes up the keymap. This means trying to lookup SDLK_DELETE to get its name will not work because the win32 conversion functions interprets as 0

WIN_UpdateKeymap(int keyboard)

Code:

scancode = win32_scancode_table[i];
if (scancode == SDL_SCANCODE_UNKNOWN ||
(keymap[scancode] & SDLK_SCANCODE_MASK)) {
continue;
}

    /* Alphabetic keys are handled specially, since Windows remaps them */
    if (i >= 'A' && i <= 'Z') {
        BYTE vsc = alpha_scancodes[i - 'A'];
        keymap[scancode] = MapVirtualKey(vsc, MAPVK_VSC_TO_VK) + 0x20;
    } else {
        keymap[scancode] = (MapVirtualKey(i, MAPVK_VK_TO_CHAR) & 0x7FFF);
    }

Specifically because it isn’t interpreted as having SDLK_SCANCODE_MASK, keymap[scancode] is set to 0 for DELETE. Changing SDLK_DELETE to :-
SDLK_DELETE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DELETE),

fixes the problem. This could also be affecting other keys that have literal values now.

There is a bug in SDL_Win32window.c and sdl_win32events.c

Basically DefWindowProc is ALWAYS called regardless of return code, so if something is processing it DefWindowProc is then processing it after you.

This is bad in numerous ways, the one I found was the F10 key. It simulates the menu key when DefWindowProc processes it, which should definitely not be happening.

The fix? in sdl_win32events.c change :-

class.lpfnWndProc = DefWindowProc;
TO
class.lpfnWndProc = WIN_WindowProc;

There seems to be confusion about how windows are chained together and the current way is broken. If someone was going to intercept the window leave it up to them to handle it, not SDL.