void MCPlatformHandleTextInputQueryTextRect(MCPlatformWindowRef p_window, MCRange p_range, MCRectangle& r_first_line_rect, MCRange& r_actual_range) { if (!MCactivefield) { r_first_line_rect = MCRectangleMake(0, 0, 0, 0); r_actual_range = MCRangeMake(UINDEX_MAX, 0); return; } int32_t t_si, t_ei; t_si = 0; t_ei = INT32_MAX; MCactivefield -> resolvechars(0, t_si, t_ei, p_range . offset, p_range . length); MCRectangle t_rect; t_rect = MCactivefield -> firstRectForCharacterRange(t_si, t_ei); MCactivefield -> unresolvechars(0, t_si, t_ei); MCPoint t_top_left, t_bottom_right; t_top_left = MCactivefield -> getstack() -> stacktowindowloc(MCPointMake(t_rect . x, t_rect . y)); t_bottom_right = MCactivefield -> getstack() -> stacktowindowloc(MCPointMake(t_rect . x + t_rect . width, t_rect . y + t_rect . height)); r_first_line_rect = MCRectangleMake(t_top_left . x, t_top_left . y, t_bottom_right . x - t_top_left . x, t_bottom_right . y - t_top_left . y); r_actual_range = MCRangeMakeMinMax(t_si, t_ei); }
void MCStack::view_update_transform(void) { MCRectangle t_view_rect; MCGAffineTransform t_transform; // IM-2014-01-16: [[ StackScale ]] Use utility method to calculate new values view_calculate_viewports(m_view_requested_stack_rect, m_view_adjusted_stack_rect, t_view_rect, t_transform); // IM-2013-12-20: [[ ShowAll ]] Calculate new stack visible rect MCRectangle t_stack_visible_rect; t_stack_visible_rect = MCRectangleGetTransformedBounds(MCRectangleMake(0, 0, t_view_rect.width, t_view_rect.height), MCGAffineTransformInvert(t_transform)); if (m_view_fullscreenmode == kMCStackFullscreenLetterbox || m_view_fullscreenmode == kMCStackFullscreenNoScale) t_stack_visible_rect = MCU_intersect_rect(t_stack_visible_rect, MCRectangleMake(0, 0, m_view_adjusted_stack_rect.width, m_view_adjusted_stack_rect.height)); // IM-2013-10-03: [[ FullscreenMode ]] if the transform has changed, redraw everything // IM-2013-12-20: [[ ShowAll ]] if the stack viewport has changed, redraw everything if (!MCU_equal_rect(t_stack_visible_rect, m_view_stack_visible_rect) || !MCGAffineTransformIsEqual(t_transform, m_view_transform)) { m_view_transform = t_transform; m_view_stack_visible_rect = t_stack_visible_rect; view_dirty_all(); } // IM-2014-01-16: [[ StackScale ]] Update view rect if needed view_setrect(t_view_rect); }
bool MCX11GetWindowWorkarea(GdkDisplay *p_display, Window p_window, MCRectangle &r_workarea) { x11::Atom t_ret; int t_format, t_status; unsigned long t_count, t_after; unsigned long *t_workarea = nil; x11::Atom XA_CARDINAL = x11::gdk_x11_atom_to_xatom_for_display(p_display, gdk_atom_intern_static_string("CARDINAL")); t_status = x11::XGetWindowProperty(x11::gdk_x11_display_get_xdisplay(p_display), x11::gdk_x11_drawable_get_xid(p_window), x11::gdk_x11_atom_to_xatom_for_display(p_display, MCworkareaatom), 0, 4, False, XA_CARDINAL, &t_ret, &t_format, &t_count, &t_after, (unsigned char**)&t_workarea); bool t_success; t_success = t_status == Success && t_ret == XA_CARDINAL && t_format == 32 && t_count == 4; if (t_success) r_workarea = MCRectangleMake(t_workarea[0], t_workarea[1], t_workarea[2], t_workarea[3]); if (t_workarea != nil) x11::XFree(t_workarea); return t_success; }
bool openpopup(MCNameRef p_kind, const MCPoint &p_at, MCArrayRef p_properties) { if (!createwidget(p_kind, p_properties)) return false; uint32_t t_width = 0; uint32_t t_height = 0; getwidgetgeometry(t_width, t_height); if (MCErrorIsPending()) return false; MCdispatcher -> addmenu(this); m_widget->setrect(MCRectangleMake(0, 0, t_width, t_height)); return ES_NORMAL == openrect(MCRectangleMake(p_at.x, p_at.y, t_width, t_height), WM_POPUP, NULL, WP_ASRECT, OP_NONE); }
MCNativeLayerX11::MCNativeLayerX11(MCObject *p_object, x11::Window p_view) : m_child_window(NULL), m_input_shape(NULL), m_socket(NULL), m_widget_xid(p_view) { m_object = p_object; m_intersect_rect = MCRectangleMake(0,0,0,0); }
void MCStack::device_updatewindow(MCRegionRef p_region) { if (m_window_shape == nil || m_window_shape -> is_sharp) { InvalidateRgn((HWND)window -> handle . window, (HRGN)p_region, FALSE); UpdateWindow((HWND)window -> handle . window); } else { MCRectangle t_device_rect; t_device_rect = MCGRectangleGetIntegerBounds(MCResUserToDeviceRect(MCRectangleMake(0, 0, m_window_shape->width, m_window_shape->height))); HBITMAP t_bitmap = nil; void *t_bits = nil; if (m_window_shape -> handle == nil) { if (!create_temporary_dib(((MCScreenDC*)MCscreen)->getdsthdc(), t_device_rect.width, t_device_rect.height, t_bitmap, t_bits)) return; m_window_shape -> handle = t_bitmap; } else { t_bitmap = (HBITMAP)m_window_shape -> handle; BITMAP t_bitmap_struct; GetObjectA(t_bitmap, sizeof(BITMAP), &t_bitmap_struct); t_bits = t_bitmap_struct.bmBits; } MCGRaster t_raster; t_raster.width = t_device_rect.width; t_raster.height = t_device_rect.height; t_raster.pixels = t_bits; t_raster.stride = t_raster.width * sizeof(uint32_t); t_raster.format = kMCGRasterFormat_ARGB; MCGRaster t_mask; /* UNCHECKED */ MCWin32GetWindowShapeAlphaMask(m_window_shape, t_mask); MCWindowsLayeredStackSurface t_surface(t_raster, &t_mask); if (t_surface.Lock()) { if (s_update_callback == nil) device_redrawwindow(&t_surface, (MCRegionRef)p_region); else s_update_callback(&t_surface, (MCRegionRef)p_region, s_update_context); t_surface.Unlock(); composite(); } } }
void MCStack::view_init(void) { m_view_fullscreen = false; m_view_fullscreenmode = kMCStackFullscreenModeDefault; m_view_adjusted_stack_rect = m_view_requested_stack_rect = m_view_rect = MCRectangleMake(0, 0, 0, 0); m_view_stack_visible_rect = MCRectangleMake(0, 0, 0, 0); // MW-2011-08-26: [[ TileCache ]] Stacks start off with no tilecache. m_view_tilecache = nil; m_view_bg_layer_id = 0; // MW-2011-08-19: [[ Redraw ]] Initialize the view's update region m_view_update_region = nil; m_view_transform = MCGAffineTransformMakeIdentity(); m_view_content_scale = 1.0; // IM-2014-01: [[ HiDPI ]] Initialize the view backing surface scale m_view_backing_scale = 1.0; }
void MCStack::view_configure(bool p_user) { MCRectangle t_view_rect; mode_getrealrect(t_view_rect); // IM-2014-09-23: [[ Bug 13349 ]] If window geometry change occurs while there's a pending resize // then use the requested rect rather than the new one. if (m_view_need_resize) t_view_rect = m_view_rect; if (!MCU_equal_rect(t_view_rect, m_view_rect)) { // IM-2014-02-13: [[ StackScale ]] Test if the view size has changed bool t_resize; t_resize = t_view_rect.width != m_view_rect.width || t_view_rect.height != m_view_rect.height; m_view_rect = t_view_rect; view_on_rect_changed(); if (view_getfullscreen()) { // IM-2014-01-16: [[ StackScale ]] recalculate fullscreenmode transform after view rect change view_update_transform(); } else { uint32_t t_current_width, t_current_height; t_current_width = m_view_adjusted_stack_rect.width; t_current_height = m_view_adjusted_stack_rect.height; // IM-2014-01-16: [[ StackScale ]] set the stack rects to the scaled down view rect m_view_requested_stack_rect = m_view_adjusted_stack_rect = MCRectangleGetTransformedBounds(m_view_rect, MCGAffineTransformInvert(m_view_transform)); // IM-2014-02-13: [[ StackScale ]] If the view size has not changed then make sure // the stack size also remains the same if (!t_resize) { //restore current logical width & height m_view_requested_stack_rect.width = m_view_adjusted_stack_rect.width = t_current_width; m_view_requested_stack_rect.height = m_view_adjusted_stack_rect.height = t_current_height; } // IM-2014-02-06: [[ ShowAll ]] Update the visible stack rect m_view_stack_visible_rect = MCRectangleMake(0, 0, m_view_adjusted_stack_rect.width, m_view_adjusted_stack_rect.height); } } configure(p_user); }
void MCStack::view_updatetilecacheviewport(void) { if (m_view_tilecache == nil) return; // IM-2013-10-02: [[ FullscreenMode ]] Use view rect when setting the size of the tilecache // IM-2013-10-10: [[ FullscreenMode ]] Align tilecache viewport to origin // IM-2014-01-24: [[ HiDPI ]] Set tilecache viewport in backing surface coords MCRectangle t_view_rect; t_view_rect = MCRectangleMake(0, 0, m_view_rect.width, m_view_rect.height); MCRectangle t_surface_rect; t_surface_rect = MCRectangleGetScaledBounds(t_view_rect, view_getbackingscale()); MCTileCacheSetViewport(m_view_tilecache, t_surface_rect); }
// IM-2014-01-29: [[ HiDPI ]] Refactored to handle display info caching in MCUIDC superclass bool MCScreenDC::device_getdisplays(bool p_effective, MCDisplay * &r_displays, uint32_t &r_display_count) { // NOTE: this code assumes that there is only one GdkScreen! GdkScreen *t_screen; t_screen = gdk_display_get_default_screen(dpy); // Get the number of monitors attached to this screen gint t_monitor_count; t_monitor_count = gdk_screen_get_n_monitors(t_screen); // Allocate the list of monitors MCDisplay *t_displays; MCMemoryNewArray(t_monitor_count, t_displays); // Get the geometry of each monitor for (gint i = 0; i < t_monitor_count; i++) { GdkRectangle t_rect; gdk_screen_get_monitor_geometry(t_screen, i, &t_rect); MCRectangle t_mc_rect; t_mc_rect = MCRectangleMake(t_rect.x, t_rect.y, t_rect.width, t_rect.height); t_displays[i].index = i; t_displays[i].pixel_scale = 1.0; t_displays[i].viewport = t_displays[i].workarea = t_mc_rect; } if (t_monitor_count == 1) { apply_workarea(t_displays, t_monitor_count) || apply_partial_struts(t_displays, t_monitor_count); } else { apply_partial_struts(t_displays, t_monitor_count); } // All done r_displays = t_displays; r_display_count = t_monitor_count; return true; }
void MCStack::composite(void) { if (m_window_shape == nil || m_window_shape -> is_sharp || m_window_shape -> handle == nil) return; POINT t_offset; POINT t_location; SIZE t_size; HDC t_dst_dc; t_dst_dc = ((MCScreenDC *)MCscreen) -> getdsthdc(); HGDIOBJ t_old_dst; HBITMAP t_bitmap; t_bitmap = (HBITMAP)m_window_shape -> handle; t_old_dst = SelectObject(t_dst_dc, t_bitmap); MCRectangle t_device_stack_rect; t_device_stack_rect = MCGRectangleGetIntegerInterior(MCResUserToDeviceRect(rect)); MCRectangle t_device_shape_rect; t_device_shape_rect = MCGRectangleGetIntegerBounds(MCResUserToDeviceRect(MCRectangleMake(0, 0, m_window_shape->width, m_window_shape->height))); t_offset . x = 0; t_offset . y = 0; t_location . x = t_device_stack_rect . x; t_location . y = t_device_stack_rect . y; t_size . cx = t_device_shape_rect . width;; t_size . cy = t_device_shape_rect . height; BLENDFUNCTION t_blend; t_blend . BlendOp = AC_SRC_OVER; t_blend . BlendFlags = 0; t_blend . SourceConstantAlpha = blendlevel * 255 / 100; t_blend . AlphaFormat = AC_SRC_ALPHA; UpdateLayeredWindow((HWND)window -> handle . window, t_dst_dc, &t_location, &t_size, t_dst_dc, &t_offset, 0, &t_blend, ULW_ALPHA); SelectObject(t_dst_dc, t_old_dst); }
// IM-2013-10-14: [[ FullscreenMode ]] Move update region tracking into view abstraction void MCStack::view_dirty_rect(const MCRectangle &p_rect) { MCRectangle t_view_rect; t_view_rect = MCRectangleMake(0, 0, m_view_rect.width, m_view_rect.height); MCRectangle t_dirty_rect; t_dirty_rect = MCU_intersect_rect(p_rect, t_view_rect); if (t_dirty_rect.width == 0 || t_dirty_rect.height == 0) return; // If there is no region yet, make one. if (m_view_update_region == nil) /* UNCHECKED */ MCRegionCreate(m_view_update_region); MCRegionIncludeRect(m_view_update_region, t_dirty_rect); // Mark the stack as needing a redraw and schedule an update. m_view_need_redraw = true; MCRedrawScheduleUpdateForStack(this); }
// IM-2013-10-14: [[ FullscreenMode ]] Move update region tracking into view abstraction void MCStack::view_dirty_all(void) { view_dirty_rect(MCRectangleMake(0, 0, m_view_rect.width, m_view_rect.height)); dirtyall(); }
MCRectangle MCStack::view_platform_setgeom(const MCRectangle &p_rect) { return MCRectangleMake(0,0,0,0); }
void MCStack::view_update_transform(bool p_ensure_onscreen) { MCRectangle t_view_rect; MCGAffineTransform t_transform; #if defined(_MOBILE) MCOrientation t_orientation; MCSystemGetOrientation(t_orientation); MCOrientationGetRectForOrientation(t_orientation ,m_view_requested_stack_rect); #endif // IM-2014-01-16: [[ StackScale ]] Use utility method to calculate new values view_calculate_viewports(m_view_requested_stack_rect, m_view_adjusted_stack_rect, t_view_rect, t_transform); // IM-2013-12-20: [[ ShowAll ]] Calculate new stack visible rect MCRectangle t_stack_visible_rect; t_stack_visible_rect = MCRectangleGetTransformedBounds(MCRectangleMake(0, 0, t_view_rect.width, t_view_rect.height), MCGAffineTransformInvert(t_transform)); if (m_view_fullscreenmode == kMCStackFullscreenLetterbox || m_view_fullscreenmode == kMCStackFullscreenNoScale) t_stack_visible_rect = MCU_intersect_rect(t_stack_visible_rect, MCRectangleMake(0, 0, m_view_adjusted_stack_rect.width, m_view_adjusted_stack_rect.height)); // IM-2013-10-03: [[ FullscreenMode ]] if the transform has changed, redraw everything // IM-2013-12-20: [[ ShowAll ]] if the stack viewport has changed, redraw everything bool t_rect_changed, t_transform_changed; t_rect_changed = !MCU_equal_rect(t_stack_visible_rect, m_view_stack_visible_rect); t_transform_changed = !MCGAffineTransformIsEqual(t_transform, m_view_transform); if (t_rect_changed || t_transform_changed) { m_view_transform = t_transform; m_view_stack_visible_rect = t_stack_visible_rect; dirtyall(); if (t_transform_changed) this->OnViewTransformChanged(); } // PM-2015-07-17: [[ Bug 13754 ]] Make sure stack does not disappear off screen when changing the scalefactor MCRectangle t_bounded_rect; if (p_ensure_onscreen) { // AL-2015-10-01: [[ Bug 16017 ]] Remember location of stacks on a second monitor const MCDisplay* t_nearest_display; t_nearest_display = MCscreen -> getnearestdisplay(t_view_rect); if (t_nearest_display != nil) { MCRectangle t_screen_rect; t_screen_rect = t_nearest_display -> viewport; t_bounded_rect = MCU_bound_rect(t_view_rect, t_screen_rect . x, t_screen_rect . y, t_screen_rect . width, t_screen_rect . height); } else { // In noUI mode, we don't have a nearest display. t_bounded_rect = MCU_bound_rect(t_view_rect, 0, 0, MCscreen -> getwidth(), MCscreen -> getheight()); } } else { t_bounded_rect = t_view_rect; } // IM-2014-01-16: [[ StackScale ]] Update view rect if needed view_setrect(t_bounded_rect); }
static inline MCRectangle MCWinRectToMCRect(RECT p_rect) { return MCRectangleMake(p_rect.left, p_rect.top, p_rect.right - p_rect.left, p_rect.bottom - p_rect.top); }