<commit_before>#include "df_input.h"

#include "df_time.h"
#include "df_window.h"

#include <ctype.h>
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>


DfInput g_input;


struct InputPrivate
{
    bool        m_lmbPrivate;
    bool		m_lmbOld;				// Mouse button states from last frame. Only
    bool		m_mmbOld;				// used to computer the deltas.
    bool		m_rmbOld;

    bool		m_lastClickWasNC;		// True if mouse was outside the client area of the window when the button was last clicked
    double		m_lastClickTime;		// Used in double click detection
    int			m_lmbRepeatsSoFar;		// When lmb is held, this value is used by IsLmbRepeatSet to determine when to return true

    int			m_mouseOldX;			// Same things but for position
    int			m_mouseOldY;
    int			m_mouseOldZ;

    signed char	m_keyNewDowns[KEY_MAX];
    signed char	m_keyNewUps[KEY_MAX];
    char		m_newKeysTyped[MAX_KEYS_TYPED_PER_FRAME];
    int			m_newNumKeysTyped;
};


void CreateInputManager()
{
    memset(&g_input, 0, sizeof(DfInput));

    g_input.priv = new InputPrivate;
    memset(g_input.priv, 0, sizeof(InputPrivate));
	g_input.priv->m_lastClickTime = 0.0;

    g_input.eventSinceAdvance = true;
    g_input.windowHasFocus = true;
}


// Returns 0 if the event is handled here, -1 otherwise
int EventHandler(unsigned int message, unsigned int wParam, int lParam, bool /*_isAReplayedEvent*/)
{
	if (!g_input.priv)
		return -1;

	switch (message)
	{
        case WM_ACTIVATE:
            break;
		case WM_SETFOCUS:
		case WM_NCACTIVATE:
			g_input.windowHasFocus = true;
			// Clear keyboard state when we regain focus
            memset(g_input.priv->m_keyNewDowns, 0, KEY_MAX);
            memset(g_input.priv->m_keyNewUps, 0, KEY_MAX);
            memset(g_input.keys, 0, KEY_MAX);
			return -1;
		case WM_KILLFOCUS:
			g_input.windowHasFocus = false;
            g_input.mouseX = -1;
            g_input.mouseY = -1;
			break;

        case WM_SYSCHAR:
            break;

		case WM_CHAR:
			if (g_input.numKeysTyped < MAX_KEYS_TYPED_PER_FRAME &&
				!g_input.keys[KEY_CONTROL] &&
				!g_input.keys[KEY_ALT] &&
				wParam != KEY_ESC)
			{
				ReleaseAssert(wParam < KEY_MAX,
					"Keypress value out of range (WM_CHAR: wParam = %d)", wParam);
				g_input.priv->m_newKeysTyped[g_input.priv->m_newNumKeysTyped] = wParam;
				g_input.priv->m_newNumKeysTyped++;
			}
			break;

		case WM_LBUTTONDOWN:
			g_input.priv->m_lmbPrivate = true;
//			g_windowManager->CaptureMouse();
			break;
		case WM_LBUTTONUP:
			g_input.priv->m_lmbPrivate = false;
//			g_windowManager->UncaptureMouse();
			break;
		case WM_MBUTTONDOWN:
			g_input.mmb = true;
//			g_windowManager->CaptureMouse();
			break;
		case WM_MBUTTONUP:
			g_input.mmb = false;
//			g_windowManager->UncaptureMouse();
			break;
		case WM_RBUTTONDOWN:
			g_input.rmb = true;
//			g_windowManager->CaptureMouse();
			break;
		case WM_RBUTTONUP:
			g_input.rmb = false;
//			g_windowManager->UncaptureMouse();
			break;

		/* Mouse clicks in the Non-client area (ie titlebar) of the window are weird. If we
		   handle them and return 0, then Windows ignores them and it is no longer possible
		   to drag the window by the title bar. If we handle them and return -1, then Windows
		   never sends us the button up event. I've chosen the second option and fix some of
		   the brokenness by generating a fake up event one frame after the down event. */
		case WM_NCLBUTTONDOWN:
			g_input.priv->m_lmbPrivate = true;
			g_input.priv->m_lastClickWasNC = true;
			return -1;
			break;
		case WM_NCMBUTTONDOWN:
			g_input.mmb = true;
			g_input.priv->m_lastClickWasNC = true;
			return -1;
			break;
		case WM_NCRBUTTONDOWN:
			g_input.rmb = true;
			g_input.priv->m_lastClickWasNC = true;
			return -1;
			break;

		case WM_MOUSEWHEEL:
		{
			int move = (short)HIWORD(wParam) / 120;
			g_input.mouseZ += move;
			break;
		}

		case WM_NCMOUSEMOVE:
			g_input.mouseX = -1;
			g_input.mouseY = -1;
			break;

		case WM_MOUSEMOVE:
		{
			short newPosX = lParam & 0xFFFF;
			short newPosY = short(lParam >> 16);
			g_input.mouseX = newPosX;
			g_input.mouseY = newPosY;
			break;
		}

		case WM_SYSKEYUP:
			ReleaseAssert(wParam < KEY_MAX,
				"Keypress value out of range (WM_SYSKEYUP: wParam = %d)", wParam);

            // If the key event is the Control part of Alt_Gr, throw it away. There
            // will be an event for the alt part too.
            if (wParam == KEY_CONTROL && GetAsyncKeyState(VK_MENU) < 0)
                break;

            g_input.keys[wParam] = 0;
            g_input.priv->m_keyNewUps[wParam] = 1;
            break;

		case WM_SYSKEYDOWN:
		{
			ReleaseAssert(wParam < KEY_MAX,
				"Keypress value out of range (WM_SYSKEYDOWN: wParam = %d)", wParam);
			//int flags = (short)HIWORD(lParam);
			g_input.keys[wParam] = 1;
			g_input.priv->m_keyNewDowns[wParam] = 1;
			break;
		}

		case WM_KEYUP:
		{
			// Alt key ups are presented here when the user keys, for example, Alt+F.
			// Windows will generate a SYSKEYUP event for the release of F, and a
			// normal KEYUP event for the release of the ALT. Very strange.
			ReleaseAssert(wParam < KEY_MAX,
				"Keypress value out of range (WM_KEYUP: wParam = %d)", wParam);
            g_input.priv->m_keyNewUps[wParam] = 1;
            g_input.keys[wParam] = 0;
			break;
		}

		case WM_KEYDOWN:
		{
			ReleaseAssert(wParam < KEY_MAX,
				"Keypress value out of range (WM_KEYDOWN: wParam = %d)", wParam);
			if (wParam == KEY_DEL)
			{
				g_input.priv->m_newKeysTyped[g_input.numKeysTyped] = 127;
				g_input.priv->m_newNumKeysTyped++;
			}
            else if (wParam == KEY_CONTROL && GetAsyncKeyState(VK_MENU) < 0)
            {
                //int res = GetAsyncKeyState(VK_MENU);
                // Key event is the Control part of Alt_Gr, so throw it away. There
                // will be an event for the alt part too.
                break;
            }
			g_input.priv->m_keyNewDowns[wParam] = 1;
			g_input.keys[wParam] = 1;
			break;
		}

		default:
			return -1;
	}

    g_input.eventSinceAdvance = true;
	return 0;
}<commit_msg>Reduced binary size a little by unifying a bunch of very similar error message strings into a single one.<commit_after>#include "df_input.h"

#include "df_time.h"
#include "df_window.h"

#include <ctype.h>
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>


DfInput g_input;


struct InputPrivate
{
    bool        m_lmbPrivate;
    bool		m_lmbOld;				// Mouse button states from last frame. Only
    bool		m_mmbOld;				// used to computer the deltas.
    bool		m_rmbOld;

    bool		m_lastClickWasNC;		// True if mouse was outside the client area of the window when the button was last clicked
    double		m_lastClickTime;		// Used in double click detection
    int			m_lmbRepeatsSoFar;		// When lmb is held, this value is used by IsLmbRepeatSet to determine when to return true

    int			m_mouseOldX;			// Same things but for position
    int			m_mouseOldY;
    int			m_mouseOldZ;

    signed char	m_keyNewDowns[KEY_MAX];
    signed char	m_keyNewUps[KEY_MAX];
    char		m_newKeysTyped[MAX_KEYS_TYPED_PER_FRAME];
    int			m_newNumKeysTyped;
};


void CreateInputManager()
{
    memset(&g_input, 0, sizeof(DfInput));

    g_input.priv = new InputPrivate;
    memset(g_input.priv, 0, sizeof(InputPrivate));
	g_input.priv->m_lastClickTime = 0.0;

    g_input.eventSinceAdvance = true;
    g_input.windowHasFocus = true;
}


// Returns 0 if the event is handled here, -1 otherwise
int EventHandler(unsigned int message, unsigned int wParam, int lParam, bool /*_isAReplayedEvent*/)
{
    static char const *s_keypressOutOfRangeMsg = "Keypress value out of range (%s: wParam = %d)";

	if (!g_input.priv)
		return -1;

	switch (message)
	{
        case WM_ACTIVATE:
            break;
		case WM_SETFOCUS:
		case WM_NCACTIVATE:
			g_input.windowHasFocus = true;
			// Clear keyboard state when we regain focus
            memset(g_input.priv->m_keyNewDowns, 0, KEY_MAX);
            memset(g_input.priv->m_keyNewUps, 0, KEY_MAX);
            memset(g_input.keys, 0, KEY_MAX);
            return -1;
		case WM_KILLFOCUS:
			g_input.windowHasFocus = false;
            g_input.mouseX = -1;
            g_input.mouseY = -1;
			break;

        case WM_SYSCHAR:
            break;

		case WM_CHAR:
			if (g_input.numKeysTyped < MAX_KEYS_TYPED_PER_FRAME &&
				!g_input.keys[KEY_CONTROL] &&
				!g_input.keys[KEY_ALT] &&
				wParam != KEY_ESC)
			{
                ReleaseAssert(wParam < KEY_MAX, s_keypressOutOfRangeMsg, "WM_CHAR", wParam);
				g_input.priv->m_newKeysTyped[g_input.priv->m_newNumKeysTyped] = wParam;
				g_input.priv->m_newNumKeysTyped++;
			}
			break;

		case WM_LBUTTONDOWN:
			g_input.priv->m_lmbPrivate = true;
//			g_windowManager->CaptureMouse();
			break;
		case WM_LBUTTONUP:
			g_input.priv->m_lmbPrivate = false;
//			g_windowManager->UncaptureMouse();
			break;
		case WM_MBUTTONDOWN:
			g_input.mmb = true;
//			g_windowManager->CaptureMouse();
			break;
		case WM_MBUTTONUP:
			g_input.mmb = false;
//			g_windowManager->UncaptureMouse();
			break;
		case WM_RBUTTONDOWN:
			g_input.rmb = true;
//			g_windowManager->CaptureMouse();
			break;
		case WM_RBUTTONUP:
			g_input.rmb = false;
//			g_windowManager->UncaptureMouse();
			break;

		/* Mouse clicks in the Non-client area (ie titlebar) of the window are weird. If we
		   handle them and return 0, then Windows ignores them and it is no longer possible
		   to drag the window by the title bar. If we handle them and return -1, then Windows
		   never sends us the button up event. I've chosen the second option and fix some of
		   the brokenness by generating a fake up event one frame after the down event. */
		case WM_NCLBUTTONDOWN:
			g_input.priv->m_lmbPrivate = true;
			g_input.priv->m_lastClickWasNC = true;
			return -1;
			break;
		case WM_NCMBUTTONDOWN:
			g_input.mmb = true;
			g_input.priv->m_lastClickWasNC = true;
			return -1;
			break;
		case WM_NCRBUTTONDOWN:
			g_input.rmb = true;
			g_input.priv->m_lastClickWasNC = true;
			return -1;
			break;

		case WM_MOUSEWHEEL:
		{
			int move = (short)HIWORD(wParam) / 120;
			g_input.mouseZ += move;
			break;
		}

		case WM_NCMOUSEMOVE:
			g_input.mouseX = -1;
			g_input.mouseY = -1;
			break;

		case WM_MOUSEMOVE:
		{
			short newPosX = lParam & 0xFFFF;
			short newPosY = short(lParam >> 16);
			g_input.mouseX = newPosX;
			g_input.mouseY = newPosY;
			break;
		}

		case WM_SYSKEYUP:
            ReleaseAssert(wParam < KEY_MAX, s_keypressOutOfRangeMsg, "WM_SYSKEYUP", wParam);

            // If the key event is the Control part of Alt_Gr, throw it away. There
            // will be an event for the alt part too.
            if (wParam == KEY_CONTROL && GetAsyncKeyState(VK_MENU) < 0)
                break;

            g_input.keys[wParam] = 0;
            g_input.priv->m_keyNewUps[wParam] = 1;
            break;

		case WM_SYSKEYDOWN:
		{
			ReleaseAssert(wParam < KEY_MAX, s_keypressOutOfRangeMsg, "WM_SYSKEYDOWN", wParam);
			//int flags = (short)HIWORD(lParam);
			g_input.keys[wParam] = 1;
			g_input.priv->m_keyNewDowns[wParam] = 1;
			break;
		}

		case WM_KEYUP:
		{
			// Alt key ups are presented here when the user keys, for example, Alt+F.
			// Windows will generate a SYSKEYUP event for the release of F, and a
			// normal KEYUP event for the release of the ALT. Very strange.
			ReleaseAssert(wParam < KEY_MAX, s_keypressOutOfRangeMsg, "WM_KEYUP", wParam);
            g_input.priv->m_keyNewUps[wParam] = 1;
            g_input.keys[wParam] = 0;
			break;
		}

		case WM_KEYDOWN:
		{
			ReleaseAssert(wParam < KEY_MAX, s_keypressOutOfRangeMsg, "WM_KEYDOWN", wParam);
			if (wParam == KEY_DEL)
			{
				g_input.priv->m_newKeysTyped[g_input.numKeysTyped] = 127;
				g_input.priv->m_newNumKeysTyped++;
			}
            else if (wParam == KEY_CONTROL && GetAsyncKeyState(VK_MENU) < 0)
            {
                //int res = GetAsyncKeyState(VK_MENU);
                // Key event is the Control part of Alt_Gr, so throw it away. There
                // will be an event for the alt part too.
                break;
            }
			g_input.priv->m_keyNewDowns[wParam] = 1;
			g_input.keys[wParam] = 1;
			break;
		}

		default:
			return -1;
	}

    g_input.eventSinceAdvance = true;
	return 0;
}
{'fraction_non_alphanumeric': 0.09892613081679141, 'fraction_numerical': 0.006671005532053368, 'mean_word_length': 2.7285410979678497, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4286319', 'n_tokens_mistral': 4982, 'n_tokens_neox': 4443, 'n_words': 1138}