📄 wmgr_policy.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)wmgr_policy.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1986 by Sun Microsystems, Inc. *//* * Implementation of window manager icon- and tool-placement policies. */#include <sunwindow/sun.h>#include <sunwindow/defaults.h>#include <suntool/wmgr_policy.h>extern char *getenv(), *index(), *malloc();struct level_parms { int self; int prev; int next; Close_level level;};typedef struct level_parms Level_parms;static struct wmgr_policy default_policy = { North, Front, Total, Icons, FALSE};static Defaults_pairs directions[] = { "North", (int)North, "South", (int)South, "East", (int)East, "West", (int)West, 0, -1}, levels[] = { "Ahead_of_all", (int)Front, "Ahead_of_icons", (int)Boundary, "Behind_all", (int)Back, 0, -1};static void fold_down(), parse_policy_attribute(), wmgr_adjust_tool(), wmgr_advance_icon(), wmgr_advance_tool(), wmgr_find_icon_slot(), wmgr_findlevel(), wmgr_get_trimmed_bounds(), wmgr_place_first_icon(), wmgr_stow_rects();static int match(), wmgr_test_rect(), wmgr_test_slots();static enum win_enumerator_result wmgr_find_boundary();static struct rectlist * wmgr_find_free_space();static voidfold_down(from, to) register char *from, *to;{ register char c; do { if (isupper(c = *from++)) *to++ = tolower(c); else *to++ = c; } while (c);}static intmatch(str1, str2) register char *str1, *str2;{ register char c1, c2; while ( (c1 = *str1++) && (c2 = *str2++) ) { if (c1 != c2) { return FALSE; } } return TRUE;}static voidparse_policy_attribute(attr, val, policy) char *attr, *val; Policy_handle policy;{ if (match(attr, "gravity") ) { switch (*val) { case 'e': policy->gravity = East; return; case 's': policy->gravity = South; return; case 'w': policy->gravity = West; return; case 'n': default: policy->gravity = North; return; } } if (match(attr, "close_level") ) { if (match(val, "front") ) { policy->close_level = Front; } else if (match(val, "cur_level") ) { policy->close_level = Cur_level; } else if (match(val, "boundary") ) { policy->close_level = Boundary; } else if (match(val, "back") ) { policy->close_level = Back; } } if (match(attr, "visibility") ) { if (match(val, "total") ) { policy->visibility = Total; } else if (match(val, "partial") ) { policy->visibility = Partial; } } if (match(attr, "free_from") ) { if (match(val, "cur_windows") ) { policy->obstructors = Cur_windows; } else if (match(val, "icons") ) { policy->obstructors = Icons; } else if (match(val, "open") ) { policy->obstructors = Open; } else if (match(val, "all_windows") ) { policy->obstructors = All_windows; } } if (match(attr, "mobile") ) { policy->mobile = TRUE; } if (match(attr, "nomobile") ) { policy->mobile = FALSE; }}Policy_handlewmgr_get_icon_policy(){static Policy_handle policy; char *parm, buffer[1024]; register char *attr, *val; Close_level level; Gravity gravity; if (policy != (Policy_handle) NULL ) return policy; policy = (Policy_handle) (LINT_CAST(sv_malloc(sizeof *policy))); *policy = default_policy; level = (Close_level) defaults_lookup( defaults_get_string("/SunView/Icon_close_level", (char *)0, (int *)0), levels); if ((int)level != -1) { policy->close_level = level; } gravity = (Gravity) defaults_lookup( defaults_get_string("/SunView/Icon_gravity", (char *)0, (int *)0), directions); if ((int)gravity != -1) { policy->gravity = gravity; } if ( (parm = getenv("ICON_POLICY") ) != NULL) { fold_down(parm, buffer); attr = buffer; while (*attr) { register char *next; if (val = index(attr, '=') ) { *val++ = '\0'; next = index(val, ','); if (!next) { next = index(val, ' '); } } else { next = 0; } if (next) { *next++ = '\0'; } else { next = index(buffer, '\0'); } parse_policy_attribute(attr, val, policy); attr = next; } if (*attr) { (void)fprintf(stderr, "unrecognized icon policy parm: %s\n", attr); } } return policy;}static intwmgr_test_rect(r, rl, policy) struct rect *r; struct rectlist *rl; Policy_handle policy;{ struct rectlist new_rl; int result; new_rl = rl_null; (void)rl_rectintersection(r, rl, &new_rl); switch (policy->visibility) { case Total: (void)rl_coalesce(&new_rl); result = rl_equalrect(r, &new_rl); break; case Partial: result = ! rl_empty(&new_rl); break; } (void)rl_free(&new_rl); return result;}static voidwmgr_place_first_icon(gravity, bounds, candidate) Gravity gravity; struct rect *bounds, *candidate;{ if (gravity == East) { candidate->r_left = bounds->r_width - candidate->r_width; } else { candidate->r_left = 0; } while (candidate->r_left % WMGR_ICON_ALIGN_X != 0) { candidate->r_left--; } if (gravity == South) { candidate->r_top = bounds->r_height - candidate->r_height; } else { candidate->r_top = 0; } while (candidate->r_top % WMGR_ICON_ALIGN_Y != 0) { candidate->r_top--; }}static voidwmgr_advance_icon(gravity, bounds, candidate) Gravity gravity; struct rect *bounds, *candidate;{ int vertical, x_advance, y_advance; switch (gravity) { case East: vertical = TRUE; x_advance = -TOOL_ICONWIDTH; y_advance = TOOL_ICONHEIGHT; break; case West: vertical = TRUE; x_advance = TOOL_ICONWIDTH; y_advance = TOOL_ICONHEIGHT; break; case North: vertical = FALSE; x_advance = TOOL_ICONWIDTH; y_advance = TOOL_ICONHEIGHT; break; case South: vertical = FALSE; x_advance = TOOL_ICONWIDTH; y_advance = -TOOL_ICONHEIGHT; break; } if (vertical) { candidate->r_top += y_advance; while (candidate->r_top % WMGR_ICON_ALIGN_Y != 0) { candidate->r_top += 1; /* y_advance is known > 0 */ } if (candidate->r_top + TOOL_ICONHEIGHT > bounds->r_height) { candidate->r_left += x_advance; while (candidate->r_left % WMGR_ICON_ALIGN_X != 0) { candidate->r_left += (x_advance > 0) ? 1 : -1; } if (candidate->r_left < 0 || candidate->r_left + TOOL_ICONWIDTH > bounds->r_width) { return; /* all spots exhausted */ } candidate->r_top = 0; } } else { candidate->r_left += x_advance; while (candidate->r_left % WMGR_ICON_ALIGN_X != 0) { candidate->r_left += 1; /* x_advance is known > 0 */ } if (candidate->r_left + TOOL_ICONWIDTH > bounds->r_width) { candidate->r_top += y_advance; while (candidate->r_top % WMGR_ICON_ALIGN_Y != 0) { candidate->r_top += (y_advance > 0) ? 1 : -1; } if (candidate->r_top < 0 || candidate->r_top + TOOL_ICONHEIGHT > bounds->r_height) { return; /* all spots exhausted */ } candidate->r_left = 0; } }}static voidwmgr_find_icon_slot(root, window, candidate, old_icon) Window_handle root, window; struct rect *candidate; int old_icon;{ struct rectlist *rl; struct rect cached_icon, root_rect; Policy_handle policy; (void)wmgr_is_child_inserted(root, window); policy = wmgr_get_icon_policy(); if (old_icon) { if (!policy->mobile) { return; } else { cached_icon = *candidate; } } else { if (candidate->r_width == WMGR_SETPOS) { candidate->r_width = TOOL_ICONWIDTH; } if (candidate->r_height == WMGR_SETPOS) { candidate->r_height = TOOL_ICONHEIGHT; } } (void)win_getrect(root, &root_rect); /* * Try all slots against increasingly laxer policies * until one passes; that's the choice. */Compute_free_space: /* top of outer loop */ rl = wmgr_find_free_space( root, window, policy);Reuse_free_space: /* top of inner loop */ if (old_icon) { if (wmgr_test_rect(&cached_icon, rl, policy)) { *candidate = cached_icon; /* old spot's as good */ goto Found_place; /* as any other; use it */ } } if (wmgr_test_slots(candidate, &root_rect, rl, policy) ) { goto Found_place; /* candidate works under this policy */ } /* if that didn't work, try relaxing something */ if (policy->visibility == Total) { policy->visibility = Partial; goto Reuse_free_space; } if (policy->obstructors == All_windows) { policy->obstructors = Cur_windows; goto Compute_free_space; } if (policy->obstructors == Cur_windows) { policy->obstructors = Icons; /* this will cycle */ policy->visibility = Total; /* the inner loop, too */ goto Compute_free_space; } /* None of that worked; give up */ if (rect_includesrect(&root_rect, &cached_icon) ) { *candidate = cached_icon; } else { candidate->r_left = (root_rect.r_width - TOOL_ICONWIDTH) / 2; candidate->r_top =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -