diff --git a/debian/changelog b/debian/changelog index 8f01a32..6a7998c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +steamos-compositor (1.30) brewmaster; urgency=medium + + * Added preliminary support for screen magnification. + * Increase cursor hiding time to 10 seconds. + * Fix bug while cursor would hide even when moving the mouse if a button was + held. + + -- Pierre-Loup A. Griffais Wed, 02 Sep 2015 16:22:38 -0700 + steamos-compositor (1.29) brewmaster; urgency=medium * Tweaking focus and display logic in steamcompmgr to avoid event storms on newer diff --git a/loadargb_cursor b/loadargb_cursor new file mode 100755 index 0000000..723a29b Binary files /dev/null and b/loadargb_cursor differ diff --git a/src/steamcompmgr.c b/src/steamcompmgr.c index 3009fb0..6d4529b 100644 --- a/src/steamcompmgr.c +++ b/src/steamcompmgr.c @@ -147,6 +147,8 @@ Bool gameFocused; unsigned int gamesRunningCount; +float overscanScaleRatio = 1.0; +float zoomScaleRatio = 1.0; float globalScaleRatio = 1.0f; Bool focusedWindowNeedsScale; @@ -168,7 +170,7 @@ Bool focusDirty = False; unsigned long damageSequence = 0; -#define CURSOR_HIDE_TIME 3000 +#define CURSOR_HIDE_TIME 10000 Bool gotXError = False; @@ -183,6 +185,7 @@ static Atom steamAtom; static Atom gameAtom; static Atom overlayAtom; static Atom gamesRunningAtom; +static Atom screenZoomAtom; static Atom screenScaleAtom; static Atom opacityAtom; static Atom winTypeAtom; @@ -208,6 +211,7 @@ GLXContext glContext; #define OVERLAY_PROP "STEAM_OVERLAY" #define GAMES_RUNNING_PROP "STEAM_GAMES_RUNNING" #define SCREEN_SCALE_PROP "STEAM_SCREEN_SCALE" +#define SCREEN_MAGNIFICATION_PROP "STEAM_SCREEN_MAGNIFICATION" #define TRANSLUCENT 0x00000000 #define OPAQUE 0xffffffff @@ -514,6 +518,54 @@ ensure_win_resources (Display *dpy, win *w) } } +static void +apply_cursor_state (Display *dpy) +{ + Bool newCursorVisibility = True; + + if (hideCursorForScale || hideCursorForMovement) + newCursorVisibility = False; + + if (newCursorVisibility != cursorVisible) + { + cursorVisible = newCursorVisibility; + + if (cursorVisible) + XFixesShowCursor(dpy, DefaultRootWindow(dpy)); + else + XFixesHideCursor(dpy, DefaultRootWindow(dpy)); + } +} + +static void +handle_mouse_movement(Display *dpy, int posX, int posY) +{ + // Some stuff likes to warp in-place + if (cursorX == posX && cursorY == posY) + return; + + cursorX = posX; + cursorY = posY; + + win *w = find_win(dpy, currentFocusWindow); + + if (w && focusedWindowNeedsScale && gameFocused) + { + w->damaged = 1; + } + + // Ignore the first events as it's likely to be non-user-initiated warps + // Account for one warp from us, one warp from the app and one warp from + // the toolkit. + if (w && (w->mouseMoved++ < 3)) + return; + + lastCursorMovedTime = get_time_in_milliseconds(); + + hideCursorForMovement = False; + apply_cursor_state(dpy); +} + static void paint_fake_cursor (Display *dpy, win *w) { @@ -528,6 +580,8 @@ paint_fake_cursor (Display *dpy, win *w) &child, &root_x, &root_y, &win_x, &win_y, &mask_return); + handle_mouse_movement( dpy, root_x, root_y ); + // Also need new texture if (cursorImageDirty) { @@ -561,6 +615,12 @@ paint_fake_cursor (Display *dpy, win *w) scaledCursorX = (win_x - w->a.x) * cursorScaleRatio * globalScaleRatio + cursorOffsetX; scaledCursorY = (win_y - w->a.y) * cursorScaleRatio * globalScaleRatio + cursorOffsetY; + if ( zoomScaleRatio != 1.0 ) + { + scaledCursorX += ((w->a.width / 2) - win_x) * cursorScaleRatio * globalScaleRatio; + scaledCursorY += ((w->a.height / 2) - win_y) * cursorScaleRatio * globalScaleRatio; + } + glEnable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, cursorTextureName); glEnable(GL_TEXTURE_2D); @@ -652,6 +712,12 @@ paint_window (Display *dpy, win *w, Bool doBlend, Bool notificationMode) drawXOffset = (root_width - sourceWidth * currentScaleRatio) / 2.0f; drawYOffset = (root_height - sourceHeight * currentScaleRatio) / 2.0f; + if ( zoomScaleRatio != 1.0 ) + { + drawXOffset += ((sourceWidth / 2) - cursorX) * currentScaleRatio; + drawYOffset += ((sourceHeight / 2) - cursorY) * currentScaleRatio; + } + isScaling = True; } @@ -1008,25 +1074,6 @@ paint_all (Display *dpy) } } -static void -apply_cursor_state (Display *dpy) -{ - Bool newCursorVisibility = True; - - if (hideCursorForScale || hideCursorForMovement) - newCursorVisibility = False; - - if (newCursorVisibility != cursorVisible) - { - cursorVisible = newCursorVisibility; - - if (cursorVisible) - XFixesShowCursor(dpy, DefaultRootWindow(dpy)); - else - XFixesHideCursor(dpy, DefaultRootWindow(dpy)); - } -} - static void setup_pointer_barriers (Display *dpy) { @@ -1852,6 +1899,7 @@ main (int argc, char **argv) opacityAtom = XInternAtom (dpy, OPACITY_PROP, False); gamesRunningAtom = XInternAtom (dpy, GAMES_RUNNING_PROP, False); screenScaleAtom = XInternAtom (dpy, SCREEN_SCALE_PROP, False); + screenZoomAtom = XInternAtom (dpy, SCREEN_MAGNIFICATION_PROP, False); winTypeAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE", False); winDesktopAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False); winDockAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DOCK", False); @@ -1980,7 +2028,10 @@ main (int argc, char **argv) apply_cursor_state(dpy); gamesRunningCount = get_prop(dpy, root, gamesRunningAtom, 0); - globalScaleRatio = get_prop(dpy, root, screenScaleAtom, 0xFFFFFFFF) / (double)0xFFFFFFFF; + overscanScaleRatio = get_prop(dpy, root, screenScaleAtom, 0xFFFFFFFF) / (double)0xFFFFFFFF; + zoomScaleRatio = get_prop(dpy, root, screenZoomAtom, 0xFFFF) / (double)0xFFFF; + + globalScaleRatio = overscanScaleRatio * zoomScaleRatio; determine_and_apply_focus(dpy); @@ -2137,7 +2188,22 @@ main (int argc, char **argv) } if (ev.xproperty.atom == screenScaleAtom) { - globalScaleRatio = get_prop(dpy, root, screenScaleAtom, 0xFFFFFFFF) / (double)0xFFFFFFFF; + overscanScaleRatio = get_prop(dpy, root, screenScaleAtom, 0xFFFFFFFF) / (double)0xFFFFFFFF; + + globalScaleRatio = overscanScaleRatio * zoomScaleRatio; + + win *w; + + if (w = find_win(dpy, currentFocusWindow)) + w->damaged = 1; + + focusDirty = True; + } + if (ev.xproperty.atom == screenZoomAtom) + { + zoomScaleRatio = get_prop(dpy, root, screenZoomAtom, 0xFFFF) / (double)0xFFFF; + + globalScaleRatio = overscanScaleRatio * zoomScaleRatio; win *w; @@ -2176,30 +2242,7 @@ main (int argc, char **argv) win * w = find_win(dpy, ev.xmotion.window); if (w && w->id == currentFocusWindow) { - // Some stuff likes to warp in-place - if (cursorX == ev.xmotion.x && cursorY == ev.xmotion.y) - break; - - cursorX = ev.xmotion.x; - cursorY = ev.xmotion.y; - - win *w = find_win(dpy, currentFocusWindow); - - if (w && focusedWindowNeedsScale && gameFocused) - { - w->damaged = 1; - } - - // Ignore the first events as it's likely to be non-user-initiated warps - // Account for one warp from us, one warp from the app and one warp from - // the toolkit. - if (w && (w->mouseMoved++ < 3)) - break; - - lastCursorMovedTime = get_time_in_milliseconds(); - - hideCursorForMovement = False; - apply_cursor_state(dpy); + handle_mouse_movement( dpy, ev.xmotion.x, ev.xmotion.y ); } break; } diff --git a/steamcompmgr b/steamcompmgr new file mode 100755 index 0000000..8ff9a1a Binary files /dev/null and b/steamcompmgr differ diff --git a/udev_is_boot_vga b/udev_is_boot_vga new file mode 100755 index 0000000..303053e Binary files /dev/null and b/udev_is_boot_vga differ