#include "../tdkpin_application.h" #include #include Win16FarPtr g_object_windows_application; HINSTANCE16 g_win16_previous_instance; HINSTANCE16 g_win16_instance; Win16FarPtr g_object_windows_dispatch_proc; uint16_t g_object_windows_thunk_code_selector; Win16FarPtr g_object_windows_free_thunk; Win16FarPtr g_object_windows_message_hook; static MSG16 g_messages[4]; static unsigned g_message_index; static unsigned g_message_count; static unsigned g_empty_before_messages; static unsigned g_wait_calls; static unsigned g_translate_calls; static unsigned g_dispatch_calls; static bool g_idle_result; static bool g_main_filter_result; static Win16FarPtr g_filter_order[4]; static unsigned g_filter_calls; static Win16FarPtr g_true_filter; static BOOL16 g_dialog_result; static HWND16 g_dialog_window; static INT16 g_accelerator_result; static HWND16 g_accelerator_window; static HACCEL16 g_accelerator; static BOOL16 g_mdi_result; static HWND16 g_mdi_window; static Win16FarPtr g_client_object; static Win16FarPtr g_client_getter; static Win16FarPtr g_bool_procedure; static Win16FarPtr g_void_method; static Win16FarPtr g_error_method; static uint16_t g_error_argument; BOOL16 PeekMessage16( MSG16 *message, HWND16 window, UINT16 minimum_message, UINT16 maximum_message, UINT16 remove_message) { assert(window == 0 && minimum_message == 0 && maximum_message == 0); assert(remove_message == 1); if (g_empty_before_messages != 0) { g_empty_before_messages--; return 0; } assert(g_message_index < g_message_count); *message = g_messages[g_message_index++]; return 1; } BOOL16 WaitMessage16(void) { g_wait_calls++; return 1; } BOOL16 TranslateMessage16(const MSG16 *message) { assert(message->message != 0x12); g_translate_calls++; return 1; } LRESULT16 DispatchMessage16(const MSG16 *message) { assert(message->message != 0x12); g_dispatch_calls++; return 0; } BOOL16 IsDialogMessage16(HWND16 dialog, MSG16 *message) { (void)message; g_dialog_window = dialog; return g_dialog_result; } INT16 TranslateAccelerator16( HWND16 window, HACCEL16 accelerator, MSG16 *message) { (void)message; g_accelerator_window = window; g_accelerator = accelerator; return g_accelerator_result; } BOOL16 TranslateMDISysAccel16(HWND16 client, MSG16 *message) { (void)message; g_mdi_window = client; return g_mdi_result; } bool win16_call_object_bool_method( Win16FarPtr procedure, Win16FarPtr object) { (void)procedure; (void)object; g_bool_procedure = procedure; return g_idle_result; } bool win16_call_application_message_filter( Win16FarPtr procedure, Win16FarPtr application, MSG16 *message) { (void)application; (void)message; g_filter_order[g_filter_calls++] = procedure; if (g_filter_calls == 1 && g_main_filter_result) { return true; } return procedure == g_true_filter; } Win16FarPtr win16_call_object_far_method( Win16FarPtr procedure, Win16FarPtr object) { assert(procedure == g_client_getter); (void)object; return g_client_object; } void win16_call_object_method( Win16FarPtr procedure, Win16FarPtr object) { (void)object; g_void_method = procedure; } void win16_call_object_u16_method( Win16FarPtr procedure, Win16FarPtr object, uint16_t argument) { (void)object; g_error_method = procedure; g_error_argument = argument; } static void write_far(uint16_t selector, uint16_t offset, Win16FarPtr value) { Win16FarPtr base = win16_make_far_pointer(selector, offset); win16_write_u16(base, 0, win16_far_offset(value)); win16_write_u16(base, 2, win16_far_selector(value)); } int main(void) { static uint8_t dgroup[0x1000]; static uint8_t application_bytes[64]; static uint8_t window_bytes[64]; static uint8_t dialog_bytes[32]; static uint8_t client_bytes[32]; win16_reset_segment_bindings(); win16_bind_segment(0x5000, dgroup, sizeof(dgroup), true); win16_set_dgroup_selector(0x5000); win16_bind_segment( 0x7000, application_bytes, sizeof(application_bytes), true); win16_bind_segment(0x7100, window_bytes, sizeof(window_bytes), true); win16_bind_segment(0x7200, dialog_bytes, sizeof(dialog_bytes), true); win16_bind_segment(0x7300, client_bytes, sizeof(client_bytes), true); Win16FarPtr application = win16_make_far_pointer(0x7000, 2); Win16FarPtr main_window = win16_make_far_pointer(0x7100, 2); Win16FarPtr dialog = win16_make_far_pointer(0x7200, 2); g_client_object = win16_make_far_pointer(0x7300, 2); const uint16_t app_vmt = 0x0100; const uint16_t window_vmt = 0x0200; win16_write_u16(application, 0, app_vmt); win16_write_u16(main_window, 0, window_vmt); write_far(0x7000, 10, main_window); write_far(0x7000, 16, dialog); win16_write_u16(main_window, 4, 0x1111); win16_write_u16(dialog, 4, 0x2222); win16_write_u16(g_client_object, 4, 0x3333); Win16FarPtr idle_proc = win16_make_far_pointer(0x6000, 0x1000); Win16FarPtr main_filter = win16_make_far_pointer(0x6000, 0x2000); Win16FarPtr run_proc = win16_make_far_pointer(0x6000, 0x2100); Win16FarPtr error_proc = win16_make_far_pointer(0x6000, 0x2200); Win16FarPtr filters[3] = { win16_make_far_pointer(0x6000, 0x3000), win16_make_far_pointer(0x6000, 0x4000), win16_make_far_pointer(0x6000, 0x5000), }; write_far(0x5000, app_vmt + 0x0c, idle_proc); write_far(0x5000, app_vmt + 0x24, main_filter); write_far(0x5000, app_vmt + 0x20, run_proc); write_far(0x5000, app_vmt + 0x40, error_proc); write_far(0x5000, app_vmt + 0x28, filters[0]); write_far(0x5000, app_vmt + 0x30, filters[1]); write_far(0x5000, app_vmt + 0x2c, filters[2]); g_client_getter = win16_make_far_pointer(0x6100, 0x6000); Win16FarPtr can_close = win16_make_far_pointer(0x6100, 0x7000); write_far(0x5000, window_vmt + 0x30, g_client_getter); write_far(0x5000, window_vmt + 0x3c, can_close); memset(g_messages, 0, sizeof(g_messages)); g_messages[0].message = 0x0100; g_messages[1].message = 0x0012; g_messages[1].wparam = 0x55aa; g_message_count = 2; g_message_index = 0; g_empty_before_messages = 1; g_wait_calls = 0; g_translate_calls = 0; g_dispatch_calls = 0; g_filter_calls = 0; g_idle_result = false; g_main_filter_result = false; g_true_filter = 0; object_windows_application_message_loop(application); assert(g_wait_calls == 1); assert(g_translate_calls == 1 && g_dispatch_calls == 1); assert(g_filter_calls == 1 && g_filter_order[0] == main_filter); assert(win16_read_u16(win16_far_add_offset(application, 2)) == 0x55aa); MSG16 message = {0}; g_filter_calls = 0; g_true_filter = filters[1]; assert(object_windows_application_preprocess_message( application, &message)); assert(g_filter_calls == 2); assert(g_filter_order[0] == filters[0] && g_filter_order[1] == filters[1]); g_filter_calls = 0; g_true_filter = 0; assert(!object_windows_application_preprocess_message( application, &message)); assert(g_filter_calls == 3); g_dialog_result = 1; assert(object_windows_application_process_dialog_message( application, &message) == 0xff01); assert(g_dialog_window == 0x2222); g_dialog_result = 0; assert(object_windows_application_process_dialog_message( application, &message) == 0); win16_write_u16(application, 0x0c, 0x4444); g_accelerator_result = 1; assert(object_windows_application_process_accelerator( application, &message)); assert(g_accelerator_window == 0x1111 && g_accelerator == 0x4444); g_mdi_result = 1; assert(object_windows_application_process_mdi_accelerator( application, &message)); assert(g_mdi_window == 0x3333); g_client_object = 0; assert(!object_windows_application_process_mdi_accelerator( application, &message)); assert(object_windows_window_get_mdi_client_default(main_window) == 0); win16_write_u16(application, 2, 0); g_void_method = 0; object_windows_application_run(application); assert(g_void_method == run_proc); win16_write_u16(application, 2, 0xfffb); g_error_method = 0; object_windows_application_run(application); assert(g_error_method == error_proc && g_error_argument == 0xfffb); g_idle_result = true; assert(object_windows_application_can_close(application)); assert(g_bool_procedure == can_close); g_idle_result = false; assert(!object_windows_application_can_close(application)); return 0; }