📄 wmgr_rect.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)wmgr_rect.c 1.1 92/07/30 Copyr 1985 Sun Micro";#endif#endif/* * Copyright (c) 1985 by Sun Microsystems, Inc. *//* * Window mgr move, stretch and refresh. */#include <stdio.h>#include <errno.h>#include <sys/file.h>#include <sunwindow/defaults.h>#include <sunwindow/sun.h>#include <sunwindow/window_hs.h>#include <sunwindow/win_ioctl.h>#include <suntool/alert.h>#include <suntool/frame.h>#include <suntool/wmgr.h>#include <suntool/fullscreen.h>#ifdef KEYMAP_DEBUG#include "../../libsunwindow/win/win_keymap.h"#else#include <sunwindow/win_keymap.h>#endif#define WMGR_ICON_GRID_X 4#define WMGR_ICON_GRID_Y 4#define STRETCH_BORDER 2#define MIN_TOOL_WIDTH STRETCH_BORDER*3#define MIN_TOOL_HEIGHT STRETCH_BORDER*3void fullscreen_pw_copy();extern int errno;extern struct cursor wmgr_move_cursor, wmgr_moveH_cursor, wmgr_moveV_cursor, wmgr_stretchMID_cursor, wmgr_stretchN_cursor, wmgr_stretchNE_cursor, wmgr_stretchE_cursor, wmgr_stretchSE_cursor, wmgr_stretchS_cursor, wmgr_stretchSW_cursor, wmgr_stretchW_cursor, wmgr_stretchNW_cursor;extern char *getenv();extern int win_getsavedrect(), win_setsavedrect();extern int win_cursor_planes_available(), win_clear_cursor_planes();#define xor_box(r) \ (void)fullscreen_not_draw_box(fsglobal->fs_pixwin, (r), STRETCH_BORDER);static WM_Direction grasps[3][3] = { WM_NW, WM_N, WM_NE, WM_W, WM_None, WM_E, WM_SW, WM_S, WM_SE };static struct cursor *stretch_cursors[9] = { &wmgr_stretchMID_cursor, &wmgr_stretchN_cursor, &wmgr_stretchNE_cursor, &wmgr_stretchE_cursor, &wmgr_stretchSE_cursor, &wmgr_stretchS_cursor, &wmgr_stretchSW_cursor, &wmgr_stretchW_cursor, &wmgr_stretchNW_cursor};static void wmgr_attach_cursor(), wmgr_constrain_point(), wmgr_set_cursor(), wmgr_move_box(), wmgr_stretch_box();static int wmgr_do_placeholders();static Bool wmgr_stretch_jump_cursor();static struct fullscreen *wmgr_grab_screen();typedef enum { Done, Error, Valid, Stop } Event_return;static Event_return wmgr_get_event();/*ARGSUSED*/voidwmgr_changerect(feedbackfd, windowfd, event, move, accelerated) int feedbackfd, /* This is IGNORED (remove later) */ windowfd; struct inputevent *event; int move, accelerated;{ struct rect rect, rectoriginal; Event alert_event; struct pr_pos old_origin; int flags = win_getuserflags(windowfd);extern struct pixfont *pw_pfsysopen(); int alert_used = 0; int result = 0; if ((!move) && (flags&WMGR_ICONIC)) return; /* Don't stretch if iconic */ if (accelerated <= 0) { result = (move) ? alert_prompt( (Frame)0, &alert_event, ALERT_MESSAGE_STRINGS, " Press and hold the middle mouse button", "near the side or corner you want to move", "and hold the button down while dragging", "the bounding box to the location you want;", "then release the mouse button.", " Otherwise, push \"Cancel\" button.", 0, ALERT_BUTTON_NO, "Cancel", ALERT_TRIGGER, MS_MIDDLE, ALERT_NO_IMAGE, 1, ALERT_NO_BEEPING, 1, 0) : alert_prompt( (Frame)0, &alert_event, ALERT_MESSAGE_STRINGS, " Press and hold the middle mouse button", "near the side or corner you want to resize", "and hold the button down while adjusting", "the bounding box to the shape and size you want;", "then release the mouse button.", " Otherwise, push \"Cancel\" button.", 0, ALERT_BUTTON_NO, "Cancel", ALERT_TRIGGER, MS_MIDDLE, ALERT_NO_IMAGE, 1, ALERT_NO_BEEPING, 1, 0); if (result == ALERT_FAILED) return; else alert_used = 1; } /* * See if user wants to continue operation based on last action */ if ((alert_used == 1) && (result == ALERT_NO)) { return; /* cancel action */ } if (alert_used) event = &alert_event; if ( (event_action(event) != MS_LEFT && event_action(event) != MS_MIDDLE) || ! win_inputposevent(event)) { return; } (void)win_getrect(windowfd, &rect); if (alert_used) { event->ie_locx -= rect.r_left; event->ie_locy -= rect.r_top; } rectoriginal = rect; old_origin.x = rect.r_left; /*save position of tool in root */ old_origin.y = rect.r_top; rect.r_left = rect.r_top = 0; /* and work in tool coords */ wmgr_providefeedback( windowfd, &rect, event, move, flags&WMGR_ICONIC, wmgr_compute_grasp(&rect, event, move, flags&WMGR_ICONIC, accelerated), (Rect *)0, (int (*)()) 0, 0, (Rectlist *)0); rect.r_left += old_origin.x; /* restore root coords */ rect.r_top += old_origin.y; if (!rect_equal(&rect, &rectoriginal)) wmgr_completechangerect(windowfd, &rect, &rectoriginal, 0, 0);}voidwmgr_completechangerect( windowfd, rectnew, rectoriginal, parentprleft, parentprtop) int windowfd; struct rect *rectnew, *rectoriginal; int parentprleft, parentprtop;{ struct pixwin *pixwin; struct rectlist rloriginal, rlnew, rlclip; struct rect rectlock, rectloop; struct rectnode *rn;#ifdef PRE_IBIS int fullplanes = 255;#else ndef PRE_IBIS int fullplanes = PIX_ALL_PLANES;#endif else ndef PRE_IBIS rloriginal = rl_null; rlnew = rl_null; rlclip = rl_null; if ((rectnew->r_left == rectoriginal->r_left) && (rectnew->r_top == rectoriginal->r_top)) { /* * Only saving bits if origin moves. * Note: Need introduce concept of "gravity" which is direction * that bits "fall" when the size changes. */ (void)win_setrect(windowfd, rectnew); return; } (void)win_lockdata(windowfd); /* * Get current exposed rl. */ if (pixwin = pw_open(windowfd)) { wmgr_winandchildrenexposed(pixwin, &rloriginal); /* * Change rect and recompute clipping. */ (void)win_setrect(windowfd, rectnew); (void)win_computeclipping(windowfd); /* * Get new exposed rl. */ wmgr_winandchildrenexposed(pixwin, &rlnew); /* * Intersection of original and new clipping are the only * bits saved. */ (void)rl_intersection(&rloriginal, &rlnew, &rlclip); (void)rl_coalesce(&rlclip); if (rect_intersectsrect(rectnew, rectoriginal)) { struct rect maxrect; int testarea, maxarea; /* * Only know how to move the biggest piece of the visible image. * Another case could be move all the rects that don't * intersect the src. * Another case could be to see if on top, then move everything. */ maxarea = 0; maxrect = rect_null; for (rn = rlclip.rl_head; rn; rn = rn->rn_next) { rl_rectoffset(&rlclip, &rn->rn_rect, &rectloop); if ((testarea=rectloop.r_width*rectloop.r_height) > maxarea) { maxarea = testarea; maxrect = rectloop; } } if (rect_isnull(&maxrect)) goto NothingToMove; (void)rl_free(&rlclip); (void)rl_initwithrect(&maxrect, &rlclip); } /* * Lock affected area */ rectlock = rect_bounding(rectnew, rectoriginal); rect_passtochild(rectnew->r_left, rectnew->r_top, &rectlock); /* * Need to grabio when violating exposed area of window */ (void)win_grabio(windowfd); (void)pw_lock(pixwin, &rectlock); /* * Fixup cms that pixwin was initially created with. * Make pixrect able to access entire depth of screen. */#ifdef planes_fully_implemented (void)pr_putattributes(pixwin->pw_pixrect, &fullplanes);#else (void)pw_full_putattributes(pixwin->pw_pixrect, &fullplanes);#endif planes_fully_implemented /* * Move data */ for (rn = rlclip.rl_head; rn; rn = rn->rn_next) { rl_rectoffset(&rlclip, &rn->rn_rect, &rectloop); fullscreen_pw_copy(pixwin, rectloop.r_left+rectnew->r_left+parentprleft, rectloop.r_top+rectnew->r_top+parentprtop, rectloop.r_width, rectloop.r_height, PIX_SRC, pixwin, rectloop.r_left+rectoriginal->r_left+parentprleft, rectloop.r_top+rectoriginal->r_top+parentprtop); } (void)pw_unlock(pixwin); (void)win_releaseio(windowfd); /* * Validate bits that preserved. */ for (rn = rlclip.rl_head; rn; rn = rn->rn_next) { rl_rectoffset(&rlclip, &rn->rn_rect, &rectloop); (void)win_partialrepair(windowfd, &rectloop); }NothingToMove: (void)rl_free(&rlclip); (void)rl_free(&rloriginal); (void)rl_free(&rlnew); (void)pw_close(pixwin); } (void)win_unlockdata(windowfd);}voidwmgr_refreshwindow(windowfd) int windowfd;{ struct rect rectoriginal, rectdif; int marginchange = -1; (void)win_lockdata(windowfd); (void)win_getrect(windowfd, &rectoriginal); /* * A position change is supposed to * invoke a repaint of the entire window and its children. * So, change position by 1,1 and then back to original position. */ rectdif = rectoriginal; if ((rectoriginal.r_width == 0) || (rectoriginal.r_height == 0)) marginchange = 1; rect_marginadjust(&rectdif, marginchange); (void)win_setrect(windowfd, &rectdif); (void)win_setrect(windowfd, &rectoriginal); if (win_cursor_planes_available(windowfd)) win_clear_cursor_planes(windowfd, &rectoriginal); (void)win_unlockdata(windowfd); return;}/* The next three routines used to be static, * but are now public for use in tool_bdry.c. */voidwmgr_providefeedback(feedbackfd, r, event, is_move, is_iconic, grasp, bounds_rect, adjust_position, swsp, obstacles) int feedbackfd; register Rect *r; register Event *event; int is_move, is_iconic; WM_Direction grasp; Rect *bounds_rect; int (*adjust_position)(); int swsp; Rectlist *obstacles;{ register Event_return status; int old_x, old_y; int activebut = event_action(event); struct fullscreen *fs; struct rect bounds; struct pr_pos offset; Rect orig_r, old_r;#ifdef KEYMAP_DEBUG /* Keymap debugging statement; to be removed later */ if (keymap_debug_mask & KEYMAP_SHOW_EVENT_STREAM) win_keymap_debug_start_blockio();#endif fs = wmgr_grab_screen(feedbackfd); orig_r = *r; wmgr_set_cursor(fs, r, event, is_move, grasp); if (wmgr_stretch_jump_cursor()) { offset.x = event->ie_locx - r->r_left; offset.y = event->ie_locy - r->r_top; } else { /* don't move cursor */ if (is_move) { offset.x = event->ie_locx - r->r_left; offset.y = event->ie_locy - r->r_top; } else { offset.x = offset.y = 0; } } if (bounds_rect) { bounds = *bounds_rect; } else { bounds = wmgr_set_bounds(r, &fs->fs_screenrect, grasp, is_move, &offset, MIN_TOOL_WIDTH, MIN_TOOL_HEIGHT); } old_x = event->ie_locx; old_y = event->ie_locy; xor_box(r); /* put the outline up to start */ status = Valid; while (status == Valid) { status = wmgr_get_event(feedbackfd, event, activebut); if (status == Stop || status == Error) { break; } if (event->ie_locx == old_x && event->ie_locy == old_y) { continue; } old_r = *r; if (is_move) { wmgr_move_box(r, &bounds, event->ie_locx, event->ie_locy, &offset,is_iconic); } else { wmgr_stretch_box(grasp, r, &bounds, event->ie_locx, event->ie_locy); } /* see if the new position is ok */ if (adjust_position) (*adjust_position)(obstacles, swsp, &old_r, r); if (!rect_equal(r, &old_r)) { xor_box(&old_r); /* remove old feedback */ xor_box(r); /* display new feedback */ } old_x = event->ie_locx; old_y = event->ie_locy; } xor_box(r); /* take box down at end */ (void)fullscreen_destroy(fs);#ifdef KEYMAP_DEBUG /* Keymap debugging statement; to be removed later */ if (keymap_debug_mask & KEYMAP_SHOW_EVENT_STREAM) win_keymap_debug_stop_blockio();#endif if (status == Stop) *r = orig_r;}/* grasp_type: 1 & 0= by position; -1= unconstrained; -2= fully constrained */WM_Directionwmgr_compute_grasp(r, event, is_move, is_iconic, grasp_type) register Rect *r; Event *event; int is_move, is_iconic,grasp_type;{ register int x = event->ie_locx, y = event->ie_locy; int row, col; if (is_move && is_iconic) return WM_None; if (grasp_type == -1) { if (x < r->r_left + r->r_width/2) col = 0; else col = 2; if (y < r->r_top + r->r_height/2) row = 0; else row = 2; } else if (grasp_type != -2) { if (x < r->r_left + r->r_width/3) col = 0; else if (x > r->r_left + (r->r_width/3) * 2) col = 2; else col = 1; if (y < r->r_top + r->r_height/3) row = 0; else if (y > r->r_top + (r->r_height/3) * 2) row = 2; else row = 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -