diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2013-05-08 12:53:44 -0700 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2013-05-08 12:53:44 -0700 |
commit | 75e68165a0a720196a152f86f76041bba1d83af6 (patch) | |
tree | f3f7c6c1ad88d73d4587faab34770bb83a0b905f | |
parent | 61c4459f0553330656a4329ca1b4c9a6063ee12b (diff) |
-rw-r--r-- | doc/version.mk | 2 | ||||
-rw-r--r-- | samples/version.mk | 2 | ||||
-rw-r--r-- | src/common-utils/common-utils.c | 13 | ||||
-rw-r--r-- | src/common-utils/common-utils.h | 1 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkdisplayconfig-utils.c | 362 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkdisplayconfig-utils.h | 25 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkdisplayconfig.c | 714 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkdisplayconfig.h | 4 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkdisplaylayout.c | 1057 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkdisplaylayout.h | 80 | ||||
-rw-r--r-- | src/version.mk | 2 | ||||
-rw-r--r-- | version.mk | 2 |
12 files changed, 1363 insertions, 901 deletions
diff --git a/doc/version.mk b/doc/version.mk index ea75111..96f272a 100644 --- a/doc/version.mk +++ b/doc/version.mk @@ -1 +1 @@ -NVIDIA_VERSION = 310.44 +NVIDIA_VERSION = 310.51 diff --git a/samples/version.mk b/samples/version.mk index ea75111..96f272a 100644 --- a/samples/version.mk +++ b/samples/version.mk @@ -1 +1 @@ -NVIDIA_VERSION = 310.44 +NVIDIA_VERSION = 310.51 diff --git a/src/common-utils/common-utils.c b/src/common-utils/common-utils.c index a8ee75a..1149a8e 100644 --- a/src/common-utils/common-utils.c +++ b/src/common-utils/common-utils.c @@ -281,6 +281,19 @@ char *tilde_expansion(const char *str) } /* tilde_expansion() */ +/* + * nv_prepend_to_string_list() - add a new string to a string list, delimited + * by the given string delimiter. The original list is freed. + */ + +char *nv_prepend_to_string_list(char *list, const char *item, const char *delim) +{ + char *new_list = nvstrcat(item, list ? delim : NULL, list, NULL); + nvfree(list); + return new_list; +} + + /****************************************************************************/ /* TextRows helper functions */ /****************************************************************************/ diff --git a/src/common-utils/common-utils.h b/src/common-utils/common-utils.h index 626fd1b..f95bfd3 100644 --- a/src/common-utils/common-utils.h +++ b/src/common-utils/common-utils.h @@ -55,6 +55,7 @@ char *nvstrtolower(char *s); void nvfree(void *s); char *tilde_expansion(const char *str); +char *nv_prepend_to_string_list(char *list, const char *item, const char *delim); TextRows *nv_format_text_rows(const char *prefix, const char *str, diff --git a/src/gtk+-2.x/ctkdisplayconfig-utils.c b/src/gtk+-2.x/ctkdisplayconfig-utils.c index 5d9ba67..8c90dfe 100644 --- a/src/gtk+-2.x/ctkdisplayconfig-utils.c +++ b/src/gtk+-2.x/ctkdisplayconfig-utils.c @@ -196,32 +196,28 @@ void apply_monitor_token(char *token, char *value, void *data) /** apply_screen_info_token() **************************************** * - * Modifies the ScreenInfo structure (pointed to by data) with + * Modifies the GdkRectangle structure (pointed to by data) with * information from the token-value pair given. Currently accepts * position and width/height data. * **/ void apply_screen_info_token(char *token, char *value, void *data) { - ScreenInfo *screen_info = (ScreenInfo *)data; + GdkRectangle *screen_info = (GdkRectangle *)data; if (!screen_info || !token || !strlen(token)) { return; } - /* X */ if (!strcasecmp("x", token)) { screen_info->x = atoi(value); - /* Y */ } else if (!strcasecmp("y", token)) { screen_info->y = atoi(value); - /* Width */ } else if (!strcasecmp("width", token)) { screen_info->width = atoi(value); - /* Height */ } else if (!strcasecmp("height", token)) { screen_info->height = atoi(value); @@ -230,8 +226,7 @@ void apply_screen_info_token(char *token, char *value, void *data) nv_warning_msg("Unknown screen info token value pair: %s=%s", token, value); } - -} /* apply_screen_info_token() */ +} @@ -435,43 +430,127 @@ static nvModeLinePtr modeline_parse(nvDisplayPtr display, /** MODE FUNCTIONS ***********************************************************/ /*****************************************************************************/ -void mode_set_dims_from_modeline(nvModePtr mode, nvModeLinePtr modeline) + +/*! + * Clamps the given dimensions to be no smaller than the mode's viewPortIn + * + * \param[in, out] rect The GdkRectangle to clamp. + * \param[in] mode The mode to clamp against. + */ +void clamp_rect_to_viewportin(GdkRectangle *rect, const nvMode *mode) +{ + if (rect->width < mode->viewPortIn.width) { + rect->width = mode->viewPortIn.width; + } + if (rect->height < mode->viewPortIn.height) { + rect->height = mode->viewPortIn.height; + } +} + + + +/*! + * Clamps the mode's panning domain to the mode's viewPortIn dimensions + * + * \param[in, out] mode The mode who's panning to clamp. + */ +void clamp_mode_panning(nvModePtr mode) +{ + clamp_rect_to_viewportin(&(mode->pan), mode); +} + + + +/*! + * Fills a rectangle struct with both position and size information of the + * given mode's viewPortIn. + * + * \param[in] mode The mode to return information for. + * \param[in, out] rect The GdkRectangle structure to populate. + */ +void get_viewportin_rect(const nvMode *mode, GdkRectangle *rect) { - int newW; - int newH; + rect->x = mode->pan.x; + rect->y = mode->pan.y; + rect->width = mode->viewPortIn.width; + rect->height = mode->viewPortIn.height; +} + + +void mode_set_modeline(nvModePtr mode, + nvModeLinePtr modeline, + const nvSize *providedViewPortIn, + const GdkRectangle *providedViewPortOut) +{ + int width; + int height; + Bool panning_modified; + + /* Figure out what dimensions to use */ + if (providedViewPortIn) { + width = providedViewPortIn->width; + height = providedViewPortIn->height; + } else if (modeline) { + width = modeline->data.hdisplay; + height = modeline->data.vdisplay; + } else { + /* NULL modeline given (display is being turned off), use a default + * resolution to show the display. + */ + if (mode->display->modelines) { + // XXX assumes that the first modeline in the display's list is the + // default (nvidia-auto-select). + width = mode->display->modelines->data.hdisplay; + height = mode->display->modelines->data.vdisplay; + } else { + /* display has no modelines, 800x600 seems reasonable */ + width = 800; + height = 600; + } + } - mode->viewPortOut[X] = 0; - mode->viewPortOut[Y] = 0; - if (modeline) { - mode->viewPortOut[W] = modeline->data.hdisplay; - mode->viewPortOut[H] = modeline->data.vdisplay; + /* Reset the viewPortOut to match the full visible size of the modeline */ + // XXX Only do this if viewport out has not been tweaked? + // XXX - Should we do any clamping? + if (providedViewPortOut) { + mode->viewPortOut = *providedViewPortOut; } else { - mode->viewPortOut[W] = 800; - mode->viewPortOut[H] = 600; + mode->viewPortOut.x = 0; + mode->viewPortOut.y = 0; + mode->viewPortOut.width = width; + mode->viewPortOut.height = height; } - /* Determine new dimensions to use */ + /* Oriented the dimensions to use for the viewPortIn and Panning */ if ((mode->rotation == ROTATION_90) || (mode->rotation == ROTATION_270)) { - newW = mode->viewPortOut[H]; - newH = mode->viewPortOut[W]; - } else { - newW = mode->viewPortOut[W]; - newH = mode->viewPortOut[H]; + int temp = width; + width = height; + height = temp; } - /* Resolve and clamp the panning domain */ - if ((mode->pan[W] == mode->viewPortIn[W]) || - mode->pan[W] < newW) { - mode->pan[W] = newW; + /* XXX Later, keep a flag in nvModePtr to track if the panning has + * been modified */ + panning_modified = + (mode->pan.width != mode->viewPortIn.width) || + (mode->pan.height != mode->viewPortIn.height); + + /* XXX Only set this if the user has not modified viewPortIn... */ + { + mode->viewPortIn.width = width; + mode->viewPortIn.height = height; + /* Panning domain must include viewPortIn */ + clamp_mode_panning(mode); } - if ((mode->pan[H] == mode->viewPortIn[H]) || - mode->pan[H] < newH) { - mode->pan[H] = newH; + + /* Only set this if the user has not modified panning... */ + if (!panning_modified) { + mode->pan.width = width; + mode->pan.height = height; } - mode->viewPortIn[W] = newW; - mode->viewPortIn[H] = newH; + + mode->modeline = modeline; } @@ -504,13 +583,13 @@ Bool mode_set_rotation(nvModePtr mode, Rotation rotation) mode->rotation = rotation; if (old_is_horiz != new_is_horiz) { - tmp = mode->viewPortIn[W]; - mode->viewPortIn[W] = mode->viewPortIn[H]; - mode->viewPortIn[H] = tmp; + tmp = mode->viewPortIn.width; + mode->viewPortIn.width = mode->viewPortIn.height; + mode->viewPortIn.height = tmp; - tmp = mode->pan[W]; - mode->pan[W] = mode->pan[H]; - mode->pan[H] = tmp; + tmp = mode->pan.width; + mode->pan.width = mode->pan.height; + mode->pan.height = tmp; } /* Mark mode as being modified */ @@ -551,20 +630,20 @@ static void apply_mode_attribute_token(char *token, char *value, void *data) /* ViewPortIn */ } else if (!strcasecmp("viewportin", token)) { parse_read_integer_pair(value, 'x', - &(mode->viewPortIn[W]), - &(mode->viewPortIn[H])); + &(mode->viewPortIn.width), + &(mode->viewPortIn.height)); /* ViewPortOut */ } else if (!strcasecmp("viewportout", token)) { const char *str; str = parse_read_integer_pair(value, 'x', - &(mode->viewPortOut[W]), - &(mode->viewPortOut[H])); + &(mode->viewPortOut.width), + &(mode->viewPortOut.height)); str = parse_read_integer_pair(str, 0, - &(mode->viewPortOut[X]), - &(mode->viewPortOut[Y])); + &(mode->viewPortOut.x), + &(mode->viewPortOut.y)); } /* Rotation */ @@ -615,6 +694,7 @@ nvModePtr mode_parse(nvDisplayPtr display, const char *mode_str) nvModePtr mode; char *mode_name; /* Modeline reference name */ const char *str = mode_str; + nvModeLinePtr modeline; @@ -639,21 +719,17 @@ nvModePtr mode_parse(nvDisplayPtr display, const char *mode_str) if (!str || !mode_name) goto fail; - /* Match the mode name to one of the modelines */ - mode->modeline = display->modelines; - while (mode->modeline) { - if (!strcmp(mode_name, mode->modeline->data.identifier)) { + /* Find the display's modeline that matches the given mode name */ + modeline = display->modelines; + while (modeline) { + if (!strcmp(mode_name, modeline->data.identifier)) { break; } - mode->modeline = mode->modeline->next; + modeline = modeline->next; } - /* If we can't find a matching modeline, don't add this mode. If the - * metamode has other (valid) displays, a NULL mode will be added for this - * display at that time - this is done to avoid potentially adding a - * metamode with no active displays. - */ - if (!mode->modeline) { + /* If we can't find a matching modeline, set the NULL mode. */ + if (!modeline) { if (strcmp(mode_str, "NULL")) { nv_warning_msg("Mode name '%s' does not match any modelines for " "display device '%s' in modeline '%s'.", @@ -661,12 +737,20 @@ nvModePtr mode_parse(nvDisplayPtr display, const char *mode_str) } free(mode_name); - mode_set_dims_from_modeline(mode, display->modelines); + mode_set_modeline(mode, + NULL /* modeline */, + NULL /* viewPortIn */, + NULL /* viewPortOut */); return mode; } free(mode_name); + /* Don't call mode_set_modeline() here since we want to apply the values + * from the string we're parsing, so just link the modeline + */ + mode->modeline = modeline; + /* Read mode information */ while (*str) { @@ -675,15 +759,16 @@ nvModePtr mode_parse(nvDisplayPtr display, const char *mode_str) if (*str == '@') { str++; str = parse_read_integer_pair(str, 'x', - &(mode->pan[W]), &(mode->pan[H])); + &(mode->pan.width), + &(mode->pan.height)); } /* Read position */ else if (*str == '+') { str++; str = parse_read_integer_pair(str, 0, - &(mode->viewPortIn[X]), - &(mode->viewPortIn[Y])); + &(mode->pan.x), + &(mode->pan.y)); } /* Read extra params */ @@ -717,13 +802,13 @@ nvModePtr mode_parse(nvDisplayPtr display, const char *mode_str) } /* Initialize defaults for the viewports if unspecified */ - if ((mode->viewPortOut[W] == 0) || (mode->viewPortOut[H] == 0)) { - mode->viewPortOut[W] = mode->modeline->data.hdisplay; - mode->viewPortOut[H] = mode->modeline->data.vdisplay; + if ((mode->viewPortOut.width == 0) || (mode->viewPortOut.height == 0)) { + mode->viewPortOut.width = mode->modeline->data.hdisplay; + mode->viewPortOut.height = mode->modeline->data.vdisplay; } - if ((mode->viewPortIn[W] == 0) || (mode->viewPortIn[H] == 0)) { - mode->viewPortIn[W] = mode->viewPortOut[W]; - mode->viewPortIn[H] = mode->viewPortOut[H]; + if ((mode->viewPortIn.width == 0) || (mode->viewPortIn.height == 0)) { + mode->viewPortIn.width = mode->viewPortOut.width; + mode->viewPortIn.height = mode->viewPortOut.height; } /* If rotation is specified, swap W/H if they are still set to the @@ -732,20 +817,15 @@ nvModePtr mode_parse(nvDisplayPtr display, const char *mode_str) */ if (((mode->rotation == ROTATION_90) || (mode->rotation == ROTATION_270)) && - (mode->viewPortIn[W] == mode->viewPortOut[W]) && - (mode->viewPortIn[H] == mode->viewPortOut[H])) { - int tmp = mode->viewPortIn[W]; - mode->viewPortIn[W] = mode->viewPortIn[H]; - mode->viewPortIn[H] = tmp; + (mode->viewPortIn.width == mode->viewPortOut.width) && + (mode->viewPortIn.height == mode->viewPortOut.height)) { + int tmp = mode->viewPortIn.width; + mode->viewPortIn.width = mode->viewPortIn.height; + mode->viewPortIn.height = tmp; } /* Clamp the panning domain */ - if (mode->pan[W] < mode->viewPortIn[W]) { - mode->pan[W] = mode->viewPortIn[W]; - } - if (mode->pan[H] < mode->viewPortIn[H]) { - mode->pan[H] = mode->viewPortIn[H]; - } + clamp_mode_panning(mode); return mode; @@ -818,10 +898,10 @@ static gchar *mode_get_str(nvModePtr mode, int be_generic) /* Panning domain */ - if (!be_generic || (mode->pan[W] != mode->viewPortIn[W] || - mode->pan[H] != mode->viewPortIn[H])) { + if (!be_generic || (mode->pan.width != mode->viewPortIn.width || + mode->pan.height != mode->viewPortIn.height)) { tmp = g_strdup_printf("%s @%dx%d", - mode_str, mode->pan[W], mode->pan[H]); + mode_str, mode->pan.width, mode->pan.height); g_free(mode_str); mode_str = tmp; } @@ -848,8 +928,8 @@ static gchar *mode_get_str(nvModePtr mode, int be_generic) tmp = g_strdup_printf("%s +%d+%d", mode_str, /* Make mode position relative */ - mode->viewPortIn[X] - mode->metamode->edim[X], - mode->viewPortIn[Y] - mode->metamode->edim[Y]); + mode->pan.x - mode->metamode->edim.x, + mode->pan.y - mode->metamode->edim.y); g_free(mode_str); mode_str = tmp; @@ -945,34 +1025,35 @@ static gchar *mode_get_str(nvModePtr mode, int be_generic) */ if ((mode->rotation == ROTATION_90) || (mode->rotation == ROTATION_270)) { - width = mode->viewPortOut[H]; - height = mode->viewPortOut[W]; + width = mode->viewPortOut.height; + height = mode->viewPortOut.width; } else { - width = mode->viewPortOut[W]; - height = mode->viewPortOut[H]; + width = mode->viewPortOut.width; + height = mode->viewPortOut.height; } - if (mode->viewPortIn[W] && mode->viewPortIn[H] && - ((mode->viewPortIn[W] != width) || - (mode->viewPortIn[H] != height))) { + if (mode->viewPortIn.width && mode->viewPortIn.height && + ((mode->viewPortIn.width != width) || + (mode->viewPortIn.height != height))) { tmp = g_strdup_printf("%s, viewportin=%dx%d", (flags_str ? flags_str : ""), - mode->viewPortIn[W], mode->viewPortIn[H]); + mode->viewPortIn.width, + mode->viewPortIn.height); g_free(flags_str); flags_str = tmp; } } /* ViewPortOut */ - if (mode->viewPortOut[X] || - mode->viewPortOut[Y] || - (mode->viewPortOut[W] && mode->viewPortOut[H] && - ((mode->viewPortOut[W] != mode->modeline->data.hdisplay) || - (mode->viewPortOut[H] != mode->modeline->data.vdisplay)))) { + if (mode->viewPortOut.x || + mode->viewPortOut.y || + (mode->viewPortOut.width && mode->viewPortOut.height && + ((mode->viewPortOut.width != mode->modeline->data.hdisplay) || + (mode->viewPortOut.height != mode->modeline->data.vdisplay)))) { tmp = g_strdup_printf("%s, viewportout=%dx%d%+d%+d", (flags_str ? flags_str : ""), - mode->viewPortOut[W], mode->viewPortOut[H], - mode->viewPortOut[X], mode->viewPortOut[Y]); + mode->viewPortOut.width, mode->viewPortOut.height, + mode->viewPortOut.x, mode->viewPortOut.y); g_free(flags_str); flags_str = tmp; } @@ -1099,14 +1180,14 @@ int display_find_closest_mode_matching_modeline(nvDisplayPtr display, */ if (best_mode) { Bool current_match_vpin = - (mode->viewPortIn[W] == targetWidth && - mode->viewPortIn[H] == targetHeight); + (mode->viewPortIn.width == targetWidth && + mode->viewPortIn.height == targetHeight); Bool best_match_vpin = - (best_mode->viewPortIn[W] == targetWidth && - best_mode->viewPortIn[H] == targetHeight); + (best_mode->viewPortIn.width == targetWidth && + best_mode->viewPortIn.height == targetHeight); Bool best_match_vpout = - (best_mode->viewPortOut[W] == targetWidth && - best_mode->viewPortOut[H] == targetHeight); + (best_mode->viewPortOut.width == targetWidth && + best_mode->viewPortOut.height == targetHeight); /* Try to find reasons why we should prefer the * previous match over the currently considered @@ -1203,6 +1284,38 @@ Bool modelines_match(nvModeLinePtr modeline1, +/** viewport_in_match() ********************************************** + * + * Helper function that returns TRUE of FALSE based on whether + * the ViewPortIn arguments match each other. + * + **/ +Bool viewports_in_match(const nvSize viewPortIn1, + const nvSize viewPortIn2) +{ + return ((viewPortIn1.width == viewPortIn2.width) && + (viewPortIn1.height == viewPortIn2.height)); +} + + + +/** viewport_out_match() ********************************************* + * + * Helper function that returns TRUE of FALSE based on whether + * the ViewPortOut arguments match each other. + * + **/ +Bool viewports_out_match(const GdkRectangle viewPortOut1, + const GdkRectangle viewPortOut2) +{ + return ((viewPortOut1.x == viewPortOut2.x) && + (viewPortOut1.y == viewPortOut2.y) && + (viewPortOut1.width == viewPortOut2.width) && + (viewPortOut1.height == viewPortOut2.height)); +} + + + /** display_has_modeline() ******************************************* * * Helper function that returns TRUE or FALSE based on whether @@ -1448,6 +1561,23 @@ static void display_free(nvDisplayPtr display) /*****************************************************************************/ +/*! + * Clamps the given (screen) dimensions to the minimum allowed screen size. + * + * \param[in, out] rect The dimensions to clamp + */ +void clamp_screen_size_rect(GdkRectangle *rect) +{ + if (rect->width < 304) { + rect->width = 304; + } + if (rect->height < 200) { + rect->height = 200; + } +} + + + /** screen_find_named_display() ************************************** * * Finds a display named 'display_name' in the list of displays on the @@ -1927,10 +2057,6 @@ static Bool screen_add_metamode(nvScreenPtr screen, const char *metamode_str, /* Make sure each display has the right number of (NULL) modes */ screen_check_metamodes(screen); - /* Set the panning offset */ - mode->pan[X] = mode->viewPortIn[X]; - mode->pan[Y] = mode->viewPortIn[Y]; - /* Add the mode at the end of the display's mode list */ xconfigAddListItem((GenericListPtr *)(&display->modes), (GenericListPtr)mode); @@ -2013,10 +2139,8 @@ static Bool screen_check_metamodes(nvScreenPtr screen) /* Duplicate position information of the last mode */ if (last_mode) { - mode->viewPortIn[X] = last_mode->viewPortIn[X]; - mode->viewPortIn[Y] = last_mode->viewPortIn[Y]; - mode->pan[X] = last_mode->pan[X]; - mode->pan[Y] = last_mode->pan[Y]; + mode->pan.x = last_mode->pan.x; + mode->pan.y = last_mode->pan.y; mode->position_type = last_mode->position_type; mode->relative_to = last_mode->relative_to; } @@ -2066,11 +2190,8 @@ static void screen_assign_dummy_metamode_positions(nvScreenPtr screen) if (ok_mode) { for (mode = display->modes; mode; mode = mode->next) { if (!mode->dummy) continue; - mode->viewPortIn[X] = ok_mode->viewPortIn[X]; - mode->viewPortIn[Y] = ok_mode->viewPortIn[Y]; - - mode->pan[X] = ok_mode->viewPortIn[X]; - mode->pan[Y] = ok_mode->viewPortIn[Y]; + mode->pan.x = ok_mode->pan.x; + mode->pan.y = ok_mode->pan.y; } } } @@ -2667,7 +2788,10 @@ Bool gpu_add_screenless_modes_to_displays(nvGpuPtr gpu) mode->display = display; mode->dummy = 1; - mode_set_dims_from_modeline(mode, NULL); + mode_set_modeline(mode, + NULL /* modeline */, + NULL /* viewPortIn */, + NULL /* viewPortOut */); /* Add the mode to the display */ display->modes = mode; @@ -3172,8 +3296,8 @@ static Bool layout_add_screen_from_server(nvLayoutPtr layout, screen->depth = NvCtrlGetScreenPlanes(screen->handle); /* Initialize the virtual X screen size */ - screen->dim[W] = NvCtrlGetScreenWidth(screen->handle); - screen->dim[H] = NvCtrlGetScreenHeight(screen->handle); + screen->dim.width = NvCtrlGetScreenWidth(screen->handle); + screen->dim.height = NvCtrlGetScreenHeight(screen->handle); /* Add the screen to the layout */ layout_add_screen(layout, screen); diff --git a/src/gtk+-2.x/ctkdisplayconfig-utils.h b/src/gtk+-2.x/ctkdisplayconfig-utils.h index 14252aa..3373f9e 100644 --- a/src/gtk+-2.x/ctkdisplayconfig-utils.h +++ b/src/gtk+-2.x/ctkdisplayconfig-utils.h @@ -33,13 +33,6 @@ G_BEGIN_DECLS /* Token parsing handlers */ -typedef struct _ScreenInfo { - int x; - int y; - int width; - int height; -} ScreenInfo; - void apply_modeline_token(char *token, char *value, void *data); void apply_metamode_token(char *token, char *value, void *data); void apply_monitor_token(char *token, char *value, void *data); @@ -48,7 +41,13 @@ void apply_screen_info_token(char *token, char *value, void *data); /* Mode functions */ -void mode_set_dims_from_modeline(nvModePtr mode, nvModeLinePtr modeline); +void clamp_rect_to_viewportin(GdkRectangle *rect, const nvMode *mode); +void clamp_mode_panning(nvModePtr mode); +void get_viewportin_rect(const nvMode *mode, GdkRectangle *rect); +void mode_set_modeline(nvModePtr mode, + nvModeLinePtr modeline, + const nvSize *providedViewPortIn, + const GdkRectangle *providedViewPortOut); Bool mode_set_rotation(nvModePtr mode, Rotation rotation); nvModePtr mode_parse(nvDisplayPtr display, const char *mode_str); @@ -59,6 +58,15 @@ void modeline_free(nvModeLinePtr m); +/* ViewPort functions */ + +Bool viewports_in_match(const nvSize viewPortIn1, + const nvSize viewPortIn2); +Bool viewports_out_match(const GdkRectangle viewPortOut1, + const GdkRectangle viewPortOut2); + + + /* Display functions */ int display_find_closest_mode_matching_modeline(nvDisplayPtr display, @@ -75,6 +83,7 @@ Bool display_set_modes_rotation(nvDisplayPtr display, Rotation rotation); /* Screen functions */ +void clamp_screen_size_rect(GdkRectangle *rect); void renumber_xscreens(nvLayoutPtr layout); void screen_unlink_display(nvDisplayPtr display); void screen_link_display(nvScreenPtr screen, nvDisplayPtr display); diff --git a/src/gtk+-2.x/ctkdisplayconfig.c b/src/gtk+-2.x/ctkdisplayconfig.c index c4965f4..aec55cd 100644 --- a/src/gtk+-2.x/ctkdisplayconfig.c +++ b/src/gtk+-2.x/ctkdisplayconfig.c @@ -181,7 +181,9 @@ static const char * __dpy_configuration_mnu_help = static const char * __dpy_resolution_mnu_help = "The Resolution drop-down allows you to select a desired resolution " -"for the currently selected display device."; +"for the currently selected display device. The 'scaled' qualifier indicates " +"an aspect-scaled common resolution simulated through a MetaMode ViewPort " +"configuration."; static const char * __dpy_refresh_mnu_help = "The Refresh drop-down allows you to select a desired refresh rate " @@ -322,11 +324,11 @@ static void get_cur_screen_pos(CtkDisplayConfig *ctk_object) { nvScreenPtr screen = ctk_display_layout_get_selected_screen (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout)); - + if (!screen) return; - ctk_object->cur_screen_pos[X] = screen->dim[X]; - ctk_object->cur_screen_pos[Y] = screen->dim[Y]; + ctk_object->cur_screen_pos.x = screen->dim.x; + ctk_object->cur_screen_pos.y = screen->dim.y; } /* get_cur_screen_pos() */ @@ -341,17 +343,17 @@ static void get_cur_screen_pos(CtkDisplayConfig *ctk_object) static void check_screen_pos_changed(CtkDisplayConfig *ctk_object) { - int old_dim[2]; + GdkPoint old_pos; /* Cache the old position */ - old_dim[X] = ctk_object->cur_screen_pos[X]; - old_dim[Y] = ctk_object->cur_screen_pos[Y]; + old_pos.x = ctk_object->cur_screen_pos.x; + old_pos.y = ctk_object->cur_screen_pos.y; /* Get the new position */ get_cur_screen_pos(ctk_object); - if (old_dim[X] != ctk_object->cur_screen_pos[X] || - old_dim[Y] != ctk_object->cur_screen_pos[Y]) { + if (old_pos.x != ctk_object->cur_screen_pos.x || + old_pos.y != ctk_object->cur_screen_pos.y) { ctk_object->apply_possible = FALSE; } @@ -640,17 +642,17 @@ static int generate_xconf_metamode_str(CtkDisplayConfig *ctk_object, metamode_strs = screen_get_metamode_str(screen, screen->cur_metamode_idx, 1); len = strlen(metamode_strs); - start_width = screen->cur_metamode->edim[W]; - start_height = screen->cur_metamode->edim[H]; + start_width = screen->cur_metamode->edim.width; + start_height = screen->cur_metamode->edim.height; } else { - start_width = screen->metamodes->edim[W]; - start_height = screen->metamodes->edim[H]; + start_width = screen->metamodes->edim.width; + start_height = screen->metamodes->edim.height; } for (metamode_idx = 0, metamode = screen->metamodes; (metamode_idx < screen->num_metamodes) && metamode; metamode_idx++, metamode = metamode->next) { - + int metamode_len; /* Only write out metamodes that were specified by the user */ @@ -670,21 +672,21 @@ static int generate_xconf_metamode_str(CtkDisplayConfig *ctk_object, * in an unwanted panning domain being setup for the first mode. */ if ((!ctk_object->advanced_mode) && - ((metamode->edim[W] > start_width) || - (metamode->edim[H] > start_height))) + ((metamode->edim.width > start_width) || + (metamode->edim.height > start_height))) continue; - + metamode_str = screen_get_metamode_str(screen, metamode_idx, 1); if (!metamode_str) continue; - + metamode_len = strlen(metamode_str); if (!longStringsOK && (len + metamode_len > 900)) { GtkWidget *dlg; gchar *msg; GtkWidget *parent; gint result; - + msg = g_strdup_printf ("Truncate the MetaMode list?\n" "\n" @@ -773,7 +775,7 @@ static void assign_screen_positions(CtkDisplayConfig *ctk_object) int initialize = 0; char *screen_info; - ScreenInfo screen_parsed_info; + GdkRectangle screen_parsed_info; ReturnStatus ret; @@ -2834,6 +2836,432 @@ static void setup_display_refresh_dropdown(CtkDisplayConfig *ctk_object) +/** get_default_modeline() ******************************************* + * + * Finds the default modeline in the list of modelines. + * + * Returns the default modeline if found, NULL otherwise. + * + */ + +static nvModeLinePtr get_default_modeline(const nvDisplayPtr display) +{ + nvModeLinePtr modeline = display->modelines; + + while (modeline) { + if (IS_NVIDIA_DEFAULT_MODE(modeline)) { + return modeline; + } + + modeline = modeline->next; + } + + return NULL; +} + + + +/** allocate_selected_mode() ***************************************** + * + * Allocates, fills and returns a nvSelectedModePtr. + * + */ + +static nvSelectedModePtr +allocate_selected_mode(char *name, + nvModeLinePtr modeline, + Bool isSpecial, + nvSize *viewPortIn, + GdkRectangle *viewPortOut) +{ + nvSelectedModePtr selected_mode; + + selected_mode = (nvSelectedModePtr)nvalloc(sizeof(nvSelectedMode)); + + selected_mode->label = gtk_menu_item_new_with_label(name); + + selected_mode->modeline = modeline; + selected_mode->isSpecial = isSpecial; + selected_mode->isScaled = (viewPortIn || viewPortOut); + + if (viewPortIn) { + selected_mode->viewPortIn.width = viewPortIn->width; + selected_mode->viewPortIn.height = viewPortIn->height; + } + + if (viewPortOut) { + selected_mode->viewPortOut.x = viewPortOut->x; + selected_mode->viewPortOut.y = viewPortOut->y; + selected_mode->viewPortOut.width = viewPortOut->width; + selected_mode->viewPortOut.height = viewPortOut->height; + } + + return selected_mode; +} + + + +/** free_selected_modes() ******************************************** + * + * Recursively frees each item of a list of selected modes. + * + */ + +static void +free_selected_modes(nvSelectedModePtr selected_mode) +{ + if (selected_mode) { + free_selected_modes(selected_mode->next); + free(selected_mode); + } +} + + + +/** append_unique_selected_mode() ************************************ + * + * Appends a selected mode to the given list only if it doesn't already exist. + * Special modes ("Auto", "Off") are not checked. Two selected modes are unique + * if their [hv]display differ in the case of regular modes, or if the + * ViewPortIn of the given mode doesn't match any existing [hv]display. + * Returns TRUE if the selected mode has been added, FALSE otherwise. + * + */ + +static Bool +append_unique_selected_mode(nvSelectedModePtr head, + const nvSelectedModePtr mode) +{ + int targetWidth, targetHeight; + nvSelectedModePtr iter, prev = NULL; + + if (mode->isScaled) { + targetWidth = mode->viewPortIn.width; + targetHeight = mode->viewPortIn.height; + } else { + targetWidth = mode->modeline->data.hdisplay; + targetHeight = mode->modeline->data.vdisplay; + } + + /* Keep the list sorted by targetted resolution */ + iter = head; + while (iter) { + int currentWidth, currentHeight; + nvModeLinePtr ml = iter->modeline; + + if (!ml || iter->isSpecial) { + goto next; + } + + if (iter->isScaled) { + currentWidth = iter->viewPortIn.width; + currentHeight = iter->viewPortIn.height; + } else { + currentWidth = ml->data.hdisplay; + currentHeight = ml->data.vdisplay; + } + + /* If we are past the sort order, stop looping */ + if ((targetWidth > currentWidth) || + ((targetWidth == currentWidth) && (targetHeight > currentHeight))) { + break; + } + + if (ml && !mode->isSpecial && + (targetWidth == currentWidth) && (targetHeight == currentHeight)) { + return FALSE; + } + +next: + prev = iter; + iter = iter->next; + } + + if (prev == NULL) { + return FALSE; + } + + /* Insert the selected mode */ + mode->next = prev->next; + prev->next = mode; + + return TRUE; +} + + + +/** matches_current_selected_mode() ********************************** + * + * Checks whether the provided selected mode matches the current mode. + * + * We need to distinguish between custom modes and scaled modes. + * + * Custom modes are modes with custom ViewPort settings, such as an + * Underscan configuration. These modes don't have an entry in the + * resolution dropdown menu. Instead, the corresponding modeline must be + * selected. + * + * Scaled modes are generated by the CPL, have a fixed ViewPort{In,Out} + * configuration and are displayed in the dropdown menu in basic mode. + * + * Therefore, we compare the raster size and the ViewPorts first, then only + * the raster size. This works because the list of selected_modes is + * generated before the scaled ones. The latter can then overwrite the + * cur_selected_mode if we find a better match. + * + * Returns TRUE if the provided selected mode matches the current mode, FALSE + * otherwise. + * + */ + +static Bool matches_current_selected_mode(const nvDisplayPtr display, + const nvSelectedModePtr selected_mode, + const Bool compare_viewports) +{ + nvModeLinePtr ml1, ml2; + nvModePtr cur_mode; + Bool mode_match; + + if (!display || !display->cur_mode || !selected_mode) { + return FALSE; + } + + cur_mode = display->cur_mode; + ml1 = cur_mode->modeline; + ml2 = selected_mode->modeline; + + if (!ml1 || !ml2) { + return FALSE; + } + + mode_match = ((ml1->data.hdisplay == ml2->data.hdisplay) && + (ml1->data.vdisplay == ml2->data.vdisplay)); + + if (compare_viewports) { + nvSize rotatedViewPortIn; + + memcpy(&rotatedViewPortIn, &selected_mode->viewPortIn, sizeof(nvSize)); + + if (cur_mode->rotation == ROTATION_90 || + cur_mode->rotation == ROTATION_270) { + int temp = rotatedViewPortIn.width; + rotatedViewPortIn.width = rotatedViewPortIn.height; + rotatedViewPortIn.height = temp; + } + + return (mode_match && + viewports_in_match(cur_mode->viewPortIn, + rotatedViewPortIn) && + viewports_out_match(cur_mode->viewPortOut, + selected_mode->viewPortOut)); + } else { + return (!IS_NVIDIA_DEFAULT_MODE(ml1) && mode_match); + } +} + + + +/** get_common_resolutions() ***************************************** + * + * Returns a constant array of a (-1, -1) terminated list of common + * resolutions. + * + */ +static const nvSize* get_common_resolutions(void) +{ + static const nvSize commonRes[] = { + { 3840, 2400 }, + { 2560, 1600 }, + { 2560, 1440 }, + { 1920, 1200 }, + { 1920, 1080 }, + { 1680, 1050 }, + { 1600, 1200 }, + { 1440, 900 }, + { 1366, 768 }, + { 1280, 1024 }, + { 1280, 800 }, + { 1280, 720 }, + { 1024, 768 }, + { 800, 600 }, + { 640, 480 }, + { -1, -1 }, + }; + + return commonRes; +} + + + +/** get_scaled_viewportout() ***************************************** + * + * Computes ViewPortOut, given raster size and ViewPortIn size. + * + * ViewPortOut should fit within the raster size, scaled to the raster + * size in one dimension, and scaled in the other dimension such that + * the aspect ratio of ViewPortIn is preserved. + * + */ +static GdkRectangle get_scaled_viewportout(const nvSize *raster, + const nvSize *viewPortIn) +{ + GdkRectangle viewPortOut; + float scaleX, scaleY; + + memset(&viewPortOut, 0, sizeof(viewPortOut)); + + scaleX = (float) raster->width / (float) viewPortIn->width; + scaleY = (float) raster->height / (float) viewPortIn->height; + + if (scaleX < scaleY) { + viewPortOut.width = raster->width; + viewPortOut.height = viewPortIn->height * scaleX; + viewPortOut.x = 0; + viewPortOut.y = (raster->height - viewPortOut.height) / 2; + } else { + viewPortOut.width = viewPortIn->width * scaleY; + viewPortOut.height = raster->height; + viewPortOut.x = (raster->width - viewPortOut.width) / 2; + viewPortOut.y = 0; + } + + return viewPortOut; +} + + + +/** generate_selected_modes() **************************************** + * + * Generates a list of selected modes. The list is generated by parsing + * modelines. This function makes sure that each item of the list is unique + * and sorted. + * + */ + +static void generate_selected_modes(const nvDisplayPtr display) +{ + nvSelectedModePtr selected_mode = NULL; + nvModeLinePtr modeline; + + /* Add the off item */ + selected_mode = allocate_selected_mode("Off", + NULL /* modeline */, + TRUE /* isSpecial */, + NULL /* viewPortIn */, + NULL /* viewPortOut */); + + display->num_selected_modes = 1; + display->selected_modes = selected_mode; + + modeline = display->modelines; + while (modeline) { + gchar *name; + Bool isSpecial; + + if (IS_NVIDIA_DEFAULT_MODE(modeline)) { + name = g_strdup_printf("Auto"); + isSpecial = TRUE; + } else { + name = g_strdup_printf("%dx%d", + modeline->data.hdisplay, + modeline->data.vdisplay); + isSpecial = FALSE; + } + + selected_mode = allocate_selected_mode(name, modeline, isSpecial, + NULL /* viewPortIn */, + NULL /* viewPortOut */); + g_free(name); + + if (append_unique_selected_mode(display->selected_modes, + selected_mode)) { + display->num_selected_modes++; + + if (matches_current_selected_mode(display, selected_mode, + FALSE /* compare_viewports */)) { + display->cur_selected_mode = selected_mode; + } + } else { + free(selected_mode); + } + + modeline = modeline->next; + } +} + + + +/** generate_scaled_selected_modes() ********************************* + * + * Appends a list of scaled selected modes. The list is generated by parsing + * an array of common resolutions. This function makes sure that each item + * of the list is unique and sorted. The generated items are appended to the + * list of selected modes returned by generate_selected_modes(). + * + */ + +static void generate_scaled_selected_modes(const nvDisplayPtr display) +{ + int resIndex; + nvModeLinePtr default_modeline; + nvSelectedModePtr selected_mode = NULL; + const nvSize *commonResolutions; + nvSize raster; + gchar *name; + + if (!display || !display->modelines) { + return; + } + + default_modeline = get_default_modeline(display); + if (default_modeline == NULL) { + return; + } + + raster.width = default_modeline->data.hdisplay; + raster.height = default_modeline->data.vdisplay; + + commonResolutions = get_common_resolutions(); + + resIndex = 0; + while ((commonResolutions[resIndex].width != -1) && + (commonResolutions[resIndex].height != -1)) { + GdkRectangle viewPortOut; + nvSize viewPortIn = commonResolutions[resIndex]; + + resIndex++; + + /* Skip resolutions that are bigger than the maximum raster size */ + if ((viewPortIn.width > raster.width) || + (viewPortIn.height > raster.height)) { + continue; + } + + viewPortOut = get_scaled_viewportout(&raster, &viewPortIn); + + name = g_strdup_printf("%dx%d (scaled)", viewPortIn.width, + viewPortIn.height); + selected_mode = allocate_selected_mode(name, default_modeline, + FALSE /* isSpecial */, + &viewPortIn, &viewPortOut); + g_free(name); + + if (append_unique_selected_mode(display->selected_modes, + selected_mode)) { + display->num_selected_modes++; + + if (matches_current_selected_mode(display, selected_mode, + TRUE /* compare_viewports */)) { + display->cur_selected_mode = selected_mode; + } + } else { + free(selected_mode); + } + } +} + + + /** setup_display_resolution_dropdown() ****************************** * * Generates the resolution dropdown based on the currently selected @@ -2849,14 +3277,10 @@ static void setup_display_resolution_dropdown(CtkDisplayConfig *ctk_object) nvDisplayPtr display = ctk_display_layout_get_selected_display (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout)); - nvModeLinePtr modeline; - nvModeLinePtr modelines; - nvModeLinePtr cur_modeline; + nvSelectedModePtr selected_mode; int cur_idx = 0; /* Currently selected modeline (resolution) */ - - /* Get selection information */ if (!display->screen || !display->cur_mode) { gtk_widget_hide(ctk_object->box_display_resolution); @@ -2865,94 +3289,60 @@ static void setup_display_resolution_dropdown(CtkDisplayConfig *ctk_object) gtk_widget_show(ctk_object->box_display_resolution); gtk_widget_set_sensitive(ctk_object->box_display_resolution, TRUE); - - cur_modeline = display->cur_mode->modeline; + /* Generate dropdown content */ + free_selected_modes(display->selected_modes); + + /* Create the selected modes lookup table for the dropdown */ + display->cur_selected_mode = NULL; + generate_selected_modes(display); + + if (!ctk_object->advanced_mode) { + generate_scaled_selected_modes(display); + } - /* Create the modeline lookup table for the dropdown */ if (ctk_object->resolution_table) { free(ctk_object->resolution_table); ctk_object->resolution_table_len = 0; } ctk_object->resolution_table = - calloc(display->num_modelines + 1, sizeof(nvModeLinePtr)); + calloc(display->num_selected_modes, sizeof(nvSelectedModePtr)); if (!ctk_object->resolution_table) { goto fail; } + if (display->cur_mode->modeline) { + cur_idx = 1; /* Modeline is set, start off as 'nvidia-auto-select' */ + } else { + cur_idx = 0; /* Modeline not set, start off as 'off'. */ + } + /* Start the menu generation */ menu = gtk_menu_new(); + /* Fill dropdown menu */ + selected_mode = display->selected_modes; + while (selected_mode) { + menu_item = selected_mode->label; - /* Add the off mode */ - menu_item = gtk_menu_item_new_with_label("Off"); - if (display->screen->num_displays <= 1) { - gtk_widget_set_sensitive(menu_item, False); - } - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - gtk_widget_show(menu_item); - ctk_object->resolution_table[ctk_object->resolution_table_len++] = NULL; - - - /* Add the 'nvidia-auto-select' modeline */ - modelines = display->modelines; - if (IS_NVIDIA_DEFAULT_MODE(modelines)) { - menu_item = gtk_menu_item_new_with_label("Auto"); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); gtk_widget_show(menu_item); - ctk_object->resolution_table[ctk_object->resolution_table_len++] = - modelines; - modelines = modelines->next; - } - - /* Set the selected modeline index */ - if (cur_modeline) { - cur_idx = 1; /* Modeline is set, start off as 'nvidia-auto-select' */ - } else { - cur_idx = 0; /* Modeline not set, start off as 'off'. */ - } - + ctk_object->resolution_table[ctk_object->resolution_table_len] = + selected_mode; - /* Generate the resolution menu */ - modeline = modelines; - while (modeline) { - nvModeLinePtr m; - gchar *name; - - /* Find the first resolution that matches the current res W & H */ - m = modelines; - while (m != modeline) { - if (modeline->data.hdisplay == m->data.hdisplay && - modeline->data.vdisplay == m->data.vdisplay) { - break; - } - m = m->next; + if (selected_mode == display->cur_selected_mode) { + cur_idx = ctk_object->resolution_table_len; } - /* Add resolution if it is the first of its kind */ - if (m == modeline) { - - /* Set the current modeline idx if not already set by default */ - if (cur_modeline) { - if (!IS_NVIDIA_DEFAULT_MODE(cur_modeline) && - cur_modeline->data.hdisplay == modeline->data.hdisplay && - cur_modeline->data.vdisplay == modeline->data.vdisplay) { - cur_idx = ctk_object->resolution_table_len; - } - } - - name = g_strdup_printf("%dx%d", modeline->data.hdisplay, - modeline->data.vdisplay); - menu_item = gtk_menu_item_new_with_label(name); - g_free(name); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - gtk_widget_show(menu_item); - ctk_object->resolution_table[ctk_object->resolution_table_len++] = - modeline; + if (selected_mode->isSpecial && + !selected_mode->modeline && + display->screen->num_displays <= 1) { + gtk_widget_set_sensitive(menu_item, FALSE); } - modeline = modeline->next; + + ctk_object->resolution_table_len++; + selected_mode = selected_mode->next; } - /* Setup the menu and select the current mode */ g_signal_handlers_block_by_func @@ -3201,8 +3591,8 @@ static void setup_display_viewport_in(CtkDisplayConfig *ctk_object) mode = display->cur_mode; tmp_str = g_strdup_printf("%dx%d", - mode->viewPortIn[W], - mode->viewPortIn[H]); + mode->viewPortIn.width, + mode->viewPortIn.height); gtk_entry_set_text(GTK_ENTRY(ctk_object->txt_display_viewport_in), tmp_str); @@ -3244,10 +3634,10 @@ static void setup_display_viewport_out(CtkDisplayConfig *ctk_object) mode = display->cur_mode; tmp_str = g_strdup_printf("%dx%d%+d%+d", - mode->viewPortOut[W], - mode->viewPortOut[H], - mode->viewPortOut[X], - mode->viewPortOut[Y]); + mode->viewPortOut.width, + mode->viewPortOut.height, + mode->viewPortOut.x, + mode->viewPortOut.y); gtk_entry_set_text(GTK_ENTRY(ctk_object->txt_display_viewport_out), tmp_str); @@ -3437,8 +3827,8 @@ static void setup_display_position_offset(CtkDisplayConfig *ctk_object) mode = display->cur_mode; tmp_str = g_strdup_printf("%+d%+d", - mode->viewPortIn[X] - mode->metamode->edim[X], - mode->viewPortIn[Y] - mode->metamode->edim[Y]); + mode->pan.x - mode->metamode->edim.x, + mode->pan.y - mode->metamode->edim.y); gtk_entry_set_text(GTK_ENTRY(ctk_object->txt_display_position_offset), tmp_str); @@ -3568,7 +3958,7 @@ static void setup_display_panning(CtkDisplayConfig *ctk_object) /* Update the panning text */ mode = display->cur_mode; - tmp_str = g_strdup_printf("%dx%d", mode->pan[W], mode->pan[H]); + tmp_str = g_strdup_printf("%dx%d", mode->pan.width, mode->pan.height); gtk_entry_set_text(GTK_ENTRY(ctk_object->txt_display_panning), tmp_str); @@ -3646,12 +4036,12 @@ static void setup_screen_virtual_size(CtkDisplayConfig *ctk_object) /* Update the virtual size text */ - tmp_str = g_strdup_printf("%dx%d", screen->dim[W], screen->dim[H]); + tmp_str = g_strdup_printf("%dx%d", screen->dim.width, screen->dim.height); gtk_entry_set_text(GTK_ENTRY(ctk_object->txt_screen_virtual_size), tmp_str); g_free(tmp_str); - + } /* setup_screen_virtual_size() */ @@ -4005,7 +4395,7 @@ static void setup_screen_position_offset(CtkDisplayConfig *ctk_object) /* Update the position text */ - tmp_str = g_strdup_printf("%+d%+d", screen->dim[X], screen->dim[Y]); + tmp_str = g_strdup_printf("%+d%+d", screen->dim.x, screen->dim.y); gtk_entry_set_text(GTK_ENTRY(ctk_object->txt_screen_position_offset), tmp_str); @@ -4132,7 +4522,7 @@ static void setup_screen_page(CtkDisplayConfig *ctk_object) **/ static gint validation_fix_crowded_metamodes(CtkDisplayConfig *ctk_object, - nvScreenPtr screen) + nvScreenPtr screen) { nvDisplayPtr display; nvModePtr first_mode = NULL; @@ -4177,7 +4567,10 @@ static gint validation_fix_crowded_metamodes(CtkDisplayConfig *ctk_object, if (num > screen->gpu->max_displays) { ctk_display_layout_set_mode_modeline (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), - mode, NULL); + mode, + NULL /* modeline */, + NULL /* viewPortIn */, + NULL /* viewPortOut */); nv_info_msg(TAB, "Setting display device '%s' as Off " "for MetaMode %d on Screen %d. (There are " @@ -4215,7 +4608,9 @@ static gint validation_fix_crowded_metamodes(CtkDisplayConfig *ctk_object, ctk_display_layout_set_mode_modeline (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), first_mode, - first_mode->display->modelines); + first_mode->display->modelines, + NULL /* viewPortIn */, + NULL /* viewPortOut */); nv_info_msg(TAB, "Activating display device '%s' for MetaMode " "%d on Screen %d. (Minimally, a Screen must have " @@ -4671,12 +5066,11 @@ static void do_enable_display_for_xscreen(CtkDisplayConfig *ctk_object, /* Setup the mode */ mode = display->modes; - - mode->modeline = display->modelines; mode->metamode = metamode; - /* XXX Hopefully display->modelines is 'nvidia-auto-select' */ - mode_set_dims_from_modeline(mode, display->modelines); + mode_set_modeline(mode, display->modelines, + NULL /* viewPortIn */, + NULL /* viewPortOut */); mode->position_type = CONF_ADJ_ABSOLUTE; @@ -4702,8 +5096,8 @@ static void do_enable_display_for_xscreen(CtkDisplayConfig *ctk_object, /* Compute the right-most screen */ for (other = layout->screens; other; other = other->next_in_layout) { if (!rightmost || - ((other->dim[X] + other->dim[W]) > - (rightmost->dim[X] + rightmost->dim[W]))) { + ((other->dim.x + other->dim.width) > + (rightmost->dim.x + rightmost->dim.width))) { rightmost = other; } } @@ -4712,14 +5106,14 @@ static void do_enable_display_for_xscreen(CtkDisplayConfig *ctk_object, if (rightmost) { screen->position_type = CONF_ADJ_RIGHTOF; screen->relative_to = rightmost; - screen->dim[X] = mode->viewPortIn[X] = rightmost->dim[X]; - screen->dim[Y] = mode->viewPortIn[Y] = rightmost->dim[Y]; + screen->dim.x = mode->pan.x = rightmost->dim.x; + screen->dim.y = mode->pan.y = rightmost->dim.y; } else { screen->position_type = CONF_ADJ_ABSOLUTE; screen->relative_to = NULL; - screen->dim[X] = mode->viewPortIn[X]; - screen->dim[Y] = mode->viewPortIn[Y]; + screen->dim.x = mode->pan.x; + screen->dim.y = mode->pan.y; } @@ -4868,8 +5262,8 @@ static void do_enable_display_for_twinview(CtkDisplayConfig *ctk_object, for (other = screen->displays; other; other = other->next_in_screen) { for (mode = other->modes; mode; mode = mode->next) { if (!rightmost || - ((mode->viewPortIn[X] + mode->viewPortIn[W]) > - (rightmost->viewPortIn[X] + rightmost->viewPortIn[W]))) { + ((mode->pan.x + mode->pan.width) > + (rightmost->pan.x + rightmost->pan.width))) { rightmost = mode; } } @@ -4891,17 +5285,13 @@ static void do_enable_display_for_twinview(CtkDisplayConfig *ctk_object, if (rightmost) { mode->position_type = CONF_ADJ_RIGHTOF; mode->relative_to = rightmost->display; - mode->viewPortIn[X] = rightmost->display->cur_mode->viewPortIn[X]; - mode->viewPortIn[Y] = rightmost->display->cur_mode->viewPortIn[Y]; - mode->pan[X] = mode->viewPortIn[X]; - mode->pan[Y] = mode->viewPortIn[Y]; + mode->pan.x = rightmost->display->cur_mode->pan.x; + mode->pan.y = rightmost->display->cur_mode->pan.y; } else { mode->position_type = CONF_ADJ_ABSOLUTE; mode->relative_to = NULL; - mode->viewPortIn[X] = metamode->dim[X] + metamode->dim[W]; - mode->viewPortIn[Y] = metamode->dim[Y]; - mode->pan[X] = mode->viewPortIn[X]; - mode->pan[Y] = mode->viewPortIn[Y]; + mode->pan.x = metamode->dim.x + metamode->dim.width; + mode->pan.y = metamode->dim.y; } @@ -5148,10 +5538,8 @@ static void do_configure_display_for_twinview(CtkDisplayConfig *ctk_object, /* Duplicate position information of the last mode */ if (last_mode) { - mode->viewPortIn[X] = last_mode->viewPortIn[X]; - mode->viewPortIn[Y] = last_mode->viewPortIn[Y]; - mode->pan[X] = last_mode->pan[X]; - mode->pan[Y] = last_mode->pan[Y]; + mode->pan.x = last_mode->pan.x; + mode->pan.y = last_mode->pan.y; mode->position_type = last_mode->position_type; mode->relative_to = last_mode->relative_to; } @@ -5445,8 +5833,10 @@ static void display_refresh_changed(GtkWidget *widget, gpointer user_data) /* Update the display's currently selected mode */ ctk_display_layout_set_mode_modeline (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), - display->cur_mode, modeline); - + display->cur_mode, + modeline, + NULL /* viewPortIn */, + NULL /* viewPortOut */); /* Update the modename */ setup_display_modename(ctk_object); @@ -5468,13 +5858,13 @@ static void display_resolution_changed(GtkWidget *widget, gpointer user_data) CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data); gint idx; gint last_idx; - nvModeLinePtr modeline; + nvSelectedModePtr selected_mode; nvDisplayPtr display; /* Get the modeline and display to set */ idx = gtk_option_menu_get_history(GTK_OPTION_MENU(widget)); - modeline = ctk_object->resolution_table[idx]; + selected_mode = ctk_object->resolution_table[idx]; display = ctk_display_layout_get_selected_display (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout)); @@ -5494,7 +5884,8 @@ static void display_resolution_changed(GtkWidget *widget, gpointer user_data) */ if (!ctk_object->advanced_mode && (display->screen->num_displays == 1)) { int metamode_idx = - display_find_closest_mode_matching_modeline(display, modeline); + display_find_closest_mode_matching_modeline(display, + selected_mode->modeline); /* Select the new metamode */ if (metamode_idx >= 0) { @@ -5506,10 +5897,21 @@ static void display_resolution_changed(GtkWidget *widget, gpointer user_data) /* Select the new modeline for its resolution */ - ctk_display_layout_set_mode_modeline - (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), - display->cur_mode, modeline); - + if (selected_mode->isScaled) { + ctk_display_layout_set_mode_modeline + (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), + display->cur_mode, + selected_mode->modeline, + &selected_mode->viewPortIn, + &selected_mode->viewPortOut); + } else { + ctk_display_layout_set_mode_modeline + (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), + display->cur_mode, + selected_mode->modeline, + NULL /* viewPortIn */, + NULL /* viewPortOut */); + } /* Update the UI */ setup_display_refresh_dropdown(ctk_object); @@ -5702,8 +6104,8 @@ static void display_position_type_changed(GtkWidget *widget, ctk_display_layout_set_display_position (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), display, position_type, relative_to, - display->cur_mode->viewPortIn[X], - display->cur_mode->viewPortIn[Y]); + display->cur_mode->pan.x, + display->cur_mode->pan.y); } @@ -5803,8 +6205,8 @@ static void display_position_offset_activate(GtkWidget *widget, } /* Make coordinates relative to top left of Screen */ - x += display->cur_mode->metamode->edim[X]; - y += display->cur_mode->metamode->edim[Y]; + x += display->cur_mode->metamode->edim.x; + y += display->cur_mode->metamode->edim.y; /* Update the absolute position */ @@ -6111,8 +6513,8 @@ static void screen_position_type_changed(GtkWidget *widget, ctk_display_layout_set_screen_position (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), screen, position_type, relative_to, - screen->dim[X], - screen->dim[Y]); + screen->dim.x, + screen->dim.y); } @@ -6478,8 +6880,8 @@ static Bool switch_to_current_metamode(CtkDisplayConfig *ctk_object, metamode = screen->cur_metamode; - new_width = metamode->edim[W]; - new_height = metamode->edim[H]; + new_width = metamode->edim.width; + new_height = metamode->edim.height; new_rate = metamode->id; @@ -7183,8 +7585,8 @@ static int update_screen_metamodes(CtkDisplayConfig *ctk_object, ctk_config_statusbar_message(ctk_object->ctk_config, "Switched to MetaMode %dx%d.", - screen->cur_metamode->edim[W], - screen->cur_metamode->edim[H]); + screen->cur_metamode->edim.width, + screen->cur_metamode->edim.height); nv_info_msg(TAB, "Using > %s", screen->cur_metamode->string); @@ -7595,9 +7997,9 @@ static Bool add_display_to_screen(nvScreenPtr screen, /* Configure the virtual screen size */ if (screen->no_scanout) { conf_display = conf_screen->displays; - - conf_display->virtualX = screen->dim[W]; - conf_display->virtualY = screen->dim[H]; + + conf_display->virtualX = screen->dim.width; + conf_display->virtualY = screen->dim.height; } /* XXX Don't do any further tweaking to the display subsection. @@ -7612,7 +8014,7 @@ static Bool add_display_to_screen(nvScreenPtr screen, xconfigFreeDisplayList(&conf_screen->displays); return FALSE; - + } /* add_display_to_screen() */ @@ -7900,11 +8302,11 @@ static Bool add_adjacency_to_xconfig(nvScreenPtr screen, XConfigPtr config) adj->scrnum = screen->scrnum; adj->screen = screen->conf_screen; adj->screen_name = xconfigStrdup(screen->conf_screen->identifier); - + /* Position the X screen */ if (screen->position_type == CONF_ADJ_ABSOLUTE) { - adj->x = screen->dim[X]; - adj->y = screen->dim[Y]; + adj->x = screen->dim.x; + adj->y = screen->dim.y; } else { adj->where = screen->position_type; adj->refscreen = diff --git a/src/gtk+-2.x/ctkdisplayconfig.h b/src/gtk+-2.x/ctkdisplayconfig.h index 3371d49..e4298b2 100644 --- a/src/gtk+-2.x/ctkdisplayconfig.h +++ b/src/gtk+-2.x/ctkdisplayconfig.h @@ -104,7 +104,7 @@ typedef struct _CtkDisplayConfig GtkWidget *box_display_resolution; GtkWidget *mnu_display_resolution; - nvModeLinePtr *resolution_table; + nvSelectedModePtr *resolution_table; int resolution_table_len; GtkWidget *mnu_display_refresh; @@ -205,7 +205,7 @@ typedef struct _CtkDisplayConfig gboolean notify_user_of_reset; /* User was notified of reset requirement */ gboolean ignore_reset_events; /* Ignore reset-causing events */ - int cur_screen_pos[2]; /* Keep track of the selected X screen's position */ + GdkPoint cur_screen_pos; /* Keep track of the selected X screen's position */ GtkWidget *btn_save; GtkWidget *btn_probe; diff --git a/src/gtk+-2.x/ctkdisplaylayout.c b/src/gtk+-2.x/ctkdisplaylayout.c index 2066d99..c385bd0 100644 --- a/src/gtk+-2.x/ctkdisplaylayout.c +++ b/src/gtk+-2.x/ctkdisplaylayout.c @@ -311,23 +311,22 @@ static nvModePtr get_mode(nvDisplayPtr display, int mode_idx) -/** get_screen_dim *************************************************** +/** get_screen_rect ************************************************** * * Returns the dimension array to use as the screen's dimensions. * **/ -static int *get_screen_dim(nvScreenPtr screen, Bool edim) +static GdkRectangle *get_screen_rect(nvScreenPtr screen, Bool edim) { if (!screen) return NULL; if (screen->no_scanout || !screen->cur_metamode) { - return screen->dim; + return &(screen->dim); } - return edim ? screen->cur_metamode->edim : screen->cur_metamode->dim; - -} /* get_screen_dim() */ + return edim ? &(screen->cur_metamode->edim) : &(screen->cur_metamode->dim); +} @@ -343,7 +342,7 @@ static Bool get_modify_info(CtkDisplayLayout *ctk_object) { ModifyInfo *info = &(ctk_object->modify_info); Bool use_screen_instead; - int *sdim; + GdkRectangle *screen_rect; info->screen = ctk_object->selected_screen; @@ -365,11 +364,8 @@ static Bool get_modify_info(CtkDisplayLayout *ctk_object) /* Gather the initial screen dimensions */ - sdim = get_screen_dim(info->screen, 0); - info->orig_screen_dim[X] = sdim[X]; - info->orig_screen_dim[Y] = sdim[Y]; - info->orig_screen_dim[W] = sdim[W]; - info->orig_screen_dim[H] = sdim[H]; + screen_rect = get_screen_rect(info->screen, 0); + info->orig_screen_dim = *(screen_rect); /* If a display device is being moved (not panned) and @@ -406,30 +402,18 @@ static Bool get_modify_info(CtkDisplayLayout *ctk_object) if (info->display) { info->target_position_type = &(info->display->cur_mode->position_type); - if (ctk_object->modify_info.modify_panning) { - info->target_dim = info->display->cur_mode->pan; - } else { - info->target_dim = info->display->cur_mode->viewPortIn; - } + info->target_dim = &(info->display->cur_mode->pan); info->gpu = info->display->gpu; } else { info->target_position_type = &(info->screen->position_type); - info->target_dim = sdim; + info->target_dim = screen_rect; info->gpu = info->screen->gpu; } info->orig_position_type = *(info->target_position_type); - info->orig_dim[X] = info->target_dim[X]; - info->orig_dim[Y] = info->target_dim[Y]; - info->orig_dim[W] = info->target_dim[W]; - info->orig_dim[H] = info->target_dim[H]; - + info->orig_dim = *(info->target_dim); /* Initialize where we moved to */ - info->dst_dim[X] = info->orig_dim[X]; - info->dst_dim[Y] = info->orig_dim[Y]; - info->dst_dim[W] = info->orig_dim[W]; - info->dst_dim[H] = info->orig_dim[H]; - + info->dst_dim = info->orig_dim; /* Initialize snapping */ info->best_snap_v = ctk_object->snap_strength +1; @@ -438,10 +422,7 @@ static Bool get_modify_info(CtkDisplayLayout *ctk_object) /* Make sure the modify dim is up to date */ if (info->modify_dirty) { - info->modify_dim[X] = info->orig_dim[X]; - info->modify_dim[Y] = info->orig_dim[Y]; - info->modify_dim[W] = info->orig_dim[W]; - info->modify_dim[H] = info->orig_dim[H]; + info->modify_dim = info->orig_dim; info->modify_dirty = 0; } @@ -459,15 +440,15 @@ static Bool get_modify_info(CtkDisplayLayout *ctk_object) static Bool sync_scaling(CtkDisplayLayout *ctk_object) { - int *dim = ctk_object->layout->dim; + GdkRectangle *dim = &(ctk_object->layout->dim); float wscale; float hscale; float prev_scale = ctk_object->scale; - wscale = (float)(ctk_object->img_dim[W]) / (float)(dim[W]); - hscale = (float)(ctk_object->img_dim[H]) / (float)(dim[H]); + wscale = (float)(ctk_object->img_dim.width) / (float)(dim->width); + hscale = (float)(ctk_object->img_dim.height) / (float)(dim->height); - if (wscale * dim[H] > ctk_object->img_dim[H]) { + if (wscale * dim->height > ctk_object->img_dim.height) { ctk_object->scale = hscale; } else { ctk_object->scale = wscale; @@ -485,27 +466,42 @@ static Bool sync_scaling(CtkDisplayLayout *ctk_object) * **/ -static int point_in_dim(int *dim, int x, int y) +static int point_in_rect(const GdkRectangle *rect, int x, int y) { - if (x > dim[X] && x < (dim[X] + dim[W]) && - y > dim[Y] && y < (dim[Y] + dim[H])) { + if (x > rect->x && x < (rect->x + rect->width) && + y > rect->y && y < (rect->y + rect->height)) { return 1; } - + return 0; +} -} /* point_in_dim() */ +static int point_in_display(nvDisplayPtr display, int x, int y) +{ + if (!display->cur_mode) { + return 0; + } + + return point_in_rect(&(display->cur_mode->pan), x, y); +} + +static int point_in_screen(nvScreenPtr screen, int x, int y) +{ + GdkRectangle *screen_rect = get_screen_rect(screen, 1); + + return point_in_rect(screen_rect, x, y); +} /** get_point_relative_position() ************************************ * - * Determines the relative position of a point to the given dimensions - * of a box. + * Returns where the point (x, y) is, relative to the given rectangle + * as: above, below, left-of, right-of, inside/clones. * **/ -static int get_point_relative_position(int *dim, int x, int y) +static int get_point_relative_position(GdkRectangle *rect, int x, int y) { float m1, b1; float m2, b2; @@ -513,30 +509,30 @@ static int get_point_relative_position(int *dim, int x, int y) /* Point insize dim */ - if ((x >= dim[X]) && (x <= dim[X] + dim[W]) && - (y >= dim[Y]) && (y <= dim[Y] + dim[H])) { + if (point_in_rect(rect, x, y)) { return CONF_ADJ_RELATIVE; } - + /* Compute cross lines of dimensions */ - m1 = ((float) dim[H]) / ((float) dim[W]); - b1 = ((float) dim[Y]) - (m1 * ((float) dim[X])); - + m1 = ((float) rect->height) / ((float) rect->width); + b1 = ((float) rect->y) - (m1 * ((float) rect->x)); + m2 = -m1; - b2 = ((float) dim[Y]) + ((float) dim[H]) - (m2 * ((float) dim[X])); - + b2 = ((float) rect->y) + ((float) rect->height) - + (m2 * ((float) rect->x)); + /* Compute where point is relative to cross lines */ l1 = m1 * ((float) x) + b1 - ((float) y); l2 = m2 * ((float) x) + b2 - ((float) y); - + if (l1 > 0.0f) { - if (l2 > 0.0f) { + if (l2 > 0.0f) { return CONF_ADJ_ABOVE; } else { return CONF_ADJ_RIGHTOF; } } else { - if (l2 > 0.0f) { + if (l2 > 0.0f) { return CONF_ADJ_LEFTOF; } else { return CONF_ADJ_BELOW; @@ -559,10 +555,8 @@ static int get_point_relative_position(int *dim, int x, int y) /* Offset a single mode */ static void offset_mode(nvModePtr mode, int x, int y) { - mode->viewPortIn[X] += x; - mode->viewPortIn[Y] += y; - mode->pan[X] = mode->viewPortIn[X]; - mode->pan[Y] = mode->viewPortIn[Y]; + mode->pan.x += x; + mode->pan.y += y; } /* Offset a display by offsetting the current mode */ @@ -579,14 +573,14 @@ static void offset_screen(nvScreenPtr screen, int x, int y) { nvMetaModePtr metamode; - screen->dim[X] += x; - screen->dim[Y] += y; - + screen->dim.x += x; + screen->dim.y += y; + for (metamode = screen->metamodes; metamode; metamode = metamode->next) { - metamode->dim[X] += x; - metamode->dim[Y] += y; - metamode->edim[X] += x; - metamode->edim[Y] += y; + metamode->dim.x += x; + metamode->dim.y += y; + metamode->edim.x += x; + metamode->edim.y += y; } } @@ -597,8 +591,8 @@ static void offset_layout(nvLayoutPtr layout, int x, int y) nvScreenPtr screen; nvDisplayPtr display; - layout->dim[X] += x; - layout->dim[Y] += y; + layout->dim.x += x; + layout->dim.y += y; /* Offset screens */ for (screen = layout->screens; screen; screen = screen->next_in_layout) { @@ -628,60 +622,60 @@ static void offset_layout(nvLayoutPtr layout, int x, int y) **/ static int resolve_display(nvDisplayPtr display, int mode_idx, - int pos[4]) + GdkRectangle *pos) { nvModePtr mode = get_mode(display, mode_idx); - int relative_pos[4]; - + GdkRectangle relative_pos; + if (!mode) return 0; /* Set the dimensions */ - pos[W] = mode->pan[W]; - pos[H] = mode->pan[H]; + pos->width = mode->pan.width; + pos->height = mode->pan.height; /* Find the position */ switch (mode->position_type) { case CONF_ADJ_ABSOLUTE: - pos[X] = mode->pan[X]; - pos[Y] = mode->pan[Y]; + pos->x = mode->pan.x; + pos->y = mode->pan.y; break; case CONF_ADJ_RIGHTOF: - resolve_display(mode->relative_to, mode_idx, relative_pos); - pos[X] = relative_pos[X] + relative_pos[W]; - pos[Y] = relative_pos[Y]; + resolve_display(mode->relative_to, mode_idx, &relative_pos); + pos->x = relative_pos.x + relative_pos.width; + pos->y = relative_pos.y; break; case CONF_ADJ_LEFTOF: - resolve_display(mode->relative_to, mode_idx, relative_pos); - pos[X] = relative_pos[X] - pos[W]; - pos[Y] = relative_pos[Y]; + resolve_display(mode->relative_to, mode_idx, &relative_pos); + pos->x = relative_pos.x - pos->width; + pos->y = relative_pos.y; break; case CONF_ADJ_BELOW: - resolve_display(mode->relative_to, mode_idx, relative_pos); - pos[X] = relative_pos[X]; - pos[Y] = relative_pos[Y] + relative_pos[H]; + resolve_display(mode->relative_to, mode_idx, &relative_pos); + pos->x = relative_pos.x; + pos->y = relative_pos.y + relative_pos.height; break; case CONF_ADJ_ABOVE: - resolve_display(mode->relative_to, mode_idx, relative_pos); - pos[X] = relative_pos[X]; - pos[Y] = relative_pos[Y] - pos[H]; + resolve_display(mode->relative_to, mode_idx, &relative_pos); + pos->x = relative_pos.x; + pos->y = relative_pos.y - pos->height; break; case CONF_ADJ_RELATIVE: /* Clone */ - resolve_display(mode->relative_to, mode_idx, relative_pos); - pos[X] = relative_pos[X]; - pos[Y] = relative_pos[Y]; + resolve_display(mode->relative_to, mode_idx, &relative_pos); + pos->x = relative_pos.x; + pos->y = relative_pos.y; break; default: return 0; } - + return 1; } /* resolve_display() */ @@ -699,7 +693,7 @@ static void resolve_displays_in_screen(nvScreenPtr screen, int resolve_all_modes) { nvDisplayPtr display; - int pos[4]; + GdkRectangle rect; int first_idx; int last_idx; int mode_idx; @@ -718,12 +712,10 @@ static void resolve_displays_in_screen(nvScreenPtr screen, display = display->next_in_screen) { for (mode_idx = first_idx; mode_idx <= last_idx; mode_idx++) { - if (resolve_display(display, mode_idx, pos)) { + if (resolve_display(display, mode_idx, &rect)) { nvModePtr mode = get_mode(display, mode_idx); - mode->viewPortIn[X] = pos[X]; - mode->viewPortIn[Y] = pos[Y]; - mode->pan[X] = pos[X]; - mode->pan[Y] = pos[Y]; + mode->pan.x = rect.x; + mode->pan.y = rect.y; } } } @@ -746,61 +738,60 @@ static void resolve_displays_in_screen(nvScreenPtr screen, * **/ -static int resolve_screen(nvScreenPtr screen, int pos[4]) +static int resolve_screen(nvScreenPtr screen, GdkRectangle *pos) { - int *sdim = get_screen_dim(screen, 0); - int relative_pos[4]; - + GdkRectangle *screen_rect = get_screen_rect(screen, 0); + GdkRectangle relative_pos; - if (!sdim) return 0; + if (!screen_rect) return 0; /* Set the dimensions */ - pos[W] = sdim[W]; - pos[H] = sdim[H]; + pos->width = screen_rect->width; + pos->height = screen_rect->height; /* Find the position */ switch (screen->position_type) { case CONF_ADJ_ABSOLUTE: - pos[X] = sdim[X]; - pos[Y] = sdim[Y]; + pos->x = screen_rect->x; + pos->y = screen_rect->y; break; case CONF_ADJ_RIGHTOF: - resolve_screen(screen->relative_to, relative_pos); - pos[X] = relative_pos[X] + relative_pos[W]; - pos[Y] = relative_pos[Y]; + resolve_screen(screen->relative_to, &relative_pos); + pos->x = relative_pos.x + relative_pos.width; + pos->y = relative_pos.y; break; case CONF_ADJ_LEFTOF: - resolve_screen(screen->relative_to, relative_pos); - pos[X] = relative_pos[X] - pos[W]; - pos[Y] = relative_pos[Y]; + resolve_screen(screen->relative_to, &relative_pos); + pos->x = relative_pos.x - pos->width; + pos->y = relative_pos.y; break; case CONF_ADJ_BELOW: - resolve_screen(screen->relative_to, relative_pos); - pos[X] = relative_pos[X]; - pos[Y] = relative_pos[Y] + relative_pos[H]; + resolve_screen(screen->relative_to, &relative_pos); + pos->x = relative_pos.x; + pos->y = relative_pos.y + relative_pos.height; break; case CONF_ADJ_ABOVE: - resolve_screen(screen->relative_to, relative_pos); - pos[X] = relative_pos[X]; - pos[Y] = relative_pos[Y] - pos[H]; + resolve_screen(screen->relative_to, &relative_pos); + pos->x = relative_pos.x; + pos->y = relative_pos.y - pos->height; break; case CONF_ADJ_RELATIVE: /* Clone */ - resolve_screen(screen->relative_to, relative_pos); - pos[X] = relative_pos[X]; - pos[Y] = relative_pos[Y]; + resolve_screen(screen->relative_to, &relative_pos); + pos->x = relative_pos.x; + pos->y = relative_pos.y; break; default: return 0; } - + return 1; } /* resolve_screen() */ @@ -817,19 +808,19 @@ static int resolve_screen(nvScreenPtr screen, int pos[4]) static void resolve_screen_in_layout(nvScreenPtr screen) { nvDisplayPtr display; - int pos[4]; + GdkRectangle pos; int x, y; - int *sdim; + GdkRectangle *screen_rect; /* Resolve the current screen location */ - if (resolve_screen(screen, pos)) { + if (resolve_screen(screen, &pos)) { /* Move the screen and the displays by offsetting */ - sdim = get_screen_dim(screen, 0); + screen_rect = get_screen_rect(screen, 0); - x = pos[X] - sdim[X]; - y = pos[Y] - sdim[Y]; + x = pos.x - screen_rect->x; + y = pos.y - screen_rect->y; offset_screen(screen, x, y); @@ -884,23 +875,20 @@ static void calc_metamode(nvScreenPtr screen, nvMetaModePtr metamode) nvModePtr mode; int init = 1; int einit = 1; - int *dim; // Bounding box for all modes, including NULL modes. - int *edim; // Bounding box for non-NULL modes. + GdkRectangle *dim; // Bounding box for all modes, including NULL modes. + GdkRectangle *edim; // Bounding box for non-NULL modes. if (!screen || !metamode) { return; } - dim = metamode->dim; - edim = metamode->edim; + dim = &(metamode->dim); + edim = &(metamode->edim); - dim[X] = edim[X] = 0; - dim[Y] = edim[Y] = 0; - dim[W] = edim[W] = 0; - dim[H] = edim[H] = 0; + memset(dim, 0, sizeof(*dim)); + memset(edim, 0, sizeof(*edim)); - /* Calculate its dimensions */ for (display = screen->displays; display; display = display->next_in_screen) { @@ -912,42 +900,23 @@ static void calc_metamode(nvScreenPtr screen, nvMetaModePtr metamode) if (!mode) continue; if (init) { - dim[X] = mode->pan[X]; - dim[Y] = mode->pan[Y]; - dim[W] = mode->pan[X] +mode->pan[W]; - dim[H] = mode->pan[Y] +mode->pan[H]; + *dim = mode->pan; init = 0; } else { - dim[X] = MIN(dim[X], mode->viewPortIn[X]); - dim[Y] = MIN(dim[Y], mode->viewPortIn[Y]); - dim[W] = MAX(dim[W], mode->viewPortIn[X] +mode->pan[W]); - dim[H] = MAX(dim[H], mode->viewPortIn[Y] +mode->pan[H]); + gdk_rectangle_union(dim, &(mode->pan), dim); } /* Don't include NULL modes in the effective dimension calculation */ if (!mode->modeline) continue; if (einit) { - edim[X] = mode->pan[X]; - edim[Y] = mode->pan[Y]; - edim[W] = mode->pan[X] +mode->pan[W]; - edim[H] = mode->pan[Y] +mode->pan[H]; + *edim = mode->pan; einit = 0; } else { - edim[X] = MIN(edim[X], mode->viewPortIn[X]); - edim[Y] = MIN(edim[Y], mode->viewPortIn[Y]); - edim[W] = MAX(edim[W], mode->viewPortIn[X] +mode->pan[W]); - edim[H] = MAX(edim[H], mode->viewPortIn[Y] +mode->pan[H]); + gdk_rectangle_union(edim, &(mode->pan), edim); } } - - dim[W] = dim[W] - dim[X]; - dim[H] = dim[H] - dim[Y]; - - edim[W] = edim[W] - edim[X]; - edim[H] = edim[H] - edim[Y]; - -} /* calc_metamode() */ +} @@ -963,43 +932,31 @@ static void calc_metamode(nvScreenPtr screen, nvMetaModePtr metamode) static void calc_screen(nvScreenPtr screen) { nvMetaModePtr metamode; - int *dim; + GdkRectangle *dim; if (!screen || screen->no_scanout) return; - dim = screen->dim; + dim = &(screen->dim); metamode = screen->metamodes; if (!metamode) { - dim[X] = 0; - dim[Y] = 0; - dim[W] = 0; - dim[H] = 0; + memset(dim, 0, sizeof(*dim)); return; } + /* Init screen dimensions to size of first metamode */ calc_metamode(screen, metamode); - dim[X] = metamode->dim[X]; - dim[Y] = metamode->dim[Y]; - dim[W] = metamode->dim[X] +metamode->dim[W]; - dim[H] = metamode->dim[Y] +metamode->dim[H]; - + *dim = metamode->dim; + for (metamode = metamode->next; metamode; metamode = metamode->next) { calc_metamode(screen, metamode); - dim[X] = MIN(dim[X], metamode->dim[X]); - dim[Y] = MIN(dim[Y], metamode->dim[Y]); - dim[W] = MAX(dim[W], metamode->dim[X] +metamode->dim[W]); - dim[H] = MAX(dim[H], metamode->dim[Y] +metamode->dim[H]); + gdk_rectangle_union(dim, &(metamode->dim), dim); } - - dim[W] = dim[W] - dim[X]; - dim[H] = dim[H] - dim[Y]; - -} /* calc_screen() */ +} @@ -1020,7 +977,7 @@ static void calc_layout(nvLayoutPtr layout) nvScreenPtr screen; nvDisplayPtr display; int init = 1; - int *dim; + GdkRectangle *dim; int x, y; @@ -1028,58 +985,41 @@ static void calc_layout(nvLayoutPtr layout) resolve_layout(layout); - dim = layout->dim; - dim[X] = 0; - dim[Y] = 0; - dim[W] = 0; - dim[H] = 0; + dim = &(layout->dim); + memset(dim, 0, sizeof(*dim)); for (screen = layout->screens; screen; screen = screen->next_in_layout) { - int *sdim; + GdkRectangle *screem_rect; calc_screen(screen); - sdim = get_screen_dim(screen, 0); + screem_rect = get_screen_rect(screen, 0); if (init) { - dim[X] = sdim[X]; - dim[Y] = sdim[Y]; - dim[W] = sdim[X] +sdim[W]; - dim[H] = sdim[Y] +sdim[H]; + *dim = *screem_rect; init = 0; continue; } - - dim[X] = MIN(dim[X], sdim[X]); - dim[Y] = MIN(dim[Y], sdim[Y]); - dim[W] = MAX(dim[W], sdim[X] +sdim[W]); - dim[H] = MAX(dim[H], sdim[Y] +sdim[H]); + gdk_rectangle_union(dim, screem_rect, dim); } - dim[W] = dim[W] - dim[X]; - dim[H] = dim[H] - dim[Y]; - - /* Position disabled display devices off to the top right */ - x = dim[W] + dim[X]; - y = dim[Y]; + x = dim->x + dim->width; + y = dim->y; for (gpu = layout->gpus; gpu; gpu = gpu->next_in_layout) { for (display = gpu->displays; display; display = display->next_on_gpu) { if (display->screen) continue; - display->cur_mode->viewPortIn[X] = x; - display->cur_mode->pan[X] = x; - display->cur_mode->viewPortIn[Y] = y; - display->cur_mode->pan[Y] = y; + display->cur_mode->pan.x = x; + display->cur_mode->pan.y = y; - x += display->cur_mode->viewPortIn[W]; - dim[W] += display->cur_mode->viewPortIn[W]; - dim[H] = MAX(dim[H], display->cur_mode->viewPortIn[H]); + x += display->cur_mode->pan.width; + dim->width += display->cur_mode->pan.width; + dim->height = MAX(dim->height, display->cur_mode->pan.height); } } - -} /* calc_layout() */ +} @@ -1101,8 +1041,8 @@ static void recenter_screen(nvScreenPtr screen) nvModePtr mode; for (mode = display->modes; mode; mode = mode->next) { - int offset_x = (screen->dim[X] - mode->metamode->dim[X]); - int offset_y = (screen->dim[Y] - mode->metamode->dim[Y]); + int offset_x = (screen->dim.x - mode->metamode->dim.x); + int offset_y = (screen->dim.y - mode->metamode->dim.y); offset_mode(mode, offset_x, offset_y); } } @@ -1140,8 +1080,8 @@ static Bool set_screen_metamode(nvLayoutPtr layout, nvScreenPtr screen, /* Recalculate the layout dimensions */ calc_layout(layout); - if (layout->dim[X] || layout->dim[Y]) { - offset_layout(layout, -layout->dim[X], -layout->dim[Y]); + if (layout->dim.x || layout->dim.y) { + offset_layout(layout, -layout->dim.x, -layout->dim.y); return TRUE; } @@ -1204,8 +1144,8 @@ static Bool recenter_layout(nvLayoutPtr layout) static void reposition_screen(nvScreenPtr screen, int resolve_all_modes) { - int orig_screen_x = screen->dim[X]; - int orig_screen_y = screen->dim[Y]; + int orig_screen_x = screen->dim.x; + int orig_screen_y = screen->dim.y; /* Resolve new relative positions. In basic mode, * relative position changes apply to all modes of a @@ -1215,8 +1155,8 @@ static void reposition_screen(nvScreenPtr screen, int resolve_all_modes) resolve_displays_in_screen(screen, resolve_all_modes); /* Reestablish the screen's original position */ - screen->dim[X] = orig_screen_x; - screen->dim[Y] = orig_screen_y; + screen->dim.x = orig_screen_x; + screen->dim.y = orig_screen_y; recenter_screen(screen); } /* reposition_screen() */ @@ -1247,7 +1187,7 @@ static void switch_screen_to_absolute(nvScreenPtr screen) /** snap_dim_to_dim() *********************************************** * - * Snaps the sides of two rectangles together. + * Snaps the sides of two rectangles together. * * Snaps the dimensions of "src" to those of "snap" if any part * of the "src" rectangle is within "snap_strength" of the "snap" @@ -1260,7 +1200,8 @@ static void switch_screen_to_absolute(nvScreenPtr screen) * **/ -static void snap_dim_to_dim(int *dst, int *src, int *snap, int snap_strength, +static void snap_dim_to_dim(GdkRectangle *dst, GdkRectangle *src, + GdkRectangle *snap, int snap_strength, int *best_vert, int *best_horz) { int dist; @@ -1270,43 +1211,43 @@ static void snap_dim_to_dim(int *dst, int *src, int *snap, int snap_strength, if (best_vert) { /* Snap top side to top side */ - dist = abs(snap[Y] - src[Y]); + dist = abs(snap->y - src->y); if (dist < *best_vert) { - dst[Y] = snap[Y]; + dst->y = snap->y; *best_vert = dist; } - + /* Snap top side to bottom side */ - dist = abs((snap[Y] + snap[H]) - src[Y]); + dist = abs((snap->y + snap->height) - src->y); if (dist < *best_vert) { - dst[Y] = snap[Y] + snap[H]; + dst->y = snap->y + snap->height; *best_vert = dist; } - + /* Snap bottom side to top side */ - dist = abs(snap[Y] - (src[Y] + src[H])); + dist = abs(snap->y - (src->y + src->height)); if (dist < *best_vert) { - dst[Y] = snap[Y] - src[H]; + dst->y = snap->y - src->height; *best_vert = dist; } - + /* Snap bottom side to bottom side */ - dist = abs((snap[Y] + snap[H]) - (src[Y] + src[H])); + dist = abs((snap->y + snap->height) - (src->y + src->height)); if (dist < *best_vert) { - dst[Y] = snap[Y] + snap[H] - src[H]; + dst->y = snap->y + snap->height - src->height; *best_vert = dist; } - + /* Snap midlines */ if (/* Top of 'src' is above bottom of 'snap' */ - (src[Y] <= snap[Y] + snap[H] + snap_strength) && + (src->y <= snap->y + snap->height + snap_strength) && /* Bottom of 'src' is below top of 'snap' */ - (src[Y] + src[H] >= snap[Y] - snap_strength)) { - + (src->y + src->height >= snap->y - snap_strength)) { + /* Snap vertically */ - dist = abs((snap[Y] + snap[H]/2) - (src[Y]+src[H]/2)); + dist = abs((snap->y + snap->height/2) - (src->y + src->height/2)); if (dist < *best_vert) { - dst[Y] = snap[Y] + snap[H]/2 - src[H]/2; + dst->y = snap->y + snap->height/2 - src->height/2; *best_vert = dist; } } @@ -1315,45 +1256,45 @@ static void snap_dim_to_dim(int *dst, int *src, int *snap, int snap_strength, /* Snap horizontally */ if (best_horz) { - + /* Snap left side to left side */ - dist = abs(snap[X] - src[X]); + dist = abs(snap->x - src->x); if (dist < *best_horz) { - dst[X] = snap[X]; + dst->x = snap->x; *best_horz = dist; } - + /* Snap left side to right side */ - dist = abs((snap[X] + snap[W]) - src[X]); + dist = abs((snap->x + snap->width) - src->x); if (dist < *best_horz) { - dst[X] = snap[X] + snap[W]; + dst->x = snap->x + snap->width; *best_horz = dist; } - + /* Snap right side to left side */ - dist = abs(snap[X] - (src[X] + src[W])); + dist = abs(snap->x - (src->x + src->width)); if (dist < *best_horz) { - dst[X] = snap[X] - src[W]; + dst->x = snap->x - src->width; *best_horz = dist; } - + /* Snap right side to right side */ - dist = abs((snap[X] + snap[W]) - (src[X]+src[W])); + dist = abs((snap->x + snap->width) - (src->x + src->width)); if (dist < *best_horz) { - dst[X] = snap[X] + snap[W] - src[W]; + dst->x = snap->x + snap->width - src->width; *best_horz = dist; } - + /* Snap midlines */ if (/* Left of 'src' is before right of 'snap' */ - (src[X] <= snap[X] + snap[W] + snap_strength) && + (src->x <= snap->x + snap->width + snap_strength) && /* Right of 'src' is after left of 'snap' */ - (src[X] + src[W] >= snap[X] - snap_strength)) { - + (src->x + src->width >= snap->x - snap_strength)) { + /* Snap vertically */ - dist = abs((snap[X] + snap[W]/2) - (src[X]+src[W]/2)); + dist = abs((snap->x + snap->width/2) - (src->x + src->width/2)); if (dist < *best_horz) { - dst[X] = snap[X] + snap[W]/2 - src[W]/2; + dst->x = snap->x + snap->width/2 - src->width/2; *best_horz = dist; } } @@ -1371,26 +1312,27 @@ static void snap_dim_to_dim(int *dst, int *src, int *snap, int snap_strength, * **/ -static void snap_side_to_dim(int *dst, int *src, int *snap, +static void snap_side_to_dim(GdkRectangle *dst, GdkRectangle *src, + GdkRectangle *snap, int *best_vert, int *best_horz) { int dist; - + /* Snap vertically */ if (best_vert) { /* Snap side to top side */ - dist = abs(snap[Y] - (src[Y] + src[H])); + dist = abs(snap->y - (src->y + src->height)); if (dist < *best_vert) { - dst[H] = snap[Y] - src[Y]; + dst->height = snap->y - src->y; *best_vert = dist; } - + /* Snap side to bottom side */ - dist = abs((snap[Y] + snap[H]) - (src[Y] + src[H])); + dist = abs((snap->y + snap->height) - (src->y + src->height)); if (dist < *best_vert) { - dst[H] = snap[Y] + snap[H] - src[Y]; + dst->height = snap->y + snap->height - src->y; *best_vert = dist; } } @@ -1400,16 +1342,16 @@ static void snap_side_to_dim(int *dst, int *src, int *snap, if (best_horz) { /* Snap side to left side */ - dist = abs(snap[X] - (src[X] + src[W])); + dist = abs(snap->x - (src->x + src->width)); if (dist < *best_horz) { - dst[W] = snap[X] - src[X]; + dst->width = snap->x - src->x; *best_horz = dist; } - + /* Snap side to right side */ - dist = abs((snap[X] + snap[W]) - (src[X] + src[W])); + dist = abs((snap->x + snap->width) - (src->x + src->width)); if (dist < *best_horz) { - dst[W] = snap[X] + snap[W] - src[X]; + dst->width = snap->x + snap->width - src->x; *best_horz = dist; } } @@ -1438,15 +1380,15 @@ static void snap_move(CtkDisplayLayout *ctk_object) nvLayoutPtr layout = ctk_object->layout; nvScreenPtr screen; nvDisplayPtr other; - int *sdim; + GdkRectangle *screen_rect; /* Snap to other display's modes */ if (info->display) { for (i = 0; i < ctk_object->Zcount; i++) { - + if (ctk_object->Zorder[i].type != ZNODE_TYPE_DISPLAY) continue; - + other = ctk_object->Zorder[i].u.display; /* Other display must have a mode */ @@ -1493,18 +1435,22 @@ static void snap_move(CtkDisplayLayout *ctk_object) (info->screen->relative_to == other->screen)) { bv = NULL; } - + /* Snap to other display's panning dimensions */ - snap_dim_to_dim(info->dst_dim, - info->src_dim, - other->cur_mode->pan, + snap_dim_to_dim(&(info->dst_dim), + &(info->src_dim), + &(other->cur_mode->pan), ctk_object->snap_strength, bv, bh); /* Snap to other display's dimensions */ - snap_dim_to_dim(info->dst_dim, - info->src_dim, - other->cur_mode->viewPortIn, - ctk_object->snap_strength, bv, bh); + { + GdkRectangle rect; + get_viewportin_rect(other->cur_mode, &rect); + snap_dim_to_dim(&(info->dst_dim), + &(info->src_dim), + &rect, + ctk_object->snap_strength, bv, bh); + } } } /* Done snapping to other displays */ @@ -1542,7 +1488,7 @@ static void snap_move(CtkDisplayLayout *ctk_object) */ if (!bh && info->display && - info->display->cur_mode->viewPortIn[Y] == info->screen->dim[Y]) { + info->display->cur_mode->pan.y == info->screen->dim.y) { bv = NULL; } @@ -1563,14 +1509,14 @@ static void snap_move(CtkDisplayLayout *ctk_object) */ if (!bv && info->display && - info->display->cur_mode->viewPortIn[X] == info->screen->dim[X]) { + info->display->cur_mode->pan.x == info->screen->dim.x) { bh = NULL; } - sdim = get_screen_dim(screen, 0); - snap_dim_to_dim(info->dst_dim, - info->src_dim, - sdim, + screen_rect = get_screen_rect(screen, 0); + snap_dim_to_dim(&(info->dst_dim), + &(info->src_dim), + screen_rect, ctk_object->snap_strength, bv, bh); } @@ -1579,18 +1525,18 @@ static void snap_move(CtkDisplayLayout *ctk_object) bh = &info->best_snap_h; if (info->display) { - dist = abs( (info->screen->dim[X] + info->gpu->max_width) - -(info->src_dim[X] + info->src_dim[W])); + dist = abs( (info->screen->dim.x + info->gpu->max_width) + -(info->src_dim.x + info->src_dim.width)); if (dist < *bh) { - info->dst_dim[X] = - info->screen->dim[X] + info->gpu->max_width - info->src_dim[W]; + info->dst_dim.x = info->screen->dim.x + info->gpu->max_width - + info->src_dim.width; *bh = dist; } - dist = abs( (info->screen->dim[Y] + info->gpu->max_height) - -(info->src_dim[Y] + info->src_dim[H])); + dist = abs( (info->screen->dim.y + info->gpu->max_height) + -(info->src_dim.y + info->src_dim.height)); if (dist < *bv) { - info->dst_dim[Y] = - info->screen->dim[Y] + info->gpu->max_height - info->src_dim[H]; + info->dst_dim.y = info->screen->dim.y + info->gpu->max_height - + info->src_dim.height; *bv = dist; } } @@ -1622,38 +1568,40 @@ static void snap_pan(CtkDisplayLayout *ctk_object) nvLayoutPtr layout = ctk_object->layout; nvScreenPtr screen; nvDisplayPtr other; - int *sdim; + GdkRectangle *screen_rect; if (info->display) { - int *cur_mode_dim = info->display->cur_mode->viewPortIn; - /* Snap to multiples of the display's dimensions */ + const nvSize *cur_mode_size = &(info->display->cur_mode->viewPortIn); + bh = &(info->best_snap_h); bv = &(info->best_snap_v); - dist = info->src_dim[W] % cur_mode_dim[W]; + dist = info->src_dim.width % cur_mode_size->width; if (dist < *bh) { - info->dst_dim[W] = cur_mode_dim[W] * - (int)(info->src_dim[W] / cur_mode_dim[W]); + info->dst_dim.width = cur_mode_size->width * + (int)(info->src_dim.width / cur_mode_size->width); *bh = dist; } - dist = cur_mode_dim[W] - (info->src_dim[W] % cur_mode_dim[W]); + dist = cur_mode_size->width - + (info->src_dim.width % cur_mode_size->width); if (dist < *bh) { - info->dst_dim[W] = cur_mode_dim[W] * - (1 + (int)(info->src_dim[W] / cur_mode_dim[W])); + info->dst_dim.width = cur_mode_size->width * + (1 + (int)(info->src_dim.width / cur_mode_size->width)); *bh = dist; } - dist = abs(info->src_dim[H] % cur_mode_dim[H]); + dist = abs(info->src_dim.height % cur_mode_size->height); if (dist < *bv) { - info->dst_dim[H] = cur_mode_dim[H] * - (int)(info->src_dim[H] / cur_mode_dim[H]); + info->dst_dim.height = cur_mode_size->height * + (int)(info->src_dim.height / cur_mode_size->height); *bv = dist; } - dist = cur_mode_dim[H] - (info->src_dim[H] % cur_mode_dim[H]); + dist = cur_mode_size->height - + (info->src_dim.height % cur_mode_size->height); if (dist < *bv) { - info->dst_dim[H] = cur_mode_dim[H] * - (1 + (int)(info->src_dim[H] / cur_mode_dim[H])); + info->dst_dim.height = cur_mode_size->height * + (1 + (int)(info->src_dim.height / cur_mode_size->height)); *bv = dist; } } @@ -1725,16 +1673,20 @@ static void snap_pan(CtkDisplayLayout *ctk_object) } /* Snap to other display panning dimensions */ - snap_side_to_dim(info->dst_dim, - info->src_dim, - other->cur_mode->pan, + snap_side_to_dim(&(info->dst_dim), + &(info->src_dim), + &(other->cur_mode->pan), bv, bh); /* Snap to other display dimensions */ - snap_side_to_dim(info->dst_dim, - info->src_dim, - other->cur_mode->viewPortIn, - bv, bh); + { + GdkRectangle rect; + get_viewportin_rect(other->cur_mode, &rect); + snap_side_to_dim(&(info->dst_dim), + &(info->src_dim), + &rect, + bv, bh); + } } @@ -1772,10 +1724,10 @@ static void snap_pan(CtkDisplayLayout *ctk_object) bv = NULL; } - sdim = get_screen_dim(screen, 0); - snap_side_to_dim(info->dst_dim, - info->src_dim, - sdim, + screen_rect = get_screen_rect(screen, 0); + snap_side_to_dim(&(info->dst_dim), + &(info->src_dim), + screen_rect, bv, bh); } @@ -1783,20 +1735,20 @@ static void snap_pan(CtkDisplayLayout *ctk_object) bv = &(info->best_snap_v); /* Snap to the maximum screen width */ - dist = abs((info->screen->dim[X] + info->gpu->max_width) - -(info->src_dim[X] + info->src_dim[W])); + dist = abs((info->screen->dim.x + info->gpu->max_width) + -(info->src_dim.x + info->src_dim.width)); if (dist < *bh) { - info->dst_dim[W] = info->screen->dim[X] + info->gpu->max_width - - info->src_dim[X]; + info->dst_dim.width = info->screen->dim.x + info->gpu->max_width - + info->src_dim.x; *bh = dist; } /* Snap to the maximum screen height */ - dist = abs((info->screen->dim[Y] + info->gpu->max_height) - -(info->src_dim[Y] + info->src_dim[H])); + dist = abs((info->screen->dim.y + info->gpu->max_height) + -(info->src_dim.y + info->src_dim.height)); if (dist < *bv) { - info->dst_dim[H] = info->screen->dim[Y] + info->gpu->max_height - - info->src_dim[Y]; + info->dst_dim.height = info->screen->dim.y + info->gpu->max_height - + info->src_dim.y; *bv = dist; } @@ -1820,8 +1772,8 @@ static int move_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap) ModifyInfo *info = &(ctk_object->modify_info); int modified = 0; - int *dim; /* Temp dimensions */ - int *sdim; /* Temp screen dimensions */ + GdkRectangle *dim; /* Temp dimensions */ + GdkRectangle *sdim; /* Temp screen dimensions */ info->modify_panning = 0; @@ -1836,15 +1788,15 @@ static int move_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap) * fairly cleanly with common code, so do that here. */ if (info->orig_position_type != CONF_ADJ_ABSOLUTE) { - int p_x = (ctk_object->mouse_x - ctk_object->img_dim[X]) / + int p_x = (ctk_object->mouse_x - ctk_object->img_dim.x) / ctk_object->scale; - int p_y = (ctk_object->mouse_y - ctk_object->img_dim[Y]) / + int p_y = (ctk_object->mouse_y - ctk_object->img_dim.y) / ctk_object->scale; if (info->display) { - dim = info->display->cur_mode->relative_to->cur_mode->viewPortIn; + dim = &(info->display->cur_mode->relative_to->cur_mode->pan); } else { - dim = get_screen_dim(info->screen->relative_to, 0); + dim = get_screen_rect(info->screen->relative_to, 0); } if (dim) { @@ -1876,87 +1828,77 @@ static int move_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap) /* Move via absolute positioning */ /* Compute pre-snap dimensions */ - info->modify_dim[X] += x; - info->modify_dim[Y] += y; + info->modify_dim.x += x; + info->modify_dim.y += y; - info->dst_dim[X] = info->modify_dim[X]; - info->dst_dim[Y] = info->modify_dim[Y]; - info->dst_dim[W] = info->modify_dim[W]; - info->dst_dim[H] = info->modify_dim[H]; + info->dst_dim = info->modify_dim; /* Snap to other screens and displays */ if (snap && ctk_object->snap_strength) { - info->src_dim[X] = info->dst_dim[X]; - info->src_dim[Y] = info->dst_dim[Y]; - info->src_dim[W] = info->dst_dim[W]; - info->src_dim[H] = info->dst_dim[H]; - + info->src_dim = info->dst_dim; snap_move(ctk_object); if (info->display) { /* Also snap display's panning box to other screens/displays */ - info->src_dim[W] = info->display->cur_mode->pan[W]; - info->src_dim[H] = info->display->cur_mode->pan[H]; - info->dst_dim[W] = info->src_dim[W]; - info->dst_dim[H] = info->src_dim[H]; + info->src_dim.width = info->display->cur_mode->pan.width; + info->src_dim.height = info->display->cur_mode->pan.height; + + info->dst_dim.width = info->src_dim.width; + info->dst_dim.height = info->src_dim.height; snap_move(ctk_object); } } /* Get the bounding dimensions of what is being moved */ - if (info->display) { - dim = info->display->cur_mode->pan; - } else { - dim = info->target_dim; - } - sdim = get_screen_dim(info->screen, 1); + dim = info->target_dim; + sdim = get_screen_rect(info->screen, 1); /* Prevent moving out of the max layout bounds */ - x = MAX_LAYOUT_WIDTH - dim[W]; - if (info->dst_dim[X] > x) { - info->modify_dim[X] += x - info->dst_dim[X]; - info->dst_dim[X] = x; + x = MAX_LAYOUT_WIDTH - dim->width; + if (info->dst_dim.x > x) { + info->modify_dim.x += x - info->dst_dim.x; + info->dst_dim.x = x; } - y = MAX_LAYOUT_HEIGHT - dim[H]; - if (info->dst_dim[Y] > y) { - info->modify_dim[Y] += y - info->dst_dim[Y]; - info->dst_dim[Y] = y; + y = MAX_LAYOUT_HEIGHT - dim->height; + if (info->dst_dim.y > y) { + info->modify_dim.y += y - info->dst_dim.y; + info->dst_dim.y = y; } - x = layout->dim[W] - MAX_LAYOUT_WIDTH; - if (info->dst_dim[X] < x) { - info->modify_dim[X] += x - info->dst_dim[X]; - info->dst_dim[X] = x; + x = layout->dim.width - MAX_LAYOUT_WIDTH; + if (info->dst_dim.x < x) { + info->modify_dim.x += x - info->dst_dim.x; + info->dst_dim.x = x; } - y = layout->dim[H] - MAX_LAYOUT_HEIGHT; - if (info->dst_dim[Y] < y) { - info->modify_dim[Y] += y - info->dst_dim[Y]; - info->dst_dim[Y] = y; + y = layout->dim.height - MAX_LAYOUT_HEIGHT; + if (info->dst_dim.y < y) { + info->modify_dim.y += y - info->dst_dim.y; + info->dst_dim.y = y; } /* Prevent screen from growing too big */ - x = sdim[X] + info->gpu->max_width - dim[W]; - if (info->dst_dim[X] > x) { - info->modify_dim[X] += x - info->dst_dim[X]; - info->dst_dim[X] = x; + x = sdim->x + info->gpu->max_width - dim->width; + if (info->dst_dim.x > x) { + info->modify_dim.x += x - info->dst_dim.x; + info->dst_dim.x = x; } - y = sdim[Y] + info->gpu->max_height - dim[H]; - if (info->dst_dim[Y] > y) { - info->modify_dim[Y] += y - info->dst_dim[Y]; - info->dst_dim[Y] = y; + y = sdim->y + info->gpu->max_height - dim->height; + if (info->dst_dim.y > y) { + info->modify_dim.y += y - info->dst_dim.y; + info->dst_dim.y = y; } - x = sdim[X] + sdim[W] - info->gpu->max_width; - if (info->dst_dim[X] < x) { - info->modify_dim[X] += x - info->dst_dim[X]; - info->dst_dim[X] = x; + x = sdim->x + sdim->width - info->gpu->max_width; + if (info->dst_dim.x < x) { + info->modify_dim.x += x - info->dst_dim.x; + info->dst_dim.x = x; } - y = sdim[Y] + sdim[H] - info->gpu->max_height; - if (info->dst_dim[Y] < y) { - info->modify_dim[Y] += y - info->dst_dim[Y]; - info->dst_dim[Y] = y; + y = sdim->y + sdim->height - info->gpu->max_height; + if (info->dst_dim.y < y) { + info->modify_dim.y += y - info->dst_dim.y; + info->dst_dim.y = y; } @@ -1965,8 +1907,8 @@ static int move_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap) /* Move the screen */ nvDisplayPtr display; - x = info->dst_dim[X] - info->orig_dim[X]; - y = info->dst_dim[Y] - info->orig_dim[Y]; + x = info->dst_dim.x - info->orig_dim.x; + y = info->dst_dim.y - info->orig_dim.y; /* Offset the screen and all its displays */ offset_screen(info->screen, x, y); @@ -1978,10 +1920,8 @@ static int move_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap) } else { /* Move the display to its destination */ - info->display->cur_mode->viewPortIn[X] = info->dst_dim[X]; - info->display->cur_mode->viewPortIn[Y] = info->dst_dim[Y]; - info->display->cur_mode->pan[X] = info->dst_dim[X]; - info->display->cur_mode->pan[Y] = info->dst_dim[Y]; + info->display->cur_mode->pan.x = info->dst_dim.x; + info->display->cur_mode->pan.y = info->dst_dim.y; /* If the screen of the display that was moved is using absolute * positioning, we should check to see if the position of the @@ -1997,8 +1937,8 @@ static int move_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap) resolve_displays_in_screen(info->screen, 0); calc_metamode(info->screen, info->screen->cur_metamode); - x = info->screen->cur_metamode->dim[X] - info->orig_screen_dim[X]; - y = info->screen->cur_metamode->dim[Y] - info->orig_screen_dim[Y]; + x = info->screen->cur_metamode->dim.x - info->orig_screen_dim.x; + y = info->screen->cur_metamode->dim.y - info->orig_screen_dim.y; if (x || y) { nvDisplayPtr other; @@ -2036,17 +1976,17 @@ static int move_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap) /* If what we moved required the layout to be shifted, offset * the modify dim (used for snapping) by the same displacement. */ - x = info->target_dim[X] - info->dst_dim[X]; - y = info->target_dim[Y] - info->dst_dim[Y]; + x = info->target_dim->x - info->dst_dim.x; + y = info->target_dim->y - info->dst_dim.y; if (x || y) { - info->modify_dim[X] += x; - info->modify_dim[Y] += y; + info->modify_dim.x += x; + info->modify_dim.y += y; } /* Check if the item being moved has a new position */ if (*(info->target_position_type) != info->orig_position_type || - info->target_dim[X] != info->orig_dim[X] || - info->target_dim[Y] != info->orig_dim[Y]) { + info->target_dim->x != info->orig_dim.x || + info->target_dim->y != info->orig_dim.y) { modified = 1; } @@ -2070,7 +2010,7 @@ static int pan_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap) ModifyInfo *info = &(ctk_object->modify_info); int modified = 0; - int *dim; + GdkRectangle *dim; int extra; @@ -2087,96 +2027,69 @@ static int pan_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap) /* Compute pre-snap dimensions */ - info->modify_dim[W] += x; - info->modify_dim[H] += y; + info->modify_dim.width += x; + info->modify_dim.height += y; - /* Don't allow the panning domain to get too small */ + /* Don't allow the thing being modified to get too small */ if (info->display) { - dim = info->display->cur_mode->viewPortIn; - if (info->modify_dim[W] < dim[W]) { - info->modify_dim[W] = dim[W]; - } - if (info->modify_dim[H] < dim[H]) { - info->modify_dim[H] = dim[H]; - } + clamp_rect_to_viewportin(&(info->modify_dim), info->display->cur_mode); } else if (info->screen->no_scanout) { - if (info->modify_dim[W] < 304) { - info->modify_dim[W] = 304; - } - if (info->modify_dim[H] < 200) { - info->modify_dim[H] = 200; - } + clamp_screen_size_rect(&(info->modify_dim)); } - info->dst_dim[W] = info->modify_dim[W]; - info->dst_dim[H] = info->modify_dim[H]; + info->dst_dim.width = info->modify_dim.width; + info->dst_dim.height = info->modify_dim.height; /* Snap to other screens and dimensions */ if (snap && ctk_object->snap_strength) { - - info->src_dim[X] = info->dst_dim[X]; - info->src_dim[Y] = info->dst_dim[Y]; - info->src_dim[W] = info->dst_dim[W]; - info->src_dim[H] = info->dst_dim[H]; - + info->src_dim = info->dst_dim; snap_pan(ctk_object); } /* Make sure no-scanout virtual screen width is at least a multiple of 8 */ if (info->screen->no_scanout) { - extra = (info->dst_dim[W] % 8); + extra = (info->dst_dim.width % 8); if (extra > 0) { - info->dst_dim[W] += (8 - extra); + info->dst_dim.width += (8 - extra); } } /* Panning should not cause us to exceed the maximum layout dimensions */ - x = MAX_LAYOUT_WIDTH - info->dst_dim[X]; - if (info->dst_dim[W] > x) { - info->modify_dim[W] += x - info->dst_dim[W]; - info->dst_dim[W] = x; + x = MAX_LAYOUT_WIDTH - info->dst_dim.x; + if (info->dst_dim.width > x) { + info->modify_dim.width += x - info->dst_dim.width; + info->dst_dim.width = x; } - y = MAX_LAYOUT_HEIGHT - info->dst_dim[Y]; - if (info->dst_dim[H] > y) { - info->modify_dim[H] += y - info->dst_dim[H]; - info->dst_dim[H] = y; + y = MAX_LAYOUT_HEIGHT - info->dst_dim.y; + if (info->dst_dim.height > y) { + info->modify_dim.height += y - info->dst_dim.height; + info->dst_dim.height = y; } /* Panning should not cause us to exceed the maximum screen dimensions */ - dim = get_screen_dim(info->screen, 1); - x = dim[X] + info->gpu->max_width - info->dst_dim[X]; - if (info->dst_dim[W] > x) { - info->modify_dim[W] += x - info->dst_dim[W]; - info->dst_dim[W] = x; + dim = get_screen_rect(info->screen, 1); + x = dim->x + info->gpu->max_width - info->dst_dim.x; + if (info->dst_dim.width > x) { + info->modify_dim.width += x - info->dst_dim.width; + info->dst_dim.width = x; } - y = dim[Y] + info->gpu->max_height - info->dst_dim[Y]; - if (info->dst_dim[H] > y) { - info->modify_dim[H] += y - info->dst_dim[H]; - info->dst_dim[H] = y; + y = dim->y + info->gpu->max_height - info->dst_dim.y; + if (info->dst_dim.height > y) { + info->modify_dim.height += y - info->dst_dim.height; + info->dst_dim.height = y; } /* Panning domain can never be smaller then the display ViewPortIn */ if (info->display) { - dim = info->display->cur_mode->viewPortIn; - if (info->dst_dim[W] < dim[W]) { - info->dst_dim[W] = dim[W]; - } - if (info->dst_dim[H] < dim[H]) { - info->dst_dim[H] = dim[H]; - } + clamp_rect_to_viewportin(&(info->dst_dim), info->display->cur_mode); } else if (info->screen->no_scanout) { - if (info->dst_dim[W] < 304) { - info->dst_dim[W] = 304; - } - if (info->dst_dim[H] < 200) { - info->dst_dim[H] = 200; - } + clamp_screen_size_rect(&(info->dst_dim)); } /* Assign the new size */ - info->target_dim[W] = info->dst_dim[W]; - info->target_dim[H] = info->dst_dim[H]; + info->target_dim->width = info->dst_dim.width; + info->target_dim->height = info->dst_dim.height; /* Recalculate layout dimensions and scaling */ @@ -2190,8 +2103,8 @@ static int pan_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap) /* Check if the item being moved has a new position */ /* Report if anything changed */ - if (info->target_dim[W] != info->orig_dim[W] || - info->target_dim[H] != info->orig_dim[H]) { + if (info->target_dim->width != info->orig_dim.width || + info->target_dim->height != info->orig_dim.height) { modified = 1; } @@ -2347,7 +2260,7 @@ static void select_display(CtkDisplayLayout *ctk_object, nvDisplayPtr display) * */ -#define DIST_SQR(D) (((D)[X] * (D)[X]) + ((D)[Y] * (D)[Y])) +#define DIST_SQR(D) (((D).x * (D).x) + ((D).y * (D).y)) static void select_default_item(CtkDisplayLayout *ctk_object) { @@ -2368,7 +2281,7 @@ static void select_default_item(CtkDisplayLayout *ctk_object) /* Ignore disabled displays */ if (!display->cur_mode) continue; - dst = DIST_SQR(display->cur_mode->viewPortIn); + dst = DIST_SQR(display->cur_mode->pan); if (best_dst < 0 || dst < best_dst) { best_dst = dst; sel_display = display; @@ -2554,21 +2467,19 @@ static char *get_tooltip_under_mouse(CtkDisplayLayout *ctk_object, nvDisplayPtr display = NULL; nvScreenPtr screen = NULL; char *tip = NULL; - int *sdim; - - + + /* Scale and offset x & y so they reside in clickable area */ - x = (x -ctk_object->img_dim[X]) / ctk_object->scale; - y = (y -ctk_object->img_dim[Y]) / ctk_object->scale; + x = (x -ctk_object->img_dim.x) / ctk_object->scale; + y = (y -ctk_object->img_dim.y) / ctk_object->scale; /* Go through the Z-order looking for what we are under */ for (i = 0; i < ctk_object->Zcount; i++) { - + if (ctk_object->Zorder[i].type == ZNODE_TYPE_DISPLAY) { display = ctk_object->Zorder[i].u.display; - if (display->cur_mode && - point_in_dim(display->cur_mode->pan, x, y)) { + if (point_in_display(display, x, y)) { screen = NULL; if (display == last_display) { goto found; @@ -2579,8 +2490,7 @@ static char *get_tooltip_under_mouse(CtkDisplayLayout *ctk_object, } else if (ctk_object->Zorder[i].type == ZNODE_TYPE_SCREEN) { screen = ctk_object->Zorder[i].u.screen; - sdim = get_screen_dim(screen, 1); - if (point_in_dim(sdim, x, y)) { + if (point_in_screen(screen, x, y)) { display = NULL; if (screen == last_screen) { goto found; @@ -2622,7 +2532,6 @@ static int click_layout(CtkDisplayLayout *ctk_object, int x, int y) nvScreenPtr cur_selected_screen = ctk_object->selected_screen; nvDisplayPtr display; nvScreenPtr screen; - int *sdim; GdkModifierType state; @@ -2639,17 +2548,14 @@ static int click_layout(CtkDisplayLayout *ctk_object, int x, int y) for (i = 0; i < ctk_object->Zcount; i++) { if (ctk_object->Zorder[i].type == ZNODE_TYPE_DISPLAY) { display = ctk_object->Zorder[i].u.display; - if (display->cur_mode && - point_in_dim(display->cur_mode->pan, x, y)) { - + if (point_in_display(display, x, y)) { select_display(ctk_object, display); ctk_object->clicked_outside = 0; break; } } else if (ctk_object->Zorder[i].type == ZNODE_TYPE_SCREEN) { screen = ctk_object->Zorder[i].u.screen; - sdim = get_screen_dim(screen, 1); - if (point_in_dim(sdim, x, y)) { + if (point_in_screen(screen, x, y)) { select_screen(ctk_object, screen); ctk_object->clicked_outside = 0; break; @@ -2874,16 +2780,13 @@ static GdkGC *get_widget_fg_gc(GtkWidget *widget) **/ static void draw_rect(CtkDisplayLayout *ctk_object, - int *dim, + GdkRectangle *rect, GdkColor *color, int fill) { GtkWidget *drawing_area = ctk_object->drawing_area; GdkGC *fg_gc = get_widget_fg_gc(drawing_area); - int w = (int)(ctk_object->scale * (dim[X] + dim[W])) - (int)(ctk_object->scale * (dim[X])); - int h = (int)(ctk_object->scale * (dim[Y] + dim[H])) - (int)(ctk_object->scale * (dim[Y])); - /* Setup color to use */ gdk_gc_set_rgb_fg_color(fg_gc, color); @@ -2891,10 +2794,10 @@ static void draw_rect(CtkDisplayLayout *ctk_object, gdk_draw_rectangle(ctk_object->pixmap, fg_gc, fill, - ctk_object->img_dim[X] + ctk_object->scale * dim[X], - ctk_object->img_dim[Y] + ctk_object->scale * dim[Y], - w, - h); + ctk_object->img_dim.x + ctk_object->scale * rect->x, + ctk_object->img_dim.y + ctk_object->scale * rect->y, + ctk_object->scale * rect->width, + ctk_object->scale * rect->height); } /* draw_rect() */ @@ -2908,7 +2811,7 @@ static void draw_rect(CtkDisplayLayout *ctk_object, **/ static void draw_rect_strs(CtkDisplayLayout *ctk_object, - int *dim, + GdkRectangle *rect, GdkColor *color, const char *str_1, const char *str_2) @@ -2929,8 +2832,8 @@ static void draw_rect_strs(CtkDisplayLayout *ctk_object, pango_layout_set_text(ctk_object->pango_layout, str_1, -1); pango_layout_get_pixel_size(ctk_object->pango_layout, &txt_w, &txt_h); - if (txt_w +8 <= ctk_object->scale * dim[W] && - txt_h +8 <= ctk_object->scale * dim[H]) { + if (txt_w +8 <= ctk_object->scale * rect->width && + txt_h +8 <= ctk_object->scale * rect->height) { draw_1 = 1; } } @@ -2939,8 +2842,8 @@ static void draw_rect_strs(CtkDisplayLayout *ctk_object, pango_layout_set_text(ctk_object->pango_layout, str_2, -1); pango_layout_get_pixel_size(ctk_object->pango_layout, &txt_w, &txt_h); - if (txt_w +8 <= ctk_object->scale * dim[W] && - txt_h +8 <= ctk_object->scale * dim[H]) { + if (txt_w +8 <= ctk_object->scale * rect->width && + txt_h +8 <= ctk_object->scale * rect->height) { draw_2 = 1; } @@ -2950,7 +2853,7 @@ static void draw_rect_strs(CtkDisplayLayout *ctk_object, pango_layout_get_pixel_size(ctk_object->pango_layout, &txt_w, &txt_h); if (draw_1 && draw_2 && - txt_h +8 > ctk_object->scale * dim[H]) { + txt_h +8 > ctk_object->scale * rect->height) { draw_2 = 0; } @@ -2961,16 +2864,16 @@ static void draw_rect_strs(CtkDisplayLayout *ctk_object, pango_layout_set_text(ctk_object->pango_layout, str_1, -1); pango_layout_get_pixel_size(ctk_object->pango_layout, &txt_w, &txt_h); - txt_x1 = ctk_object->scale*(dim[X] + dim[W] / 2) - (txt_w / 2); - txt_y1 = ctk_object->scale*(dim[Y] + dim[H] / 2) - (txt_h / 2); + txt_x1 = ctk_object->scale*(rect->x + rect->width / 2) - (txt_w / 2); + txt_y1 = ctk_object->scale*(rect->y + rect->height / 2) - (txt_h / 2); /* Write name */ gdk_gc_set_rgb_fg_color(fg_gc, color); gdk_draw_layout(ctk_object->pixmap, fg_gc, - ctk_object->img_dim[X] + txt_x1, - ctk_object->img_dim[Y] + txt_y1, + ctk_object->img_dim.x + txt_x1, + ctk_object->img_dim.y + txt_y1, ctk_object->pango_layout); } @@ -2978,16 +2881,16 @@ static void draw_rect_strs(CtkDisplayLayout *ctk_object, pango_layout_set_text(ctk_object->pango_layout, str_2, -1); pango_layout_get_pixel_size(ctk_object->pango_layout, &txt_w, &txt_h); - txt_x2 = ctk_object->scale*(dim[X] + dim[W] / 2) - (txt_w / 2); - txt_y2 = ctk_object->scale*(dim[Y] + dim[H] / 2) - (txt_h / 2); + txt_x2 = ctk_object->scale*(rect->x + rect->width / 2) - (txt_w / 2); + txt_y2 = ctk_object->scale*(rect->y + rect->height / 2) - (txt_h / 2); /* Write dimensions */ gdk_gc_set_rgb_fg_color(fg_gc, color); gdk_draw_layout(ctk_object->pixmap, fg_gc, - ctk_object->img_dim[X] + txt_x2, - ctk_object->img_dim[Y] + txt_y2, + ctk_object->img_dim.x + txt_x2, + ctk_object->img_dim.y + txt_y2, ctk_object->pango_layout); } @@ -2997,16 +2900,16 @@ static void draw_rect_strs(CtkDisplayLayout *ctk_object, pango_layout_set_text(ctk_object->pango_layout, str, -1); pango_layout_get_pixel_size(ctk_object->pango_layout, &txt_w, &txt_h); - txt_x = ctk_object->scale*(dim[X] + dim[W] / 2) - (txt_w / 2); - txt_y = ctk_object->scale*(dim[Y] + dim[H] / 2) - (txt_h / 2); + txt_x = ctk_object->scale*(rect->x + rect->width / 2) - (txt_w / 2); + txt_y = ctk_object->scale*(rect->y + rect->height / 2) - (txt_h / 2); /* Write both */ gdk_gc_set_rgb_fg_color(fg_gc, color); gdk_draw_layout(ctk_object->pixmap, fg_gc, - ctk_object->img_dim[X] + txt_x, - ctk_object->img_dim[Y] + txt_y, + ctk_object->img_dim.x + txt_x, + ctk_object->img_dim.y + txt_y, ctk_object->pango_layout); g_free(str); @@ -3029,6 +2932,7 @@ static void draw_display(CtkDisplayLayout *ctk_object, int base_color_idx; int color_idx; char *tmp_str; + GdkRectangle rect; if (!display || !(display->cur_mode)) { return; @@ -3041,29 +2945,29 @@ static void draw_display(CtkDisplayLayout *ctk_object, /* Draw panning */ color_idx = base_color_idx + ((mode->modeline) ? BG_PAN_ON : BG_PAN_OFF); - draw_rect(ctk_object, mode->pan, &(ctk_object->color_palettes[color_idx]), - 1); - draw_rect(ctk_object, mode->pan, &(ctk_object->fg_color), 0); + draw_rect(ctk_object, &(mode->pan), + &(ctk_object->color_palettes[color_idx]), 1); + draw_rect(ctk_object, &(mode->pan), &(ctk_object->fg_color), 0); /* Draw ViewPortIn */ + get_viewportin_rect(mode, &rect); color_idx = base_color_idx + ((mode->modeline) ? BG_SCR_ON : BG_SCR_OFF); - draw_rect(ctk_object, mode->viewPortIn, &(ctk_object->color_palettes[color_idx]), - 1); - draw_rect(ctk_object, mode->viewPortIn, &(ctk_object->fg_color), 0); + draw_rect(ctk_object, &rect, &(ctk_object->color_palettes[color_idx]), 1); + draw_rect(ctk_object, &rect, &(ctk_object->fg_color), 0); /* Draw text information */ if (!mode->display->screen) { tmp_str = g_strdup("(Disabled)"); } else if (mode->modeline) { - tmp_str = g_strdup_printf("%dx%d", mode->viewPortIn[W], - mode->viewPortIn[H]); + tmp_str = g_strdup_printf("%dx%d", mode->viewPortIn.width, + mode->viewPortIn.height); } else { tmp_str = g_strdup("(Off)"); } draw_rect_strs(ctk_object, - mode->viewPortIn, + &rect, &(ctk_object->fg_color), display->logName, tmp_str); @@ -3085,7 +2989,7 @@ static void draw_screen(CtkDisplayLayout *ctk_object, GtkWidget *drawing_area = ctk_object->drawing_area; GdkGC *fg_gc = get_widget_fg_gc(drawing_area); - int *sdim; /* Screen dimensions */ + GdkRectangle *sdim; /* Screen dimensions */ GdkColor bg_color; /* Background color */ GdkColor bd_color; /* Border color */ char *tmp_str; @@ -3098,7 +3002,7 @@ static void draw_screen(CtkDisplayLayout *ctk_object, gdk_color_parse("#888888", &bg_color); gdk_color_parse("#777777", &bd_color); - sdim = get_screen_dim(screen, 1); + sdim = get_screen_rect(screen, 1); /* Draw the screen background */ draw_rect(ctk_object, sdim, &bg_color, 1); @@ -3108,16 +3012,16 @@ static void draw_screen(CtkDisplayLayout *ctk_object, GDK_CAP_NOT_LAST, GDK_JOIN_ROUND); draw_rect(ctk_object, sdim, &(ctk_object->fg_color), 0); - + gdk_gc_set_line_attributes(fg_gc, 1, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_ROUND); /* Show the name of the screen if no-scanout is selected */ if (screen->no_scanout) { tmp_str = g_strdup_printf("X Screen %d", screen->scrnum); - + draw_rect_strs(ctk_object, - screen->dim, + &(screen->dim), &(ctk_object->fg_color), tmp_str, "(No Scanout)"); @@ -3163,17 +3067,20 @@ static void draw_layout(CtkDisplayLayout *ctk_object) int w, h; int size; /* Hilite line size */ int offset; /* Hilite box offset */ - int *dim; + GdkRectangle vpiRect; + GdkRectangle *rect; if (ctk_object->selected_display) { - dim = ctk_object->selected_display->cur_mode->viewPortIn; + get_viewportin_rect(ctk_object->selected_display->cur_mode, + &vpiRect); + rect = &vpiRect; } else { - dim = get_screen_dim(ctk_object->selected_screen, 0); + rect = get_screen_rect(ctk_object->selected_screen, 0); } /* Draw red selection border */ - w = (int)(ctk_object->scale * (dim[X] + dim[W])) - (int)(ctk_object->scale * (dim[X])); - h = (int)(ctk_object->scale * (dim[Y] + dim[H])) - (int)(ctk_object->scale * (dim[Y])); + w = (int)(ctk_object->scale * rect->width); + h = (int)(ctk_object->scale * rect->height); /* Setup color to use */ gdk_gc_set_rgb_fg_color(fg_gc, &(ctk_object->select_color)); @@ -3183,8 +3090,8 @@ static void draw_layout(CtkDisplayLayout *ctk_object) offset = (size/2) +1; if ((w -(2* offset) < 0) || (h -(2 *offset) < 0)) { - draw_rect(ctk_object, dim, &(ctk_object->select_color), 1); - draw_rect(ctk_object, dim, &(ctk_object->fg_color), 0); + draw_rect(ctk_object, rect, &(ctk_object->select_color), 1); + draw_rect(ctk_object, rect, &(ctk_object->fg_color), 0); } else { gdk_gc_set_line_attributes(fg_gc, size, GDK_LINE_SOLID, @@ -3193,8 +3100,8 @@ static void draw_layout(CtkDisplayLayout *ctk_object) gdk_draw_rectangle(ctk_object->pixmap, fg_gc, 0, - ctk_object->img_dim[X] +(ctk_object->scale * dim[X]) +offset, - ctk_object->img_dim[Y] +(ctk_object->scale * dim[Y]) +offset, + ctk_object->img_dim.x +(ctk_object->scale * rect->x) +offset, + ctk_object->img_dim.y +(ctk_object->scale * rect->y) +offset, w -(2 * offset), h -(2 * offset)); @@ -3218,14 +3125,14 @@ static void draw_layout(CtkDisplayLayout *ctk_object) // with display devices that are "off" gdk_color_parse("#0000FF", &bg_color); draw_rect(ctk_object, - ctk_object->selected_screen->cur_metamode->viewPortIn, + &(ctk_object->selected_screen->cur_metamode->viewPortIn), &(bg_color), 0); // Shows the current screen dimensions used for relative // positioning of the screen (w/o displays that are "off") gdk_color_parse("#FF00FF", &bg_color); draw_rect(ctk_object, - ctk_object->selected_screen->cur_metamode->edim, + &(ctk_object->selected_screen->cur_metamode->edim), &(bg_color), 0); } } @@ -3318,8 +3225,8 @@ static Bool sync_layout(nvLayoutPtr layout) calc_layout(layout); /* If layout needs to offset, it was modified */ - if (layout->dim[X] || layout->dim[Y]) { - offset_layout(layout, -layout->dim[X], -layout->dim[Y]); + if (layout->dim.x || layout->dim.y) { + offset_layout(layout, -layout->dim.x, -layout->dim.y); modified = TRUE; } @@ -3689,13 +3596,15 @@ void ctk_display_layout_disable_display(CtkDisplayLayout *ctk_object, /** ctk_display_layout_set_mode_modeline() *************************** * - * Sets which modeline the mode should use. + * Sets which modeline, ViewPortIn and ViewPortOut the mode should use. * **/ void ctk_display_layout_set_mode_modeline(CtkDisplayLayout *ctk_object, nvModePtr mode, - nvModeLinePtr modeline) + nvModeLinePtr modeline, + const nvSize *viewPortIn, + const GdkRectangle *viewPortOut) { nvModeLinePtr old_modeline; @@ -3705,16 +3614,8 @@ void ctk_display_layout_set_mode_modeline(CtkDisplayLayout *ctk_object, /* Set the new modeline */ old_modeline = mode->modeline; - mode->modeline = modeline; - - /* Setup the mode's dimensions based on the modeline */ - if (modeline) { - mode_set_dims_from_modeline(mode, modeline); - } else if (mode->display) { - /* Display is being turned off, set the default width/height */ - mode_set_dims_from_modeline(mode, mode->display->modelines); - } + mode_set_modeline(mode, modeline, viewPortIn, viewPortOut); /* In advanced mode, changing the resolution a display uses for a * particular metamode should make this metamode non-implicit. @@ -3760,16 +3661,10 @@ void ctk_display_layout_set_mode_viewport_in(CtkDisplayLayout *ctk_object, h = 1; } - mode->viewPortIn[W] = w; - mode->viewPortIn[H] = h; + mode->viewPortIn.width = w; + mode->viewPortIn.height = h; - /* Clamp the panning domain to the new ViewPortIn dimensions */ - if (mode->pan[W] < mode->viewPortIn[W]) { - mode->pan[W] = mode->viewPortIn[W]; - } - if (mode->pan[H] < mode->viewPortIn[H]) { - mode->pan[H] = mode->viewPortIn[H]; - } + clamp_mode_panning(mode); if (modified) { /* Update the layout */ @@ -3845,10 +3740,10 @@ void ctk_display_layout_set_mode_viewport_out(CtkDisplayLayout *ctk_object, y = 0; } - mode->viewPortOut[X] = x; - mode->viewPortOut[Y] = y; - mode->viewPortOut[W] = w; - mode->viewPortOut[H] = h; + mode->viewPortOut.x = x; + mode->viewPortOut.y = y; + mode->viewPortOut.width = w; + mode->viewPortOut.height = h; if (modified) { /* Update the layout */ @@ -3939,15 +3834,15 @@ void ctk_display_layout_set_display_position(CtkDisplayLayout *ctk_object, /* Do the move by offsetting */ ctk_object->modify_info.modify_dirty = 1; modified = move_selected(ctk_object, - x - display->cur_mode->viewPortIn[X], - y - display->cur_mode->viewPortIn[Y], + x - display->cur_mode->pan.x, + y - display->cur_mode->pan.y, 0); /* Report back result of move */ if (ctk_object->modified_callback && (modified || - x != display->cur_mode->viewPortIn[X] || - y != display->cur_mode->viewPortIn[Y])) { + x != display->cur_mode->pan.x || + y != display->cur_mode->pan.y)) { ctk_object->modified_callback (ctk_object->layout, ctk_object->modified_callback_data); } @@ -3986,15 +3881,15 @@ void ctk_display_layout_set_display_panning(CtkDisplayLayout *ctk_object, /* Change the panning */ ctk_object->modify_info.modify_dirty = 1; modified = pan_selected(ctk_object, - width - display->cur_mode->pan[W], - height - display->cur_mode->pan[H], + width - display->cur_mode->pan.width, + height - display->cur_mode->pan.height, 0); /* Report back result of move */ if (ctk_object->modified_callback && (modified || - width != display->cur_mode->pan[W] || - height != display->cur_mode->pan[H])) { + width != display->cur_mode->pan.width || + height != display->cur_mode->pan.height)) { ctk_object->modified_callback(ctk_object->layout, ctk_object->modified_callback_data); } @@ -4213,14 +4108,14 @@ void ctk_display_layout_set_screen_virtual_size(CtkDisplayLayout *ctk_object, // what is selected. ctk_object->modify_info.modify_dirty = 1; modified = pan_selected(ctk_object, - width - screen->dim[W], - height - screen->dim[H], + width - screen->dim.width, + height - screen->dim.height, 0); if (ctk_object->modified_callback && (modified || - width != screen->dim[W] || - height != screen->dim[H])) { + width != screen->dim.width || + height != screen->dim.height)) { ctk_object->modified_callback(ctk_object->layout, ctk_object->modified_callback_data); } @@ -4297,9 +4192,9 @@ void ctk_display_layout_set_screen_position(CtkDisplayLayout *ctk_object, case CONF_ADJ_ABSOLUTE: { nvDisplayPtr other; - int x_offset = x - screen->dim[X]; - int y_offset = y - screen->dim[Y]; - int *sdim; + int x_offset = x - screen->dim.x; + int y_offset = y - screen->dim.y; + GdkRectangle *sdim; /* Make sure this screen use absolute positioning */ switch_screen_to_absolute(screen); @@ -4316,8 +4211,8 @@ void ctk_display_layout_set_screen_position(CtkDisplayLayout *ctk_object, ctk_display_layout_update(ctk_object); /* Report back result of move */ - sdim = get_screen_dim(screen, 1); - if (x != sdim[X] || y != sdim[Y]) { + sdim = get_screen_rect(screen, 1); + if (x != sdim->x || y != sdim->y) { modified = 1; } @@ -4474,10 +4369,10 @@ configure_event_callback(GtkWidget *widget, GdkEventConfigure *event, int width = widget->allocation.width; int height = widget->allocation.height; - ctk_object->img_dim[X] = LAYOUT_IMG_OFFSET + LAYOUT_IMG_BORDER_PADDING; - ctk_object->img_dim[Y] = LAYOUT_IMG_OFFSET + LAYOUT_IMG_BORDER_PADDING; - ctk_object->img_dim[W] = width -2*(ctk_object->img_dim[X]); - ctk_object->img_dim[H] = height -2*(ctk_object->img_dim[Y]); + ctk_object->img_dim.x = LAYOUT_IMG_OFFSET + LAYOUT_IMG_BORDER_PADDING; + ctk_object->img_dim.y = LAYOUT_IMG_OFFSET + LAYOUT_IMG_BORDER_PADDING; + ctk_object->img_dim.width = width -2*(ctk_object->img_dim.x); + ctk_object->img_dim.height = height -2*(ctk_object->img_dim.y); sync_scaling(ctk_object); @@ -4602,8 +4497,8 @@ button_press_event_callback(GtkWidget *widget, GdkEventButton *event, CtkDisplayLayout *ctk_object = CTK_DISPLAY_LAYOUT(data); /* Scale and offset x & y so they reside in the clickable area */ - int x = (event->x -ctk_object->img_dim[X]) / ctk_object->scale; - int y = (event->y -ctk_object->img_dim[Y]) / ctk_object->scale; + int x = (event->x -ctk_object->img_dim.x) / ctk_object->scale; + int y = (event->y -ctk_object->img_dim.y) / ctk_object->scale; GdkEvent *next_event; diff --git a/src/gtk+-2.x/ctkdisplaylayout.h b/src/gtk+-2.x/ctkdisplaylayout.h index 07e494e..2e77f9c 100644 --- a/src/gtk+-2.x/ctkdisplaylayout.h +++ b/src/gtk+-2.x/ctkdisplaylayout.h @@ -57,17 +57,6 @@ G_BEGIN_DECLS #define MAX_DEVICES 8 /* Max number of GPUs */ -/* Rectangle/Dim data positions */ -#define LEFT 0 -#define TOP 1 -#define WIDTH 2 -#define HEIGHT 3 -#define X LEFT -#define Y TOP -#define W WIDTH -#define H HEIGHT - - /* XF86VIDMODE */ #define V_PHSYNC 0x0001 #define V_NHSYNC 0x0002 @@ -151,6 +140,13 @@ typedef enum { METAMODE_SOURCE_RANDR, } MetaModeSource; + +typedef struct nvSizeRec { + int width; + int height; +} nvSize; + + typedef struct nvModeLineRec { struct nvModeLineRec *next; @@ -166,6 +162,22 @@ typedef struct nvModeLineRec { +typedef struct nvSelectedModeRec { + struct nvSelectedModeRec *next; + + GtkWidget *label; /* Label shown in dropdown menu */ + + nvModeLinePtr modeline; /* Modeline this mode references */ + + Bool isSpecial; /* Whether this mode is "Off" or "Auto" */ + Bool isScaled; /* Whether custom viewports are set */ + + nvSize viewPortIn; + GdkRectangle viewPortOut; +} nvSelectedMode, *nvSelectedModePtr; + + + /* Mode (A particular configuration for a display within an X screen) * * NOTE: When metamodes are duplicated, the modes are memcpy'ed over, so @@ -189,10 +201,10 @@ typedef struct nvModeRec { struct nvModeLineRec *modeline; /* Modeline this mode references */ int dummy; /* Dummy mode, don't print out */ - int viewPortIn[4]; /* Viewport In (absolute) */ - int pan[4]; /* Panning Domain (absolute) */ + nvSize viewPortIn; /* Viewport In */ + GdkRectangle pan; /* Panning Domain (absolute) */ - int viewPortOut[4]; /* ViewPort Out (WH) */ + GdkRectangle viewPortOut; /* ViewPort Out (WH) */ int position_type; /* Relative, Absolute, etc. */ struct nvDisplayRec *relative_to; /* Display Relative/RightOf etc */ @@ -231,6 +243,10 @@ typedef struct nvDisplayRec { nvModeLinePtr modelines; /* Modelines validated by X */ int num_modelines; + nvSelectedModePtr selected_modes; /* List of modes to show in the dropdown menu */ + int num_selected_modes; + nvSelectedModePtr cur_selected_mode; /* Current mode selected in the dropdown menu */ + nvModePtr modes; /* List of modes this display uses */ int num_modes; nvModePtr cur_mode; /* Current mode display uses */ @@ -249,10 +265,10 @@ typedef struct nvMetaModeRec { Bool switchable; /* Can the metamode be accessed through Ctrl Alt +- */ // Used for drawing & moving metamode boxes - int dim[4]; /* Bounding box of all modes */ + GdkRectangle dim; /* Bounding box of all modes */ // Used for applying and generating metamodes (effective dimensions) - int edim[4]; /* Bounding box of all non-NULL modes */ + GdkRectangle edim; /* Bounding box of all non-NULL modes */ char *string; /* Temp string used for modifying the metamode list */ @@ -294,7 +310,7 @@ typedef struct nvScreenRec { int cur_metamode_idx; /* Current metamode to display */ nvDisplayPtr primaryDisplay; // Used for generating metamode strings. - int dim[4]; /* Bounding box of all metamodes (Absolute coords) */ + GdkRectangle dim; /* Bounding box of all metamodes (Absolute coords) */ int position_type; /* Relative, Absolute, etc. */ struct nvScreenRec *relative_to; /* Screen Relative/RightOf etc */ @@ -361,7 +377,7 @@ typedef struct nvLayoutRec { int num_screens; /* Used for drawing the layout */ - int dim[4]; /* Bounding box of All X screens (Absolute coords) */ + GdkRectangle dim; /* Bounding box of All X screens (Absolute coords) */ int xinerama_enabled; @@ -382,14 +398,14 @@ typedef struct ModifyInfoRec { /* What to move */ nvDisplayPtr display; nvScreenPtr screen; - int orig_screen_dim[4]; // Used when moding display = moding screen. + GdkRectangle orig_screen_dim; // Used when moding display = moding screen. nvGpuPtr gpu; int orig_position_type; // Original values of what is being - int orig_dim[4]; // modified. + GdkRectangle orig_dim; // modified. int *target_position_type; // Pointers to values of thing that - int *target_dim; // is being modified. + GdkRectangle *target_dim; // is being modified. /* Snapping */ @@ -397,12 +413,12 @@ typedef struct ModifyInfoRec { int best_snap_v; int best_snap_h; - int modify_dirty; // Sync the modify_dim before moving/panning. - int modify_panning; // Modifying panning (instead of position) - int modify_dim[4]; // Dimensions to snap from + int modify_dirty; // Sync the modify_dim before moving/panning. + int modify_panning; // Modifying panning (instead of position) + GdkRectangle modify_dim; // Dimensions to snap from - int src_dim[4]; // Pre-snap (To allow snapping of pan box on move) - int dst_dim[4]; // Post-snap position + GdkRectangle src_dim; // Pre-snap (To allow snapping of pan box on move) + GdkRectangle dst_dim; // Post-snap position } ModifyInfo; @@ -442,8 +458,8 @@ typedef struct _CtkDisplayLayout GdkPixmap *pixmap; /* Image information */ - int img_dim[4]; /* Dimensions used to draw in */ - float scale; + GdkRectangle img_dim; + float scale; /* Colors */ GdkColor *color_palettes; /* Colors to use to display screens */ @@ -517,9 +533,11 @@ nvScreenPtr ctk_display_layout_get_selected_screen (CtkDisplayLayout *); nvGpuPtr ctk_display_layout_get_selected_gpu (CtkDisplayLayout *); -void ctk_display_layout_set_mode_modeline (CtkDisplayLayout *, - nvModePtr mode, - nvModeLinePtr modeline); +void ctk_display_layout_set_mode_modeline(CtkDisplayLayout *, + nvModePtr mode, + nvModeLinePtr modeline, + const nvSize *viewPortIn, + const GdkRectangle *viewPortOut); void ctk_display_layout_set_mode_viewport_in(CtkDisplayLayout *ctk_object, nvModePtr mode, diff --git a/src/version.mk b/src/version.mk index ea75111..96f272a 100644 --- a/src/version.mk +++ b/src/version.mk @@ -1 +1 @@ -NVIDIA_VERSION = 310.44 +NVIDIA_VERSION = 310.51 @@ -1 +1 @@ -NVIDIA_VERSION = 310.44 +NVIDIA_VERSION = 310.51 |