<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def prepare_intercept(callback):
 """ Registers a Windows low level keyboard hook. The provided callback will be invoked for each high-level keyboard event, and is expected to return True if the key event should be passed to the next program, or False if the event is to be blocked. No event is processed until the Windows messages are pumped (see start_intercept). """

    _setup_name_tables()
    
    def process_key(event_type, vk, scan_code, is_extended):
        global shift_is_pressed, altgr_is_pressed, ignore_next_right_alt
        #print(event_type, vk, scan_code, is_extended)

        # Pressing alt-gr also generates an extra "right alt" event
        if vk == 0xA5 and ignore_next_right_alt:
            ignore_next_right_alt = False
            return True

        modifiers = (
            ('shift',) * shift_is_pressed +
            ('alt gr',) * altgr_is_pressed +
            ('num lock',) * (user32.GetKeyState(0x90) & 1) +
            ('caps lock',) * (user32.GetKeyState(0x14) & 1) +
            ('scroll lock',) * (user32.GetKeyState(0x91) & 1)
        )
        entry = (scan_code, vk, is_extended, modifiers)
        if entry not in to_name:
            to_name[entry] = list(get_event_names(*entry))

        names = to_name[entry]
        name = names[0] if names else None

        # TODO: inaccurate when holding multiple different shifts.
        if vk in shift_vks:
            shift_is_pressed = event_type == KEY_DOWN
        if scan_code == 541 and vk == 162:
            ignore_next_right_alt = True
            altgr_is_pressed = event_type == KEY_DOWN

        is_keypad = (scan_code, vk, is_extended) in keypad_keys
        return callback(KeyboardEvent(event_type=event_type, scan_code=scan_code or -vk, name=name, is_keypad=is_keypad))

    def low_level_keyboard_handler(nCode, wParam, lParam):
        try:
            vk = lParam.contents.vk_code
            # Ignore the second `alt` DOWN observed in some cases.
            fake_alt = (LLKHF_INJECTED | 0x20)
            # Ignore events generated by SendInput with Unicode.
            if vk != VK_PACKET and lParam.contents.flags & fake_alt != fake_alt:
                event_type = keyboard_event_types[wParam]
                is_extended = lParam.contents.flags & 1
                scan_code = lParam.contents.scan_code
                should_continue = process_key(event_type, vk, scan_code, is_extended)
                if not should_continue:
                    return -1
        except Exception as e:
            print('Error in keyboard hook:')
            traceback.print_exc()

        return CallNextHookEx(None, nCode, wParam, lParam)

    WH_KEYBOARD_LL = c_int(13)
    keyboard_callback = LowLevelKeyboardProc(low_level_keyboard_handler)
    handle =  GetModuleHandleW(None)
    thread_id = DWORD(0)
    keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboard_callback, handle, thread_id)

    # Register to remove the hook when the interpreter exits. Unfortunately a
    # try/finally block doesn't seem to work here.
    atexit.register(UnhookWindowsHookEx, keyboard_callback)