summaryrefslogtreecommitdiffstats
path: root/src/prompt_toolkit/eventloop/win32.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/prompt_toolkit/eventloop/win32.py')
-rw-r--r--src/prompt_toolkit/eventloop/win32.py72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/prompt_toolkit/eventloop/win32.py b/src/prompt_toolkit/eventloop/win32.py
new file mode 100644
index 0000000..56a0c7d
--- /dev/null
+++ b/src/prompt_toolkit/eventloop/win32.py
@@ -0,0 +1,72 @@
+from __future__ import annotations
+
+import sys
+
+assert sys.platform == "win32"
+
+from ctypes import pointer
+
+from ..utils import SPHINX_AUTODOC_RUNNING
+
+# Do not import win32-specific stuff when generating documentation.
+# Otherwise RTD would be unable to generate docs for this module.
+if not SPHINX_AUTODOC_RUNNING:
+ from ctypes import windll
+
+from ctypes.wintypes import BOOL, DWORD, HANDLE
+
+from prompt_toolkit.win32_types import SECURITY_ATTRIBUTES
+
+__all__ = ["wait_for_handles", "create_win32_event"]
+
+
+WAIT_TIMEOUT = 0x00000102
+INFINITE = -1
+
+
+def wait_for_handles(handles: list[HANDLE], timeout: int = INFINITE) -> HANDLE | None:
+ """
+ Waits for multiple handles. (Similar to 'select') Returns the handle which is ready.
+ Returns `None` on timeout.
+ http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx
+
+ Note that handles should be a list of `HANDLE` objects, not integers. See
+ this comment in the patch by @quark-zju for the reason why:
+
+ ''' Make sure HANDLE on Windows has a correct size
+
+ Previously, the type of various HANDLEs are native Python integer
+ types. The ctypes library will treat them as 4-byte integer when used
+ in function arguments. On 64-bit Windows, HANDLE is 8-byte and usually
+ a small integer. Depending on whether the extra 4 bytes are zero-ed out
+ or not, things can happen to work, or break. '''
+
+ This function returns either `None` or one of the given `HANDLE` objects.
+ (The return value can be tested with the `is` operator.)
+ """
+ arrtype = HANDLE * len(handles)
+ handle_array = arrtype(*handles)
+
+ ret: int = windll.kernel32.WaitForMultipleObjects(
+ len(handle_array), handle_array, BOOL(False), DWORD(timeout)
+ )
+
+ if ret == WAIT_TIMEOUT:
+ return None
+ else:
+ return handles[ret]
+
+
+def create_win32_event() -> HANDLE:
+ """
+ Creates a Win32 unnamed Event .
+ http://msdn.microsoft.com/en-us/library/windows/desktop/ms682396(v=vs.85).aspx
+ """
+ return HANDLE(
+ windll.kernel32.CreateEventA(
+ pointer(SECURITY_ATTRIBUTES()),
+ BOOL(True), # Manual reset event.
+ BOOL(False), # Initial state.
+ None, # Unnamed event object.
+ )
+ )