#include "../tdkpin_window_placement.h" #include #include #include #include enum { WINDOW_HANDLE = 4, WINDOW_PARENT = 6, WINDOW_FLAGS = 0x16, WINDOW_ATTRIBUTES = 0x21, WINDOW_X = 0x29, WINDOW_Y = 0x2b, WINDOW_WIDTH = 0x2d, WINDOW_HEIGHT = 0x2f, WINDOW_ATTACHED = 0x3b, }; static uint8_t g_dgroup[0x1000]; static uint8_t g_objects[0x1000]; static Win16FarPtr g_window; static Win16FarPtr g_parent; static Win16FarPtr g_client; static Win16FarPtr g_attached; static Win16FarPtr g_parent_getter; static Win16FarPtr g_attached_setup; static Win16FarPtr g_client_result; static bool g_iconic; static bool g_zoomed; static RECT16 g_native_rectangle; static unsigned g_is_iconic_calls; static unsigned g_is_zoomed_calls; static unsigned g_get_rect_calls; static unsigned g_screen_to_client_calls; static HWND16 g_screen_to_client_window; static POINT16 g_client_delta; static unsigned g_prepare_calls; static unsigned g_flag_calls; static unsigned g_focus_calls; static HWND16 g_focused_window; static unsigned g_parent_getter_calls; static unsigned g_attached_setup_calls; static Win16FarPtr object_at(uint16_t offset) { return win16_make_far_pointer(0x6000, offset); } static Win16FarPtr dgroup_at(uint16_t offset) { return win16_make_far_pointer(0x5000, offset); } static void write_far(Win16FarPtr base, uint16_t offset, Win16FarPtr value) { win16_write_u32(base, offset, value); } static void reset_fixture(void) { memset(g_objects, 0, sizeof(g_objects)); memset(g_dgroup, 0, sizeof(g_dgroup)); g_window = object_at(0x100); g_parent = object_at(0x200); g_client = object_at(0x300); g_attached = object_at(0x400); g_parent_getter = win16_make_far_pointer(0x7000, 0x1234); g_attached_setup = win16_make_far_pointer(0x7000, 0x5678); win16_write_u16(g_parent, 0, 0x0100); win16_write_u16(g_attached, 0, 0x0200); write_far(dgroup_at(0x0100), 0x30, g_parent_getter); write_far(dgroup_at(0x0200), 0x10, g_attached_setup); win16_write_u16(g_window, WINDOW_HANDLE, 0x1111); win16_write_u16(g_parent, WINDOW_HANDLE, 0x2222); win16_write_u16(g_client, WINDOW_HANDLE, 0x3333); g_native_rectangle = (RECT16){10, 20, 110, 220}; g_client_delta = (POINT16){3, 5}; g_client_result = 0; g_iconic = false; g_zoomed = false; g_is_iconic_calls = 0; g_is_zoomed_calls = 0; g_get_rect_calls = 0; g_screen_to_client_calls = 0; g_screen_to_client_window = 0; g_prepare_calls = 0; g_flag_calls = 0; g_focus_calls = 0; g_focused_window = 0; g_parent_getter_calls = 0; g_attached_setup_calls = 0; } BOOL16 IsIconic16(HWND16 window) { assert(window == 0x1111); g_is_iconic_calls++; return g_iconic; } BOOL16 IsZoomed16(HWND16 window) { assert(window == 0x1111); g_is_zoomed_calls++; return g_zoomed; } BOOL16 GetWindowRect16(HWND16 window, Win16FarPtr rectangle) { assert(window == 0x1111); win16_write_u16(rectangle, 0, (uint16_t)g_native_rectangle.left); win16_write_u16(rectangle, 2, (uint16_t)g_native_rectangle.top); win16_write_u16(rectangle, 4, (uint16_t)g_native_rectangle.right); win16_write_u16(rectangle, 6, (uint16_t)g_native_rectangle.bottom); g_get_rect_calls++; return 1; } BOOL16 ScreenToClient16(HWND16 window, Win16FarPtr point) { int16_t x = (int16_t)win16_read_u16(point); int16_t y = (int16_t)win16_read_u16(win16_far_add_offset(point, 2)); win16_write_u16(point, 0, (uint16_t)(x - g_client_delta.x)); win16_write_u16(point, 2, (uint16_t)(y - g_client_delta.y)); g_screen_to_client_window = window; g_screen_to_client_calls++; return 1; } bool object_windows_has_flags(Win16FarPtr object, uint8_t mask) { assert(object == g_window && mask == 8); g_flag_calls++; return (win16_read_u8( win16_far_add_offset(object, WINDOW_FLAGS)) & mask) == mask; } Win16FarPtr win16_call_object_far_method( Win16FarPtr procedure, Win16FarPtr object) { assert(procedure == g_parent_getter && object == g_parent); g_parent_getter_calls++; return g_client_result; } void object_windows_prepare_window(Win16FarPtr window) { assert(window == g_window); g_prepare_calls++; } HWND16 SetFocus16(HWND16 window) { g_focused_window = window; g_focus_calls++; return 0x9999; } void win16_call_object_method( Win16FarPtr procedure, Win16FarPtr object) { assert(procedure == g_attached_setup && object == g_attached); g_attached_setup_calls++; } static void assert_placement( int16_t x, int16_t y, uint16_t width, uint16_t height) { assert((int16_t)win16_read_u16( win16_far_add_offset(g_window, WINDOW_X)) == x); assert((int16_t)win16_read_u16( win16_far_add_offset(g_window, WINDOW_Y)) == y); assert(win16_read_u16( win16_far_add_offset(g_window, WINDOW_WIDTH)) == width); assert(win16_read_u16( win16_far_add_offset(g_window, WINDOW_HEIGHT)) == height); } static void test_minimized_and_maximized_skip(void) { reset_fixture(); win16_write_u16(g_window, WINDOW_X, 0xaaaa); win16_write_u16(g_window, WINDOW_Y, 0xbbbb); win16_write_u16(g_window, WINDOW_WIDTH, 0xcccc); win16_write_u16(g_window, WINDOW_HEIGHT, 0xdddd); g_iconic = true; object_windows_capture_normal_placement(g_window); assert(g_is_iconic_calls == 1 && g_is_zoomed_calls == 0); assert(g_get_rect_calls == 0); assert_placement( (int16_t)0xaaaa, (int16_t)0xbbbb, 0xcccc, 0xdddd); g_iconic = false; g_zoomed = true; object_windows_capture_normal_placement(g_window); assert(g_is_iconic_calls == 2 && g_is_zoomed_calls == 1); assert(g_get_rect_calls == 0); } static void test_screen_and_parent_coordinates(void) { reset_fixture(); object_windows_capture_normal_placement(g_window); assert(g_get_rect_calls == 1 && g_screen_to_client_calls == 0); assert_placement(10, 20, 100, 200); reset_fixture(); write_far(g_window, WINDOW_PARENT, g_parent); g_client_result = g_client; win16_write_u8(win16_far_add_offset(g_window, WINDOW_FLAGS), 8); object_windows_capture_normal_placement(g_window); assert(g_parent_getter_calls == 1 && g_flag_calls == 1); assert(g_screen_to_client_calls == 1); assert(g_screen_to_client_window == 0x3333); assert_placement(7, 15, 100, 200); reset_fixture(); write_far(g_window, WINDOW_PARENT, g_parent); g_client_result = 0; win16_write_u32(g_window, WINDOW_ATTRIBUTES, 0x40000000U); object_windows_capture_normal_placement(g_window); assert(g_parent_getter_calls == 1 && g_flag_calls == 0); assert(g_screen_to_client_window == 0x2222); assert_placement(7, 15, 100, 200); reset_fixture(); write_far(g_window, WINDOW_PARENT, g_parent); g_client_result = g_client; object_windows_capture_normal_placement(g_window); assert(g_flag_calls == 1 && g_screen_to_client_calls == 0); assert_placement(10, 20, 100, 200); } static void test_setup_sequence(void) { reset_fixture(); win16_write_u8(win16_far_add_offset(g_window, WINDOW_FLAGS), 8); write_far(g_window, WINDOW_ATTACHED, g_attached); object_windows_setup_window(g_window); assert(g_prepare_calls == 1 && g_flag_calls == 1); assert(g_focus_calls == 1 && g_focused_window == 0x1111); assert(g_attached_setup_calls == 1); assert(g_get_rect_calls == 1); assert_placement(10, 20, 100, 200); reset_fixture(); object_windows_setup_window(g_window); assert(g_prepare_calls == 1 && g_flag_calls == 1); assert(g_focus_calls == 0 && g_attached_setup_calls == 0); assert(g_get_rect_calls == 1); } int main(void) { uint8_t stack_marker; uintptr_t stack_base = (uintptr_t)&stack_marker - 0x8000; win16_reset_segment_bindings(); win16_bind_segment(0x5000, g_dgroup, sizeof(g_dgroup), true); win16_bind_segment(0x6000, g_objects, sizeof(g_objects), true); win16_bind_segment(0x9000, (void *)stack_base, 0x10000, true); win16_set_dgroup_selector(0x5000); test_minimized_and_maximized_skip(); test_screen_and_parent_coordinates(); test_setup_sequence(); return 0; }