static void get_min_bounds(win_window_info *window, RECT *bounds, int constrain) { INT32 minwidth, minheight; assert(GetCurrentThreadId() == window_threadid); // get the minimum target size render_target_get_minimum_size(window->target, &minwidth, &minheight); // expand to our minimum dimensions if (minwidth < MIN_WINDOW_DIM) minwidth = MIN_WINDOW_DIM; if (minheight < MIN_WINDOW_DIM) minheight = MIN_WINDOW_DIM; // account for extra window stuff minwidth += wnd_extra_width(window); minheight += wnd_extra_height(window); // if we want it constrained, figure out which one is larger if (constrain) { RECT test1, test2; // first constrain with no height limit test1.top = test1.left = 0; test1.right = minwidth; test1.bottom = 10000; constrain_to_aspect_ratio(window, &test1, WMSZ_BOTTOMRIGHT); // then constrain with no width limit test2.top = test2.left = 0; test2.right = 10000; test2.bottom = minheight; constrain_to_aspect_ratio(window, &test2, WMSZ_BOTTOMRIGHT); // pick the larger if (rect_width(&test1) > rect_width(&test2)) { minwidth = rect_width(&test1); minheight = rect_height(&test1); } else { minwidth = rect_width(&test2); minheight = rect_height(&test2); } } // get the window rect GetWindowRect(window->hwnd, bounds); // now adjust bounds->right = bounds->left + minwidth; bounds->bottom = bounds->top + minheight; }
osd_dim sdl_window_info::get_min_bounds(int constrain) { INT32 minwidth, minheight; //assert(GetCurrentThreadId() == window_threadid); // get the minimum target size m_target->compute_minimum_size(minwidth, minheight); // expand to our minimum dimensions if (minwidth < MIN_WINDOW_DIM) minwidth = MIN_WINDOW_DIM; if (minheight < MIN_WINDOW_DIM) minheight = MIN_WINDOW_DIM; // account for extra window stuff minwidth += wnd_extra_width(); minheight += wnd_extra_height(); // if we want it constrained, figure out which one is larger if (constrain) { // first constrain with no height limit osd_rect test1(0,0,minwidth,10000); test1 = constrain_to_aspect_ratio(test1, WMSZ_BOTTOMRIGHT); // then constrain with no width limit osd_rect test2(0,0,10000,minheight); test2 = constrain_to_aspect_ratio(test2, WMSZ_BOTTOMRIGHT); // pick the larger if (test1.width() > test2.width()) { minwidth = test1.width(); minheight = test1.height(); } else { minwidth = test2.width(); minheight = test2.height(); } } // remove extra window stuff minwidth -= wnd_extra_width(); minheight -= wnd_extra_height(); return osd_dim(minwidth, minheight); }
static void get_max_bounds(sdl_window_info *window, int *window_width, int *window_height, int constrain) { INT32 maxwidth, maxheight; // compute the maximum client area maxwidth = window->monitor->center_width; maxheight = window->monitor->center_height; // clamp to the window's max if (window->maxwidth != 0) { int temp = window->maxwidth + WINDOW_DECORATION_WIDTH; if (temp < maxwidth) maxwidth = temp; } if (window->maxheight != 0) { int temp = window->maxheight + WINDOW_DECORATION_HEIGHT; if (temp < maxheight) maxheight = temp; } // constrain to fit if (constrain) constrain_to_aspect_ratio(window, &maxwidth, &maxheight, WMSZ_BOTTOMRIGHT); //else { maxwidth -= WINDOW_DECORATION_WIDTH; maxheight -= WINDOW_DECORATION_HEIGHT; *window_width = maxwidth; *window_height = maxheight; } }
osd_dim sdl_window_info::get_max_bounds(int constrain) { //assert(GetCurrentThreadId() == window_threadid); // compute the maximum client area // m_monitor->refresh(); osd_rect maximum = m_monitor->usuable_position_size(); // clamp to the window's max int tempw = maximum.width(); int temph = maximum.height(); if (m_win_config.width != 0) { int temp = m_win_config.width + wnd_extra_width(); if (temp < maximum.width()) tempw = temp; } if (m_win_config.height != 0) { int temp = m_win_config.height + wnd_extra_height(); if (temp < maximum.height()) temph = temp; } maximum = maximum.resize(tempw, temph); // constrain to fit if (constrain) maximum = constrain_to_aspect_ratio(maximum, WMSZ_BOTTOMRIGHT); else { maximum = maximum.resize(maximum.width() - wnd_extra_width(), maximum.height() - wnd_extra_height()); } return maximum.dim(); }
static void get_min_bounds(sdl_window_info *window, int *window_width, int *window_height, int constrain) { INT32 minwidth, minheight; // get the minimum target size window->target->compute_minimum_size(minwidth, minheight); // expand to our minimum dimensions if (minwidth < MIN_WINDOW_DIM) minwidth = MIN_WINDOW_DIM; if (minheight < MIN_WINDOW_DIM) minheight = MIN_WINDOW_DIM; // if we want it constrained, figure out which one is larger if (constrain) { int test1w, test1h; int test2w, test2h; // first constrain with no height limit test1w = minwidth; test1h = 10000; constrain_to_aspect_ratio(window, &test1w, &test1h, WMSZ_BOTTOMRIGHT); // then constrain with no width limit test2w = 10000; test2h = minheight; constrain_to_aspect_ratio(window, &test2w, &test2h, WMSZ_BOTTOMRIGHT); // pick the larger if ( test1w > test2w ) { minwidth = test1w; minheight = test1h; } else { minwidth = test2w; minheight = test2h; } } *window_width = minwidth; *window_height = minheight; }
static void adjust_window_position_after_major_change(win_window_info *window) { RECT oldrect, newrect; assert(GetCurrentThreadId() == window_threadid); // get the current size GetWindowRect(window->hwnd, &oldrect); // adjust the window size so the client area is what we want if (!window->fullscreen) { // constrain the existing size to the aspect ratio newrect = oldrect; if (video_config.keepaspect) constrain_to_aspect_ratio(window, &newrect, WMSZ_BOTTOMRIGHT); } // in full screen, make sure it covers the primary display else { win_monitor_info *monitor = winwindow_video_window_monitor(window, NULL); newrect = monitor->info.rcMonitor; } // adjust the position if different if (oldrect.left != newrect.left || oldrect.top != newrect.top || oldrect.right != newrect.right || oldrect.bottom != newrect.bottom) SetWindowPos(window->hwnd, window->fullscreen ? HWND_TOPMOST : HWND_TOP, newrect.left, newrect.top, rect_width(&newrect), rect_height(&newrect), 0); // take note of physical window size (used for lightgun coordinate calculation) if (window == win_window_list) { win_physical_width = rect_width(&newrect); win_physical_height = rect_height(&newrect); logerror("Physical width %d, height %d\n",win_physical_width,win_physical_height); } // update the cursor state winwindow_update_cursor_state(); }
static void get_max_bounds(win_window_info *window, RECT *bounds, int constrain) { RECT maximum; assert(GetCurrentThreadId() == window_threadid); // compute the maximum client area winvideo_monitor_refresh(window->monitor); maximum = window->monitor->info.rcWork; // clamp to the window's max if (window->maxwidth != 0) { int temp = window->maxwidth + wnd_extra_width(window); if (temp < rect_width(&maximum)) maximum.right = maximum.left + temp; } if (window->maxheight != 0) { int temp = window->maxheight + wnd_extra_height(window); if (temp < rect_height(&maximum)) maximum.bottom = maximum.top + temp; } // constrain to fit if (constrain) constrain_to_aspect_ratio(window, &maximum, WMSZ_BOTTOMRIGHT); else { maximum.right -= wnd_extra_width(window); maximum.bottom -= wnd_extra_height(window); } // center within the work area bounds->left = window->monitor->info.rcWork.left + (rect_width(&window->monitor->info.rcWork) - rect_width(&maximum)) / 2; bounds->top = window->monitor->info.rcWork.top + (rect_height(&window->monitor->info.rcWork) - rect_height(&maximum)) / 2; bounds->right = bounds->left + rect_width(&maximum); bounds->bottom = bounds->top + rect_height(&maximum); }
LRESULT CALLBACK winwindow_video_window_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam) { LONG_PTR ptr = GetWindowLongPtr(wnd, GWLP_USERDATA); win_window_info *window = (win_window_info *)ptr; // we may get called before SetWindowLongPtr is called if (window != NULL) { assert(GetCurrentThreadId() == window_threadid); update_minmax_state(window); } // handle a few messages switch (message) { // paint: redraw the last bitmap case WM_PAINT: { PAINTSTRUCT pstruct; HDC hdc = BeginPaint(wnd, &pstruct); draw_video_contents(window, hdc, TRUE); if (win_has_menu(window)) DrawMenuBar(window->hwnd); EndPaint(wnd, &pstruct); break; } // non-client paint: punt if full screen case WM_NCPAINT: if (!window->fullscreen || HAS_WINDOW_MENU) return DefWindowProc(wnd, message, wparam, lparam); break; // input: handle the raw mouse input case WM_INPUT: if (win_use_raw_mouse) win_raw_mouse_update((HRAWINPUT)lparam); break; // syskeys - ignore case WM_SYSKEYUP: case WM_SYSKEYDOWN: break; // pause the system when we start a menu or resize case WM_ENTERSIZEMOVE: window->resize_state = RESIZE_STATE_RESIZING; case WM_ENTERMENULOOP: winwindow_ui_pause_from_window_thread(TRUE); break; // unpause the system when we stop a menu or resize and force a redraw case WM_EXITSIZEMOVE: window->resize_state = RESIZE_STATE_PENDING; case WM_EXITMENULOOP: winwindow_ui_pause_from_window_thread(FALSE); InvalidateRect(wnd, NULL, FALSE); break; // get min/max info: set the minimum window size case WM_GETMINMAXINFO: { MINMAXINFO *minmax = (MINMAXINFO *)lparam; minmax->ptMinTrackSize.x = MIN_WINDOW_DIM; minmax->ptMinTrackSize.y = MIN_WINDOW_DIM; break; } // sizing: constrain to the aspect ratio unless control key is held down case WM_SIZING: { RECT *rect = (RECT *)lparam; if (video_config.keepaspect && !(GetAsyncKeyState(VK_CONTROL) & 0x8000)) constrain_to_aspect_ratio(window, rect, wparam); InvalidateRect(wnd, NULL, FALSE); break; } // syscommands: catch win_start_maximized case WM_SYSCOMMAND: { // prevent screensaver or monitor power events if (wparam == SC_MONITORPOWER || wparam == SC_SCREENSAVE) return 1; // most SYSCOMMANDs require us to invalidate the window InvalidateRect(wnd, NULL, FALSE); // handle maximize if ((wparam & 0xfff0) == SC_MAXIMIZE) { update_minmax_state(window); if (window->ismaximized) minimize_window(window); else maximize_window(window); break; } return DefWindowProc(wnd, message, wparam, lparam); } // track whether we are in the foreground case WM_ACTIVATEAPP: in_background = !wparam; break; // close: cause MAME to exit case WM_CLOSE: if (multithreading_enabled) PostThreadMessage(main_threadid, WM_USER_REQUEST_EXIT, 0, 0); else mame_schedule_exit(Machine); break; // destroy: clean up all attached rendering bits and NULL out our hwnd case WM_DESTROY: (*draw.window_destroy)(window); window->hwnd = NULL; return DefWindowProc(wnd, message, wparam, lparam); // self redraw: draw ourself in a non-painty way case WM_USER_REDRAW: { HDC hdc = GetDC(wnd); mtlog_add("winwindow_video_window_proc: WM_USER_REDRAW begin"); window->primlist = (const render_primitive_list *)lparam; draw_video_contents(window, hdc, FALSE); mtlog_add("winwindow_video_window_proc: WM_USER_REDRAW end"); ReleaseDC(wnd, hdc); break; } // self destruct case WM_USER_SELF_TERMINATE: DestroyWindow(window->hwnd); break; // fullscreen set case WM_USER_SET_FULLSCREEN: set_fullscreen(window, wparam); break; // minimum size set case WM_USER_SET_MINSIZE: minimize_window(window); break; // maximum size set case WM_USER_SET_MAXSIZE: maximize_window(window); break; // set focus: if we're not the primary window, switch back // commented out ATM because this prevents us from resizing secondary windows // case WM_SETFOCUS: // if (window != win_window_list && win_window_list != NULL) // SetFocus(win_window_list->hwnd); // break; // everything else: defaults default: return DefWindowProc(wnd, message, wparam, lparam); } return 0; }