We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
WM touch/pen warning messages after 1.9.1
```
[WARNING           ] [Input       ] WM_Touch/WM_Pen not supported by your version of Windows
[WARNING           ] [Base        ] Unknown <wm_touch> provider
[WARNING           ] [Base        ] Unknown <wm_pen> provider
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kivy/input/providers/wm_touch.py`
Content:
```
1 '''
2 Support for WM_TOUCH messages (Windows platform)
3 ================================================
4 '''
5 
6 __all__ = ('WM_MotionEventProvider', 'WM_MotionEvent')
7 
8 import os
9 from kivy.input.providers.wm_common import (
10     WM_TABLET_QUERYSYSTEMGESTURE,
11     GWL_WNDPROC, QUERYSYSTEMGESTURE_WNDPROC, WM_TOUCH, WM_MOUSEMOVE,
12     WM_MOUSELAST, PEN_OR_TOUCH_MASK, PEN_OR_TOUCH_SIGNATURE,
13     PEN_EVENT_TOUCH_MASK, TOUCHEVENTF_UP, TOUCHEVENTF_DOWN,
14     TOUCHEVENTF_MOVE, SM_CYCAPTION)
15 from kivy.input.motionevent import MotionEvent
16 from kivy.input.shape import ShapeRect
17 from kivy.core.window import Window
18 
19 
20 class WM_MotionEvent(MotionEvent):
21     '''MotionEvent representing the WM_MotionEvent event.
22        Supports pos, shape and size profiles.
23     '''
24     __attrs__ = ('size', )
25 
26     def depack(self, args):
27         self.is_touch = True
28         self.shape = ShapeRect()
29         self.sx, self.sy = args[0], args[1]
30         self.shape.width = args[2][0]
31         self.shape.height = args[2][1]
32         self.size = self.shape.width * self.shape.height
33         self.profile = ('pos', 'shape', 'size')
34 
35         super(WM_MotionEvent, self).depack(args)
36 
37     def __str__(self):
38         args = (self.id, self.uid, str(self.spos), self.device)
39         return '<WMMotionEvent id:%d uid:%d pos:%s device:%s>' % args
40 
41 if 'KIVY_DOC' in os.environ:
42     # documentation hack
43     WM_MotionEventProvider = None
44 
45 else:
46     from ctypes.wintypes import (ULONG, HANDLE, DWORD, LONG, UINT,
47                                  WPARAM, LPARAM, BOOL)
48     from ctypes import (windll, WINFUNCTYPE, POINTER,
49                         c_int, Structure, sizeof, byref)
50     from collections import deque
51     from kivy.input.provider import MotionEventProvider
52     from kivy.input.factory import MotionEventFactory
53 
54     # check availability of RegisterTouchWindow
55     if not hasattr(windll.user32, 'RegisterTouchWindow'):
56         raise Exception('Unsupported Window version')
57 
58     LRESULT = LPARAM
59     WNDPROC = WINFUNCTYPE(LRESULT, HANDLE, UINT, WPARAM, LPARAM)
60 
61     class TOUCHINPUT(Structure):
62         _fields_ = [
63             ('x', LONG),
64             ('y', LONG),
65             ('pSource', HANDLE),
66             ('id', DWORD),
67             ('flags', DWORD),
68             ('mask', DWORD),
69             ('time', DWORD),
70             ('extraInfo', POINTER(ULONG)),
71             ('size_x', DWORD),
72             ('size_y', DWORD)]
73 
74         def size(self):
75             return (self.size_x, self.size_y)
76 
77         def screen_x(self):
78             return self.x / 100.0
79 
80         def screen_y(self):
81             return self.y / 100.0
82 
83         def _event_type(self):
84             if self.flags & TOUCHEVENTF_MOVE:
85                 return 'update'
86             if self.flags & TOUCHEVENTF_DOWN:
87                 return 'begin'
88             if self.flags & TOUCHEVENTF_UP:
89                 return 'end'
90         event_type = property(_event_type)
91 
92     class RECT(Structure):
93         _fields_ = [
94             ('left', LONG),
95             ('top', LONG),
96             ('right', LONG),
97             ('bottom', LONG)]
98 
99         x = property(lambda self: self.left)
100         y = property(lambda self: self.top)
101         w = property(lambda self: self.right - self.left)
102         h = property(lambda self: self.bottom - self.top)
103 
104     try:
105         windll.user32.SetWindowLongPtrW.restype = WNDPROC
106         windll.user32.SetWindowLongPtrW.argtypes = [HANDLE, c_int, WNDPROC]
107         SetWindowLong_wrapper = windll.user32.SetWindowLongPtrW
108     except AttributeError:
109         windll.user32.SetWindowLongW.restype = WNDPROC
110         windll.user32.SetWindowLongW.argtypes = [HANDLE, c_int, WNDPROC]
111         SetWindowLong_wrapper = windll.user32.SetWindowLongW
112 
113     windll.user32.GetMessageExtraInfo.restype = LPARAM
114     windll.user32.GetMessageExtraInfo.argtypes = []
115     windll.user32.GetClientRect.restype = BOOL
116     windll.user32.GetClientRect.argtypes = [HANDLE, POINTER(RECT)]
117     windll.user32.GetWindowRect.restype = BOOL
118     windll.user32.GetWindowRect.argtypes = [HANDLE, POINTER(RECT)]
119     windll.user32.CallWindowProcW.restype = LRESULT
120     windll.user32.CallWindowProcW.argtypes = [WNDPROC, HANDLE, UINT, WPARAM,
121                                               LPARAM]
122     windll.user32.GetActiveWindow.restype = HANDLE
123     windll.user32.GetActiveWindow.argtypes = []
124     windll.user32.RegisterTouchWindow.restype = BOOL
125     windll.user32.RegisterTouchWindow.argtypes = [HANDLE, ULONG]
126     windll.user32.UnregisterTouchWindow.restype = BOOL
127     windll.user32.UnregisterTouchWindow.argtypes = [HANDLE]
128     windll.user32.GetTouchInputInfo.restype = BOOL
129     windll.user32.GetTouchInputInfo.argtypes = [HANDLE, UINT,
130                                                 POINTER(TOUCHINPUT), c_int]
131     windll.user32.GetSystemMetrics.restype = c_int
132     windll.user32.GetSystemMetrics.argtypes = [c_int]
133 
134     class WM_MotionEventProvider(MotionEventProvider):
135 
136         def start(self):
137             self.touch_events = deque()
138             self.touches = {}
139             self.uid = 0
140 
141             # get window handle, and register to recive WM_TOUCH messages
142             self.hwnd = windll.user32.GetActiveWindow()
143             windll.user32.RegisterTouchWindow(self.hwnd, 1)
144 
145             # inject our own wndProc to handle messages
146             # before window manager does
147             self.new_windProc = WNDPROC(self._touch_wndProc)
148             self.old_windProc = SetWindowLong_wrapper(
149                 self.hwnd, GWL_WNDPROC, self.new_windProc)
150 
151             if Window.borderless or Window.fullscreen:
152                 self.caption_size = 0
153             else:
154                 self.caption_size = windll.user32.GetSystemMetrics(SM_CYCAPTION)
155 
156         def update(self, dispatch_fn):
157             win_rect = RECT()
158             windll.user32.GetWindowRect(self.hwnd, byref(win_rect))
159             caption = self.caption_size
160 
161             while True:
162                 try:
163                     t = self.touch_events.pop()
164                 except:
165                     break
166 
167                 # adjust x,y to window coordinates (0.0 to 1.0)
168                 x = (t.screen_x() - win_rect.x) / float(win_rect.w)
169                 y = 1.0 - (t.screen_y() - win_rect.y - caption
170                            ) / float(win_rect.h)
171 
172                 # actually dispatch input
173                 if t.event_type == 'begin':
174                     self.uid += 1
175                     self.touches[t.id] = WM_MotionEvent(
176                         self.device, self.uid, [x, y, t.size()])
177                     dispatch_fn('begin', self.touches[t.id])
178 
179                 if t.event_type == 'update' and t.id in self.touches:
180                     self.touches[t.id].move([x, y, t.size()])
181                     dispatch_fn('update', self.touches[t.id])
182 
183                 if t.event_type == 'end' and t.id in self.touches:
184                     touch = self.touches[t.id]
185                     touch.move([x, y, t.size()])
186                     touch.update_time_end()
187                     dispatch_fn('end', touch)
188                     del self.touches[t.id]
189 
190         def stop(self):
191             windll.user32.UnregisterTouchWindow(self.hwnd)
192             self.new_windProc = SetWindowLong_wrapper(
193                 self.hwnd, GWL_WNDPROC, self.old_windProc)
194 
195         # we inject this wndProc into our main window, to process
196         # WM_TOUCH and mouse messages before the window manager does
197         def _touch_wndProc(self, hwnd, msg, wParam, lParam):
198             done = False
199             if msg == WM_TABLET_QUERYSYSTEMGESTURE:
200                 return QUERYSYSTEMGESTURE_WNDPROC
201 
202             if msg == WM_TOUCH:
203                 done = self._touch_handler(msg, wParam, lParam)
204 
205             if msg >= WM_MOUSEMOVE and msg <= WM_MOUSELAST:
206                 done = self._mouse_handler(msg, wParam, lParam)
207 
208             if not done:
209                 return windll.user32.CallWindowProcW(self.old_windProc,
210                                                      hwnd, msg, wParam,
211                                                      lParam)
212             return 1
213 
214         # this on pushes WM_TOUCH messages onto our event stack
215         def _touch_handler(self, msg, wParam, lParam):
216             touches = (TOUCHINPUT * wParam)()
217             windll.user32.GetTouchInputInfo(HANDLE(lParam),
218                                             wParam,
219                                             touches,
220                                             sizeof(TOUCHINPUT))
221             for i in range(wParam):
222                 self.touch_events.appendleft(touches[i])
223             windll.user32.CloseTouchInputHandle(HANDLE(lParam))
224             return True
225 
226         # filter fake mouse events, because touch and stylus
227         # also make mouse events
228         def _mouse_handler(self, msg, wparam, lParam):
229             info = windll.user32.GetMessageExtraInfo()
230             # its a touch or a pen
231             if (info & PEN_OR_TOUCH_MASK) == PEN_OR_TOUCH_SIGNATURE:
232                 if info & PEN_EVENT_TOUCH_MASK:
233                     return True
234 
235     MotionEventFactory.register('wm_touch', WM_MotionEventProvider)
236
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/kivy/input/providers/wm_touch.py b/kivy/input/providers/wm_touch.py
--- a/kivy/input/providers/wm_touch.py
+++ b/kivy/input/providers/wm_touch.py
@@ -14,7 +14,8 @@
     TOUCHEVENTF_MOVE, SM_CYCAPTION)
 from kivy.input.motionevent import MotionEvent
 from kivy.input.shape import ShapeRect
-from kivy.core.window import Window
+
+Window = None
 
 
 class WM_MotionEvent(MotionEvent):
@@ -134,6 +135,10 @@
     class WM_MotionEventProvider(MotionEventProvider):
 
         def start(self):
+            global Window
+            if not Window:
+                from kivy.core.window import Window
+
             self.touch_events = deque()
             self.touches = {}
             self.uid = 0

{"golden_diff": "diff --git a/kivy/input/providers/wm_touch.py b/kivy/input/providers/wm_touch.py\n--- a/kivy/input/providers/wm_touch.py\n+++ b/kivy/input/providers/wm_touch.py\n@@ -14,7 +14,8 @@\n     TOUCHEVENTF_MOVE, SM_CYCAPTION)\n from kivy.input.motionevent import MotionEvent\n from kivy.input.shape import ShapeRect\n-from kivy.core.window import Window\n+\n+Window = None\n \n \n class WM_MotionEvent(MotionEvent):\n@@ -134,6 +135,10 @@\n     class WM_MotionEventProvider(MotionEventProvider):\n \n         def start(self):\n+            global Window\n+            if not Window:\n+                from kivy.core.window import Window\n+\n             self.touch_events = deque()\n             self.touches = {}\n             self.uid = 0\n", "issue": "WM touch/pen warning messages after 1.9.1\n```\n[WARNING           ] [Input       ] WM_Touch/WM_Pen not supported by your version of Windows\n[WARNING           ] [Base        ] Unknown <wm_touch> provider\n[WARNING           ] [Base        ] Unknown <wm_pen> provider\n```\n\n", "before_files": [{"content": "'''\nSupport for WM_TOUCH messages (Windows platform)\n================================================\n'''\n\n__all__ = ('WM_MotionEventProvider', 'WM_MotionEvent')\n\nimport os\nfrom kivy.input.providers.wm_common import (\n    WM_TABLET_QUERYSYSTEMGESTURE,\n    GWL_WNDPROC, QUERYSYSTEMGESTURE_WNDPROC, WM_TOUCH, WM_MOUSEMOVE,\n    WM_MOUSELAST, PEN_OR_TOUCH_MASK, PEN_OR_TOUCH_SIGNATURE,\n    PEN_EVENT_TOUCH_MASK, TOUCHEVENTF_UP, TOUCHEVENTF_DOWN,\n    TOUCHEVENTF_MOVE, SM_CYCAPTION)\nfrom kivy.input.motionevent import MotionEvent\nfrom kivy.input.shape import ShapeRect\nfrom kivy.core.window import Window\n\n\nclass WM_MotionEvent(MotionEvent):\n    '''MotionEvent representing the WM_MotionEvent event.\n       Supports pos, shape and size profiles.\n    '''\n    __attrs__ = ('size', )\n\n    def depack(self, args):\n        self.is_touch = True\n        self.shape = ShapeRect()\n        self.sx, self.sy = args[0], args[1]\n        self.shape.width = args[2][0]\n        self.shape.height = args[2][1]\n        self.size = self.shape.width * self.shape.height\n        self.profile = ('pos', 'shape', 'size')\n\n        super(WM_MotionEvent, self).depack(args)\n\n    def __str__(self):\n        args = (self.id, self.uid, str(self.spos), self.device)\n        return '<WMMotionEvent id:%d uid:%d pos:%s device:%s>' % args\n\nif 'KIVY_DOC' in os.environ:\n    # documentation hack\n    WM_MotionEventProvider = None\n\nelse:\n    from ctypes.wintypes import (ULONG, HANDLE, DWORD, LONG, UINT,\n                                 WPARAM, LPARAM, BOOL)\n    from ctypes import (windll, WINFUNCTYPE, POINTER,\n                        c_int, Structure, sizeof, byref)\n    from collections import deque\n    from kivy.input.provider import MotionEventProvider\n    from kivy.input.factory import MotionEventFactory\n\n    # check availability of RegisterTouchWindow\n    if not hasattr(windll.user32, 'RegisterTouchWindow'):\n        raise Exception('Unsupported Window version')\n\n    LRESULT = LPARAM\n    WNDPROC = WINFUNCTYPE(LRESULT, HANDLE, UINT, WPARAM, LPARAM)\n\n    class TOUCHINPUT(Structure):\n        _fields_ = [\n            ('x', LONG),\n            ('y', LONG),\n            ('pSource', HANDLE),\n            ('id', DWORD),\n            ('flags', DWORD),\n            ('mask', DWORD),\n            ('time', DWORD),\n            ('extraInfo', POINTER(ULONG)),\n            ('size_x', DWORD),\n            ('size_y', DWORD)]\n\n        def size(self):\n            return (self.size_x, self.size_y)\n\n        def screen_x(self):\n            return self.x / 100.0\n\n        def screen_y(self):\n            return self.y / 100.0\n\n        def _event_type(self):\n            if self.flags & TOUCHEVENTF_MOVE:\n                return 'update'\n            if self.flags & TOUCHEVENTF_DOWN:\n                return 'begin'\n            if self.flags & TOUCHEVENTF_UP:\n                return 'end'\n        event_type = property(_event_type)\n\n    class RECT(Structure):\n        _fields_ = [\n            ('left', LONG),\n            ('top', LONG),\n            ('right', LONG),\n            ('bottom', LONG)]\n\n        x = property(lambda self: self.left)\n        y = property(lambda self: self.top)\n        w = property(lambda self: self.right - self.left)\n        h = property(lambda self: self.bottom - self.top)\n\n    try:\n        windll.user32.SetWindowLongPtrW.restype = WNDPROC\n        windll.user32.SetWindowLongPtrW.argtypes = [HANDLE, c_int, WNDPROC]\n        SetWindowLong_wrapper = windll.user32.SetWindowLongPtrW\n    except AttributeError:\n        windll.user32.SetWindowLongW.restype = WNDPROC\n        windll.user32.SetWindowLongW.argtypes = [HANDLE, c_int, WNDPROC]\n        SetWindowLong_wrapper = windll.user32.SetWindowLongW\n\n    windll.user32.GetMessageExtraInfo.restype = LPARAM\n    windll.user32.GetMessageExtraInfo.argtypes = []\n    windll.user32.GetClientRect.restype = BOOL\n    windll.user32.GetClientRect.argtypes = [HANDLE, POINTER(RECT)]\n    windll.user32.GetWindowRect.restype = BOOL\n    windll.user32.GetWindowRect.argtypes = [HANDLE, POINTER(RECT)]\n    windll.user32.CallWindowProcW.restype = LRESULT\n    windll.user32.CallWindowProcW.argtypes = [WNDPROC, HANDLE, UINT, WPARAM,\n                                              LPARAM]\n    windll.user32.GetActiveWindow.restype = HANDLE\n    windll.user32.GetActiveWindow.argtypes = []\n    windll.user32.RegisterTouchWindow.restype = BOOL\n    windll.user32.RegisterTouchWindow.argtypes = [HANDLE, ULONG]\n    windll.user32.UnregisterTouchWindow.restype = BOOL\n    windll.user32.UnregisterTouchWindow.argtypes = [HANDLE]\n    windll.user32.GetTouchInputInfo.restype = BOOL\n    windll.user32.GetTouchInputInfo.argtypes = [HANDLE, UINT,\n                                                POINTER(TOUCHINPUT), c_int]\n    windll.user32.GetSystemMetrics.restype = c_int\n    windll.user32.GetSystemMetrics.argtypes = [c_int]\n\n    class WM_MotionEventProvider(MotionEventProvider):\n\n        def start(self):\n            self.touch_events = deque()\n            self.touches = {}\n            self.uid = 0\n\n            # get window handle, and register to recive WM_TOUCH messages\n            self.hwnd = windll.user32.GetActiveWindow()\n            windll.user32.RegisterTouchWindow(self.hwnd, 1)\n\n            # inject our own wndProc to handle messages\n            # before window manager does\n            self.new_windProc = WNDPROC(self._touch_wndProc)\n            self.old_windProc = SetWindowLong_wrapper(\n                self.hwnd, GWL_WNDPROC, self.new_windProc)\n\n            if Window.borderless or Window.fullscreen:\n                self.caption_size = 0\n            else:\n                self.caption_size = windll.user32.GetSystemMetrics(SM_CYCAPTION)\n\n        def update(self, dispatch_fn):\n            win_rect = RECT()\n            windll.user32.GetWindowRect(self.hwnd, byref(win_rect))\n            caption = self.caption_size\n\n            while True:\n                try:\n                    t = self.touch_events.pop()\n                except:\n                    break\n\n                # adjust x,y to window coordinates (0.0 to 1.0)\n                x = (t.screen_x() - win_rect.x) / float(win_rect.w)\n                y = 1.0 - (t.screen_y() - win_rect.y - caption\n                           ) / float(win_rect.h)\n\n                # actually dispatch input\n                if t.event_type == 'begin':\n                    self.uid += 1\n                    self.touches[t.id] = WM_MotionEvent(\n                        self.device, self.uid, [x, y, t.size()])\n                    dispatch_fn('begin', self.touches[t.id])\n\n                if t.event_type == 'update' and t.id in self.touches:\n                    self.touches[t.id].move([x, y, t.size()])\n                    dispatch_fn('update', self.touches[t.id])\n\n                if t.event_type == 'end' and t.id in self.touches:\n                    touch = self.touches[t.id]\n                    touch.move([x, y, t.size()])\n                    touch.update_time_end()\n                    dispatch_fn('end', touch)\n                    del self.touches[t.id]\n\n        def stop(self):\n            windll.user32.UnregisterTouchWindow(self.hwnd)\n            self.new_windProc = SetWindowLong_wrapper(\n                self.hwnd, GWL_WNDPROC, self.old_windProc)\n\n        # we inject this wndProc into our main window, to process\n        # WM_TOUCH and mouse messages before the window manager does\n        def _touch_wndProc(self, hwnd, msg, wParam, lParam):\n            done = False\n            if msg == WM_TABLET_QUERYSYSTEMGESTURE:\n                return QUERYSYSTEMGESTURE_WNDPROC\n\n            if msg == WM_TOUCH:\n                done = self._touch_handler(msg, wParam, lParam)\n\n            if msg >= WM_MOUSEMOVE and msg <= WM_MOUSELAST:\n                done = self._mouse_handler(msg, wParam, lParam)\n\n            if not done:\n                return windll.user32.CallWindowProcW(self.old_windProc,\n                                                     hwnd, msg, wParam,\n                                                     lParam)\n            return 1\n\n        # this on pushes WM_TOUCH messages onto our event stack\n        def _touch_handler(self, msg, wParam, lParam):\n            touches = (TOUCHINPUT * wParam)()\n            windll.user32.GetTouchInputInfo(HANDLE(lParam),\n                                            wParam,\n                                            touches,\n                                            sizeof(TOUCHINPUT))\n            for i in range(wParam):\n                self.touch_events.appendleft(touches[i])\n            windll.user32.CloseTouchInputHandle(HANDLE(lParam))\n            return True\n\n        # filter fake mouse events, because touch and stylus\n        # also make mouse events\n        def _mouse_handler(self, msg, wparam, lParam):\n            info = windll.user32.GetMessageExtraInfo()\n            # its a touch or a pen\n            if (info & PEN_OR_TOUCH_MASK) == PEN_OR_TOUCH_SIGNATURE:\n                if info & PEN_EVENT_TOUCH_MASK:\n                    return True\n\n    MotionEventFactory.register('wm_touch', WM_MotionEventProvider)\n", "path": "kivy/input/providers/wm_touch.py"}], "after_files": [{"content": "'''\nSupport for WM_TOUCH messages (Windows platform)\n================================================\n'''\n\n__all__ = ('WM_MotionEventProvider', 'WM_MotionEvent')\n\nimport os\nfrom kivy.input.providers.wm_common import (\n    WM_TABLET_QUERYSYSTEMGESTURE,\n    GWL_WNDPROC, QUERYSYSTEMGESTURE_WNDPROC, WM_TOUCH, WM_MOUSEMOVE,\n    WM_MOUSELAST, PEN_OR_TOUCH_MASK, PEN_OR_TOUCH_SIGNATURE,\n    PEN_EVENT_TOUCH_MASK, TOUCHEVENTF_UP, TOUCHEVENTF_DOWN,\n    TOUCHEVENTF_MOVE, SM_CYCAPTION)\nfrom kivy.input.motionevent import MotionEvent\nfrom kivy.input.shape import ShapeRect\n\nWindow = None\n\n\nclass WM_MotionEvent(MotionEvent):\n    '''MotionEvent representing the WM_MotionEvent event.\n       Supports pos, shape and size profiles.\n    '''\n    __attrs__ = ('size', )\n\n    def depack(self, args):\n        self.is_touch = True\n        self.shape = ShapeRect()\n        self.sx, self.sy = args[0], args[1]\n        self.shape.width = args[2][0]\n        self.shape.height = args[2][1]\n        self.size = self.shape.width * self.shape.height\n        self.profile = ('pos', 'shape', 'size')\n\n        super(WM_MotionEvent, self).depack(args)\n\n    def __str__(self):\n        args = (self.id, self.uid, str(self.spos), self.device)\n        return '<WMMotionEvent id:%d uid:%d pos:%s device:%s>' % args\n\nif 'KIVY_DOC' in os.environ:\n    # documentation hack\n    WM_MotionEventProvider = None\n\nelse:\n    from ctypes.wintypes import (ULONG, HANDLE, DWORD, LONG, UINT,\n                                 WPARAM, LPARAM, BOOL)\n    from ctypes import (windll, WINFUNCTYPE, POINTER,\n                        c_int, Structure, sizeof, byref)\n    from collections import deque\n    from kivy.input.provider import MotionEventProvider\n    from kivy.input.factory import MotionEventFactory\n\n    # check availability of RegisterTouchWindow\n    if not hasattr(windll.user32, 'RegisterTouchWindow'):\n        raise Exception('Unsupported Window version')\n\n    LRESULT = LPARAM\n    WNDPROC = WINFUNCTYPE(LRESULT, HANDLE, UINT, WPARAM, LPARAM)\n\n    class TOUCHINPUT(Structure):\n        _fields_ = [\n            ('x', LONG),\n            ('y', LONG),\n            ('pSource', HANDLE),\n            ('id', DWORD),\n            ('flags', DWORD),\n            ('mask', DWORD),\n            ('time', DWORD),\n            ('extraInfo', POINTER(ULONG)),\n            ('size_x', DWORD),\n            ('size_y', DWORD)]\n\n        def size(self):\n            return (self.size_x, self.size_y)\n\n        def screen_x(self):\n            return self.x / 100.0\n\n        def screen_y(self):\n            return self.y / 100.0\n\n        def _event_type(self):\n            if self.flags & TOUCHEVENTF_MOVE:\n                return 'update'\n            if self.flags & TOUCHEVENTF_DOWN:\n                return 'begin'\n            if self.flags & TOUCHEVENTF_UP:\n                return 'end'\n        event_type = property(_event_type)\n\n    class RECT(Structure):\n        _fields_ = [\n            ('left', LONG),\n            ('top', LONG),\n            ('right', LONG),\n            ('bottom', LONG)]\n\n        x = property(lambda self: self.left)\n        y = property(lambda self: self.top)\n        w = property(lambda self: self.right - self.left)\n        h = property(lambda self: self.bottom - self.top)\n\n    try:\n        windll.user32.SetWindowLongPtrW.restype = WNDPROC\n        windll.user32.SetWindowLongPtrW.argtypes = [HANDLE, c_int, WNDPROC]\n        SetWindowLong_wrapper = windll.user32.SetWindowLongPtrW\n    except AttributeError:\n        windll.user32.SetWindowLongW.restype = WNDPROC\n        windll.user32.SetWindowLongW.argtypes = [HANDLE, c_int, WNDPROC]\n        SetWindowLong_wrapper = windll.user32.SetWindowLongW\n\n    windll.user32.GetMessageExtraInfo.restype = LPARAM\n    windll.user32.GetMessageExtraInfo.argtypes = []\n    windll.user32.GetClientRect.restype = BOOL\n    windll.user32.GetClientRect.argtypes = [HANDLE, POINTER(RECT)]\n    windll.user32.GetWindowRect.restype = BOOL\n    windll.user32.GetWindowRect.argtypes = [HANDLE, POINTER(RECT)]\n    windll.user32.CallWindowProcW.restype = LRESULT\n    windll.user32.CallWindowProcW.argtypes = [WNDPROC, HANDLE, UINT, WPARAM,\n                                              LPARAM]\n    windll.user32.GetActiveWindow.restype = HANDLE\n    windll.user32.GetActiveWindow.argtypes = []\n    windll.user32.RegisterTouchWindow.restype = BOOL\n    windll.user32.RegisterTouchWindow.argtypes = [HANDLE, ULONG]\n    windll.user32.UnregisterTouchWindow.restype = BOOL\n    windll.user32.UnregisterTouchWindow.argtypes = [HANDLE]\n    windll.user32.GetTouchInputInfo.restype = BOOL\n    windll.user32.GetTouchInputInfo.argtypes = [HANDLE, UINT,\n                                                POINTER(TOUCHINPUT), c_int]\n    windll.user32.GetSystemMetrics.restype = c_int\n    windll.user32.GetSystemMetrics.argtypes = [c_int]\n\n    class WM_MotionEventProvider(MotionEventProvider):\n\n        def start(self):\n            global Window\n            if not Window:\n                from kivy.core.window import Window\n\n            self.touch_events = deque()\n            self.touches = {}\n            self.uid = 0\n\n            # get window handle, and register to recive WM_TOUCH messages\n            self.hwnd = windll.user32.GetActiveWindow()\n            windll.user32.RegisterTouchWindow(self.hwnd, 1)\n\n            # inject our own wndProc to handle messages\n            # before window manager does\n            self.new_windProc = WNDPROC(self._touch_wndProc)\n            self.old_windProc = SetWindowLong_wrapper(\n                self.hwnd, GWL_WNDPROC, self.new_windProc)\n\n            if Window.borderless or Window.fullscreen:\n                self.caption_size = 0\n            else:\n                self.caption_size = windll.user32.GetSystemMetrics(SM_CYCAPTION)\n\n        def update(self, dispatch_fn):\n            win_rect = RECT()\n            windll.user32.GetWindowRect(self.hwnd, byref(win_rect))\n            caption = self.caption_size\n\n            while True:\n                try:\n                    t = self.touch_events.pop()\n                except:\n                    break\n\n                # adjust x,y to window coordinates (0.0 to 1.0)\n                x = (t.screen_x() - win_rect.x) / float(win_rect.w)\n                y = 1.0 - (t.screen_y() - win_rect.y - caption\n                           ) / float(win_rect.h)\n\n                # actually dispatch input\n                if t.event_type == 'begin':\n                    self.uid += 1\n                    self.touches[t.id] = WM_MotionEvent(\n                        self.device, self.uid, [x, y, t.size()])\n                    dispatch_fn('begin', self.touches[t.id])\n\n                if t.event_type == 'update' and t.id in self.touches:\n                    self.touches[t.id].move([x, y, t.size()])\n                    dispatch_fn('update', self.touches[t.id])\n\n                if t.event_type == 'end' and t.id in self.touches:\n                    touch = self.touches[t.id]\n                    touch.move([x, y, t.size()])\n                    touch.update_time_end()\n                    dispatch_fn('end', touch)\n                    del self.touches[t.id]\n\n        def stop(self):\n            windll.user32.UnregisterTouchWindow(self.hwnd)\n            self.new_windProc = SetWindowLong_wrapper(\n                self.hwnd, GWL_WNDPROC, self.old_windProc)\n\n        # we inject this wndProc into our main window, to process\n        # WM_TOUCH and mouse messages before the window manager does\n        def _touch_wndProc(self, hwnd, msg, wParam, lParam):\n            done = False\n            if msg == WM_TABLET_QUERYSYSTEMGESTURE:\n                return QUERYSYSTEMGESTURE_WNDPROC\n\n            if msg == WM_TOUCH:\n                done = self._touch_handler(msg, wParam, lParam)\n\n            if msg >= WM_MOUSEMOVE and msg <= WM_MOUSELAST:\n                done = self._mouse_handler(msg, wParam, lParam)\n\n            if not done:\n                return windll.user32.CallWindowProcW(self.old_windProc,\n                                                     hwnd, msg, wParam,\n                                                     lParam)\n            return 1\n\n        # this on pushes WM_TOUCH messages onto our event stack\n        def _touch_handler(self, msg, wParam, lParam):\n            touches = (TOUCHINPUT * wParam)()\n            windll.user32.GetTouchInputInfo(HANDLE(lParam),\n                                            wParam,\n                                            touches,\n                                            sizeof(TOUCHINPUT))\n            for i in range(wParam):\n                self.touch_events.appendleft(touches[i])\n            windll.user32.CloseTouchInputHandle(HANDLE(lParam))\n            return True\n\n        # filter fake mouse events, because touch and stylus\n        # also make mouse events\n        def _mouse_handler(self, msg, wparam, lParam):\n            info = windll.user32.GetMessageExtraInfo()\n            # its a touch or a pen\n            if (info & PEN_OR_TOUCH_MASK) == PEN_OR_TOUCH_SIGNATURE:\n                if info & PEN_EVENT_TOUCH_MASK:\n                    return True\n\n    MotionEventFactory.register('wm_touch', WM_MotionEventProvider)\n", "path": "kivy/input/providers/wm_touch.py"}]}