ruaaaa
This commit is contained in:
沈瑗杰 2022-05-01 08:39:37 +08:00
commit 327fe5f324
183 changed files with 1080 additions and 434 deletions

View File

@ -128,7 +128,7 @@ class ClientWindow(Window):
self.fps_label = pyglet.text.Label(x=10, y=self.height - 10, self.fps_label = pyglet.text.Label(x=10, y=self.height - 10,
width=self.width - 20, height=20, width=self.width - 20, height=20,
anchor_x='left', anchor_y='top', anchor_x='left', anchor_y='top',
font_name=tr.微软等宽无线, font_size=20, font_name=translate.微软等宽无线, font_size=20,
multiline=True, multiline=True,
batch=self.label_batch, group=self.command_group) batch=self.label_batch, group=self.command_group)
# 设置刷新率 # 设置刷新率

View File

@ -57,6 +57,7 @@ command_tree = {
} }
} }
} }
# TODO 给爷做了他
class CommandTree: class CommandTree:

View File

@ -10,10 +10,10 @@ using PyCall
include("../../utils/translate.jl") include("../../utils/translate.jl")
struct default_style struct default_style
# font_name::String = fonts.HOS_S() font_name::String
font_size::UInt8 font_size::UInt8
bold::Bool bold::Bool
italic::Bool italic::Bool
end end
a = default_style(1, true, true) default_style = default_style(fonts.HOS)

View File

@ -8,10 +8,10 @@ translate:
module fonts module fonts
export HOS, HOS_C, HOS_S, HOS_T export HOS, HOS_C, HOS_S, HOS_T
HOS = "HarmonyOS Sans" :: String const HOS = "HarmonyOS Sans" :: String
HOS_S = "HarmonyOS Sans SC" :: String const HOS_S = "HarmonyOS Sans SC" :: String
HOS_T = "HarmonyOS Sans TC" :: String const HOS_T = "HarmonyOS Sans TC" :: String
HOS_C = "HarmonyOS Sans Condensed" :: String const HOS_C = "HarmonyOS Sans Condensed" :: String
export 鸿蒙字体, 鸿蒙简体, 鸿蒙繁体, 鸿蒙窄体 export 鸿蒙字体, 鸿蒙简体, 鸿蒙繁体, 鸿蒙窄体
鸿蒙字体 = HOS 鸿蒙字体 = HOS

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -44,7 +44,7 @@ import sys
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
#: The release version #: The release version
version = '2.0.a3' version = '2.0.dev14'
__version__ = version __version__ = version
if sys.version_info < (3, 6): if sys.version_info < (3, 6):
@ -159,6 +159,7 @@ options = {
'headless': False, 'headless': False,
'headless_device': 0, 'headless_device': 0,
'win32_disable_shaping': False, 'win32_disable_shaping': False,
'xinput_controllers': True,
} }
_option_types = { _option_types = {
@ -186,7 +187,8 @@ _option_types = {
'win32_gdi_font': bool, 'win32_gdi_font': bool,
'headless': bool, 'headless': bool,
'headless_device': int, 'headless_device': int,
'win32_disable_shaping': bool 'win32_disable_shaping': bool,
'xinput_controllers': bool
} }

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -694,9 +694,6 @@ class TextureGroup(Group):
glActiveTexture(GL_TEXTURE0) glActiveTexture(GL_TEXTURE0)
glBindTexture(self.texture.target, self.texture.id) glBindTexture(self.texture.target, self.texture.id)
def unset_state(self):
glBindTexture(self.texture.target, 0)
def __hash__(self): def __hash__(self):
return hash((self.texture.target, self.texture.id, self.order, self.parent)) return hash((self.texture.target, self.texture.id, self.order, self.parent))

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,11 +1,11 @@
import warnings import warnings
from pyglet.image import * from pyglet.image import *
from pyglet.image.codecs import * from pyglet.image.codecs import *
from pyglet import com
from pyglet.libs.win32.constants import *
from pyglet.libs.win32.types import *
from pyglet.libs.win32 import _kernel32 as kernel32 from pyglet.libs.win32 import _kernel32 as kernel32
from pyglet.libs.win32 import _ole32 as ole32 from pyglet.libs.win32 import _ole32 as ole32
from pyglet.libs.win32.constants import *
from pyglet.libs.win32.types import *
CLSID_WICImagingFactory1 = com.GUID(0xcacaf262, 0x9370, 0x4615, 0xa1, 0x3b, 0x9f, 0x55, 0x39, 0xda, 0x4c, 0xa) CLSID_WICImagingFactory1 = com.GUID(0xcacaf262, 0x9370, 0x4615, 0xa1, 0x3b, 0x9f, 0x55, 0x39, 0xda, 0x4c, 0xa)
CLSID_WICImagingFactory2 = com.GUID(0x317d06e8, 0x5f24, 0x433d, 0xbd, 0xf7, 0x79, 0xce, 0x68, 0xd8, 0xab, 0xc2) CLSID_WICImagingFactory2 = com.GUID(0x317d06e8, 0x5f24, 0x433d, 0xbd, 0xf7, 0x79, 0xce, 0x68, 0xd8, 0xab, 0xc2)
@ -61,7 +61,7 @@ WICBITMAPENCODERCACHEOPTION_FORCE_DWORD = 0x7fffffff
# Different pixel formats. # Different pixel formats.
REFWICPixelFormatGUID = com.GUID REFWICPixelFormatGUID = com.GUID
GUID_WICPixelFormatDontCare = com.GUID(0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x00) GUID_WICPixelFormatDontCare = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x00)
GUID_WICPixelFormat1bppIndexed = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x01) GUID_WICPixelFormat1bppIndexed = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x01)
GUID_WICPixelFormat2bppIndexed = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x02) GUID_WICPixelFormat2bppIndexed = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x02)
GUID_WICPixelFormat4bppIndexed = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x03) GUID_WICPixelFormat4bppIndexed = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x03)
@ -80,7 +80,8 @@ GUID_WICPixelFormat24bppRGB = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0
GUID_WICPixelFormat32bppBGR = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0e) GUID_WICPixelFormat32bppBGR = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0e)
GUID_WICPixelFormat32bppBGRA = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0f) GUID_WICPixelFormat32bppBGRA = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0f)
GUID_WICPixelFormat32bppPBGRA = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x10) GUID_WICPixelFormat32bppPBGRA = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x10)
GUID_WICPixelFormat32bppRGB = com.GUID(0xd98c6b95, 0x3efe, 0x47d6, 0xbb, 0x25, 0xeb, 0x17, 0x48, 0xab, 0x0c, 0xf1) # 7 platform update? GUID_WICPixelFormat32bppRGB = com.GUID(0xd98c6b95, 0x3efe, 0x47d6, 0xbb, 0x25, 0xeb, 0x17, 0x48, 0xab, 0x0c,
0xf1) # 7 platform update?
GUID_WICPixelFormat32bppRGBA = com.GUID(0xf5c7ad2d, 0x6a8d, 0x43dd, 0xa7, 0xa8, 0xa2, 0x99, 0x35, 0x26, 0x1a, 0xe9) GUID_WICPixelFormat32bppRGBA = com.GUID(0xf5c7ad2d, 0x6a8d, 0x43dd, 0xa7, 0xa8, 0xa2, 0x99, 0x35, 0x26, 0x1a, 0xe9)
GUID_WICPixelFormat32bppPRGBA = com.GUID(0x3cc4a650, 0xa527, 0x4d37, 0xa9, 0x16, 0x31, 0x42, 0xc7, 0xeb, 0xed, 0xba) GUID_WICPixelFormat32bppPRGBA = com.GUID(0x3cc4a650, 0xa527, 0x4d37, 0xa9, 0x16, 0x31, 0x42, 0xc7, 0xeb, 0xed, 0xba)
GUID_WICPixelFormat48bppRGB = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x15) GUID_WICPixelFormat48bppRGB = com.GUID(0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x15)
@ -110,16 +111,6 @@ class IPropertyBag2(com.pIUnknown):
] ]
# class PROPBAG2(Structure):
# _fields_ = [
# ('dwType', DWORD),
# ('vt', VARTYPE),
# ('cfType', CLIPFORMAT),
# ('dwHint', DWORD),
# ('pstrName', LPOLESTR),
# ('clsid', CLSID)
# ]
class IWICPalette(com.pIUnknown): class IWICPalette(com.pIUnknown):
_methods_ = [ _methods_ = [
('InitializePredefined', ('InitializePredefined',
@ -143,36 +134,16 @@ class IWICPalette(com.pIUnknown):
('HasAlpha', ('HasAlpha',
com.STDMETHOD()), com.STDMETHOD()),
] ]
class IWICStream(com.pIUnknown):
class IWICStream(IStream, com.pIUnknown):
_methods_ = [ _methods_ = [
('Read',
com.STDMETHOD()),
('Write',
com.STDMETHOD()),
('Seek',
com.STDMETHOD()),
('SetSize',
com.STDMETHOD()),
('CopyTo',
com.STDMETHOD()),
('Commit',
com.STDMETHOD()),
('Revert',
com.STDMETHOD()),
('LockRegion',
com.STDMETHOD()),
('UnlockRegion',
com.STDMETHOD()),
('Stat',
com.STDMETHOD()),
('Clone',
com.STDMETHOD()),
('InitializeFromIStream', ('InitializeFromIStream',
com.STDMETHOD()), com.STDMETHOD(IStream)),
('InitializeFromFilename', ('InitializeFromFilename',
com.STDMETHOD(LPCWSTR, DWORD)), com.STDMETHOD(LPCWSTR, DWORD)),
('InitializeFromMemory', ('InitializeFromMemory',
com.STDMETHOD(c_void_p, DWORD)), com.STDMETHOD(POINTER(BYTE), DWORD)),
('InitializeFromIStreamRegion', ('InitializeFromIStreamRegion',
com.STDMETHOD()), com.STDMETHOD()),
] ]
@ -187,7 +158,7 @@ class IWICBitmapFrameEncode(com.pIUnknown):
('SetResolution', ('SetResolution',
com.STDMETHOD()), com.STDMETHOD()),
('SetPixelFormat', ('SetPixelFormat',
com.STDMETHOD(REFWICPixelFormatGUID)), com.STDMETHOD(POINTER(REFWICPixelFormatGUID))),
('SetColorContexts', ('SetColorContexts',
com.STDMETHOD()), com.STDMETHOD()),
('SetPalette', ('SetPalette',
@ -384,7 +355,7 @@ class IWICImagingFactory(com.pIUnknown):
('CreateDecoder', ('CreateDecoder',
com.STDMETHOD()), com.STDMETHOD()),
('CreateEncoder', ('CreateEncoder',
com.STDMETHOD(com.GUID, POINTER(com.GUID), POINTER(IWICBitmapEncoder))), com.STDMETHOD(POINTER(com.GUID), POINTER(com.GUID), POINTER(IWICBitmapEncoder))),
('CreatePalette', ('CreatePalette',
com.STDMETHOD(POINTER(IWICPalette))), com.STDMETHOD(POINTER(IWICPalette))),
('CreateFormatConverter', ('CreateFormatConverter',
@ -587,7 +558,7 @@ class WICEncoder(ImageEncoder):
def encode(self, image, filename, file): def encode(self, image, filename, file):
image = image.get_image_data() image = image.get_image_data()
stream = IWICStream() wicstream = IWICStream()
encoder = IWICBitmapEncoder() encoder = IWICBitmapEncoder()
frame = IWICBitmapFrameEncode() frame = IWICBitmapFrameEncode()
property_bag = IPropertyBag2() property_bag = IPropertyBag2()
@ -597,7 +568,7 @@ class WICEncoder(ImageEncoder):
# Choose container based on extension. Default to PNG. # Choose container based on extension. Default to PNG.
container = extension_to_container.get(ext, GUID_ContainerFormatPng) container = extension_to_container.get(ext, GUID_ContainerFormatPng)
_factory.CreateStream(byref(stream)) _factory.CreateStream(byref(wicstream))
# https://docs.microsoft.com/en-us/windows/win32/wic/-wic-codec-native-pixel-formats#native-image-formats # https://docs.microsoft.com/en-us/windows/win32/wic/-wic-codec-native-pixel-formats#native-image-formats
if container == GUID_ContainerFormatJpeg: if container == GUID_ContainerFormatJpeg:
# Expects BGR, no transparency available. Hard coded. # Expects BGR, no transparency available. Hard coded.
@ -616,18 +587,18 @@ class WICEncoder(ImageEncoder):
image_data = image.get_data(fmt, -pitch) image_data = image.get_data(fmt, -pitch)
size = len(image_data) size = pitch * image.height
if file: if file:
buf = create_string_buffer(size) istream = IStream()
ole32.CreateStreamOnHGlobal(None, True, byref(istream))
stream.InitializeFromMemory(byref(buf), size) wicstream.InitializeFromIStream(istream)
else: else:
stream.InitializeFromFilename(filename, GENERIC_WRITE) wicstream.InitializeFromFilename(filename, GENERIC_WRITE)
_factory.CreateEncoder(container, None, byref(encoder)) _factory.CreateEncoder(container, None, byref(encoder))
encoder.Initialize(stream, WICBitmapEncoderNoCache) encoder.Initialize(wicstream, WICBitmapEncoderNoCache)
encoder.CreateNewFrame(byref(frame), byref(property_bag)) encoder.CreateNewFrame(byref(frame), byref(property_bag))
@ -635,7 +606,7 @@ class WICEncoder(ImageEncoder):
frame.SetSize(image.width, image.height) frame.SetSize(image.width, image.height)
frame.SetPixelFormat(default_format) frame.SetPixelFormat(byref(default_format))
data = (c_byte * size).from_buffer(bytearray(image_data)) data = (c_byte * size).from_buffer(bytearray(image_data))
@ -646,12 +617,26 @@ class WICEncoder(ImageEncoder):
encoder.Commit() encoder.Commit()
if file: if file:
sts = STATSTG()
istream.Stat(byref(sts), 0)
stream_size = sts.cbSize
istream.Seek(0, STREAM_SEEK_SET, None)
buf = (BYTE * stream_size)()
written = ULONG()
istream.Read(byref(buf), stream_size, byref(written))
if written.value == stream_size:
file.write(buf) file.write(buf)
else:
print(f"Failed to read all of the data from stream attempting to save {file}")
istream.Release()
encoder.Release() encoder.Release()
frame.Release() frame.Release()
property_bag.Release() property_bag.Release()
stream.Release() wicstream.Release()
def get_encoders(): def get_encoders():

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -33,7 +33,7 @@
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
"""Joystick, Game Controller, tablet and USB HID device support. """Joystick, Game Controller, Tablet and USB HID device support.
This module provides a unified interface to almost any input device, besides This module provides a unified interface to almost any input device, besides
the regular mouse and keyboard support provided by the regular mouse and keyboard support provided by
@ -52,20 +52,21 @@ not. In these cases the device API may still be useful -- the user will have
to be asked to press each button in turn or move each axis separately to to be asked to press each button in turn or move each axis separately to
identify them. identify them.
Higher-level interfaces are provided for joysticks, tablets and the Apple Higher-level interfaces are provided for joysticks, game controllers, tablets
remote control. These devices can usually be identified by pyglet positively, and the Apple remote control. These devices can usually be identified by pyglet
and a base level of functionality for each one provided through a common positively, and a base level of functionality for each one provided through a
interface. common interface.
To use an input device: To use an input device:
1. Call :py:func:`get_devices`, :py:func:`get_apple_remote` or 1. Call :py:func:`get_devices`, :py:func:`get_apple_remote`,
:py:func:`get_joysticks` :py:func:`get_controllers` or :py:func:`get_joysticks` to retrieve and
to retrieve and identify the device. identify the device.
2. For low-level devices (retrieved by :py:func:`get_devices`), query the 2. For low-level devices (retrieved by :py:func:`get_devices`), query the
devices list of controls and determine which ones you are interested in. For devices list of controls and determine which ones you are interested in. For
high-level interfaces the set of controls is provided by the interface. high-level interfaces the set of controls is provided by the interface.
3. Optionally attach event handlers to controls on the device. 3. Optionally attach event handlers to controls on the device. For high-level
interfaces, additional events are available.
4. Call :py:meth:`Device.open` to begin receiving events on the device. You can 4. Call :py:meth:`Device.open` to begin receiving events on the device. You can
begin querying the control values after this time; they will be updated begin querying the control values after this time; they will be updated
asynchronously. asynchronously.
@ -77,13 +78,16 @@ note that no control list is available; instead, calling :py:meth:`Tablet.open`
returns a :py:class:`TabletCanvas` onto which you should set your event returns a :py:class:`TabletCanvas` onto which you should set your event
handlers. handlers.
For game controllers, the :py:class:`ControllerManager` is available. This
provides a convenient way to handle hot-plugging of controllers.
.. versionadded:: 1.2 .. versionadded:: 1.2
""" """
import sys import sys
from .base import Device, Control, RelativeAxis, AbsoluteAxis from .base import Device, Control, RelativeAxis, AbsoluteAxis, ControllerManager
from .base import Button, Joystick, AppleRemote, Tablet, Controller from .base import Button, Joystick, AppleRemote, Tablet, Controller
from .base import DeviceException, DeviceOpenException, DeviceExclusiveException from .base import DeviceException, DeviceOpenException, DeviceExclusiveException
@ -167,29 +171,44 @@ else:
def get_tablets(display=None): def get_tablets(display=None):
return [] return []
from pyglet import compat_platform from pyglet import compat_platform, options
if compat_platform.startswith('linux'): if compat_platform.startswith('linux'):
from .x11_xinput_tablet import get_tablets from .x11_xinput_tablet import get_tablets
from .x11_xinput import get_devices as xinput_get_devices from .x11_xinput import get_devices as x11xinput_get_devices
from .evdev import get_devices as evdev_get_devices from .evdev import get_devices as evdev_get_devices
from .evdev import get_joysticks from .evdev import get_joysticks
from .evdev import get_controllers from .evdev import get_controllers
from .evdev import EvdevControllerManager as ControllerManager
def get_devices(display=None): def get_devices(display=None):
return evdev_get_devices(display) + xinput_get_devices(display) return evdev_get_devices(display) + x11xinput_get_devices(display)
elif compat_platform in ('cygwin', 'win32'): elif compat_platform in ('cygwin', 'win32'):
from .directinput import get_devices from .directinput import get_devices as dinput_get_devices
from .directinput import get_controllers as dinput_get_controllers
from .directinput import get_joysticks from .directinput import get_joysticks
from .directinput import get_controllers
try: try:
from .wintab import get_tablets from .wintab import get_tablets
except: except:
pass pass
if options["xinput_controllers"] is False:
get_devices = dinput_get_devices
get_controllers = dinput_get_controllers
else:
from .xinput import get_devices as xinput_get_devices
from .xinput import get_controllers as xinput_get_controllers
from .xinput import XInputControllerManager as ControllerManager
def get_devices(display=None):
return xinput_get_devices() + dinput_get_devices(display)
def get_controllers(display=None):
return xinput_get_controllers() + dinput_get_controllers(display)
elif compat_platform == 'darwin': elif compat_platform == 'darwin':
from .darwin_hid import get_devices from .darwin_hid import get_devices
from .darwin_hid import get_joysticks from .darwin_hid import get_joysticks
from .darwin_hid import get_apple_remote from .darwin_hid import get_apple_remote
from .darwin_hid import get_controllers from .darwin_hid import get_controllers
# TODO: create ControllerManager for OSX

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -77,6 +77,10 @@ class Device:
self.manufacturer = None self.manufacturer = None
self._is_open = False self._is_open = False
@property
def is_open(self):
return self._is_open
def open(self, window=None, exclusive=False): def open(self, window=None, exclusive=False):
"""Open the device to begin receiving input from it. """Open the device to begin receiving input from it.
@ -595,13 +599,15 @@ class Controller(EventDispatcher):
`dpdown` : bool `dpdown` : bool
`dpleft` : bool `dpleft` : bool
`dpright` : bool `dpright` : bool
.. versionadded:: 1.2
""" """
self.device = device self.device = device
self._mapping = mapping self._mapping = mapping
self.name = self._mapping['name'] self.name = mapping.get('name')
self.guid = self._mapping['guid'] self.guid = mapping.get('guid')
self.a = False self.a = False
self.b = False self.b = False
@ -614,8 +620,8 @@ class Controller(EventDispatcher):
self.rightshoulder = False self.rightshoulder = False
self.leftstick = False # stick press button self.leftstick = False # stick press button
self.rightstick = False # stick press button self.rightstick = False # stick press button
self.lefttrigger = -1 # default to rest position self.lefttrigger = 0
self.righttrigger = -1 # default to rest position self.righttrigger = 0
self.leftx = 0 self.leftx = 0
self.lefty = 0 self.lefty = 0
self.rightx = 0 self.rightx = 0
@ -631,7 +637,12 @@ class Controller(EventDispatcher):
self._hat_x_control = None self._hat_x_control = None
self._hat_y_control = None self._hat_y_control = None
self._initialize_controls()
def _initialize_controls(self):
def add_axis(control, axis_name): def add_axis(control, axis_name):
tscale = 1.0 / (control.max - control.min)
scale = 2.0 / (control.max - control.min) scale = 2.0 / (control.max - control.min)
bias = -1.0 - control.min * scale bias = -1.0 - control.min * scale
if control.inverted: if control.inverted:
@ -665,7 +676,7 @@ class Controller(EventDispatcher):
elif axis_name in ("lefttrigger", "righttrigger"): elif axis_name in ("lefttrigger", "righttrigger"):
@control.event @control.event
def on_change(value): def on_change(value):
normalized_value = value * scale + bias normalized_value = value * tscale
setattr(self, axis_name, normalized_value) setattr(self, axis_name, normalized_value)
self.dispatch_event('on_trigger_motion', self, axis_name, normalized_value) self.dispatch_event('on_trigger_motion', self, axis_name, normalized_value)
@ -731,10 +742,11 @@ class Controller(EventDispatcher):
self.dispatch_event('on_dpad_motion', self, self.dispatch_event('on_dpad_motion', self,
self.dpleft, self.dpright, self.dpup, self.dpdown) self.dpleft, self.dpright, self.dpup, self.dpdown)
for control in device.get_controls(): for control in self.device.get_controls():
"""Categorize the various control types""" """Categorize the various control types"""
if isinstance(control, Button): if isinstance(control, Button):
self._button_controls.append(control) self._button_controls.append(control)
elif isinstance(control, AbsoluteAxis): elif isinstance(control, AbsoluteAxis):
if control.name in ('x', 'y', 'z', 'rx', 'ry', 'rz'): if control.name in ('x', 'y', 'z', 'rx', 'ry', 'rz'):
self._axis_controls.append(control) self._axis_controls.append(control)
@ -858,7 +870,7 @@ class Controller(EventDispatcher):
"""A button on the controller was pressed. """A button on the controller was pressed.
:Parameters: :Parameters:
`controller` : `Controller` `controller` : :py:class:`Controller`
The controller whose button was pressed. The controller whose button was pressed.
`button` : string `button` : string
The name of the button that was pressed. The name of the button that was pressed.
@ -874,6 +886,9 @@ class Controller(EventDispatcher):
The name of the button that was released. The name of the button that was released.
""" """
def __repr__(self):
return f"Controller(name={self.name})"
Controller.register_event_type('on_button_press') Controller.register_event_type('on_button_press')
Controller.register_event_type('on_button_release') Controller.register_event_type('on_button_release')
@ -965,7 +980,7 @@ class AppleRemote(EventDispatcher):
whether or not the user has released the button. whether or not the user has released the button.
:Parameters: :Parameters:
`button` : unicode `button` : str
The name of the button that was released. The valid names are The name of the button that was released. The valid names are
'up', 'down', 'left', 'right', 'left_hold', 'right_hold', 'up', 'down', 'left', 'right', 'left_hold', 'right_hold',
'menu', 'menu_hold', 'select', and 'select_hold' 'menu', 'menu_hold', 'select', and 'select_hold'
@ -1112,3 +1127,74 @@ class TabletCursor:
def __repr__(self): def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, self.name) return '%s(%s)' % (self.__class__.__name__, self.name)
class ControllerManager(EventDispatcher):
"""High level interface for managing game Controllers.
This class provides a convenient way to handle the
connection and disconnection of devices. A list of all
connected Controllers can be queried at any time with the
`get_controllers` method. For hot-plugging, events are
dispatched for `on_connect` and `on_disconnect`.
To use the ControllerManager, first make an instance::
controller_man = pyglet.input.ControllerManager()
At the start of your game, query for any Controllers
that are already connected::
controllers = controller_man.get_controllers()
To handle Controllers that are connected or disconnected
after the start of your game, register handlers for the
appropriate events::
@controller_man.event
def on_connect(controller):
# code to handle newly connected
# (or re-connected) controllers
controller.open()
print("Connect:", controller)
@controller_man.event
def on_disconnect(controller):
# code to handle disconnected Controller
print("Disconnect:", controller)
.. versionadded:: 1.2
"""
def get_controllers(self):
"""Get a list of all connected Controllers
:rtype: list of :py:class:`Controller`
"""
raise NotImplementedError
def on_connect(self, controller):
"""A Controller has been connected. If this is
a previously dissconnected Controller that is
being re-connected, the same Controller instance
will be returned.
:Parameters:
`controller` : :py:class:`Controller`
An un-opened Controller instance.
:event:
"""
def on_disconnect(self, controller):
"""A Controller has been disconnected.
:Parameters:
`controller` : :py:class:`Controller`
An un-opened Controller instance.
:event:
"""
ControllerManager.register_event_type('on_connect')
ControllerManager.register_event_type('on_disconnect')

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -226,8 +226,21 @@ def _init_directinput():
def get_devices(display=None): def get_devices(display=None):
_init_directinput() _init_directinput()
_devices = [] _devices = []
_xinput_devices = []
if pyglet.options["xinput_controllers"]:
try:
from .xinput import get_xinput_guids
_xinput_devices = get_xinput_guids()
except ImportError:
pass
def _device_enum(device_instance, arg): def _device_enum(device_instance, arg):
guid_id = format(device_instance.contents.guidProduct.Data1, "08x")
# Only XInput should handle DirectInput devices if enabled. Filter them out.
if guid_id in _xinput_devices:
# Log somewhere?
return dinput.DIENUM_CONTINUE
device = dinput.IDirectInputDevice8() device = dinput.IDirectInputDevice8()
_i_dinput.CreateDevice(device_instance.contents.guidInstance, ctypes.byref(device), None) _i_dinput.CreateDevice(device_instance.contents.guidInstance, ctypes.byref(device), None)
_devices.append(DirectInputDevice(display, device, device_instance.contents)) _devices.append(DirectInputDevice(display, device, device_instance.contents))

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -34,6 +34,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
import os import os
import time
import fcntl import fcntl
import ctypes import ctypes
@ -42,12 +43,13 @@ from ctypes import c_int16 as _s16
from ctypes import c_uint32 as _u32 from ctypes import c_uint32 as _u32
from ctypes import c_int32 as _s32 from ctypes import c_int32 as _s32
from ctypes import c_int64 as _s64 from ctypes import c_int64 as _s64
from concurrent.futures import ThreadPoolExecutor
import pyglet import pyglet
from pyglet.app.xlib import XlibSelectDevice from pyglet.app.xlib import XlibSelectDevice
from .base import Device, RelativeAxis, AbsoluteAxis, Button, Joystick, Controller from .base import Device, RelativeAxis, AbsoluteAxis, Button, Joystick, Controller
from .base import DeviceOpenException from .base import DeviceOpenException, ControllerManager
from .evdev_constants import * from .evdev_constants import *
from .controller import get_mapping, Relation from .controller import get_mapping, Relation
@ -498,14 +500,90 @@ class FFController(Controller):
self.device.ff_upload_effect(self._play_strong_event) self.device.ff_upload_effect(self._play_strong_event)
def rumble_stop_weak(self): def rumble_stop_weak(self):
"""Stop playing rumble effects on the weak motor."""
self.device.ff_upload_effect(self._stop_weak_event) self.device.ff_upload_effect(self._stop_weak_event)
def rumble_stop_strong(self): def rumble_stop_strong(self):
"""Stop playing rumble effects on the strong motor."""
self.device.ff_upload_effect(self._stop_strong_event) self.device.ff_upload_effect(self._stop_strong_event)
class EvdevControllerManager(ControllerManager, XlibSelectDevice):
def __init__(self, display=None):
super().__init__()
self._display = display
self._devices_file = open('/proc/bus/input/devices')
self._device_names = self._get_device_names()
self._controllers = {}
self._thread_pool = ThreadPoolExecutor(max_workers=1)
for name in self._device_names:
path = os.path.join('/dev/input', name)
try:
device = EvdevDevice(self._display, path)
except OSError:
continue
controller = _create_controller(device)
if controller:
self._controllers[name] = controller
pyglet.app.platform_event_loop.select_devices.add(self)
def __del__(self):
self._devices_file.close()
def fileno(self):
"""Allow this class to be Selectable"""
return self._devices_file.fileno()
@staticmethod
def _get_device_names():
return {name for name in os.listdir('/dev/input') if name.startswith('event')}
def _make_device_callback(self, future):
name, device = future.result()
if not device:
return
if name in self._controllers:
controller = self._controllers.get(name)
else:
controller = _create_controller(device)
self._controllers[name] = controller
if controller:
self.dispatch_event('on_connect', controller)
def _make_device(self, name, count=1):
path = os.path.join('/dev/input', name)
while count > 0:
try:
return name, EvdevDevice(self._display, path)
except OSError:
if count > 0:
time.sleep(0.1)
count -= 1
return None, None
def select(self):
"""Triggered whenever the devices_file changes."""
new_device_files = self._get_device_names()
appeared = new_device_files - self._device_names
disappeared = self._device_names - new_device_files
self._device_names = new_device_files
for name in appeared:
future = self._thread_pool.submit(self._make_device, name, count=10)
future.add_done_callback(self._make_device_callback)
for name in disappeared:
controller = self._controllers.get(name)
if controller:
self.dispatch_event('on_disconnect', controller)
def get_controllers(self) -> list[Controller]:
return list(self._controllers.values())
def get_devices(display=None): def get_devices(display=None):
_devices = {} _devices = {}
base = '/dev/input' base = '/dev/input'
@ -548,8 +626,10 @@ def get_joysticks(display=None):
def _detect_controller_mapping(device): def _detect_controller_mapping(device):
# detect Controller mapping from the Linux gamepad specification: # If no explicit mapping is available, we can
# detect it from the Linux gamepad specification:
# https://www.kernel.org/doc/html/v4.13/input/gamepad.html # https://www.kernel.org/doc/html/v4.13/input/gamepad.html
# Note: legacy device drivers don't always adhere to this.
mapping = dict(guid=device.get_guid(), name=device.name) mapping = dict(guid=device.get_guid(), name=device.name)
_aliases = {BTN_MODE: 'guide', BTN_SELECT: 'back', BTN_START: 'start', _aliases = {BTN_MODE: 'guide', BTN_SELECT: 'back', BTN_START: 'start',

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,15 +1,21 @@
import time import time
import ctypes
import weakref import weakref
import threading import threading
import pyglet import pyglet
from pyglet import com
from pyglet.event import EventDispatcher
from pyglet.libs.win32.types import * from pyglet.libs.win32.types import *
from pyglet.input.base import Device, Button, AbsoluteAxis from pyglet.libs.win32 import _ole32 as ole32, _oleaut32 as oleaut32
from pyglet.libs.win32.constants import CLSCTX_INPROC_SERVER
from pyglet.input.base import Device, Controller, Button, AbsoluteAxis, ControllerManager
lib = pyglet.lib.load_library('xinput1_4') lib = pyglet.lib.load_library('xinput1_4')
# TODO Add: xinput1_3 and xinput9_1_0 support
library_name = lib._name
XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE = 7849 XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE = 7849
@ -39,6 +45,7 @@ XINPUT_GAMEPAD_LEFT_THUMB = 0x0040
XINPUT_GAMEPAD_RIGHT_THUMB = 0x0080 XINPUT_GAMEPAD_RIGHT_THUMB = 0x0080
XINPUT_GAMEPAD_LEFT_SHOULDER = 0x0100 XINPUT_GAMEPAD_LEFT_SHOULDER = 0x0100
XINPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200 XINPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200
XINPUT_GAMEPAD_GUIDE = 0x0400
XINPUT_GAMEPAD_A = 0x1000 XINPUT_GAMEPAD_A = 0x1000
XINPUT_GAMEPAD_B = 0x2000 XINPUT_GAMEPAD_B = 0x2000
XINPUT_GAMEPAD_X = 0x4000 XINPUT_GAMEPAD_X = 0x4000
@ -90,32 +97,20 @@ VK_PAD_RTHUMB_UPRIGHT = 0x5835
VK_PAD_RTHUMB_DOWNRIGHT = 0x5836 VK_PAD_RTHUMB_DOWNRIGHT = 0x5836
VK_PAD_RTHUMB_DOWNLEFT = 0x5837 VK_PAD_RTHUMB_DOWNLEFT = 0x5837
# /* XUSER_MAX_COUNT = 4 # Cannot go over this number.
# * How many joysticks can be used with this library. Games that
# * use the xinput library will not go over this number.
# */
XUSER_MAX_COUNT = 4
XUSER_INDEX_ANY = 0x000000FF XUSER_INDEX_ANY = 0x000000FF
# define XUSER_INDEX_ANY 0x000000FF
# define XINPUT_CAPS_FFB_SUPPORTED 0x0001
# define XINPUT_CAPS_WIRELESS 0x0002
# define XINPUT_CAPS_PMD_SUPPORTED 0x0008
# define XINPUT_CAPS_NO_NAVIGATION 0x0010
ERROR_DEVICE_NOT_CONNECTED = 1167 ERROR_DEVICE_NOT_CONNECTED = 1167
ERROR_EMPTY = 4306 ERROR_EMPTY = 4306
ERROR_SUCCESS = 0 ERROR_SUCCESS = 0
class XINPUT_GAMEPAD(ctypes.Structure): class XINPUT_GAMEPAD(Structure):
_fields_ = [ _fields_ = [
('wButtons', WORD), ('wButtons', WORD),
('bLeftTrigger', BYTE), ('bLeftTrigger', UBYTE),
('bRightTrigger', BYTE), ('bRightTrigger', UBYTE),
('sThumbLX', SHORT), ('sThumbLX', SHORT),
('sThumbLY', SHORT), ('sThumbLY', SHORT),
('sThumbRX', SHORT), ('sThumbRX', SHORT),
@ -123,7 +118,7 @@ class XINPUT_GAMEPAD(ctypes.Structure):
] ]
class XINPUT_STATE(ctypes.Structure): class XINPUT_STATE(Structure):
_fields_ = [ _fields_ = [
('dwPacketNumber', DWORD), ('dwPacketNumber', DWORD),
('Gamepad', XINPUT_GAMEPAD) ('Gamepad', XINPUT_GAMEPAD)
@ -137,7 +132,7 @@ class XINPUT_VIBRATION(Structure):
] ]
class XINPUT_CAPABILITIES(ctypes.Structure): class XINPUT_CAPABILITIES(Structure):
_fields_ = [ _fields_ = [
('Type', BYTE), ('Type', BYTE),
('SubType', BYTE), ('SubType', BYTE),
@ -154,7 +149,7 @@ class XINPUT_BATTERY_INFORMATION(Structure):
] ]
class XINPUT_CAPABILITIES_EX(ctypes.Structure): class XINPUT_CAPABILITIES_EX(Structure):
_fields_ = [ _fields_ = [
('Capabilities', XINPUT_CAPABILITIES), ('Capabilities', XINPUT_CAPABILITIES),
('vendorId', WORD), ('vendorId', WORD),
@ -168,6 +163,10 @@ XInputGetState = lib.XInputGetState
XInputGetState.restype = DWORD XInputGetState.restype = DWORD
XInputGetState.argtypes = [DWORD, POINTER(XINPUT_STATE)] XInputGetState.argtypes = [DWORD, POINTER(XINPUT_STATE)]
XInputGetStateEx = lib[100]
XInputGetStateEx.restype = DWORD
XInputGetStateEx.argtypes = [DWORD, POINTER(XINPUT_STATE)]
XInputSetState = lib.XInputSetState XInputSetState = lib.XInputSetState
XInputSetState.argtypes = [DWORD, POINTER(XINPUT_VIBRATION)] XInputSetState.argtypes = [DWORD, POINTER(XINPUT_VIBRATION)]
XInputSetState.restype = DWORD XInputSetState.restype = DWORD
@ -182,9 +181,167 @@ XInputGetCapabilitiesEx.restype = DWORD
XInputGetCapabilitiesEx.argtypes = [DWORD, DWORD, DWORD, POINTER(XINPUT_CAPABILITIES_EX)] XInputGetCapabilitiesEx.argtypes = [DWORD, DWORD, DWORD, POINTER(XINPUT_CAPABILITIES_EX)]
# Only available for 1.4+ # Only available for 1.4+
XInputGetBatteryInformation = lib.XInputGetBatteryInformation if library_name == "xinput1_4":
XInputGetBatteryInformation.argtypes = [DWORD, BYTE, POINTER(XINPUT_BATTERY_INFORMATION)] XInputGetBatteryInformation = lib.XInputGetBatteryInformation
XInputGetBatteryInformation.restype = DWORD XInputGetBatteryInformation.argtypes = [DWORD, BYTE, POINTER(XINPUT_BATTERY_INFORMATION)]
XInputGetBatteryInformation.restype = DWORD
else:
XInputGetBatteryInformation = None
# wbemcli #################################################
BSTR = LPCWSTR
IWbemContext = c_void_p
RPC_C_AUTHN_WINNT = 10
RPC_C_AUTHZ_NONE = 0
RPC_C_AUTHN_LEVEL_CALL = 0x03
RPC_C_IMP_LEVEL_IMPERSONATE = 3
EOAC_NONE = 0
VT_BSTR = 8
CLSID_WbemLocator = com.GUID(0x4590f811, 0x1d3a, 0x11d0, 0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24)
IID_IWbemLocator = com.GUID(0xdc12a687, 0x737f, 0x11cf, 0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24)
class IWbemClassObject(com.pIUnknown):
_methods_ = [
('GetQualifierSet',
com.STDMETHOD()),
('Get',
com.STDMETHOD(BSTR, LONG, POINTER(VARIANT), c_void_p, c_void_p))
# ... long, unneeded
]
class IEnumWbemClassObject(com.pIUnknown):
_methods_ = [
('Reset',
com.STDMETHOD()),
('Next',
com.STDMETHOD(LONG, ULONG, POINTER(IWbemClassObject), POINTER(ULONG))),
('NextAsync',
com.STDMETHOD()),
('Clone',
com.STDMETHOD()),
('Skip',
com.STDMETHOD())
]
class IWbemServices(com.pIUnknown):
_methods_ = [
('OpenNamespace',
com.STDMETHOD()),
('CancelAsyncCall',
com.STDMETHOD()),
('QueryObjectSink',
com.STDMETHOD()),
('GetObject',
com.STDMETHOD()),
('GetObjectAsync',
com.STDMETHOD()),
('PutClass',
com.STDMETHOD()),
('PutClassAsync',
com.STDMETHOD()),
('DeleteClass',
com.STDMETHOD()),
('DeleteClassAsync',
com.STDMETHOD()),
('CreateClassEnum',
com.STDMETHOD()),
('CreateClassEnumAsync',
com.STDMETHOD()),
('PutInstance',
com.STDMETHOD()),
('PutInstanceAsync',
com.STDMETHOD()),
('DeleteInstance',
com.STDMETHOD()),
('DeleteInstanceAsync',
com.STDMETHOD()),
('CreateInstanceEnum',
com.STDMETHOD(BSTR, LONG, IWbemContext, POINTER(IEnumWbemClassObject))),
('CreateInstanceEnumAsync',
com.STDMETHOD()),
# ... much more.
]
class IWbemLocator(com.pIUnknown):
_methods_ = [
('ConnectServer',
com.STDMETHOD(BSTR, BSTR, BSTR, LONG, LONG, BSTR, IWbemContext, POINTER(IWbemServices))),
]
def get_xinput_guids():
"""We iterate over all devices in the system looking for IG_ in the device ID, which indicates it's an
XInput device. Returns a list of strings containing pid/vid.
Monstrosity found at: https://docs.microsoft.com/en-us/windows/win32/xinput/xinput-and-directinput
"""
ole32.CoInitialize(None)
guids_found = []
locator = IWbemLocator()
services = IWbemServices()
enum_devices = IEnumWbemClassObject()
devices = (IWbemClassObject * 20)()
ole32.CoCreateInstance(CLSID_WbemLocator, None, CLSCTX_INPROC_SERVER, IID_IWbemLocator, byref(locator))
name_space = BSTR("\\\\.\\root\\cimv2")
class_name = BSTR("Win32_PNPEntity")
device_id = BSTR("DeviceID")
# Connect to WMI
hr = locator.ConnectServer(name_space, None, None, 0, 0, None, None, byref(services))
if hr != 0:
return guids_found
# Switch security level to IMPERSONATE.
hr = ole32.CoSetProxyBlanket(services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, None, RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE, None, EOAC_NONE)
if hr != 0:
return guids_found
hr = services.CreateInstanceEnum(class_name, 0, None, byref(enum_devices))
if hr != 0:
return guids_found
var = VARIANT()
oleaut32.VariantInit(byref(var))
while True:
returned = ULONG()
_hr = enum_devices.Next(10000, len(devices), devices, byref(returned))
if returned.value == 0:
break
for i in range(returned.value):
result = devices[i].Get(device_id, 0, byref(var), None, None)
if result == 0:
if var.vt == VT_BSTR and var.bstrVal != "":
if 'IG_' in var.bstrVal:
guid = var.bstrVal
pid_start = guid.index("PID_") + 4
dev_pid = guid[pid_start:pid_start + 4]
vid_start = guid.index("VID_") + 4
dev_vid = guid[vid_start:vid_start + 4]
sdl_guid = f"{dev_pid}{dev_vid}".lower()
if sdl_guid not in guids_found:
guids_found.append(sdl_guid)
oleaut32.VariantClear(var)
ole32.CoUninitialize()
return guids_found
# ######################################################### # #########################################################
@ -196,6 +353,7 @@ controller_api_to_pyglet = {
XINPUT_GAMEPAD_DPAD_RIGHT: "dpright", XINPUT_GAMEPAD_DPAD_RIGHT: "dpright",
XINPUT_GAMEPAD_START: "start", XINPUT_GAMEPAD_START: "start",
XINPUT_GAMEPAD_BACK: "back", XINPUT_GAMEPAD_BACK: "back",
XINPUT_GAMEPAD_GUIDE: "guide",
XINPUT_GAMEPAD_LEFT_THUMB: "leftstick", XINPUT_GAMEPAD_LEFT_THUMB: "leftstick",
XINPUT_GAMEPAD_RIGHT_THUMB: "rightstick", XINPUT_GAMEPAD_RIGHT_THUMB: "rightstick",
XINPUT_GAMEPAD_LEFT_SHOULDER: "leftshoulder", XINPUT_GAMEPAD_LEFT_SHOULDER: "leftshoulder",
@ -207,91 +365,21 @@ controller_api_to_pyglet = {
} }
class XInputManager:
def __init__(self):
self._available_idx = []
self._open_devices = set()
self._devices = [XInputDevice(i, self) for i in range(XUSER_MAX_COUNT)]
self._exit = threading.Event()
self._dev_lock = threading.Lock()
self._thread = threading.Thread(target=self._check_state, daemon=True)
self._thread.start()
def create_device(self):
with self._dev_lock:
try:
index = self._available_idx.pop(0)
return self._devices[index]
except IndexError:
raise IndexError('No available devices')
def open(self, device):
with self._dev_lock:
self._open_devices.add(device)
def close(self, device):
with self._dev_lock:
if device in self._open_devices:
self._open_devices.remove(device)
def _check_state(self):
while not self._exit.is_set():
self._dev_lock.acquire()
for i in range(XUSER_MAX_COUNT):
controller = self._devices[i]
controller.current_state = XINPUT_STATE()
result = XInputGetState(i, byref(controller.current_state))
if result == ERROR_DEVICE_NOT_CONNECTED:
if i in self._available_idx:
self._available_idx.remove(i)
if controller.connected:
print(f"Controller #{controller} was disconnected.")
controller.connected = False
continue
elif result == ERROR_SUCCESS:
if i not in self._available_idx:
self._available_idx.append(i)
if not controller.connected:
controller.connected = True
print(f"Controller #{controller} was connected.")
# Just testing
capabilities = XINPUT_CAPABILITIES_EX()
result = XInputGetCapabilitiesEx(1, i, 0, byref(capabilities))
print(capabilities.vendorId, capabilities.revisionId, capabilities.productId)
# TODO: skip not-open devices
for button, name in controller_api_to_pyglet.items():
controller.controls[name].value = controller.current_state.Gamepad.wButtons & button
controller.controls['lefttrigger'].value = controller.current_state.Gamepad.bLeftTrigger
controller.controls['righttrigger'].value = controller.current_state.Gamepad.bRightTrigger
controller.controls['leftx'].value = controller.current_state.Gamepad.sThumbLX
controller.controls['lefty'].value = controller.current_state.Gamepad.sThumbLY
controller.controls['rightx'].value = controller.current_state.Gamepad.sThumbRX
controller.controls['righty'].value = controller.current_state.Gamepad.sThumbRY
self._dev_lock.release()
time.sleep(0.016)
class XInputDevice(Device): class XInputDevice(Device):
def __init__(self, index, manager, display=None): def __init__(self, index, manager):
super().__init__(display, f'XInput Controller {index}') super().__init__(None, f"XInput{index}")
self._manager = weakref.proxy(manager)
self.index = index self.index = index
self.current_state = None self._manager = weakref.proxy(manager)
self.connected = False self.connected = False
self.xinput_state = XINPUT_STATE()
self.packet_number = 0
self.vibration = XINPUT_VIBRATION()
self.weak_duration = None
self.strong_duration = None
self.controls = { self.controls = {
'a': Button('a'), 'a': Button('a'),
'b': Button('b'), 'b': Button('b'),
@ -299,6 +387,7 @@ class XInputDevice(Device):
'y': Button('y'), 'y': Button('y'),
'back': Button('back'), 'back': Button('back'),
'start': Button('start'), 'start': Button('start'),
'guide': Button('guide'),
'leftshoulder': Button('leftshoulder'), 'leftshoulder': Button('leftshoulder'),
'rightshoulder': Button('rightshoulder'), 'rightshoulder': Button('rightshoulder'),
'leftstick': Button('leftstick'), 'leftstick': Button('leftstick'),
@ -312,20 +401,235 @@ class XInputDevice(Device):
'lefty': AbsoluteAxis('lefty', -32768, 32768), 'lefty': AbsoluteAxis('lefty', -32768, 32768),
'rightx': AbsoluteAxis('rightx', -32768, 32768), 'rightx': AbsoluteAxis('rightx', -32768, 32768),
'righty': AbsoluteAxis('righty', -32768, 32768), 'righty': AbsoluteAxis('righty', -32768, 32768),
'lefttrigger': AbsoluteAxis('lefttrigger', -32768, 32768), 'lefttrigger': AbsoluteAxis('lefttrigger', 0, 255),
'righttrigger': AbsoluteAxis('righttrigger', -32768, 32768) 'righttrigger': AbsoluteAxis('righttrigger', 0, 255)
} }
def open(self, window=None, exclusive=False): def set_rumble_state(self):
super().open(window, exclusive) XInputSetState(self.index, byref(self.vibration))
self._manager.open(self)
def close(self):
self._manager.close(self)
super().close()
def get_controls(self): def get_controls(self):
return list(self.controls.values()) return list(self.controls.values())
def get_guid(self): def get_guid(self):
return "XINPUTCONTROLLER" return "XINPUTCONTROLLER"
class XInputDeviceManager(EventDispatcher):
def __init__(self):
self.all_devices = [XInputDevice(i, self) for i in range(XUSER_MAX_COUNT)]
self._connected_devices = set()
for i in range(XUSER_MAX_COUNT):
device = self.all_devices[i]
if XInputGetStateEx(i, byref(device.xinput_state)) == ERROR_DEVICE_NOT_CONNECTED:
continue
device.connected = True
self._connected_devices.add(i)
self._polling_rate = 0.016
self._detection_rate = 2.0
self._exit = threading.Event()
self._dev_lock = threading.Lock()
self._thread = threading.Thread(target=self._get_state, daemon=True)
self._thread.start()
def get_devices(self):
with self._dev_lock:
return [dev for dev in self.all_devices if dev.connected]
def _get_state(self):
xuser_max_count = set(range(XUSER_MAX_COUNT)) # {0, 1, 2, 3}
polling_rate = self._polling_rate
detect_rate = self._detection_rate
elapsed = 0.0
while not self._exit.is_set():
self._dev_lock.acquire()
elapsed += polling_rate
# Every few seconds check for new connections:
if elapsed >= detect_rate:
# Only check if not currently connected:
for i in xuser_max_count - self._connected_devices:
device = self.all_devices[i]
if XInputGetStateEx(i, byref(device.xinput_state)) == ERROR_DEVICE_NOT_CONNECTED:
continue
# Found a new connection:
device.connected = True
self._connected_devices.add(i)
self.dispatch_event('on_connect', device)
elapsed = 0.0
# At the set polling rate, update all connected and
# opened devices. Skip unopened devices to save CPU:
for i in self._connected_devices.copy():
device = self.all_devices[i]
result = XInputGetStateEx(i, byref(device.xinput_state))
if result == ERROR_DEVICE_NOT_CONNECTED:
# Newly disconnected device:
if device.connected:
device.connected = False
self._connected_devices.remove(i)
self.dispatch_event('on_disconnect', device)
continue
elif result == ERROR_SUCCESS and device.is_open:
# Stop Rumble effects if a duration is set:
if device.weak_duration:
device.weak_duration -= polling_rate
if device.weak_duration <= 0:
device.weak_duration = None
device.vibration.wRightMotorSpeed = 0
device.set_rumble_state()
if device.strong_duration:
device.strong_duration -= polling_rate
if device.strong_duration <= 0:
device.strong_duration = None
device.vibration.wLeftMotorSpeed = 0
device.set_rumble_state()
# Don't update the Control values if XInput has no new input:
if device.xinput_state.dwPacketNumber == device.packet_number:
continue
for button, name in controller_api_to_pyglet.items():
device.controls[name].value = device.xinput_state.Gamepad.wButtons & button
device.controls['lefttrigger'].value = device.xinput_state.Gamepad.bLeftTrigger
device.controls['righttrigger'].value = device.xinput_state.Gamepad.bRightTrigger
device.controls['leftx'].value = device.xinput_state.Gamepad.sThumbLX
device.controls['lefty'].value = device.xinput_state.Gamepad.sThumbLY
device.controls['rightx'].value = device.xinput_state.Gamepad.sThumbRX
device.controls['righty'].value = device.xinput_state.Gamepad.sThumbRY
device.packet_number = device.xinput_state.dwPacketNumber
self._dev_lock.release()
time.sleep(polling_rate)
def on_connect(self, device):
"""A device was connected."""
def on_disconnect(self, device):
"""A device was disconnected"""
XInputDeviceManager.register_event_type('on_connect')
XInputDeviceManager.register_event_type('on_disconnect')
_device_manager = XInputDeviceManager()
class XInputController(Controller):
def _initialize_controls(self):
for button_name in controller_api_to_pyglet.values():
control = self.device.controls[button_name]
self._button_controls.append(control)
self._add_button(control, button_name)
for axis_name in "leftx", "lefty", "rightx", "righty", "lefttrigger", "righttrigger":
control = self.device.controls[axis_name]
self._axis_controls.append(control)
self._add_axis(control, axis_name)
def _add_axis(self, control, name):
tscale = 1.0 / (control.max - control.min)
scale = 2.0 / (control.max - control.min)
bias = -1.0 - control.min * scale
if name in ("lefttrigger", "righttrigger"):
@control.event
def on_change(value):
normalized_value = value * tscale
setattr(self, name, normalized_value)
self.dispatch_event('on_trigger_motion', self, name, normalized_value)
elif name in ("leftx", "lefty"):
@control.event
def on_change(value):
normalized_value = value * scale + bias
setattr(self, name, normalized_value)
self.dispatch_event('on_stick_motion', self, "leftstick", self.leftx, self.lefty)
elif name in ("rightx", "righty"):
@control.event
def on_change(value):
normalized_value = value * scale + bias
setattr(self, name, normalized_value)
self.dispatch_event('on_stick_motion', self, "rightstick", self.rightx, self.righty)
def _add_button(self, control, name):
if name in ("dpleft", "dpright", "dpup", "dpdown"):
@control.event
def on_change(value):
setattr(self, name, value)
self.dispatch_event('on_dpad_motion', self, self.dpleft, self.dpright, self.dpup, self.dpdown)
else:
@control.event
def on_change(value):
setattr(self, name, value)
@control.event
def on_press():
self.dispatch_event('on_button_press', self, name)
@control.event
def on_release():
self.dispatch_event('on_button_release', self, name)
def rumble_play_weak(self, strength=1.0, duration=0.5):
self.device.vibration.wRightMotorSpeed = int(max(min(1.0, strength), 0) * 0xFFFF)
self.device.weak_duration = duration
self.device.set_rumble_state()
def rumble_play_strong(self, strength=1.0, duration=0.5):
self.device.vibration.wLeftMotorSpeed = int(max(min(1.0, strength), 0) * 0xFFFF)
self.device.strong_duration = duration
self.device.set_rumble_state()
def rumble_stop_weak(self):
self.device.vibration.wRightMotorSpeed = 0
self.device.set_rumble_state()
def rumble_stop_strong(self):
self.device.vibration.wLeftMotorSpeed = 0
self.device.set_rumble_state()
class XInputControllerManager(ControllerManager):
def __init__(self):
self._controllers = {}
for device in _device_manager.all_devices:
meta = {'name': device.name, 'guid': "XINPUTCONTROLLER"}
self._controllers[device] = XInputController(device, meta)
@_device_manager.event
def on_connect(xdevice):
self.dispatch_event('on_connect', self._controllers[xdevice])
@_device_manager.event
def on_disconnect(xdevice):
self.dispatch_event('on_disconnect', self._controllers[xdevice])
def get_controllers(self):
return [ctlr for ctlr in self._controllers.values() if ctlr.device.connected]
def get_devices():
return _device_manager.get_devices()
def get_controllers():
return [XInputController(device, {'name': device.name, 'guid': device.get_guid()}) for device in get_devices()]

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -162,7 +162,8 @@ class LibraryLoader:
except OSError: except OSError:
pass pass
elif self.platform == "win32" and o.winerror != 126: elif self.platform == "win32" and o.winerror != 126:
raise ImportError("Unexpected error loading library %s: %s" % (name, str(o))) if _debug_lib:
print(f"Unexpected error loading library {name}: {str(o)}")
raise ImportError('Library "%s" not found.' % names[0]) raise ImportError('Library "%s" not found.' % names[0])

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -91,6 +91,7 @@ _user32 = DebugLibrary(windll.user32)
_dwmapi = DebugLibrary(windll.dwmapi) _dwmapi = DebugLibrary(windll.dwmapi)
_shell32 = DebugLibrary(windll.shell32) _shell32 = DebugLibrary(windll.shell32)
_ole32 = DebugLibrary(windll.ole32) _ole32 = DebugLibrary(windll.ole32)
_oleaut32 = DebugLibrary(windll.oleaut32)
# _gdi32 # _gdi32
_gdi32.AddFontMemResourceEx.restype = HANDLE _gdi32.AddFontMemResourceEx.restype = HANDLE
@ -292,6 +293,8 @@ _shell32.DragQueryPoint.argtypes = [HDROP, LPPOINT]
# ole32 # ole32
_ole32.CreateStreamOnHGlobal.argtypes = [HGLOBAL, BOOL, LPSTREAM] _ole32.CreateStreamOnHGlobal.argtypes = [HGLOBAL, BOOL, LPSTREAM]
_ole32.CoInitialize.restype = HRESULT
_ole32.CoInitialize.argtypes = [LPVOID]
_ole32.CoInitializeEx.restype = HRESULT _ole32.CoInitializeEx.restype = HRESULT
_ole32.CoInitializeEx.argtypes = [LPVOID, DWORD] _ole32.CoInitializeEx.argtypes = [LPVOID, DWORD]
_ole32.CoUninitialize.restype = HRESULT _ole32.CoUninitialize.restype = HRESULT
@ -300,3 +303,12 @@ _ole32.PropVariantClear.restype = HRESULT
_ole32.PropVariantClear.argtypes = [c_void_p] _ole32.PropVariantClear.argtypes = [c_void_p]
_ole32.CoCreateInstance.restype = HRESULT _ole32.CoCreateInstance.restype = HRESULT
_ole32.CoCreateInstance.argtypes = [com.REFIID, c_void_p, DWORD, com.REFIID, c_void_p] _ole32.CoCreateInstance.argtypes = [com.REFIID, c_void_p, DWORD, com.REFIID, c_void_p]
_ole32.CoSetProxyBlanket.restype = HRESULT
_ole32.CoSetProxyBlanket.argtypes = (c_void_p, DWORD, DWORD, c_void_p, DWORD, DWORD, c_void_p, DWORD)
# oleaut32
_oleaut32.VariantInit.restype = c_void_p
_oleaut32.VariantInit.argtypes = [c_void_p]
_oleaut32.VariantClear.restype = HRESULT
_oleaut32.VariantClear.argtypes = [c_void_p]

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -5092,3 +5092,7 @@ CLSCTX_INPROC_SERVER = 0x1
DWM_BB_ENABLE = 0x00000001 DWM_BB_ENABLE = 0x00000001
DWM_BB_BLURREGION = 0x00000002 DWM_BB_BLURREGION = 0x00000002
DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004 DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004
STREAM_SEEK_SET = 0
STREAM_SEEK_CUR = 1
STREAM_SEEK_END = 2

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -35,6 +35,7 @@
import sys import sys
import ctypes import ctypes
from pyglet import com
from ctypes import * from ctypes import *
from ctypes.wintypes import * from ctypes.wintypes import *
@ -82,6 +83,7 @@ def POINTER_(obj):
c_void_p = POINTER_(c_void) c_void_p = POINTER_(c_void)
INT = c_int INT = c_int
UBYTE = c_ubyte
LPVOID = c_void_p LPVOID = c_void_p
HCURSOR = HANDLE HCURSOR = HANDLE
LRESULT = LPARAM LRESULT = LPARAM
@ -509,6 +511,23 @@ class PROPVARIANT(ctypes.Structure):
('union', _VarTable) ('union', _VarTable)
] ]
class _VarTableVariant(ctypes.Union):
"""Must be in an anonymous union or values will not work across various VT's."""
_fields_ = [
('bstrVal', LPCWSTR)
]
class VARIANT(ctypes.Structure):
_anonymous_ = ['union']
_fields_ = [
('vt', ctypes.c_ushort),
('wReserved1', WORD),
('wReserved2', WORD),
('wReserved3', WORD),
('union', _VarTableVariant)
]
class DWM_BLURBEHIND(ctypes.Structure): class DWM_BLURBEHIND(ctypes.Structure):
_fields_ = [ _fields_ = [
@ -517,3 +536,45 @@ class DWM_BLURBEHIND(ctypes.Structure):
("hRgnBlur", HRGN), ("hRgnBlur", HRGN),
("fTransitionOnMaximized", DWORD), ("fTransitionOnMaximized", DWORD),
] ]
class STATSTG(ctypes.Structure):
_fields_ = [
('pwcsName', LPOLESTR),
('type', DWORD),
('cbSize', ULARGE_INTEGER),
('mtime', FILETIME),
('ctime', FILETIME),
('atime', FILETIME),
('grfMode', DWORD),
('grfLocksSupported', DWORD),
('clsid', DWORD),
('grfStateBits', DWORD),
('reserved', DWORD),
]
class IStream(com.pIUnknown):
_methods_ = [
('Read',
com.STDMETHOD(c_void_p, ULONG, POINTER(ULONG))),
('Write',
com.STDMETHOD()),
('Seek',
com.STDMETHOD(LARGE_INTEGER, DWORD, POINTER(ULARGE_INTEGER))),
('SetSize',
com.STDMETHOD()),
('CopyTo',
com.STDMETHOD()),
('Commit',
com.STDMETHOD()),
('Revert',
com.STDMETHOD()),
('LockRegion',
com.STDMETHOD()),
('UnlockRegion',
com.STDMETHOD()),
('Stat',
com.STDMETHOD(POINTER(STATSTG), UINT)),
('Clone',
com.STDMETHOD()),
]

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# pyglet # pyglet
# Copyright (c) 2006-2008 Alex Holkner # Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2021 pyglet contributors # Copyright (c) 2008-2022 pyglet contributors
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without

Some files were not shown because too many files have changed in this diff Show More