void WidgetZoomHandler::multiply_scale_factor(const double multiplier)
{
    m_state.m_scale_factor =
        clamp(
            m_state.m_scale_factor * multiplier,
            m_min_scale_factor,
            m_max_scale_factor);

    apply_scale_factor();
}
void WidgetZoomHandler::load_state(const State& state)
{
    m_state = state;

    apply_scale_factor();
}
void WidgetZoomHandler::reset_zoom()
{
    m_state.m_scale_factor = 1.0;
    apply_scale_factor();
}
static void
reload_monitor_infos (CsScreen *screen)
{
    GdkDisplay *gdk_display;
    Display *xdisplay;
    Window xroot;

    gdk_display = gdk_screen_get_display (screen->gdk_screen);
    xdisplay = gdk_x11_display_get_xdisplay (gdk_display);

    xroot = gdk_x11_window_get_xid (gdk_screen_get_root_window (screen->gdk_screen));

    /* Any previous screen->monitor_infos is freed by the caller */

    screen->monitor_infos = NULL;
    screen->n_monitor_infos = 0;

    /* Xinerama doesn't have a concept of primary monitor, however XRandR
     * does. However, the XRandR xinerama compat code always sorts the
     * primary output first, so we rely on that here. We could use the
     * native XRandR calls instead of xinerama, but that would be
     * slightly problematic for _NET_WM_FULLSCREEN_MONITORS support, as
     * that is defined in terms of xinerama monitor indexes.
     * So, since we don't need anything in xrandr except the primary
     * we can keep using xinerama and use the first monitor as the
     * primary.
     */

    screen->primary_monitor_index = PRIMARY_MONITOR;


#ifdef HAVE_XFREE_XINERAMA
    if (screen->n_monitor_infos == 0 &&
        XineramaIsActive (xdisplay))
    {
        XineramaScreenInfo *infos;
        int n_infos;
        int i;

        n_infos = 0;
        infos = XineramaQueryScreens (xdisplay, &n_infos);

        DEBUG ("Found %d Xinerama screens on display %s\n",
               n_infos, gdk_display_get_name (gdk_display));

        if (n_infos > 0)
        {
            screen->monitor_infos = g_new0 (CsMonitorInfo, n_infos);
            screen->n_monitor_infos = n_infos;

            i = 0;
            while (i < n_infos)
            {
                screen->monitor_infos[i].number = infos[i].screen_number;
                screen->monitor_infos[i].rect.x = infos[i].x_org;
                screen->monitor_infos[i].rect.y = infos[i].y_org;
                screen->monitor_infos[i].rect.width = infos[i].width;
                screen->monitor_infos[i].rect.height = infos[i].height;

                DEBUG ("Monitor %d is %d,%d %d x %d\n",
                       screen->monitor_infos[i].number,
                       screen->monitor_infos[i].rect.x,
                       screen->monitor_infos[i].rect.y,
                       screen->monitor_infos[i].rect.width,
                       screen->monitor_infos[i].rect.height);

                ++i;
            }
        }

        cs_XFree (infos);

#ifdef HAVE_RANDR
    {
        XRRScreenResources *resources;

        resources = XRRGetScreenResourcesCurrent (xdisplay, xroot);

        if (resources)
        {
            for (i = 0; i < resources->ncrtc; i++)
            {
                XRRCrtcInfo *crtc;
                CsMonitorInfo *info;

                crtc = XRRGetCrtcInfo (xdisplay, resources, resources->crtcs[i]);
                info = find_monitor_with_rect (screen, crtc->x, crtc->y, (int)crtc->width, (int)crtc->height);

                if (info)
                {
                  info->output = find_main_output_for_crtc (resources, crtc, xdisplay, xroot);
                }

                XRRFreeCrtcInfo (crtc);
            }

            XRRFreeScreenResources (resources);
        }
    }
#endif
    }
    else if (screen->n_monitor_infos > 0)
    {
        DEBUG ("No XFree86 Xinerama extension or XFree86 Xinerama inactive on display %s\n",
               gdk_display_get_name (gdk_display));
    }
#else
    DEBUG ("Muffin compiled without XFree86 Xinerama support\n");
#endif /* HAVE_XFREE_XINERAMA */

#ifdef HAVE_SOLARIS_XINERAMA
    /* This code from GDK, Copyright (C) 2002 Sun Microsystems */
    if (screen->n_monitor_infos == 0 &&
        XineramaGetState (xdisplay,
                          gdk_screen_get_number (screen->gdk_screen)))
    {
        XRectangle monitors[MAXFRAMEBUFFERS];
        unsigned char hints[16];
        int result;
        int n_monitors;
        int i;

        n_monitors = 0;
        result = XineramaGetInfo (xdisplay,
                                  gdk_screen_get_number (screen->gdk_screen),
                                  monitors, hints,
                                  &n_monitors);
        /* Yes I know it should be Success but the current implementation
         * returns the num of monitor
         */
        if (result > 0)
        {
            g_assert (n_monitors > 0);

            screen->monitor_infos = g_new0 (CsMonitorInfo, n_monitors);
            screen->n_monitor_infos = n_monitors;

            i = 0;
            while (i < n_monitors)
            {
                screen->monitor_infos[i].number = i;
                screen->monitor_infos[i].rect.x = monitors[i].x;
                screen->monitor_infos[i].rect.y = monitors[i].y;
                screen->monitor_infos[i].rect.width = monitors[i].width;
                screen->monitor_infos[i].rect.height = monitors[i].height;

                DEBUG ("Monitor %d is %d,%d %d x %d\n",
                       screen->monitor_infos[i].number,
                       screen->monitor_infos[i].rect.x,
                       screen->monitor_infos[i].rect.y,
                       screen->monitor_infos[i].rect.width,
                       screen->monitor_infos[i].rect.height);
                ++i;
            }
        }
    }
    else if (screen->n_monitor_infos == 0)
    {
        DEBUG ("No Solaris Xinerama extension or Solaris Xinerama inactive on display %s\n",
               gdk_display_get_name (gdk_display));
    }
#else
    DEBUG ("Cinnamon Screensaver compiled without Solaris Xinerama support\n");
#endif /* HAVE_SOLARIS_XINERAMA */

    /* If no Xinerama, fill in the single screen info so
     * we can use the field unconditionally
    */
    if (screen->n_monitor_infos == 0)
    {
        DEBUG ("No Xinerama screens, using default screen info\n");

        screen->monitor_infos = g_new0 (CsMonitorInfo, 1);
        screen->n_monitor_infos = 1;

        screen->monitor_infos[0].number = 0;
        screen->monitor_infos[0].rect = screen->rect;
    }

    filter_mirrored_monitors (screen);

    screen->monitor_infos[screen->primary_monitor_index].is_primary = TRUE;

    apply_scale_factor (screen->monitor_infos,
                        screen->n_monitor_infos,
                        gdk_screen_get_monitor_scale_factor (screen->gdk_screen, PRIMARY_MONITOR));

    g_assert (screen->n_monitor_infos > 0);
    g_assert (screen->monitor_infos != NULL);
}