mirror of
https://github.com/ValveSoftware/Proton.git
synced 2024-12-30 16:45:36 +03:00
parent
c9dda0d5b7
commit
e1c7f3e3f3
@ -685,18 +685,12 @@ def get_path_converter(parent):
|
|||||||
return conv
|
return conv
|
||||||
return None
|
return None
|
||||||
|
|
||||||
class DummyWriter(object):
|
|
||||||
def write(self, s):
|
|
||||||
#noop
|
|
||||||
pass
|
|
||||||
|
|
||||||
def to_c_bool(b):
|
def to_c_bool(b):
|
||||||
if b:
|
if b:
|
||||||
return "1"
|
return "1"
|
||||||
return "0"
|
return "0"
|
||||||
|
|
||||||
dummy_writer = DummyWriter()
|
|
||||||
|
|
||||||
|
|
||||||
def method_unique_name(method, existing_methods):
|
def method_unique_name(method, existing_methods):
|
||||||
used_name = method.spelling
|
used_name = method.spelling
|
||||||
@ -753,34 +747,15 @@ def handle_method_hpp(method_name, cppname, method, cpp_h):
|
|||||||
cpp_h.write(f'extern {ret}{cppname}_{method_name}({", ".join(params)});\n')
|
cpp_h.write(f'extern {ret}{cppname}_{method_name}({", ".join(params)});\n')
|
||||||
|
|
||||||
|
|
||||||
def handle_method(used_name, cfile, classname, winclassname, cppname, method, cpp):
|
def handle_method_cpp(method_name, classname, cppname, method, cpp):
|
||||||
returns_record = method.result_type.get_canonical().kind == TypeKind.RECORD
|
returns_record = method.result_type.get_canonical().kind == TypeKind.RECORD
|
||||||
if returns_record:
|
|
||||||
parambytes = 8 #_this + return pointer
|
|
||||||
else:
|
|
||||||
parambytes = 4 #_this
|
|
||||||
for param in list(method.get_children()):
|
|
||||||
if param.kind == CursorKind.PARM_DECL:
|
|
||||||
if param.type.kind == TypeKind.LVALUEREFERENCE:
|
|
||||||
parambytes += 4
|
|
||||||
else:
|
|
||||||
parambytes += int(math.ceil(param.type.get_size()/4.0) * 4)
|
|
||||||
if method_needs_manual_handling(cppname, used_name):
|
|
||||||
cpp = dummy_writer #just don't write the cpp function
|
|
||||||
cfile.write(f"DEFINE_THISCALL_WRAPPER({winclassname}_{used_name}, {parambytes})\n")
|
|
||||||
if method.result_type.spelling.startswith("ISteam"):
|
if method.result_type.spelling.startswith("ISteam"):
|
||||||
cfile.write(f"win{method.result_type.spelling} ")
|
|
||||||
cpp.write("void *")
|
cpp.write("void *")
|
||||||
elif returns_record:
|
elif returns_record:
|
||||||
cfile.write(f"{method.result_type.spelling} *")
|
|
||||||
cpp.write(f"{method.result_type.spelling} ")
|
cpp.write(f"{method.result_type.spelling} ")
|
||||||
else:
|
else:
|
||||||
cfile.write(f"{method.result_type.spelling} ")
|
|
||||||
cpp.write(f"{method.result_type.spelling} ")
|
cpp.write(f"{method.result_type.spelling} ")
|
||||||
cfile.write(f'__thiscall {winclassname}_{used_name}({winclassname} *_this')
|
cpp.write(f"{cppname}_{method_name}(void *linux_side")
|
||||||
cpp.write(f"{cppname}_{used_name}(void *linux_side")
|
|
||||||
if returns_record:
|
|
||||||
cfile.write(f", {method.result_type.spelling} *_r")
|
|
||||||
unnamed = 'a'
|
unnamed = 'a'
|
||||||
need_convert = []
|
need_convert = []
|
||||||
manual_convert = []
|
manual_convert = []
|
||||||
@ -801,33 +776,12 @@ def handle_method(used_name, cfile, classname, winclassname, cppname, method, cp
|
|||||||
win_name = declspec(param, "")
|
win_name = declspec(param, "")
|
||||||
|
|
||||||
if param.spelling == "":
|
if param.spelling == "":
|
||||||
cfile.write(f", {win_name} _{unnamed}")
|
|
||||||
cpp.write(f", {win_name} _{unnamed}")
|
cpp.write(f", {win_name} _{unnamed}")
|
||||||
unnamed = chr(ord(unnamed) + 1)
|
unnamed = chr(ord(unnamed) + 1)
|
||||||
else:
|
else:
|
||||||
cfile.write(f", {win_name} {param.spelling}")
|
|
||||||
cpp.write(f", {win_name} {param.spelling}")
|
cpp.write(f", {win_name} {param.spelling}")
|
||||||
cfile.write(")\n{\n")
|
|
||||||
cpp.write(")\n{\n")
|
cpp.write(")\n{\n")
|
||||||
|
|
||||||
path_conv = get_path_converter(method)
|
|
||||||
|
|
||||||
if path_conv:
|
|
||||||
for i in range(len(path_conv["w2l_names"])):
|
|
||||||
if path_conv["w2l_arrays"][i]:
|
|
||||||
cfile.write(f" const char **lin_{path_conv['w2l_names'][i]} = steamclient_dos_to_unix_stringlist({path_conv['w2l_names'][i]});\n")
|
|
||||||
# TODO
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
cfile.write(f" char lin_{path_conv['w2l_names'][i]}[PATH_MAX];\n")
|
|
||||||
cfile.write(f" steamclient_dos_path_to_unix_path({path_conv['w2l_names'][i]}, lin_{path_conv['w2l_names'][i]}, {to_c_bool(path_conv['w2l_urls'][i])});\n")
|
|
||||||
if None in path_conv["l2w_names"]:
|
|
||||||
cfile.write(" const char *path_result;\n")
|
|
||||||
elif path_conv["return_is_size"]:
|
|
||||||
cfile.write(" uint32 path_result;\n")
|
|
||||||
elif len(path_conv["l2w_names"]) > 0:
|
|
||||||
cfile.write(f" {method.result_type.spelling} path_result;\n")
|
|
||||||
|
|
||||||
for param in need_convert:
|
for param in need_convert:
|
||||||
if param.type.kind == TypeKind.POINTER:
|
if param.type.kind == TypeKind.POINTER:
|
||||||
#handle single pointers, but not double pointers
|
#handle single pointers, but not double pointers
|
||||||
@ -849,17 +803,6 @@ def handle_method(used_name, cfile, classname, winclassname, cppname, method, cp
|
|||||||
else:
|
else:
|
||||||
cpp.write(f" {param.spelling} = ({param.type.spelling})manual_convert_{param.type.spelling}((void*){param.spelling});\n")
|
cpp.write(f" {param.spelling} = ({param.type.spelling})manual_convert_{param.type.spelling}((void*){param.spelling});\n")
|
||||||
|
|
||||||
cfile.write(" TRACE(\"%p\\n\", _this);\n")
|
|
||||||
|
|
||||||
if method.result_type.kind == TypeKind.VOID:
|
|
||||||
cfile.write(" ")
|
|
||||||
elif path_conv and (len(path_conv["l2w_names"]) > 0 or path_conv["return_is_size"]):
|
|
||||||
cfile.write(" path_result = ")
|
|
||||||
elif returns_record:
|
|
||||||
cfile.write(" *_r = ")
|
|
||||||
else:
|
|
||||||
cfile.write(" return ")
|
|
||||||
|
|
||||||
if method.result_type.kind == TypeKind.VOID:
|
if method.result_type.kind == TypeKind.VOID:
|
||||||
cpp.write(" ")
|
cpp.write(" ")
|
||||||
elif len(need_convert) > 0:
|
elif len(need_convert) > 0:
|
||||||
@ -871,17 +814,6 @@ def handle_method(used_name, cfile, classname, winclassname, cppname, method, cp
|
|||||||
if post_exec != None:
|
if post_exec != None:
|
||||||
cpp.write(post_exec + '(');
|
cpp.write(post_exec + '(');
|
||||||
|
|
||||||
should_do_cb_wrap = "GetAPICallResult" in used_name
|
|
||||||
should_gen_wrapper = cpp != dummy_writer and \
|
|
||||||
(method.result_type.spelling.startswith("ISteam") or \
|
|
||||||
used_name.startswith("GetISteamGenericInterface"))
|
|
||||||
|
|
||||||
if should_do_cb_wrap:
|
|
||||||
cfile.write(f"do_cb_wrap(0, &{cppname}_{used_name}, _this->linux_side")
|
|
||||||
else:
|
|
||||||
if should_gen_wrapper:
|
|
||||||
cfile.write("create_win_interface(pchVersion,\n ")
|
|
||||||
cfile.write(f"{cppname}_{used_name}(_this->linux_side")
|
|
||||||
cpp.write(f"(({classname}*)linux_side)->{method.spelling}(")
|
cpp.write(f"(({classname}*)linux_side)->{method.spelling}(")
|
||||||
unnamed = 'a'
|
unnamed = 'a'
|
||||||
first = True
|
first = True
|
||||||
@ -892,35 +824,129 @@ def handle_method(used_name, cfile, classname, winclassname, cppname, method, cp
|
|||||||
else:
|
else:
|
||||||
first = False
|
first = False
|
||||||
if param.spelling == "":
|
if param.spelling == "":
|
||||||
cfile.write(f", _{unnamed}")
|
|
||||||
cpp.write(f"({param.type.spelling})_{unnamed}")
|
cpp.write(f"({param.type.spelling})_{unnamed}")
|
||||||
unnamed = chr(ord(unnamed) + 1)
|
unnamed = chr(ord(unnamed) + 1)
|
||||||
elif param.type.kind == TypeKind.POINTER and \
|
elif param.type.kind == TypeKind.POINTER and \
|
||||||
param.type.get_pointee().spelling in WRAPPED_CLASSES:
|
param.type.get_pointee().spelling in WRAPPED_CLASSES:
|
||||||
cfile.write(f", create_Linux{param.type.get_pointee().spelling}({param.spelling}, \"{winclassname}\")")
|
|
||||||
cpp.write(f"({param.type.spelling}){param.spelling}")
|
|
||||||
elif path_conv and param.spelling in path_conv["w2l_names"]:
|
|
||||||
cfile.write(f", {param.spelling} ? lin_{param.spelling} : NULL")
|
|
||||||
cpp.write(f"({param.type.spelling}){param.spelling}")
|
cpp.write(f"({param.type.spelling}){param.spelling}")
|
||||||
elif param in need_convert:
|
elif param in need_convert:
|
||||||
cfile.write(f", {param.spelling}")
|
|
||||||
if param.type.kind != TypeKind.POINTER:
|
if param.type.kind != TypeKind.POINTER:
|
||||||
cpp.write(f"lin_{param.spelling}")
|
cpp.write(f"lin_{param.spelling}")
|
||||||
else:
|
else:
|
||||||
cpp.write(f"&lin_{param.spelling}")
|
cpp.write(f"&lin_{param.spelling}")
|
||||||
elif param.type.kind == TypeKind.LVALUEREFERENCE:
|
elif param.type.kind == TypeKind.LVALUEREFERENCE:
|
||||||
cfile.write(f", {param.spelling}")
|
|
||||||
cpp.write(f"*{param.spelling}")
|
cpp.write(f"*{param.spelling}")
|
||||||
else:
|
else:
|
||||||
cfile.write(f", {param.spelling}")
|
|
||||||
cpp.write(f"({param.type.spelling}){param.spelling}")
|
cpp.write(f"({param.type.spelling}){param.spelling}")
|
||||||
|
|
||||||
|
if post_exec != None:
|
||||||
|
cpp.write(")")
|
||||||
|
cpp.write(");\n")
|
||||||
|
for param in need_convert:
|
||||||
|
if param.type.kind == TypeKind.POINTER:
|
||||||
|
if not "const " in param.type.spelling: #don't modify const arguments
|
||||||
|
real_type = param.type
|
||||||
|
while real_type.kind == TypeKind.POINTER:
|
||||||
|
real_type = real_type.get_pointee()
|
||||||
|
cpp.write(f" lin_to_win_struct_{real_type.spelling}_{sdkver}(&lin_{param.spelling}, {param.spelling});\n")
|
||||||
|
else:
|
||||||
|
cpp.write(f" lin_to_win_struct_{param.type.spelling}_{sdkver}(&lin_{param.spelling}, &{param.spelling});\n")
|
||||||
|
if method.result_type.kind != TypeKind.VOID and \
|
||||||
|
len(need_convert) > 0:
|
||||||
|
cpp.write(" return retval;\n")
|
||||||
|
cpp.write("}\n\n")
|
||||||
|
|
||||||
|
|
||||||
|
def handle_method_c(method_name, winclassname, cppname, method, cfile):
|
||||||
|
returns_record = method.result_type.get_canonical().kind == TypeKind.RECORD
|
||||||
|
if returns_record:
|
||||||
|
parambytes = 8 #_this + return pointer
|
||||||
|
else:
|
||||||
|
parambytes = 4 #_this
|
||||||
|
for param in list(method.get_children()):
|
||||||
|
if param.kind == CursorKind.PARM_DECL:
|
||||||
|
if param.type.kind == TypeKind.LVALUEREFERENCE:
|
||||||
|
parambytes += 4
|
||||||
|
else:
|
||||||
|
parambytes += int(math.ceil(param.type.get_size()/4.0) * 4)
|
||||||
|
cfile.write(f"DEFINE_THISCALL_WRAPPER({winclassname}_{method_name}, {parambytes})\n")
|
||||||
|
if method.result_type.spelling.startswith("ISteam"):
|
||||||
|
cfile.write(f"win{method.result_type.spelling} ")
|
||||||
|
elif returns_record:
|
||||||
|
cfile.write(f"{method.result_type.spelling} *")
|
||||||
|
else:
|
||||||
|
cfile.write(f"{method.result_type.spelling} ")
|
||||||
|
cfile.write(f'__thiscall {winclassname}_{method_name}({winclassname} *_this')
|
||||||
|
if returns_record:
|
||||||
|
cfile.write(f", {method.result_type.spelling} *_r")
|
||||||
|
unnamed = 'a'
|
||||||
|
for param in list(method.get_children()):
|
||||||
|
if param.kind == CursorKind.PARM_DECL:
|
||||||
|
win_name = declspec(param, "")
|
||||||
|
if param.spelling == "":
|
||||||
|
cfile.write(f", {win_name} _{unnamed}")
|
||||||
|
unnamed = chr(ord(unnamed) + 1)
|
||||||
|
else:
|
||||||
|
cfile.write(f", {win_name} {param.spelling}")
|
||||||
|
cfile.write(")\n{\n")
|
||||||
|
|
||||||
|
path_conv = get_path_converter(method)
|
||||||
|
|
||||||
|
if path_conv:
|
||||||
|
for i in range(len(path_conv["w2l_names"])):
|
||||||
|
if path_conv["w2l_arrays"][i]:
|
||||||
|
cfile.write(f" const char **lin_{path_conv['w2l_names'][i]} = steamclient_dos_to_unix_stringlist({path_conv['w2l_names'][i]});\n")
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
cfile.write(f" char lin_{path_conv['w2l_names'][i]}[PATH_MAX];\n")
|
||||||
|
cfile.write(f" steamclient_dos_path_to_unix_path({path_conv['w2l_names'][i]}, lin_{path_conv['w2l_names'][i]}, {to_c_bool(path_conv['w2l_urls'][i])});\n")
|
||||||
|
if None in path_conv["l2w_names"]:
|
||||||
|
cfile.write(" const char *path_result;\n")
|
||||||
|
elif path_conv["return_is_size"]:
|
||||||
|
cfile.write(" uint32 path_result;\n")
|
||||||
|
elif len(path_conv["l2w_names"]) > 0:
|
||||||
|
cfile.write(f" {method.result_type.spelling} path_result;\n")
|
||||||
|
|
||||||
|
cfile.write(" TRACE(\"%p\\n\", _this);\n")
|
||||||
|
|
||||||
|
if method.result_type.kind == TypeKind.VOID:
|
||||||
|
cfile.write(" ")
|
||||||
|
elif path_conv and (len(path_conv["l2w_names"]) > 0 or path_conv["return_is_size"]):
|
||||||
|
cfile.write(" path_result = ")
|
||||||
|
elif returns_record:
|
||||||
|
cfile.write(" *_r = ")
|
||||||
|
else:
|
||||||
|
cfile.write(" return ")
|
||||||
|
|
||||||
|
should_do_cb_wrap = "GetAPICallResult" in method_name
|
||||||
|
should_gen_wrapper = not method_needs_manual_handling(cppname, method_name) and \
|
||||||
|
(method.result_type.spelling.startswith("ISteam") or \
|
||||||
|
method_name.startswith("GetISteamGenericInterface"))
|
||||||
|
|
||||||
|
if should_do_cb_wrap:
|
||||||
|
cfile.write(f"do_cb_wrap(0, &{cppname}_{method_name}, _this->linux_side")
|
||||||
|
else:
|
||||||
|
if should_gen_wrapper:
|
||||||
|
cfile.write("create_win_interface(pchVersion,\n ")
|
||||||
|
cfile.write(f"{cppname}_{method_name}(_this->linux_side")
|
||||||
|
unnamed = 'a'
|
||||||
|
for param in list(method.get_children()):
|
||||||
|
if param.kind == CursorKind.PARM_DECL:
|
||||||
|
if param.spelling == "":
|
||||||
|
cfile.write(f", _{unnamed}")
|
||||||
|
unnamed = chr(ord(unnamed) + 1)
|
||||||
|
elif param.type.kind == TypeKind.POINTER and \
|
||||||
|
param.type.get_pointee().spelling in WRAPPED_CLASSES:
|
||||||
|
cfile.write(f", create_Linux{param.type.get_pointee().spelling}({param.spelling}, \"{winclassname}\")")
|
||||||
|
elif path_conv and param.spelling in path_conv["w2l_names"]:
|
||||||
|
cfile.write(f", {param.spelling} ? lin_{param.spelling} : NULL")
|
||||||
|
else:
|
||||||
|
cfile.write(f", {param.spelling}")
|
||||||
if should_gen_wrapper:
|
if should_gen_wrapper:
|
||||||
cfile.write(")")
|
cfile.write(")")
|
||||||
|
|
||||||
cfile.write(");\n")
|
cfile.write(");\n")
|
||||||
if post_exec != None:
|
|
||||||
cpp.write(")")
|
|
||||||
cpp.write(");\n")
|
|
||||||
if returns_record:
|
if returns_record:
|
||||||
cfile.write(" return _r;\n")
|
cfile.write(" return _r;\n")
|
||||||
if path_conv and len(path_conv["l2w_names"]) > 0:
|
if path_conv and len(path_conv["l2w_names"]) > 0:
|
||||||
@ -935,19 +961,6 @@ def handle_method(used_name, cfile, classname, winclassname, cppname, method, cp
|
|||||||
if path_conv["w2l_arrays"][i]:
|
if path_conv["w2l_arrays"][i]:
|
||||||
cfile.write(f" steamclient_free_stringlist(lin_{path_conv['w2l_names'][i]});\n")
|
cfile.write(f" steamclient_free_stringlist(lin_{path_conv['w2l_names'][i]});\n")
|
||||||
cfile.write("}\n\n")
|
cfile.write("}\n\n")
|
||||||
for param in need_convert:
|
|
||||||
if param.type.kind == TypeKind.POINTER:
|
|
||||||
if not "const " in param.type.spelling: #don't modify const arguments
|
|
||||||
real_type = param.type
|
|
||||||
while real_type.kind == TypeKind.POINTER:
|
|
||||||
real_type = real_type.get_pointee()
|
|
||||||
cpp.write(f" lin_to_win_struct_{real_type.spelling}_{sdkver}(&lin_{param.spelling}, {param.spelling});\n")
|
|
||||||
else:
|
|
||||||
cpp.write(f" lin_to_win_struct_{param.type.spelling}_{sdkver}(&lin_{param.spelling}, &{param.spelling});\n")
|
|
||||||
if method.result_type.kind != TypeKind.VOID and \
|
|
||||||
len(need_convert) > 0:
|
|
||||||
cpp.write(" return retval;\n")
|
|
||||||
cpp.write("}\n\n")
|
|
||||||
|
|
||||||
|
|
||||||
def handle_class(sdkver, klass, version, file):
|
def handle_class(sdkver, klass, version, file):
|
||||||
@ -1007,7 +1020,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(steamclient);
|
|||||||
child.is_virtual_method():
|
child.is_virtual_method():
|
||||||
method_name = method_unique_name(child, methods)
|
method_name = method_unique_name(child, methods)
|
||||||
handle_method_hpp(method_name, cppname, child, cpp_h)
|
handle_method_hpp(method_name, cppname, child, cpp_h)
|
||||||
handle_method(method_name, cfile, klass.spelling, winclassname, cppname, child, cpp)
|
if not method_needs_manual_handling(cppname, method_name):
|
||||||
|
handle_method_cpp(method_name, klass.spelling, cppname, child, cpp)
|
||||||
|
handle_method_c(method_name, winclassname, cppname, child, cfile)
|
||||||
elif child.kind == CursorKind.DESTRUCTOR:
|
elif child.kind == CursorKind.DESTRUCTOR:
|
||||||
methods.append(handle_destructor(cfile, klass.spelling, winclassname, child))
|
methods.append(handle_destructor(cfile, klass.spelling, winclassname, child))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user