⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 windows.c

📁 linux下的任天堂模拟器代码。供大家参考。
💻 C
📖 第 1 页 / 共 2 页
字号:
                      sizeof (RAWINPUTHEADER));    if (dwSize < sizeof (RAWINPUT))        return;  /* unexpected packet? */    lpb = (LPBYTE) alloca(dwSize);    if (lpb == NULL)        return;    if (pGetRawInputData((HRAWINPUT) lParam, RID_INPUT, lpb, &dwSize,                          sizeof (RAWINPUTHEADER)) != dwSize)        return;    queue_from_rawinput((RAWINPUT *) lpb);} /* wminput_handler */static LRESULT CALLBACK RawWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam){    if (Msg == WM_INPUT)        wminput_handler(wParam, lParam);    else if (Msg == WM_DESTROY)        return(0);    return pDefWindowProcA(hWnd, Msg, wParam, lParam);} /* RawWndProc */static int init_event_queue(void){    HINSTANCE hInstance = pGetModuleHandleA(NULL);    WNDCLASSEX wce;    RAWINPUTDEVICE rid;    ZeroMemory(input_events, sizeof (input_events));    input_events_read = input_events_write = 0;    ZeroMemory(&wce, sizeof (wce));    wce.cbSize = sizeof(WNDCLASSEX);    wce.lpfnWndProc = RawWndProc;    wce.lpszClassName = class_name;    wce.hInstance = hInstance;    class_atom = pRegisterClassExA(&wce);    if (class_atom == 0)        return(0);    raw_hwnd = pCreateWindowExA(0, class_name, win_name, WS_OVERLAPPEDWINDOW,                        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,                        CW_USEDEFAULT, HWND_MESSAGE, NULL, hInstance, NULL);    if (raw_hwnd == NULL)        return(0);    pInitializeCriticalSection(&mutex);    ZeroMemory(&rid, sizeof (rid));    rid.usUsagePage = 1; /* GenericDesktop page */    rid.usUsage = 2; /* GeneralDestop Mouse usage. */    rid.dwFlags = RIDEV_INPUTSINK;    rid.hwndTarget = raw_hwnd;    if (!pRegisterRawInputDevices(&rid, 1, sizeof (rid)))    {        pDeleteCriticalSection(&mutex);        return(0);    } /* if */    return(1);} /* init_event_queue */static void cleanup_window(void){    if (raw_hwnd)    {        MSG Msg;        pDestroyWindow(raw_hwnd);        while (pPeekMessageA(&Msg, raw_hwnd, 0, 0, PM_REMOVE))        {            pTranslateMessage(&Msg);            pDispatchMessageA(&Msg);        } /* while */        raw_hwnd = 0;    } /* if */    if (class_atom)    {        pUnregisterClassA(class_name, pGetModuleHandleA(NULL));        class_atom = 0;    } /* if */} /* cleanup_window */static int accept_device(const RAWINPUTDEVICELIST *dev){    const char rdp_ident[] = "\\??\\Root#RDP_MOU#0000#";    char *buf = NULL;    UINT ct = 0;    if (dev->dwType != RIM_TYPEMOUSE)        return(0);  /* keyboard or some other fruity thing. */    if (pGetRawInputDeviceInfoA(dev->hDevice, RIDI_DEVICENAME, NULL, &ct) < 0)        return(0);    /* ct == is chars, not bytes, but we used the ASCII version. */    buf = (char *) alloca(ct);    if (buf == NULL)        return(0);    if (pGetRawInputDeviceInfoA(dev->hDevice, RIDI_DEVICENAME, buf, &ct) < 0)        return(0);    /*     * Apparently there's a fake "RDP" device...I guess this is     *  "Remote Desktop Protocol" for controlling the system pointer     *  remotely via Windows Remote Desktop, but that's just a guess.     * At any rate, we don't want that device, so skip it if detected.     *     * Idea for this found here:     *   http://link.mywwwserver.com/~jstookey/arcade/rawmouse/raw_mouse.c     */    /* avoiding memcmp here so we don't get a C runtime dependency... */    if (ct >= sizeof (rdp_ident) - 1)    {        int i;        for (i = 0; i < sizeof (rdp_ident) - 1; i++)        {            if (buf[i] != rdp_ident[i])                break;        } /* for */        if (i == sizeof (rdp_ident) - 1)            return(0);  /* this is an RDP thing. Skip this device. */    } /* if */    return(1);  /* we want this device. */} /* accept_device *//* !!! FIXME: this code sucks. */static void get_device_product_name(char *name, size_t namesize,                                     const RAWINPUTDEVICELIST *dev){    const char regkeyroot[] = "System\\CurrentControlSet\\Enum\\";    const char default_device_name[] = "Unidentified input device";    DWORD outsize = namesize;    DWORD regtype = REG_SZ;    char *buf = NULL;    char *ptr = NULL;    char *keyname = NULL;    UINT i = 0;    UINT ct = 0;    LONG rc = 0;    HKEY hkey;    *name = '\0';  /* really insane default. */    if (sizeof (default_device_name) >= namesize)        return;    /* in case we can't stumble upon something better... */    CopyMemory(name, default_device_name, sizeof (default_device_name));    if (pGetRawInputDeviceInfoA(dev->hDevice, RIDI_DEVICENAME, NULL, &ct) < 0)        return;    /* ct == is chars, not bytes, but we used the ASCII version. */    buf = (char *) alloca(ct+1);    keyname = (char *) alloca(ct + sizeof (regkeyroot));    if ((buf == NULL) || (keyname == NULL))        return;    if (pGetRawInputDeviceInfoA(dev->hDevice, RIDI_DEVICENAME, buf, &ct) < 0)        return;    /*     * This string tap dancing gets us a registry keyname in this form:     *   SYSTEM\CurrentControlSet\Enum\BUSTYPE\DEVICECLASS\DEVICEID     * (those are my best-guess for the actual elements, but the format     *  appears to be sound.)     */    ct -= 4;    buf += 4;  /* skip the "\\??\\" on the front of the string. */    for (i = 0, ptr = buf; i < ct; i++, ptr++)  /* convert '#' to '\\' ... */    {        if (*ptr == '#')            *ptr = '\\';        else if (*ptr == '{')  /* hit the GUID part of the string. */            break;    } /* for */    *ptr = '\0';    CopyMemory(keyname, regkeyroot, sizeof (regkeyroot) - 1);    CopyMemory(keyname + (sizeof (regkeyroot) - 1), buf, i + 1);    rc = pRegOpenKeyExA(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &hkey);    if (rc != ERROR_SUCCESS)        return;    rc = pRegQueryValueExA(hkey, "DeviceDesc", NULL, &regtype, name, &outsize);    pRegCloseKey(hkey);    if (rc != ERROR_SUCCESS)    {        /* msdn says failure may mangle the buffer, so default it again. */        CopyMemory(name, default_device_name, sizeof (default_device_name));        return;    } /* if */    name[namesize-1] = '\0';  /* just in case. */} /* get_device_product_name */static void init_mouse(const RAWINPUTDEVICELIST *dev){    MouseStruct *mouse = &mice[available_mice];    if (accept_device(dev))    {        ZeroMemory(mouse, sizeof (MouseStruct));        get_device_product_name(mouse->name, sizeof (mouse->name), dev);        mouse->handle = dev->hDevice;        available_mice++;  /* we're good. */    } /* if */} /* init_mouse */static int windows_wminput_init(void){    RAWINPUTDEVICELIST *devlist = NULL;    UINT ct = 0;    UINT i;    available_mice = 0;    if (!find_api_symbols())  /* only supported on WinXP and later. */        return(0);    pGetRawInputDeviceList(NULL, &ct, sizeof (RAWINPUTDEVICELIST));    if (ct == 0)  /* no devices. */        return(0);    devlist = (PRAWINPUTDEVICELIST) alloca(sizeof (RAWINPUTDEVICELIST) * ct);    pGetRawInputDeviceList(devlist, &ct, sizeof (RAWINPUTDEVICELIST));    for (i = 0; i < ct; i++)        init_mouse(&devlist[i]);    if (!init_event_queue())    {        cleanup_window();        available_mice = 0;    } /* if */    return(available_mice);} /* windows_wminput_init */static void windows_wminput_quit(void){    /* unregister WM_INPUT devices... */    RAWINPUTDEVICE rid;    ZeroMemory(&rid, sizeof (rid));    rid.usUsagePage = 1; /* GenericDesktop page */    rid.usUsage = 2; /* GeneralDestop Mouse usage. */    rid.dwFlags |= RIDEV_REMOVE;    pRegisterRawInputDevices(&rid, 1, sizeof (rid));    cleanup_window();    available_mice = 0;    pDeleteCriticalSection(&mutex);} /* windows_wminput_quit */static const char *windows_wminput_name(unsigned int index){    if (index < available_mice)        return(mice[index].name);    return(NULL);} /* windows_wminput_name *//* * Windows doesn't send a WM_INPUT event when you unplug a mouse, *  so we try to do a basic query by device handle here; if the *  query fails, we assume the device has vanished and generate a *  disconnect. */static int check_for_disconnects(ManyMouseEvent *ev){    /*     * (i) is static so we iterate through all mice round-robin and check     *  one mouse per call to ManyMouse_PollEvent(). This makes this test O(1).     */    static unsigned int i = 0;    MouseStruct *mouse = NULL;    if (++i >= available_mice)  /* check first in case of redetect */        i = 0;    mouse = &mice[i];    if (mouse->handle != NULL)  /* not NULL == still plugged in. */    {        UINT size = 0;        UINT rc = pGetRawInputDeviceInfoA(mouse->handle, RIDI_DEVICEINFO,                                          NULL, &size);        if (rc == (UINT) -1)  /* failed...probably unplugged... */        {            mouse->handle = NULL;            ev->type = MANYMOUSE_EVENT_DISCONNECT;            ev->device = i;            return(1);        } /* if */    } /* if */    return(0);  /* no disconnect event this time. */} /* check_for_disconnects */static int windows_wminput_poll(ManyMouseEvent *ev){    MSG Msg;  /* run the queue for WM_INPUT messages, etc ... */    int found = 0;    /* ...favor existing events in the queue... */    pEnterCriticalSection(&mutex);    if (input_events_read != input_events_write)  /* no events if equal. */    {        CopyMemory(ev, &input_events[input_events_read], sizeof (*ev));        input_events_read = ((input_events_read + 1) % MAX_EVENTS);        found = 1;    } /* if */    pLeaveCriticalSection(&mutex);    if (!found)    {        /* pump Windows for new hardware events... */        while (pPeekMessageA(&Msg, raw_hwnd, 0, 0, PM_REMOVE))        {            pTranslateMessage(&Msg);            pDispatchMessageA(&Msg);        } /* while */        /* In case something new came in, give it to the app... */        pEnterCriticalSection(&mutex);        if (input_events_read != input_events_write)  /* no events if equal. */        {            CopyMemory(ev, &input_events[input_events_read], sizeof (*ev));            input_events_read = ((input_events_read + 1) % MAX_EVENTS);            found = 1;        } /* if */        pLeaveCriticalSection(&mutex);    } /* if */    /*     * Check for disconnects if queue is totally empty and Windows didn't     *  report anything new at this time. This ensures that we don't send a     *  disconnect event through ManyMouse and then later give a valid     *  event to the app for a device that is now missing.     */    if (!found)        found = check_for_disconnects(ev);    return(found);} /* windows_wminput_poll */#elsestatic int windows_wminput_init(void) { return(-1); }static void windows_wminput_quit(void) {}static const char *windows_wminput_name(unsigned int index) { return(0); }static int windows_wminput_poll(ManyMouseEvent *event) { return(0); }#endif  /* ifdef WINDOWS blocker */ManyMouseDriver ManyMouseDriver_windows ={    windows_wminput_init,    windows_wminput_quit,    windows_wminput_name,    windows_wminput_poll};/* end of windows_wminput.c ... */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -