From 9b3c0a162e7876bab09c299ff4d803b632bf3ac8 Mon Sep 17 00:00:00 2001 From: Martin Rudalics Date: Tue, 31 Dec 2013 10:48:54 +0100 Subject: [PATCH 1/2] Some more fixes following pixelwise resize changes including one for Bug#16306. * gtkutil.c (x_wm_set_size_hint): Have size hints respect value of frame_resize_pixelwise. * widget.c (pixel_to_text_size): New function. (update_wm_hints): Have size hints respect value of frame_resize_pixelwise. (EmacsFrameResize): Alway process resize requests pixelwise. * window.c (grow_mini_window): Make sure mini window is at least one line tall. * xdisp.c (display_menu_bar): Make sure menubar extends till right end of frame. * xfns.c (x_set_menu_bar_lines): Resize frame windows pixelwise. (x_set_tool_bar_lines): Calculate pixelwise. * xterm.c (x_wm_set_size_hint): Have size hints respect value of frame_resize_pixelwise. --- src/ChangeLog | 21 ++++++++++++++++++++- src/gtkutil.c | 8 ++++---- src/widget.c | 49 +++++++++++++++++++++++++++++++++++++++---------- src/window.c | 10 ++++++---- src/xdisp.c | 6 ++---- src/xfns.c | 33 +++++++++++++++++++++------------ src/xterm.c | 17 +++++++++++++---- 7 files changed, 105 insertions(+), 39 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index bfc4ac548c9..d7c772df2dd 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,22 @@ +2013-12-31 Martin Rudalics + + Some more fixes following pixelwise resize changes including one + for Bug#16306. + * gtkutil.c (x_wm_set_size_hint): Have size hints respect value + of frame_resize_pixelwise. + * widget.c (pixel_to_text_size): New function. + (update_wm_hints): Have size hints respect value of + frame_resize_pixelwise. + (EmacsFrameResize): Alway process resize requests pixelwise. + * window.c (grow_mini_window): Make sure mini window is at least + one line tall. + * xdisp.c (display_menu_bar): Make sure menubar extends till + right end of frame. + * xfns.c (x_set_menu_bar_lines): Resize frame windows pixelwise. + (x_set_tool_bar_lines): Calculate pixelwise. + * xterm.c (x_wm_set_size_hint): Have size hints respect value of + frame_resize_pixelwise. + 2013-12-30 Juanma Barranquero * fileio.c (Fcopy_file) [!WINDOWSNT]: Don't declare on Windows @@ -10,7 +29,7 @@ 2013-12-30 Martin Rudalics * dispnew.c (change_frame_size_1): Take old width of root window - from that window's pixel width. Bug#16284. + from that window's pixel width. (Bug#16284) 2013-12-29 Paul Eggert diff --git a/src/gtkutil.c b/src/gtkutil.c index e5d6414cf75..3f4e44eb196 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -1354,8 +1354,8 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position) hint_flags = f->output_data.x->hint_flags; hint_flags |= GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE; - size_hints.width_inc = FRAME_COLUMN_WIDTH (f); - size_hints.height_inc = FRAME_LINE_HEIGHT (f); + size_hints.width_inc = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f); + size_hints.height_inc = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f); hint_flags |= GDK_HINT_BASE_SIZE; /* Use one row/col here so base_height/width does not become zero. @@ -1370,8 +1370,8 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position) size_hints.base_width = base_width; size_hints.base_height = base_height; - size_hints.min_width = base_width + min_cols * size_hints.width_inc; - size_hints.min_height = base_height + min_rows * size_hints.height_inc; + size_hints.min_width = base_width + min_cols * FRAME_COLUMN_WIDTH (f);; + size_hints.min_height = base_height + min_rows * FRAME_LINE_HEIGHT (f); /* These currently have a one to one mapping with the X values, but I don't think we should rely on that. */ diff --git a/src/widget.c b/src/widget.c index 73c5149e2cd..7f6722f9ec7 100644 --- a/src/widget.c +++ b/src/widget.c @@ -189,6 +189,14 @@ pixel_to_char_size (EmacsFrame ew, Dimension pixel_width, Dimension pixel_height *char_height = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, (int) pixel_height); } +static void +pixel_to_text_size (EmacsFrame ew, Dimension pixel_width, Dimension pixel_height, int *text_width, int *text_height) +{ + struct frame* f = ew->emacs_frame.frame; + *text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, (int) pixel_width); + *text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, (int) pixel_height); +} + static void char_to_pixel_size (EmacsFrame ew, int char_width, int char_height, Dimension *pixel_width, Dimension *pixel_height) { @@ -487,8 +495,8 @@ update_wm_hints (EmacsFrame ew) XtVaSetValues (wmshell, XtNbaseWidth, (XtArgVal) base_width, XtNbaseHeight, (XtArgVal) base_height, - XtNwidthInc, (XtArgVal) cw, - XtNheightInc, (XtArgVal) ch, + XtNwidthInc, (XtArgVal) (frame_resize_pixelwise ? 1 : cw), + XtNheightInc, (XtArgVal) (frame_resize_pixelwise ? 1 : ch), XtNminWidth, (XtArgVal) (base_width + min_cols * cw), XtNminHeight, (XtArgVal) (base_height + min_rows * ch), NULL); @@ -670,21 +678,41 @@ EmacsFrameResize (Widget widget) EmacsFrame ew = (EmacsFrame)widget; struct frame *f = ew->emacs_frame.frame; struct x_output *x = f->output_data.x; - int columns; - int rows; - pixel_to_char_size (ew, ew->core.width, ew->core.height, &columns, &rows); - if (columns != FRAME_COLS (f) - || rows != FRAME_LINES (f) - || ew->core.width != FRAME_PIXEL_WIDTH (f) - || ew->core.height + x->menubar_height != FRAME_PIXEL_HEIGHT (f)) +#if 0 /* Always process resize requests pixelwise. Frame maximizing + should work even when frame_resize_pixelwise is nil. */ + if (frame_resize_pixelwise) { - change_frame_size (f, columns, rows, 0, 1, 0, 0); +#endif /* 0 */ + int width, height; + + pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height); + change_frame_size (f, width, height, 0, 1, 0, 1); + update_wm_hints (ew); update_various_frame_slots (ew); cancel_mouse_face (f); +#if 0 /* See comment above. */ } + else + { + int columns, rows; + + pixel_to_char_size (ew, ew->core.width, ew->core.height, &columns, &rows); + if (columns != FRAME_COLS (f) + || rows != FRAME_LINES (f) + || ew->core.width != FRAME_PIXEL_WIDTH (f) + || ew->core.height + x->menubar_height != FRAME_PIXEL_HEIGHT (f)) + { + change_frame_size (f, columns, rows, 0, 1, 0, 0); + update_wm_hints (ew); + update_various_frame_slots (ew); + + cancel_mouse_face (f); + } + } +#endif /* 0 */ } static Boolean @@ -724,6 +752,7 @@ EmacsFrameSetValues (Widget cur_widget, Widget req_widget, Widget new_widget, Ar if (has_to_recompute_size) { + /* Don't do this pixelwise, hopefully. */ pixel_width = new->core.width; pixel_height = new->core.height; pixel_to_char_size (new, pixel_width, pixel_height, &char_width, diff --git a/src/window.c b/src/window.c index 9bc95224f7c..1e3d70fd88d 100644 --- a/src/window.c +++ b/src/window.c @@ -4582,14 +4582,16 @@ grow_mini_window (struct window *w, int delta, bool pixelwise) if (pixelwise) { - pixel_height = min (-XINT (height), INT_MAX - w->pixel_height); + pixel_height = max (min (-XINT (height), INT_MAX - w->pixel_height), + FRAME_LINE_HEIGHT (f)); line_height = pixel_height / FRAME_LINE_HEIGHT (f); } else { - line_height = min (-XINT (height), - ((INT_MAX - w->pixel_height) - / FRAME_LINE_HEIGHT (f))); + line_height = max (min (-XINT (height), + ((INT_MAX - w->pixel_height) + / FRAME_LINE_HEIGHT (f))), + 1); pixel_height = line_height * FRAME_LINE_HEIGHT (f); } diff --git a/src/xdisp.c b/src/xdisp.c index 1c157c7be0a..8a0a714cdfc 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -20882,8 +20882,7 @@ display_menu_bar (struct window *w) eassert (!FRAME_WINDOW_P (f)); init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID); it.first_visible_x = 0; - /* PXW: Use FRAME_PIXEL_WIDTH (f) here? */ - it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); + it.last_visible_x = FRAME_PIXEL_WIDTH (f); #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */ if (FRAME_WINDOW_P (f)) { @@ -20894,8 +20893,7 @@ display_menu_bar (struct window *w) init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows, MENU_FACE_ID); it.first_visible_x = 0; - /* PXW: Use FRAME_PIXEL_WIDTH (f) here? */ - it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); + it.last_visible_x = FRAME_PIXEL_WIDTH (f); } else #endif /* not USE_X_TOOLKIT and not USE_GTK */ diff --git a/src/xfns.c b/src/xfns.c index 7200c5fb2e7..3b49ab5af75 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -997,7 +997,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) #else /* not USE_X_TOOLKIT && not USE_GTK */ FRAME_MENU_BAR_LINES (f) = nlines; FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f); - resize_frame_windows (f, FRAME_LINES (f), 0, 0); + resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1); /* If the menu bar height gets changed, the internal border below the top margin has to be cleared. Also, if the menu bar gets @@ -1052,7 +1052,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) int nlines; #if ! defined (USE_GTK) int delta, root_height; - Lisp_Object root_window; + int unit = FRAME_LINE_HEIGHT (f); #endif /* Treat tool bars like menu bars. */ @@ -1089,20 +1089,29 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) /* Make sure we redisplay all windows in this frame. */ windows_or_buffers_changed = 60; - delta = nlines - FRAME_TOOL_BAR_LINES (f); + /* DELTA is in pixels now. */ + delta = (nlines - FRAME_TOOL_BAR_LINES (f)) * unit; - /* Don't resize the tool-bar to more than we have room for. */ - root_window = FRAME_ROOT_WINDOW (f); - root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window)); - if (root_height - delta < 1) + /* Don't resize the tool-bar to more than we have room for. Note: The + calculations below and the subsequent call to resize_frame_windows + are inherently flawed because they can make the toolbar higher than + the containing frame. */ + if (delta > 0) { - delta = root_height - 1; - nlines = FRAME_TOOL_BAR_LINES (f) + delta; + root_height = WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f))); + if (root_height - delta < unit) + { + delta = root_height - unit; + /* When creating a new frame and toolbar mode is enabled, we + need at least one toolbar line. */ + nlines = max (FRAME_TOOL_BAR_LINES (f) + delta / unit, 1); + } } FRAME_TOOL_BAR_LINES (f) = nlines; FRAME_TOOL_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f); - resize_frame_windows (f, FRAME_LINES (f), 0, 0); + ++windows_or_buffers_changed; + resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1); adjust_frame_glyphs (f); /* We also have to make sure that the internal border at the top of @@ -1124,7 +1133,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) { int height = FRAME_INTERNAL_BORDER_WIDTH (f); int width = FRAME_PIXEL_WIDTH (f); - int y = (FRAME_MENU_BAR_LINES (f) + nlines) * FRAME_LINE_HEIGHT (f); + int y = nlines * unit; /* height can be zero here. */ if (height > 0 && width > 0) @@ -1139,7 +1148,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix); } - run_window_configuration_change_hook (f); + run_window_configuration_change_hook (f); #endif /* USE_GTK */ } diff --git a/src/xterm.c b/src/xterm.c index f634feb21f9..399262e0fb1 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -9293,8 +9293,9 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position) size_hints.height = FRAME_PIXEL_HEIGHT (f); size_hints.width = FRAME_PIXEL_WIDTH (f); - size_hints.width_inc = FRAME_COLUMN_WIDTH (f); - size_hints.height_inc = FRAME_LINE_HEIGHT (f); + size_hints.width_inc = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f); + size_hints.height_inc = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f); + size_hints.max_width = x_display_pixel_width (FRAME_DISPLAY_INFO (f)) - FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); size_hints.max_height = x_display_pixel_height (FRAME_DISPLAY_INFO (f)) @@ -9310,6 +9311,14 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position) check_frame_size (f, &min_cols, &min_rows, 0); + if (frame_resize_pixelwise) + /* Needed to prevent a bad protocol error crash when making the + frame size very small. */ + { + min_cols = 2 * min_cols; + min_rows = 2 * min_rows; + } + /* The window manager uses the base width hints to calculate the current number of rows and columns in the frame while resizing; min_width and min_height aren't useful for this @@ -9323,8 +9332,8 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position) size_hints.flags |= PBaseSize; size_hints.base_width = base_width; size_hints.base_height = base_height + FRAME_MENUBAR_HEIGHT (f); - size_hints.min_width = base_width + min_cols * size_hints.width_inc; - size_hints.min_height = base_height + min_rows * size_hints.height_inc; + size_hints.min_width = base_width + min_cols * FRAME_COLUMN_WIDTH (f); + size_hints.min_height = base_height + min_rows * FRAME_LINE_HEIGHT (f); } /* If we don't need the old flags, we don't need the old hint at all. */ From 0bbd0e0b1d5f358c85506dcc5451e14fb95864a8 Mon Sep 17 00:00:00 2001 From: Fabrice Popineau Date: Tue, 31 Dec 2013 17:00:43 +0200 Subject: [PATCH 2/2] Fall back on SetNamedSecurityInfo if SetFileSecurity fails in acl_set_file. src/w32.c (set_named_security_info): New function. (acl_set_file): Fall back on set_named_security_info if set_file_security fails. Fixes rare failures in backups. (g_b_init_set_named_security_info_w) (g_b_init_set_named_security_info_a): New static variables. (globals_of_w32): Initialize them to zero. (set_named_security_info): Set them to non-zero if the corresponding API is available. (SetNamedSecurityInfoW_Proc, SetNamedSecurityInfoA_Proc): New function typedefs. --- src/ChangeLog | 13 ++++++ src/w32.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 115 insertions(+), 5 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index d7c772df2dd..356d0b7bbf5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2013-12-31 Fabrice Popineau + + * w32.c (set_named_security_info): New function. + (acl_set_file): Fall back on set_named_security_info if + set_file_security fails. + (g_b_init_set_named_security_info_w) + (g_b_init_set_named_security_info_a): New static variables. + (globals_of_w32): Initialize them to zero. + (set_named_security_info): Set them to non-zero if the + corresponding API is available. + (SetNamedSecurityInfoW_Proc, SetNamedSecurityInfoA_Proc): New + function typedefs. + 2013-12-31 Martin Rudalics Some more fixes following pixelwise resize changes including one diff --git a/src/w32.c b/src/w32.c index 3fdb673b63f..4e7f77e9b95 100644 --- a/src/w32.c +++ b/src/w32.c @@ -303,6 +303,8 @@ static BOOL g_b_init_convert_sddl_to_sd; static BOOL g_b_init_is_valid_security_descriptor; static BOOL g_b_init_set_file_security_w; static BOOL g_b_init_set_file_security_a; +static BOOL g_b_init_set_named_security_info_w; +static BOOL g_b_init_set_named_security_info_a; static BOOL g_b_init_get_adapters_info; /* @@ -377,6 +379,22 @@ typedef BOOL (WINAPI *SetFileSecurityA_Proc) ( LPCSTR lpFileName, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor); +typedef DWORD (WINAPI *SetNamedSecurityInfoW_Proc) ( + LPCWSTR lpObjectName, + SE_OBJECT_TYPE ObjectType, + SECURITY_INFORMATION SecurityInformation, + PSID psidOwner, + PSID psidGroup, + PACL pDacl, + PACL pSacl); +typedef DWORD (WINAPI *SetNamedSecurityInfoA_Proc) ( + LPCSTR lpObjectName, + SE_OBJECT_TYPE ObjectType, + SECURITY_INFORMATION SecurityInformation, + PSID psidOwner, + PSID psidGroup, + PACL pDacl, + PACL pSacl); typedef BOOL (WINAPI * GetSecurityDescriptorOwner_Proc) ( PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID *pOwner, @@ -811,6 +829,69 @@ set_file_security (const char *lpFileName, } } +static DWORD WINAPI +set_named_security_info (LPCTSTR lpObjectName, + SE_OBJECT_TYPE ObjectType, + SECURITY_INFORMATION SecurityInformation, + PSID psidOwner, + PSID psidGroup, + PACL pDacl, + PACL pSacl) +{ + static SetNamedSecurityInfoW_Proc s_pfn_Set_Named_Security_InfoW = NULL; + static SetNamedSecurityInfoA_Proc s_pfn_Set_Named_Security_InfoA = NULL; + HMODULE hm_advapi32 = NULL; + if (is_windows_9x () == TRUE) + { + errno = ENOTSUP; + return ENOTSUP; + } + if (w32_unicode_filenames) + { + wchar_t filename_w[MAX_PATH]; + + if (g_b_init_set_named_security_info_w == 0) + { + g_b_init_set_named_security_info_w = 1; + hm_advapi32 = LoadLibrary ("Advapi32.dll"); + s_pfn_Set_Named_Security_InfoW = + (SetNamedSecurityInfoW_Proc) GetProcAddress (hm_advapi32, + "SetNamedSecurityInfoW"); + } + if (s_pfn_Set_Named_Security_InfoW == NULL) + { + errno = ENOTSUP; + return ENOTSUP; + } + filename_to_utf16 (lpObjectName, filename_w); + return (s_pfn_Set_Named_Security_InfoW (filename_w, ObjectType, + SecurityInformation, psidOwner, + psidGroup, pDacl, pSacl)); + } + else + { + char filename_a[MAX_PATH]; + + if (g_b_init_set_named_security_info_a == 0) + { + g_b_init_set_named_security_info_a = 1; + hm_advapi32 = LoadLibrary ("Advapi32.dll"); + s_pfn_Set_Named_Security_InfoA = + (SetNamedSecurityInfoA_Proc) GetProcAddress (hm_advapi32, + "SetNamedSecurityInfoA"); + } + if (s_pfn_Set_Named_Security_InfoA == NULL) + { + errno = ENOTSUP; + return ENOTSUP; + } + filename_to_ansi (lpObjectName, filename_a); + return (s_pfn_Set_Named_Security_InfoA (filename_a, ObjectType, + SecurityInformation, psidOwner, + psidGroup, pDacl, pSacl)); + } +} + static BOOL WINAPI get_security_descriptor_owner (PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID *pOwner, @@ -5903,7 +5984,7 @@ acl_set_file (const char *fname, acl_type_t type, acl_t acl) DWORD err; int st = 0, retval = -1; SECURITY_INFORMATION flags = 0; - PSID psid; + PSID psidOwner, psidGroup; PACL pacl; BOOL dflt; BOOL dacl_present; @@ -5929,11 +6010,13 @@ acl_set_file (const char *fname, acl_type_t type, acl_t acl) else fname = filename; - if (get_security_descriptor_owner ((PSECURITY_DESCRIPTOR)acl, &psid, &dflt) - && psid) + if (get_security_descriptor_owner ((PSECURITY_DESCRIPTOR)acl, &psidOwner, + &dflt) + && psidOwner) flags |= OWNER_SECURITY_INFORMATION; - if (get_security_descriptor_group ((PSECURITY_DESCRIPTOR)acl, &psid, &dflt) - && psid) + if (get_security_descriptor_group ((PSECURITY_DESCRIPTOR)acl, &psidGroup, + &dflt) + && psidGroup) flags |= GROUP_SECURITY_INFORMATION; if (get_security_descriptor_dacl ((PSECURITY_DESCRIPTOR)acl, &dacl_present, &pacl, &dflt) @@ -5960,10 +6043,22 @@ acl_set_file (const char *fname, acl_type_t type, acl_t acl) e = errno; errno = 0; + /* SetFileSecurity is deprecated by MS, and sometimes fails when + DACL inheritance is involved, but it seems to preserve ownership + better than SetNamedSecurity, which is important e.g., in + copy-file. */ if (!set_file_security (fname, flags, (PSECURITY_DESCRIPTOR)acl)) { err = GetLastError (); + if (errno != ENOTSUP) + err = set_named_security_info (fname, SE_FILE_OBJECT, flags, + psidOwner, psidGroup, pacl, NULL); + } + else + err = ERROR_SUCCESS; + if (err != ERROR_SUCCESS) + { if (errno == ENOTSUP) ; else if (err == ERROR_INVALID_OWNER @@ -8878,6 +8973,8 @@ globals_of_w32 (void) g_b_init_is_valid_security_descriptor = 0; g_b_init_set_file_security_w = 0; g_b_init_set_file_security_a = 0; + g_b_init_set_named_security_info_w = 0; + g_b_init_set_named_security_info_a = 0; g_b_init_get_adapters_info = 0; num_of_processors = 0; /* The following sets a handler for shutdown notifications for