void Vibrate(const nsTArray<uint32>& pattern, const WindowIdentifier &id) { AssertMainThread(); // Only active windows may start vibrations. If |id| hasn't gone // through the IPC layer -- that is, if our caller is the outside // world, not hal_proxy -- check whether the window is active. If // |id| has gone through IPC, don't check the window's visibility; // only the window corresponding to the bottommost process has its // visibility state set correctly. if (!id.HasTraveledThroughIPC() && !WindowIsActive(id.GetWindow())) { HAL_LOG(("Vibrate: Window is inactive, dropping vibrate.")); return; } if (InSandbox()) { hal_sandbox::Vibrate(pattern, id); } else { if (!gLastIDToVibrate) InitLastIDToVibrate(); *gLastIDToVibrate = id.AsArray(); HAL_LOG(("Vibrate: Forwarding to hal_impl.")); // hal_impl doesn't need |id|. Send it an empty id, which will // assert if it's used. hal_impl::Vibrate(pattern, WindowIdentifier()); } }
void Vibrate(const nsTArray<uint32_t>& pattern, const WindowIdentifier &id) { AssertMainThread(); // Only active windows may start vibrations. If |id| hasn't gone // through the IPC layer -- that is, if our caller is the outside // world, not hal_proxy -- check whether the window is active. If // |id| has gone through IPC, don't check the window's visibility; // only the window corresponding to the bottommost process has its // visibility state set correctly. if (!id.HasTraveledThroughIPC() && !WindowIsActive(id.GetWindow())) { HAL_LOG(("Vibrate: Window is inactive, dropping vibrate.")); return; } if (!InSandbox()) { if (!gLastIDToVibrate) { InitLastIDToVibrate(); } *gLastIDToVibrate = id.AsArray(); } // Don't forward our ID if we are not in the sandbox, because hal_impl // doesn't need it, and we don't want it to be tempted to read it. The // empty identifier will assert if it's used. PROXY_IF_SANDBOXED(Vibrate(pattern, InSandbox() ? id : WindowIdentifier())); }
// Message определяет пришедшее сообщение. VOID Diver_DiverMessageProcessing( PQMSG Message ) { // Устанавливаем приоритет потока. if( Message->msg == SM_PRIORITY ) { // Устанавливаем приоритет. LONG Class = (LONG) Message->mp1; LONG Delta = (LONG) Message->mp2; DosSetPriority( PRTYS_THREAD, Class, Delta, 0 ); // Запоминаем приоритет. Enhancer.Modules.Diver->Priority = MAKELONG( Class, Delta ); } // Узнаем свойства окна. if( Message->msg == SM_QUERY_PROPERTIES ) { // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Если окна рамки нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return; // Узнаем, какое свойство надо узнать. ULONG Target = (ULONG) Message->mp2; // Узнаем значок и ширину рамки окна. if( Target & WT_UNKNOWN || Target & WT_SYSMENU ) Diver_QueryWindowProperty( Frame_window, WT_SYSMENU ); // Если окно заголовка было перерисовано - узнаем заголовок. if( Target & WT_UNKNOWN || Target & WT_TITLEBAR ) Diver_QueryWindowProperty( Frame_window, WT_TITLEBAR ); // Если заголовок есть, но он еще не определен - узнаем его, когда перерисовывается рамка. if( Target & WT_BORDER ) { // Узнаем окно заголовка. HWND TitleBar_window = WinWindowFromID( Frame_window, FID_TITLEBAR ); // Если оно есть: if( TitleBar_window != NULLHANDLE ) { // Узнаем, есть ли в списке заголовок окна. CHAR Title[ SIZE_OF_TITLE ] = ""; FindProperty( Frame_window, PRP_TITLE, Title ); // Если его нет - узнаем его. if( Title[ 0 ] == 0 ) Diver_QueryWindowProperty( Frame_window, WT_TITLEBAR, NO_ACTION, 1 ); } } // Узнаем состояние кнопок в правом верхнем углу окна. // Проверять кнопки при Target == WT_TITLEBAR нельзя - может // возникнуть постоянное рисование, которое выглядит как "мигание" рамки. if( Target & WT_UNKNOWN || Target & WT_SYSMENU ) Diver_QueryWindowProperty( Frame_window, WT_MINMAX ); // Если состояние кнопок еще не определено - узнаем его, когда перерисовывается рамка. if( Target & WT_BORDER ) { // Узнаем, есть ли в списке состояние кнопок. BYTE Actions_are_detected = 0; FindProperty( Frame_window, PRP_ACTIONS, &Actions_are_detected ); // Если его нет - узнаем его. if( !Actions_are_detected ) Diver_QueryWindowProperty( Frame_window, WT_MINMAX ); } } // Проверяет состояние всех окон, когда одно из окон становится выбранным. if( Message->msg == SM_CHECK_CONTROLS ) { // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Если окна рамки нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return; // Проверяем состояние кнопок в окнах приложения, а также их значки. Diver_CheckWindowControls( Frame_window ); // Если окно не перестало быть выбранным - проверяем, нет ли в списке двух одновременно выбранных окон. // Для окон диалога эту проверку выполнять не надо - они всегда работают правильно. if( WindowIsActive( Frame_window ) ) if( !WindowIsAppDialog( Frame_window ) ) CheckActivityProperties( Frame_window ); } // Проверяем рамки окон постоянного размера. if( Message->msg == SM_CHECK_FRAME ) { // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Узнаем окно, которое надо проверить. HWND Window = (HWND) Message->mp2; // Если одного из окон нет - возврат. HAB Application = WinQueryAnchorBlock( Frame_window ); if( !WinIsWindow( Application, Frame_window ) ) return; if( !WinIsWindow( Application, Window ) ) return; // Выполняем проверку. Diver_CheckWindowFrame( Frame_window, Window ); } // Возврат. return; }
// Frame_window - окно рамки, Target - какое из окон надо перерисовать. VOID Painter_DrawWindowFrame( HWND Frame_window, ULONG Target ) { // Узнаем размер и расположение окна. RECT Frame_rectangle = {0}; SWP Frame_placement = {0}; Painter_QueryFrameRectangeAndPlacement( Frame_window, &Frame_rectangle, &Frame_placement ); // Если окно не показано - возврат. if( Frame_rectangle.yTop <= 1 || Frame_rectangle.xRight <= 1 ) return; // Узнаем, как выглядит рамка окна. LONG Frame_type = FrameType( Frame_window ); // Узнаем, выбрано ли окно. BYTE Window_is_active = WindowIsActive( Frame_window ); // Устанавливаем свойство. SetProperty( Frame_window, PRP_ACTIVATED, &Window_is_active ); // Узнаем окно заголовка. HWND TitleBar_window = WinWindowFromID( Frame_window, FID_TITLEBAR ); // Для некоторых окон можно рисовать только заголовок. BYTE Draw_TitleBar_only = 0; if( !Painter_PermissionForCompleteDrawing( Frame_window ) ) { Draw_TitleBar_only = 1; Target = WT_TITLEBAR; } // Рисуем рамку для окна. if( !Draw_TitleBar_only ) { for( INT Step = 0; Step < MAX_FCHECKS; Step ++ ) { if( Painter_FrameRectangleIsChanged( Frame_window, &Frame_rectangle, &Frame_placement ) ) Painter_QueryFrameRectangeAndPlacement( Frame_window, &Frame_rectangle, &Frame_placement ); Painter_DrawFrameRectangle( Frame_window, Frame_type, &Frame_rectangle, &Frame_placement, Window_is_active ); if( Step != MAX_FCHECKS - 1 ) if( !Painter_FrameRectangleIsChanged( Frame_window, &Frame_rectangle, &Frame_placement ) ) break; } } // Подчеркиваем объем меню окна. if( Painter.Settings.Draw_menus ) if( Frame_type != FT_FLAT ) if( Target & WT_UNKNOWN || Target & WT_MENU ) { HWND Menu_window = WinWindowFromID( Frame_window, FID_MENU ); if( Menu_window != NULLHANDLE ) { for( INT Step = 0; Step < MAX_FCHECKS; Step ++ ) { if( Painter_FrameRectangleIsChanged( Frame_window, &Frame_rectangle, &Frame_placement ) ) Painter_QueryFrameRectangeAndPlacement( Frame_window, &Frame_rectangle, &Frame_placement ); Painter_DrawWindowMenu( Menu_window, Frame_window, &Frame_rectangle, &Frame_placement ); if( Step != MAX_FCHECKS - 1 ) if( !Painter_FrameRectangleIsChanged( Frame_window, &Frame_rectangle, &Frame_placement ) ) break; } } } // Узнаем окно обычных кнопок. HWND MinMax_window = WinWindowFromID( Frame_window, FID_MINMAX ); // Если окно плоское: if( Frame_type == FT_FLAT ) { // Если в нем есть окно обычных кнопок - скрываем его. if( Painter.Settings.Draw_buttons ) if( MinMax_window != NULLHANDLE ) WinShowWindow( MinMax_window, 0 ); // Возврат. return; } // А если это не плоское окно: else { // Если свойства окна неизвестны и могут быть определены в будущем - возврат. if( !PropertiesForDrawingAreDetected( Frame_window ) ) if( WinWindowFromID( Frame_window, FID_SYSMENU ) != NULLHANDLE ) return; } // Узнаем окно картинки. HWND SysMenu_window = WinWindowFromID( Frame_window, FID_SYSMENU ); // Узнаем высоту заголовка и картинки. INT TitleBar_height = 0; if( TitleBar_window != NULLHANDLE ) { RECT Rectangle = {0}; WinQueryWindowRect( TitleBar_window, &Rectangle ); TitleBar_height = Rectangle.yTop - 1; } else { TitleBar_height = WinQuerySysValue( QueryDesktopWindow(), SV_CYMINMAXBUTTON ) - 1; } // Окна заголовка и картинки должны быть расположены на одной линии. // Если это не так - окно надо обновить и ничего не рисовать в нем. if( SysMenu_window != NULLHANDLE ) if( TitleBar_window != NULLHANDLE ) if( WinIsWindowVisible( SysMenu_window ) ) { // Узнаем ширину рамки окна. INT Frame_width = 0; FindProperty( Frame_window, PRP_BORDER, &Frame_width ); if( !Frame_width ) Frame_width = FrameWidth( Frame_window ); // Узнаем расположение окна картинки. SWP SysMenu_placement = {0}; WinQueryWindowPos( SysMenu_window, &SysMenu_placement ); // Если оно расположено на своем месте: INT Y_middle_line = Frame_rectangle.yTop - Frame_width - TitleBar_height / 2; if( SysMenu_placement.y < Y_middle_line ) if( SysMenu_placement.y + SysMenu_placement.cy > Y_middle_line ) { // Узнаем расположение окна заголовка. SWP TitleBar_placement = {0}; WinQueryWindowPos( TitleBar_window, &TitleBar_placement ); // Если заголовок расположен не на своем месте: if( TitleBar_placement.y > Y_middle_line || TitleBar_placement.y + TitleBar_placement.cy < Y_middle_line ) { // Обновляем окно. UpdateWindow( Frame_window ); // Возврат. return; } } } // Узнаем, можно ли рисовать для окна новые кнопки. BYTE Draw_new_buttons = 0; if( Painter.Settings.Draw_buttons ) { // Узнаем, было ли определено состояние кнопок. BYTE Actions_are_detected = 0; FindProperty( Frame_window, PRP_ACTIONS, &Actions_are_detected ); // Если оно известно - кнопки можно рисовать. if( Actions_are_detected ) Draw_new_buttons = Painter_PermissionForButtonsDrawing( Frame_window ); } // Кнопки уменьшения и увеличения окна надо скрыть и сжать в "|". Кроме того, рамка // может содержать несколько кнопок слева и справа от заголовка, их надо передвинуть. BYTE Advanced_controls = 0; // Если надо рисовать рамку или заголовок: if( Target & WT_UNKNOWN || Target & WT_BORDER || Target & WT_TITLEBAR ) { // Передвигаем окна в заголовке и задаем подходящие цвета. if( TitleBar_window != NULLHANDLE || MinMax_window != NULLHANDLE ) if( Painter_PermissionForCompleteDrawing( Frame_window ) ) Advanced_controls = Painter_PrepareWindowControls( Frame_window, Frame_type, &Frame_rectangle, &Frame_placement, TitleBar_window, SysMenu_window, MinMax_window ); // Если справа от заголовка были найдены дополнительные окна - запоминаем это. if( Advanced_controls ) SetProperty( Frame_window, PRP_CONTROLS, &Advanced_controls ); } // Рисуем новые кнопки в правом верхнем углу окна. if( Draw_new_buttons ) if( Target & WT_UNKNOWN || Target & WT_BORDER ) if( TitleBar_window != NULLHANDLE ) { for( INT Step = 0; Step < MAX_FCHECKS; Step ++ ) { if( Painter_FrameRectangleIsChanged( Frame_window, &Frame_rectangle, &Frame_placement ) ) Painter_QueryFrameRectangeAndPlacement( Frame_window, &Frame_rectangle, &Frame_placement ); Painter_DrawButtons( Frame_window, Frame_type, &Frame_rectangle, &Frame_placement, TitleBar_window ); if( Step != MAX_FCHECKS - 1 ) if( !Painter_FrameRectangleIsChanged( Frame_window, &Frame_rectangle, &Frame_placement ) ) break; } } // Рисуем картинку в левом верхнем углу окна. if( Painter.Settings.Draw_system_menus ) if( Target & WT_UNKNOWN || Target & WT_SYSMENU ) if( SysMenu_window != NULLHANDLE ) { // Рисуем картинку. HPOINTER Icon = NULLHANDLE; FindProperty( Frame_window, PRP_ICON, &Icon ); for( INT Step = 0; Step < MAX_FCHECKS; Step ++ ) { if( Painter_FrameRectangleIsChanged( Frame_window, &Frame_rectangle, &Frame_placement ) ) Painter_QueryFrameRectangeAndPlacement( Frame_window, &Frame_rectangle, &Frame_placement ); Painter_DrawSystemMenu( SysMenu_window, Frame_window, &Frame_rectangle, &Frame_placement, Icon, Frame_type, 0 ); if( Step != MAX_FCHECKS - 1 ) if( !Painter_FrameRectangleIsChanged( Frame_window, &Frame_rectangle, &Frame_placement ) ) break; } // Если окно картинки закрывает рамку - перерисовываем ее. if( Frame_rectangle.xRight + 1 < TitleBar_height * 2 ) { for( INT Step = 0; Step < MAX_FCHECKS; Step ++ ) { if( Painter_FrameRectangleIsChanged( Frame_window, &Frame_rectangle, &Frame_placement ) ) Painter_QueryFrameRectangeAndPlacement( Frame_window, &Frame_rectangle, &Frame_placement ); Painter_DrawFrameRectangle( Frame_window, Frame_type, &Frame_rectangle, &Frame_placement, Window_is_active ); if( Step != MAX_FCHECKS - 1 ) if( !Painter_FrameRectangleIsChanged( Frame_window, &Frame_rectangle, &Frame_placement ) ) break; } } } // Рисуем заголовок окна. if( Painter.Settings.Draw_titles ) if( Target & WT_UNKNOWN || Target & WT_TITLEBAR ) if( TitleBar_window != NULLHANDLE ) { // Рисуем заголовок. Только подчеркивать его объем нельзя - может получиться окно с незакрашенным заголовком и линиями по краям. CHAR Title[ SIZE_OF_TITLE ] = ""; FindProperty( Frame_window, PRP_TITLE, Title ); for( INT Step = 0; Step < MAX_FCHECKS; Step ++ ) { if( Painter_FrameRectangleIsChanged( Frame_window, &Frame_rectangle, &Frame_placement ) ) Painter_QueryFrameRectangeAndPlacement( Frame_window, &Frame_rectangle, &Frame_placement ); Painter_DrawTitleBar( TitleBar_window, Frame_window, Frame_type, &Frame_rectangle, &Frame_placement, Title, Window_is_active, Advanced_controls ); if( Step != MAX_FCHECKS - 1 ) if( !Painter_FrameRectangleIsChanged( Frame_window, &Frame_rectangle, &Frame_placement ) ) break; } } // Возврат. return; }