diff options
Diffstat (limited to 'vcl/unx')
32 files changed, 1269 insertions, 594 deletions
diff --git a/vcl/unx/gtk/a11y/atkbridge.cxx b/vcl/unx/gtk/a11y/atkbridge.cxx index 9498c4570ae0..25add8e0dd18 100644 --- a/vcl/unx/gtk/a11y/atkbridge.cxx +++ b/vcl/unx/gtk/a11y/atkbridge.cxx @@ -40,17 +40,14 @@ bool InitAtkBridge(void) { const char* pVersion = atk_get_toolkit_version(); if( ! pVersion ) - { - g_warning( "unable to get gail version number" ); return false; - } unsigned int major, minor, micro; /* check gail minimum version requirements */ if( sscanf( pVersion, "%u.%u.%u", &major, &minor, µ) < 3 ) { - g_warning( "unable to parse gail version number" ); + // g_warning( "unable to parse gail version number" ); return false; } diff --git a/vcl/unx/gtk/a11y/atktext.cxx b/vcl/unx/gtk/a11y/atktext.cxx index f346a6a5a02c..e6d3276891de 100644 --- a/vcl/unx/gtk/a11y/atktext.cxx +++ b/vcl/unx/gtk/a11y/atktext.cxx @@ -454,6 +454,84 @@ text_wrapper_set_caret_offset (AtkText *text, return FALSE; } +// --> OD 2010-03-04 #i92232# +AtkAttributeSet* +handle_text_markup_as_run_attribute( accessibility::XAccessibleTextMarkup* pTextMarkup, + const gint nTextMarkupType, + const gint offset, + AtkAttributeSet* pSet, + gint *start_offset, + gint *end_offset ) +{ + const gint nTextMarkupCount( pTextMarkup->getTextMarkupCount( nTextMarkupType ) ); + if ( nTextMarkupCount > 0 ) + { + for ( gint nTextMarkupIndex = 0; + nTextMarkupIndex < nTextMarkupCount; + ++nTextMarkupIndex ) + { + accessibility::TextSegment aTextSegment = + pTextMarkup->getTextMarkup( nTextMarkupIndex, nTextMarkupType ); + const gint nStartOffsetTextMarkup = aTextSegment.SegmentStart; + const gint nEndOffsetTextMarkup = aTextSegment.SegmentEnd; + if ( nStartOffsetTextMarkup <= offset ) + { + if ( offset < nEndOffsetTextMarkup ) + { + // text markup at <offset> + *start_offset = ::std::max( *start_offset, + nStartOffsetTextMarkup ); + *end_offset = ::std::min( *end_offset, + nEndOffsetTextMarkup ); + switch ( nTextMarkupType ) + { + case com::sun::star::text::TextMarkupType::SPELLCHECK: + { + pSet = attribute_set_prepend_misspelled( pSet ); + } + break; + case com::sun::star::text::TextMarkupType::TRACK_CHANGE_INSERTION: + { + pSet = attribute_set_prepend_tracked_change_insertion( pSet ); + } + break; + case com::sun::star::text::TextMarkupType::TRACK_CHANGE_DELETION: + { + pSet = attribute_set_prepend_tracked_change_deletion( pSet ); + } + break; + case com::sun::star::text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE: + { + pSet = attribute_set_prepend_tracked_change_formatchange( pSet ); + } + break; + default: + { + OSL_ASSERT( false ); + } + } + break; // no further iteration needed. + } + else + { + *start_offset = ::std::max( *start_offset, + nEndOffsetTextMarkup ); + // continue iteration. + } + } + else + { + *end_offset = ::std::min( *end_offset, + nStartOffsetTextMarkup ); + break; // no further iteration. + } + } // eof iteration over text markups + } + + return pSet; +} +// <-- + static AtkAttributeSet * text_wrapper_get_run_attributes( AtkText *text, gint offset, @@ -491,41 +569,41 @@ text_wrapper_get_run_attributes( AtkText *text, } } - // Special handling for missspelled + // Special handling for misspelled text + // --> OD 2010-03-01 #i92232# + // - add special handling for tracked changes and refactor the + // corresponding code for handling misspelled text. accessibility::XAccessibleTextMarkup* pTextMarkup = getTextMarkup( text ); if( pTextMarkup ) { - uno::Sequence< accessibility::TextSegment > aTextSegmentSeq = - pTextMarkup->getTextMarkupAtIndex( offset, com::sun::star::text::TextMarkupType::SPELLCHECK ); - if( aTextSegmentSeq.getLength() > 0 ) + // Get attribute run here if it hasn't been done before + if( !bOffsetsAreValid ) { - accessibility::TextSegment aTextSegment = aTextSegmentSeq[0]; - gint nStartOffsetMisspelled = aTextSegment.SegmentStart; - gint nEndOffsetMisspelled = aTextSegment.SegmentEnd; - - // Get attribute run here if it hasn't been done before - if( !bOffsetsAreValid ) - { - accessibility::TextSegment aAttributeTextSegment = - pText->getTextAtIndex(offset, accessibility::AccessibleTextType::ATTRIBUTE_RUN); - *start_offset = aAttributeTextSegment.SegmentStart; - *end_offset = aAttributeTextSegment.SegmentEnd; - } - - if( nEndOffsetMisspelled <= offset ) - *start_offset = ::std::max( *start_offset, nEndOffsetMisspelled ); - else if( nStartOffsetMisspelled <= offset ) - *start_offset = ::std::max( *start_offset, nStartOffsetMisspelled ); - - if( nStartOffsetMisspelled > offset ) - *end_offset = ::std::min( *end_offset, nStartOffsetMisspelled ); - else if( nEndOffsetMisspelled > offset ) - *end_offset = ::std::min( *end_offset, nEndOffsetMisspelled ); - - if( nStartOffsetMisspelled <= offset && nEndOffsetMisspelled > offset ) - pSet = attribute_set_prepend_misspelled( pSet ); + accessibility::TextSegment aAttributeTextSegment = + pText->getTextAtIndex(offset, accessibility::AccessibleTextType::ATTRIBUTE_RUN); + *start_offset = aAttributeTextSegment.SegmentStart; + *end_offset = aAttributeTextSegment.SegmentEnd; } + // handle misspelled text + pSet = handle_text_markup_as_run_attribute( + pTextMarkup, + com::sun::star::text::TextMarkupType::SPELLCHECK, + offset, pSet, start_offset, end_offset ); + // handle tracked changes + pSet = handle_text_markup_as_run_attribute( + pTextMarkup, + com::sun::star::text::TextMarkupType::TRACK_CHANGE_INSERTION, + offset, pSet, start_offset, end_offset ); + pSet = handle_text_markup_as_run_attribute( + pTextMarkup, + com::sun::star::text::TextMarkupType::TRACK_CHANGE_DELETION, + offset, pSet, start_offset, end_offset ); + pSet = handle_text_markup_as_run_attribute( + pTextMarkup, + com::sun::star::text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE, + offset, pSet, start_offset, end_offset ); } + // <-- } catch(const uno::Exception& e){ diff --git a/vcl/unx/gtk/a11y/atktextattributes.cxx b/vcl/unx/gtk/a11y/atktextattributes.cxx index 02624a9628cf..04498810597f 100644 --- a/vcl/unx/gtk/a11y/atktextattributes.cxx +++ b/vcl/unx/gtk/a11y/atktextattributes.cxx @@ -74,6 +74,12 @@ static AtkTextAttribute atk_text_attribute_tab_stops = ATK_TEXT_ATTR_INVALID; static AtkTextAttribute atk_text_attribute_writing_mode = ATK_TEXT_ATTR_INVALID; static AtkTextAttribute atk_text_attribute_vertical_align = ATK_TEXT_ATTR_INVALID; static AtkTextAttribute atk_text_attribute_misspelled = ATK_TEXT_ATTR_INVALID; +// --> OD 2010-03-01 #i92232# +static AtkTextAttribute atk_text_attribute_tracked_change = ATK_TEXT_ATTR_INVALID; +// <-- +// --> OD 2010-03-05 #i92233# +static AtkTextAttribute atk_text_attribute_mm_to_pixel_ratio = ATK_TEXT_ATTR_INVALID; +// <-- /*****************************************************************************/ @@ -103,6 +109,9 @@ enum ExportedAttribute TEXT_ATTRIBUTE_STRIKETHROUGH, TEXT_ATTRIBUTE_UNDERLINE, TEXT_ATTRIBUTE_WEIGHT, + // --> OD 2010-03-05 #i92233# + TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO, + // <-- TEXT_ATTRIBUTE_JUSTIFICATION, TEXT_ATTRIBUTE_BOTTOM_MARGIN, TEXT_ATTRIBUTE_FIRST_LINE_INDENT, @@ -137,6 +146,9 @@ static const char * ExportedTextAttributes[TEXT_ATTRIBUTE_LAST] = "CharStrikeout", // TEXT_ATTRIBUTE_STRIKETHROUGH "CharUnderline", // TEXT_ATTRIBUTE_UNDERLINE "CharWeight", // TEXT_ATTRIBUTE_WEIGHT + // --> OD 2010-03-05 #i92233# + "MMToPixelRatio", // TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO + // <-- "ParaAdjust", // TEXT_ATTRIBUTE_JUSTIFICATION "ParaBottomMargin", // TEXT_ATTRIBUTE_BOTTOM_MARGIN "ParaFirstLineIndent", // TEXT_ATTRIBUTE_FIRST_LINE_INDENT @@ -1293,6 +1305,14 @@ attribute_set_new_from_property_values( attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_tab_stops, get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_TAB_STOPS], TabStops2String)); + // --> OD 2010-03-05 #i92233# + if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_mm_to_pixel_ratio ) + atk_text_attribute_mm_to_pixel_ratio = atk_text_attribute_register("mm-to-pixel-ratio"); + + attribute_set = attribute_set_prepend( attribute_set, atk_text_attribute_mm_to_pixel_ratio, + get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO], Float2String)); + // <-- + return attribute_set; } @@ -1308,6 +1328,49 @@ AtkAttributeSet* attribute_set_prepend_misspelled( AtkAttributeSet* attribute_se return attribute_set; } +// --> OD 2010-03-01 #i92232# +AtkAttributeSet* attribute_set_prepend_tracked_change_insertion( AtkAttributeSet* attribute_set ) +{ + if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change ) + { + atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" ); + } + + attribute_set = attribute_set_prepend( attribute_set, + atk_text_attribute_tracked_change, + g_strdup_printf( "insertion" ) ); + + return attribute_set; +} + +AtkAttributeSet* attribute_set_prepend_tracked_change_deletion( AtkAttributeSet* attribute_set ) +{ + if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change ) + { + atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" ); + } + + attribute_set = attribute_set_prepend( attribute_set, + atk_text_attribute_tracked_change, + g_strdup_printf( "deletion" ) ); + + return attribute_set; +} + +AtkAttributeSet* attribute_set_prepend_tracked_change_formatchange( AtkAttributeSet* attribute_set ) +{ + if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change ) + { + atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" ); + } + + attribute_set = attribute_set_prepend( attribute_set, + atk_text_attribute_tracked_change, + g_strdup_printf( "attribute-change" ) ); + + return attribute_set; +} +// <-- /*****************************************************************************/ diff --git a/vcl/unx/gtk/a11y/atktextattributes.hxx b/vcl/unx/gtk/a11y/atktextattributes.hxx index e363460bb578..9c7628bf927e 100644 --- a/vcl/unx/gtk/a11y/atktextattributes.hxx +++ b/vcl/unx/gtk/a11y/atktextattributes.hxx @@ -45,5 +45,10 @@ attribute_set_map_to_property_values( com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& rValueList ); AtkAttributeSet* attribute_set_prepend_misspelled( AtkAttributeSet* attribute_set ); +// --> OD 2010-03-01 #i92232# +AtkAttributeSet* attribute_set_prepend_tracked_change_insertion( AtkAttributeSet* attribute_set ); +AtkAttributeSet* attribute_set_prepend_tracked_change_deletion( AtkAttributeSet* attribute_set ); +AtkAttributeSet* attribute_set_prepend_tracked_change_formatchange( AtkAttributeSet* attribute_set ); +// <-- #endif diff --git a/vcl/unx/gtk/a11y/atkutil.cxx b/vcl/unx/gtk/a11y/atkutil.cxx index 6ed99d0cf3a3..13492f3d4a5c 100644 --- a/vcl/unx/gtk/a11y/atkutil.cxx +++ b/vcl/unx/gtk/a11y/atkutil.cxx @@ -500,6 +500,7 @@ static void handle_toolbox_buttonchange(VclWindowEvent const *pEvent) /*****************************************************************************/ +/* currently not needed anymore... static void create_wrapper_for_children(Window *pWindow) { if( pWindow && pWindow->IsReallyVisible() ) @@ -517,6 +518,7 @@ static void create_wrapper_for_children(Window *pWindow) } } } +*/ /*****************************************************************************/ @@ -695,7 +697,11 @@ long WindowEventHandler(void *, ::VclSimpleEvent const * pEvent) break; case VCLEVENT_COMBOBOX_SETTEXT: - create_wrapper_for_children(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); + // MT 2010/02: This looks quite strange to me. Stumbled over this when fixing #i104290#. + // This kicked in when leaving the combobox in the toolbar, after that the events worked. + // I guess this was a try to work around missing combobox events, which didn't do the full job, and shouldn't be necessary anymore. + // Fix for #i104290# was done in toolkit/source/awt/vclxaccessiblecomponent, FOCUSED state for compound controls in general. + // create_wrapper_for_children(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); break; default: diff --git a/vcl/unx/gtk/a11y/atkwindow.cxx b/vcl/unx/gtk/a11y/atkwindow.cxx index f588c1e345e4..5448235998e8 100644 --- a/vcl/unx/gtk/a11y/atkwindow.cxx +++ b/vcl/unx/gtk/a11y/atkwindow.cxx @@ -143,6 +143,22 @@ ooo_window_wrapper_real_focus_gtk (GtkWidget *, GdkEventFocus *) return FALSE; } +static gboolean ooo_tooltip_map( GtkWidget* pToolTip, gpointer ) +{ + AtkObject* pAccessible = gtk_widget_get_accessible( pToolTip ); + if( pAccessible ) + atk_object_notify_state_change( pAccessible, ATK_STATE_SHOWING, TRUE ); + return FALSE; +} + +static gboolean ooo_tooltip_unmap( GtkWidget* pToolTip, gpointer ) +{ + AtkObject* pAccessible = gtk_widget_get_accessible( pToolTip ); + if( pAccessible ) + atk_object_notify_state_change( pAccessible, ATK_STATE_SHOWING, FALSE ); + return FALSE; +} + /*****************************************************************************/ static bool @@ -208,6 +224,16 @@ ooo_window_wrapper_real_initialize(AtkObject *obj, gpointer data) g_signal_connect_after( GTK_WIDGET( data ), "focus-out-event", G_CALLBACK (ooo_window_wrapper_real_focus_gtk), NULL); + + if( obj->role == ATK_ROLE_TOOL_TIP ) + { + g_signal_connect_after( GTK_WIDGET( data ), "map-event", + G_CALLBACK (ooo_tooltip_map), + NULL); + g_signal_connect_after( GTK_WIDGET( data ), "unmap-event", + G_CALLBACK (ooo_tooltip_unmap), + NULL); + } } /*****************************************************************************/ diff --git a/vcl/unx/gtk/a11y/atkwrapper.cxx b/vcl/unx/gtk/a11y/atkwrapper.cxx index 5beb838c0e82..10f75309708d 100644 --- a/vcl/unx/gtk/a11y/atkwrapper.cxx +++ b/vcl/unx/gtk/a11y/atkwrapper.cxx @@ -283,7 +283,9 @@ static AtkRole mapToAtkRole( sal_Int16 nRole ) ATK_ROLE_RULER, ATK_ROLE_UNKNOWN, // SECTION - registered below ATK_ROLE_UNKNOWN, // TREE_ITEM - registered below - ATK_ROLE_TREE_TABLE + ATK_ROLE_TREE_TABLE, + ATK_ROLE_SCROLL_PANE, // COMMENT - mapped to atk_role_scroll_pane + ATK_ROLE_UNKNOWN // COMMENT_END - mapped to atk_role_unknown }; static bool initialized = false; diff --git a/vcl/unx/gtk/app/gtkdata.cxx b/vcl/unx/gtk/app/gtkdata.cxx index b1529e060270..f63f999738a7 100644 --- a/vcl/unx/gtk/app/gtkdata.cxx +++ b/vcl/unx/gtk/app/gtkdata.cxx @@ -221,8 +221,7 @@ void GtkSalDisplay::monitorsChanged( GdkScreen* pScreen ) { GdkRectangle dest; gdk_screen_get_monitor_geometry(pScreen, i, &dest); - m_aXineramaScreens.push_back( Rectangle( Point(dest.x, - dest.y ), Size( dest.width, dest.height ) ) ); + addXineramaScreenUnique( dest.x, dest.y, dest.width, dest.height ); } m_bXinerama = m_aXineramaScreens.size() > 1; if( ! m_aFrames.empty() ) @@ -663,7 +662,8 @@ void GtkXLib::Init() if( pScreen ) { g_signal_connect( G_OBJECT(pScreen), "size-changed", G_CALLBACK(signalScreenSizeChanged), m_pGtkSalDisplay ); - g_signal_connect( G_OBJECT(pScreen), "monitors-changed", G_CALLBACK(signalMonitorsChanged), m_pGtkSalDisplay ); + if( ! gtk_check_version( 2, 14, 0 ) ) // monitors-changed came in with 2.14, avoid an assertion + g_signal_connect( G_OBJECT(pScreen), "monitors-changed", G_CALLBACK(signalMonitorsChanged), m_pGtkSalDisplay ); } } } @@ -800,15 +800,12 @@ void GtkXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) */ bool bDispatchThread = false; + gboolean wasEvent = FALSE; { // release YieldMutex (and re-acquire at block end) YieldMutexReleaser aReleaser; if( osl_tryToAcquireMutex( m_aDispatchMutex ) ) - { - // we are the dispatch thread - osl_resetCondition( m_aDispatchCondition ); bDispatchThread = true; - } else if( ! bWait ) return; // someone else is waiting already, return @@ -816,7 +813,7 @@ void GtkXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) if( bDispatchThread ) { int nMaxEvents = bHandleAllCurrentEvents ? 100 : 1; - gboolean wasEvent = FALSE, wasOneEvent = TRUE; + gboolean wasOneEvent = TRUE; while( nMaxEvents-- && wasOneEvent ) { wasOneEvent = g_main_context_iteration( NULL, FALSE ); @@ -824,17 +821,17 @@ void GtkXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) wasEvent = TRUE; } if( bWait && ! wasEvent ) - g_main_context_iteration( NULL, TRUE ); + wasEvent = g_main_context_iteration( NULL, TRUE ); } - else if( userEventFn( this ) ) + else if( bWait ) { /* #i41693# in case the dispatch thread hangs in join * for this thread the condition will never be set * workaround: timeout of 1 second a emergency exit */ - TimeValue aValue; - aValue.Seconds = 1; - aValue.Nanosec = 0; + // we are the dispatch thread + osl_resetCondition( m_aDispatchCondition ); + TimeValue aValue = { 1, 0 }; osl_waitCondition( m_aDispatchCondition, &aValue ); } } @@ -842,8 +839,8 @@ void GtkXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) if( bDispatchThread ) { osl_releaseMutex( m_aDispatchMutex ); - osl_setCondition( m_aDispatchCondition ); // trigger non dispatch thread yields - osl_resetCondition( m_aDispatchCondition ); + if( wasEvent ) + osl_setCondition( m_aDispatchCondition ); // trigger non dispatch thread yields } } diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx index 869189fb1415..de4d55b0230a 100644 --- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx @@ -99,6 +99,8 @@ struct NWFWidgetData GtkWidget * gTooltipPopup; GtkWidget * gProgressBar; GtkWidget * gTreeView; + GtkWidget * gHScale; + GtkWidget * gVScale; NWPixmapCacheList* gNWPixmapCacheList; NWPixmapCache* gCacheTabItems; @@ -131,10 +133,12 @@ struct NWFWidgetData gMenuItemMenuWidget( NULL ), gMenuItemCheckMenuWidget( NULL ), gMenuItemRadioMenuWidget( NULL ), - gImageMenuItem( NULL ), + gImageMenuItem( NULL ), gTooltipPopup( NULL ), gProgressBar( NULL ), gTreeView( NULL ), + gHScale( NULL ), + gVScale( NULL ), gNWPixmapCacheList( NULL ), gCacheTabItems( NULL ), gCacheTabPages( NULL ) @@ -172,6 +176,7 @@ static void NWEnsureGTKMenu ( int nScreen ); static void NWEnsureGTKTooltip ( int nScreen ); static void NWEnsureGTKProgressBar ( int nScreen ); static void NWEnsureGTKTreeView ( int nScreen ); +static void NWEnsureGTKSlider ( int nScreen ); static void NWConvertVCLStateToGTKState( ControlState nVCLState, GtkStateType* nGTKState, GtkShadowType* nGTKShadow ); static void NWAddWidgetToCacheWindow( GtkWidget* widget, int nScreen ); @@ -589,8 +594,13 @@ BOOL GtkSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nP ) || ((nType == CTRL_LISTNODE || nType == CTRL_LISTNET) && ( (nPart == PART_ENTIRE_CONTROL) ) + ) || + ((nType == CTRL_SLIDER) && + ( (nPart == PART_TRACK_HORZ_AREA) + || (nPart == PART_TRACK_VERT_AREA) ) ) + ) return( TRUE ); return( FALSE ); @@ -875,6 +885,10 @@ BOOL GtkSalGraphics::drawNativeControl( ControlType nType, // don't actually draw anything; gtk treeviews do not draw lines returnVal = true; } + else if( (nType == CTRL_SLIDER) ) + { + returnVal = NWPaintGTKSlider( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rControlHandle, rCaption ); + } if( pixmap ) { @@ -1103,6 +1117,30 @@ BOOL GtkSalGraphics::getNativeControlRegion( ControlType nType, rNativeContentRegion = rNativeBoundingRegion; returnVal = TRUE; } + if( (nType == CTRL_SLIDER) && (nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT) ) + { + NWEnsureGTKSlider( m_nScreen ); + GtkWidget* widget = (nPart == PART_THUMB_HORZ) ? gWidgetData[m_nScreen].gHScale : gWidgetData[m_nScreen].gVScale; + gint slider_length = 10; + gint slider_width = 10; + gtk_widget_style_get( widget, + "slider-width", &slider_width, + "slider-length", &slider_length, + (char *)NULL); + Rectangle aRect( rControlRegion.GetBoundRect() ); + if( nPart == PART_THUMB_HORZ ) + { + aRect.Right() = aRect.Left() + slider_length - 1; + aRect.Bottom() = aRect.Top() + slider_width - 1; + } + else + { + aRect.Bottom() = aRect.Top() + slider_length - 1; + aRect.Right() = aRect.Left() + slider_width - 1; + } + rNativeBoundingRegion = rNativeContentRegion = Region( aRect ); + returnVal = TRUE; + } return( returnVal ); } @@ -3012,6 +3050,133 @@ BOOL GtkSalGraphics::NWPaintGTKProgress( return bRet; } +BOOL GtkSalGraphics::NWPaintGTKSlider( + GdkDrawable*, + ControlType, ControlPart nPart, + const Rectangle& rControlRectangle, + const clipList&, + ControlState nState, const ImplControlValue& rValue, + SalControlHandle&, const OUString& ) +{ + NWEnsureGTKSlider( m_nScreen ); + + gint w, h; + w = rControlRectangle.GetWidth(); + h = rControlRectangle.GetHeight(); + + SliderValue* pVal = (SliderValue*)rValue.getOptionalVal(); + + GdkPixmap* pixmap = NWGetPixmapFromScreen( rControlRectangle ); + if( ! pixmap ) + return FALSE; + + (void)pVal; + + GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap ); + GtkWidget* pWidget = (nPart == PART_TRACK_HORZ_AREA) + ? GTK_WIDGET(gWidgetData[m_nScreen].gHScale) + : GTK_WIDGET(gWidgetData[m_nScreen].gVScale); + const gchar* pDetail = (nPart == PART_TRACK_HORZ_AREA) ? "hscale" : "vscale"; + GtkOrientation eOri = (nPart == PART_TRACK_HORZ_AREA) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL; + GtkStateType eState = (nState & CTRL_STATE_ENABLED) ? GTK_STATE_ACTIVE : GTK_STATE_INSENSITIVE; + gint slider_width = 10; + gint slider_length = 10; + gint trough_border = 0; + gtk_widget_style_get( pWidget, + "slider-width", &slider_width, + "slider-length", &slider_length, + "trough-border", &trough_border, + NULL); + + eState = (nState & CTRL_STATE_ENABLED) ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE; + if( nPart == PART_TRACK_HORZ_AREA ) + { + gtk_paint_box( pWidget->style, + pixDrawable, + eState, + GTK_SHADOW_IN, + NULL, + pWidget, + "trough", + 0, (h-slider_width-2*trough_border)/2, w, slider_width + 2*trough_border); + gint x = (w - slider_length + 1) * (pVal->mnCur - pVal->mnMin) / (pVal->mnMax - pVal->mnMin); + gtk_paint_slider( pWidget->style, + pixDrawable, + eState, + GTK_SHADOW_OUT, + NULL, + pWidget, + pDetail, + x, (h-slider_width)/2, + slider_length, slider_width, + eOri ); + } + else + { + gtk_paint_box( pWidget->style, + pixDrawable, + eState, + GTK_SHADOW_IN, + NULL, + pWidget, + "trough", + (w-slider_width-2*trough_border)/2, 0, slider_width + 2*trough_border, h); + gint y = (h - slider_length + 1) * (pVal->mnCur - pVal->mnMin) / (pVal->mnMax - pVal->mnMin); + gtk_paint_slider( pWidget->style, + pixDrawable, + eState, + GTK_SHADOW_OUT, + NULL, + pWidget, + pDetail, + (w-slider_width)/2, y, + slider_width, slider_length, + eOri ); + } + #if 0 + // paint background + gtk_paint_flat_box( gWidgetData[m_nScreen].gProgressBar->style, + pixDrawable, + GTK_STATE_NORMAL, + GTK_SHADOW_NONE, + NULL, + gWidgetData[m_nScreen].gProgressBar, + "trough", + 0, 0, w, h ); + if( nProgressWidth > 0 ) + { + // paint progress + if( Application::GetSettings().GetLayoutRTL() ) + { + gtk_paint_box( gWidgetData[m_nScreen].gProgressBar->style, + pixDrawable, + GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, + NULL, + gWidgetData[m_nScreen].gProgressBar, + "bar", + w-nProgressWidth, 0, nProgressWidth, h + ); + } + else + { + gtk_paint_box( gWidgetData[m_nScreen].gProgressBar->style, + pixDrawable, + GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, + NULL, + gWidgetData[m_nScreen].gProgressBar, + "bar", + 0, 0, nProgressWidth, h + ); + } + } + #endif + + BOOL bRet = NWRenderPixmapToScreen( pixmap, rControlRectangle ); + g_object_unref( pixmap ); + + return bRet; +} + //---- static Rectangle NWGetListBoxButtonRect( int nScreen, @@ -3271,20 +3436,23 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings ) aStyleSet.SetHighlightColor( aHighlightColor ); aStyleSet.SetHighlightTextColor( aHighlightTextColor ); - // hyperlink colors - GdkColor *link_color = NULL; - gtk_widget_style_get (m_pWindow, "link-color", &link_color, NULL); - if (link_color) - { - aStyleSet.SetLinkColor(getColor(*link_color)); - gdk_color_free (link_color); - link_color = NULL; - } - gtk_widget_style_get (m_pWindow, "visited-link-color", &link_color, NULL); - if (link_color) + if( ! gtk_check_version( 2, 10, 0 ) ) // link colors came in with 2.10, avoid an assertion { - aStyleSet.SetVisitedLinkColor(getColor(*link_color)); - gdk_color_free (link_color); + // hyperlink colors + GdkColor *link_color = NULL; + gtk_widget_style_get (m_pWindow, "link-color", &link_color, NULL); + if (link_color) + { + aStyleSet.SetLinkColor(getColor(*link_color)); + gdk_color_free (link_color); + link_color = NULL; + } + gtk_widget_style_get (m_pWindow, "visited-link-color", &link_color, NULL); + if (link_color) + { + aStyleSet.SetVisitedLinkColor(getColor(*link_color)); + gdk_color_free (link_color); + } } // Tab colors @@ -3962,3 +4130,17 @@ static void NWEnsureGTKTreeView( int nScreen ) NWAddWidgetToCacheWindow( gWidgetData[nScreen].gTreeView, nScreen ); } } + +static void NWEnsureGTKSlider( int nScreen ) +{ + if( !gWidgetData[nScreen].gHScale ) + { + gWidgetData[nScreen].gHScale = gtk_hscale_new_with_range(0, 10, 1); + NWAddWidgetToCacheWindow( gWidgetData[nScreen].gHScale, nScreen ); + } + if( !gWidgetData[nScreen].gVScale ) + { + gWidgetData[nScreen].gVScale = gtk_vscale_new_with_range(0, 10, 1); + NWAddWidgetToCacheWindow( gWidgetData[nScreen].gVScale, nScreen ); + } +} diff --git a/vcl/unx/gtk/window/gtkframe.cxx b/vcl/unx/gtk/window/gtkframe.cxx index ba42cfc5ae82..16e478c22f6e 100644 --- a/vcl/unx/gtk/window/gtkframe.cxx +++ b/vcl/unx/gtk/window/gtkframe.cxx @@ -690,7 +690,7 @@ static void lcl_set_accept_focus( GtkWindow* pWindow, gboolean bAccept, bool bBe XFree( pHints ); if (GetX11SalData()->GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii("compiz")) - return; + return; /* remove WM_TAKE_FOCUS protocol; this would usually be the * right thing, but gtk handles it internally whereas we @@ -806,8 +806,15 @@ void GtkSalFrame::Init( SalFrame* pParent, ULONG nStyle ) /* #i100116# metacity has a peculiar behavior regarding WM_HINT accept focus and _NET_WM_USER_TIME at some point that may be fixed in metacity and we will have to revisit this */ - bool bMetaCityToolWindowHack = getDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii("Metacity") && - (nStyle & SAL_FRAME_STYLE_TOOLWINDOW ); + + // MT/PL 2010/02: #i102694# and #i102803# have been introduced by this hack + // Nowadays the original issue referenced above doesn't seem to exist anymore, tested different szenarious described in the issues + // If some older versions of MetaCity are still in use somewhere, they need to be updated, instead of using strange hacks in OOo. + // As a work around for such old systems, people might consider to not use the GTK plugin. + + bool bMetaCityToolWindowHack = false; + // bMetaCityToolWindowHack = getDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii("Metacity") && (nStyle & SAL_FRAME_STYLE_TOOLWINDOW ); + if( bDecoHandling ) { bool bNoDecor = ! (nStyle & (SAL_FRAME_STYLE_MOVEABLE | SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_CLOSEABLE ) ); @@ -837,7 +844,8 @@ void GtkSalFrame::Init( SalFrame* pParent, ULONG nStyle ) eType = GDK_WINDOW_TYPE_HINT_UTILITY; } - if( (nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) ) + if( (nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) + && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) { eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), true ); @@ -1297,7 +1305,8 @@ void GtkSalFrame::Show( BOOL bVisible, BOOL bNoActivate ) { if( m_pWindow ) { - if( m_pParent && (m_pParent->m_nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) ) + if( m_pParent && (m_pParent->m_nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) + && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), bVisible ); if( bVisible ) { @@ -1458,6 +1467,12 @@ void GtkSalFrame::setMinMaxSize() aHints |= GDK_HINT_MAX_SIZE; } } + if( m_bFullscreen ) + { + aGeo.max_width = m_aMaxSize.Width(); + aGeo.max_height = m_aMaxSize.Height(); + aHints |= GDK_HINT_MAX_SIZE; + } if( aHints ) gtk_window_set_geometry_hints( GTK_WINDOW(m_pWindow), NULL, @@ -1809,8 +1824,6 @@ void GtkSalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nScreen ) { m_aRestorePosSize = Rectangle( Point( maGeometry.nX, maGeometry.nY ), Size( maGeometry.nWidth, maGeometry.nHeight ) ); - // workaround different window managers have different opinions about - // _NET_WM_STATE_FULLSCREEN (Metacity <-> KWin) bool bVisible = GTK_WIDGET_MAPPED(m_pWindow); if( bVisible ) Show( FALSE ); @@ -1827,12 +1840,22 @@ void GtkSalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nScreen ) gtk_window_move( GTK_WINDOW(m_pWindow), maGeometry.nX = aNewPosSize.Left(), maGeometry.nY = aNewPosSize.Top() ); + // #i110881# for the benefit of compiz set a max size here + // else setting to fullscreen fails for unknown reasons + m_aMaxSize.Width() = aNewPosSize.GetWidth()+100; + m_aMaxSize.Height() = aNewPosSize.GetHeight()+100; + // workaround different legacy version window managers have different opinions about + // _NET_WM_STATE_FULLSCREEN (Metacity <-> KWin) + if( ! getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + gtk_window_fullscreen( GTK_WINDOW( m_pWindow ) ); if( bVisible ) Show( TRUE ); } else { bool bVisible = GTK_WIDGET_MAPPED(m_pWindow); + if( ! getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + gtk_window_unfullscreen( GTK_WINDOW(m_pWindow) ); if( bVisible ) Show( FALSE ); m_nStyle &= ~SAL_FRAME_STYLE_PARTIAL_FULLSCREEN; @@ -1855,8 +1878,11 @@ void GtkSalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nScreen ) { if( bFullScreen ) { - if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) - gtk_window_set_resizable( GTK_WINDOW(m_pWindow), TRUE ); + if( getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + { + if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) + gtk_window_set_resizable( GTK_WINDOW(m_pWindow), TRUE ); + } gtk_window_fullscreen( GTK_WINDOW(m_pWindow) ); moveToScreen( nScreen ); Size aScreenSize = pDisp->GetScreenSize( m_nScreen ); @@ -1868,8 +1894,11 @@ void GtkSalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nScreen ) else { gtk_window_unfullscreen( GTK_WINDOW(m_pWindow) ); - if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) - gtk_window_set_resizable( GTK_WINDOW(m_pWindow), FALSE ); + if( getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + { + if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) + gtk_window_set_resizable( GTK_WINDOW(m_pWindow), FALSE ); + } moveToScreen( nScreen ); } } @@ -2081,7 +2110,14 @@ void GtkSalFrame::ToTop( USHORT nFlags ) * is set to false. */ if( (m_nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_FLOAT_FOCUSABLE)) ) + { + // sad but true: this can cause an XError, we need to catch that + // to do this we need to synchronize with the XServer + getDisplay()->GetXLib()->PushXErrorLevel( true ); XSetInputFocus( getDisplay()->GetDisplay(), GDK_WINDOW_XWINDOW( m_pWindow->window ), RevertToParent, CurrentTime ); + XSync( getDisplay()->GetDisplay(), False ); + getDisplay()->GetXLib()->PopXErrorLevel(); + } } else { @@ -3170,6 +3206,15 @@ gboolean GtkSalFrame::signalState( GtkWidget*, GdkEvent* pEvent, gpointer frame } pThis->m_nState = pEvent->window_state.new_window_state; + #if OSL_DEBUG_LEVEL > 1 + if( (pEvent->window_state.changed_mask & GDK_WINDOW_STATE_FULLSCREEN) ) + { + fprintf( stderr, "window %p %s full screen state\n", + pThis, + (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ? "enters" : "leaves"); + } + #endif + return FALSE; } diff --git a/vcl/unx/headless/svpframe.cxx b/vcl/unx/headless/svpframe.cxx index 37c5eeb846a4..1adf9a51cce4 100644 --- a/vcl/unx/headless/svpframe.cxx +++ b/vcl/unx/headless/svpframe.cxx @@ -82,6 +82,33 @@ SvpSalFrame::~SvpSalFrame() (*it)->SetParent( m_pParent ); if( m_pParent ) m_pParent->m_aChildren.remove( this ); + + if( s_pFocusFrame == this ) + { + s_pFocusFrame = NULL; + // call directly here, else an event for a destroyed frame would be dispatched + CallCallback( SALEVENT_LOSEFOCUS, NULL ); + // if the handler has not set a new focus frame + // pass focus to another frame, preferably a document style window + if( s_pFocusFrame == NULL ) + { + const std::list< SalFrame* >& rFrames( m_pInstance->getFrames() ); + for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it ) + { + SvpSalFrame* pFrame = const_cast<SvpSalFrame*>(static_cast<const SvpSalFrame*>(*it)); + if( pFrame->m_bVisible && + pFrame->m_pParent == NULL && + (pFrame->m_nStyle & (SAL_FRAME_STYLE_MOVEABLE | + SAL_FRAME_STYLE_SIZEABLE | + SAL_FRAME_STYLE_CLOSEABLE) ) != 0 + ) + { + pFrame->GetFocus(); + break; + } + } + } + } } void SvpSalFrame::GetFocus() diff --git a/vcl/unx/headless/svpinst.cxx b/vcl/unx/headless/svpinst.cxx index 485062bf0617..466b56868900 100644 --- a/vcl/unx/headless/svpinst.cxx +++ b/vcl/unx/headless/svpinst.cxx @@ -55,6 +55,19 @@ extern "C" } } +bool SvpSalInstance::isFrameAlive( const SalFrame* pFrame ) const +{ + for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin(); + it != m_aFrames.end(); ++it ) + { + if( *it == pFrame ) + { + return true; + } + } + return false; +} + SvpSalInstance* SvpSalInstance::s_pDefaultInstance = NULL; SvpSalInstance::SvpSalInstance() @@ -346,12 +359,15 @@ void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) { for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it != aEvents.end(); ++it ) { - it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData ); - if( it->m_nEvent == SALEVENT_RESIZE ) + if ( isFrameAlive( it->m_pFrame ) ) { - // this would be a good time to post a paint - const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame); - pSvpFrame->PostPaint(); + it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData ); + if( it->m_nEvent == SALEVENT_RESIZE ) + { + // this would be a good time to post a paint + const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame); + pSvpFrame->PostPaint(); + } } } } diff --git a/vcl/unx/headless/svpinst.hxx b/vcl/unx/headless/svpinst.hxx index d37c1c7e126e..284a2d11cd82 100644 --- a/vcl/unx/headless/svpinst.hxx +++ b/vcl/unx/headless/svpinst.hxx @@ -108,6 +108,9 @@ class SvpSalInstance : public SalInstance std::list< SalUserEvent > m_aUserEvents; std::list< SalFrame* > m_aFrames; + + bool isFrameAlive( const SalFrame* pFrame ) const; + public: static SvpSalInstance* s_pDefaultInstance; diff --git a/vcl/unx/inc/plugins/gtk/gtkgdi.hxx b/vcl/unx/inc/plugins/gtk/gtkgdi.hxx index 9db81aa30a4d..ed3f782c8576 100644 --- a/vcl/unx/inc/plugins/gtk/gtkgdi.hxx +++ b/vcl/unx/inc/plugins/gtk/gtkgdi.hxx @@ -168,6 +168,11 @@ protected: const clipList& rClipList, ControlState nState, const ImplControlValue& aValue, SalControlHandle& rControlHandle, const OUString& rCaption ); + BOOL NWPaintGTKSlider( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart, + const Rectangle& rControlRectangle, + const clipList& rClipList, + ControlState nState, const ImplControlValue& aValue, + SalControlHandle& rControlHandle, const OUString& rCaption ); BOOL NWPaintGTKListNode( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart, const Rectangle& rControlRectangle, const clipList& rClipList, diff --git a/vcl/unx/inc/saldata.hxx b/vcl/unx/inc/saldata.hxx index 3810558d470d..7e38e0a89bf2 100644 --- a/vcl/unx/inc/saldata.hxx +++ b/vcl/unx/inc/saldata.hxx @@ -62,6 +62,7 @@ protected: SalXLib *pXLib_; SalDisplay *m_pSalDisplay; pthread_t hMainThread_; + rtl::OUString maLocalHostName; public: X11SalData(); @@ -87,6 +88,9 @@ public: inline void StopTimer(); void Timeout() const; + const rtl::OUString& GetLocalHostName() const + { return maLocalHostName; } + static int XErrorHdl( Display*, XErrorEvent* ); static int XIOErrorHdl( Display* ); diff --git a/vcl/unx/inc/saldisp.hxx b/vcl/unx/inc/saldisp.hxx index 368e554794ad..e54d6e828911 100644 --- a/vcl/unx/inc/saldisp.hxx +++ b/vcl/unx/inc/saldisp.hxx @@ -404,6 +404,7 @@ protected: int processRandREvent( XEvent* ); void doDestruct(); + void addXineramaScreenUnique( long i_nX, long i_nY, long i_nWidth, long i_nHeight ); public: static SalDisplay *GetSalDisplay( Display* display ); static BOOL BestVisual( Display *pDisp, diff --git a/vcl/unx/inc/wmadaptor.hxx b/vcl/unx/inc/wmadaptor.hxx index c628cfe091ef..cbedede2cc99 100644 --- a/vcl/unx/inc/wmadaptor.hxx +++ b/vcl/unx/inc/wmadaptor.hxx @@ -58,6 +58,8 @@ public: NET_WM_NAME, NET_WM_DESKTOP, NET_WM_ICON_NAME, + NET_WM_PID, + NET_WM_PING, NET_WM_STATE, NET_WM_STATE_MAXIMIZED_HORZ, NET_WM_STATE_MAXIMIZED_VERT, @@ -160,6 +162,7 @@ protected: m_aWMWorkAreas; bool m_bTransientBehaviour; bool m_bEnableAlwaysOnTopWorks; + bool m_bLegacyPartialFullscreen; int m_nWinGravity; int m_nInitWinGravity; @@ -220,6 +223,18 @@ public: virtual void setWMName( X11SalFrame* pFrame, const String& rWMName ) const; /* + * set NET_WM_PID + */ + virtual void setPID( X11SalFrame* pFrame ) const; + + /* + * set WM_CLIENT_MACHINE + */ + virtual void setClientMachine( X11SalFrame* pFrame ) const; + + virtual void answerPing( X11SalFrame*, XClientMessageEvent* ) const; + + /* * maximizes frame * maximization can be toggled in either direction * to get the original position and size @@ -231,6 +246,15 @@ public: */ virtual void showFullScreen( X11SalFrame* pFrame, bool bFullScreen ) const; /* + * tell whether legacy partial full screen handling is necessary + * see #i107249#: NET_WM_STATE_FULLSCREEN is not well defined, but de facto + * modern WM's interpret it the "right" way, namely they make "full screen" + * taking twin view or Xinerama into accound and honor the positioning hints + * to see which screen actually was meant to use for fullscreen. + */ + bool isLegacyPartialFullscreen() const + { return m_bLegacyPartialFullscreen; } + /* * set window struts */ virtual void setFrameStruts( X11SalFrame*pFrame, diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx index 79de48302649..25dd50ce3958 100644 --- a/vcl/unx/kde4/KDESalGraphics.cxx +++ b/vcl/unx/kde4/KDESalGraphics.cxx @@ -88,8 +88,18 @@ QRect region2QRect( const Region& rControlRegion ) { Rectangle aRect = rControlRegion.GetBoundRect(); - return QRect( QPoint( aRect.Left(), aRect.Top() ), - QPoint( aRect.Right(), aRect.Bottom() ) ); + return QRect(aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight()); +} + +KDESalGraphics::KDESalGraphics() : + m_image(0) +{ +} + +KDESalGraphics::~KDESalGraphics() +{ + if (m_image) + delete m_image; } BOOL KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart part ) @@ -133,6 +143,9 @@ BOOL KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart par if (type == CTRL_RADIOBUTTON) return true; + if (type == CTRL_SLIDER && (part == PART_TRACK_HORZ_AREA || part == PART_TRACK_VERT_AREA) ) + return true; + return false; if ( (type == CTRL_TAB_ITEM) && (part == PART_ENTIRE_CONTROL) ) return true; @@ -143,7 +156,6 @@ BOOL KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart par return false; } - BOOL KDESalGraphics::hitTestNativeControl( ControlType, ControlPart, const Region&, const Point&, SalControlHandle&, BOOL& ) @@ -151,28 +163,59 @@ BOOL KDESalGraphics::hitTestNativeControl( ControlType, ControlPart, return FALSE; } -void lcl_drawFrame( QRect& i_rRect, QPainter& i_rPainter, QStyle::PrimitiveElement i_nElement, - ControlState i_nState, const ImplControlValue& i_rValue ) +/// helper drawing methods +namespace { + void draw( QStyle::ControlElement element, QStyleOption* option, QImage* image, QStyle::State state ) + { + option->state |= state; + option->rect = image->rect(); + + QPainter painter(image); + kapp->style()->drawControl(element, option, &painter); + } + + void draw( QStyle::PrimitiveElement element, QStyleOption* option, QImage* image, QStyle::State state, int nAdjust = 0 ) + { + option->state |= state; + option->rect = image->rect(); + if( nAdjust ) + option->rect.adjust( nAdjust, nAdjust, -nAdjust, -nAdjust ); + + QPainter painter(image); + kapp->style()->drawPrimitive(element, option, &painter); + } + + void draw( QStyle::ComplexControl element, QStyleOptionComplex* option, QImage* image, QStyle::State state ) + { + option->state |= state; + option->rect = image->rect(); + + QPainter painter(image); + kapp->style()->drawComplexControl(element, option, &painter); + } + + void lcl_drawFrame(QStyle::PrimitiveElement element, QImage* image, QStyle::State state) + { #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) - QStyleOptionFrameV3 styleOption; - styleOption.frameShape = QFrame::StyledPanel; + QStyleOptionFrameV3 option; + option.frameShape = QFrame::StyledPanel; + option.state = QStyle::State_Sunken; #else - QStyleOptionFrame styleOption; - QFrame aFrame( NULL ); - aFrame.setFrameRect( QRect(0, 0, i_rRect.width(), i_rRect.height()) ); - aFrame.setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); - aFrame.ensurePolished(); - styleOption.initFrom( &aFrame ); - styleOption.lineWidth = aFrame.lineWidth(); - styleOption.midLineWidth = aFrame.midLineWidth(); - #endif - styleOption.rect = QRect(0, 0, i_rRect.width(), i_rRect.height()); - styleOption.state = vclStateValue2StateFlag( i_nState, i_rValue ); - #if ( QT_VERSION < QT_VERSION_CHECK( 4, 5, 0 ) ) - styleOption.state |= QStyle::State_Sunken; + QStyleOptionFrame option; + + QFrame aFrame( NULL ); + aFrame.setFrameRect( QRect(0, 0, image->width(), image->height()) ); + aFrame.setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + aFrame.ensurePolished(); + + option.initFrom( &aFrame ); + option.lineWidth = aFrame.lineWidth(); + option.midLineWidth = aFrame.midLineWidth(); #endif - kapp->style()->drawPrimitive(i_nElement, &styleOption, &i_rPainter); + + draw(element, &option, image, state); + } } BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, @@ -188,10 +231,6 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, BOOL returnVal = true; - Display* dpy = GetXDisplay(); - XLIB_Window drawable = GetDrawable(); - GC gc = SelectPen(); - QRect widgetRect = region2QRect(rControlRegion); if( type == CTRL_SPINBOX && part == PART_ALL_BUTTONS ) type = CTRL_SPINBUTTONS; @@ -204,337 +243,287 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, aButtonRect.Right(), aButtonRect.Bottom() ); } - //draw right onto the window - QPixmap pixmap(widgetRect.width(), widgetRect.height()); - - if (pixmap.isNull()) + //if no image, or resized, make a new image + if (!m_image || m_image->size() != widgetRect.size()) { - return false; + if (m_image) + delete m_image; + + m_image = new QImage( widgetRect.width(), + widgetRect.height(), + QImage::Format_ARGB32 ); } + m_image->fill(KApplication::palette().color(QPalette::Window).rgb()); - QPainter painter(&pixmap); - // painter.setBackgroundMode(Qt::OpaqueMode); - //copy previous screen contents for proper blending - #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) - QPixmap screen = QPixmap::fromX11Pixmap(drawable); - painter.drawPixmap(0,0, screen, widgetRect.left(), widgetRect.top(), widgetRect.width(), widgetRect.height()); - #else - const QX11Info& rX11Info( pixmap.x11Info() ); - X11SalGraphics::CopyScreenArea( dpy, - drawable, GetScreenNumber(), GetBitCount(), - pixmap.handle(), rX11Info.screen(), rX11Info.depth(), - GetDisplay()->GetCopyGC( GetScreenNumber() ), - widgetRect.left(), widgetRect.top(), widgetRect.width(), widgetRect.height(), - 0, 0 ); - #endif + XLIB_Region pTempClipRegion = 0; if (type == CTRL_PUSHBUTTON) { - QStyleOptionButton styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state =vclStateValue2StateFlag( nControlState, value ); - - kapp->style()->drawControl( QStyle::CE_PushButton, &styleOption, &painter); + QStyleOptionButton option; + draw( QStyle::CE_PushButton, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if ( (type == CTRL_MENUBAR)) { if (part == PART_MENU_ITEM) { - QStyleOptionMenuItem styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - kapp->style()->drawControl( QStyle::CE_MenuBarItem, &styleOption, &painter); + QStyleOptionMenuItem option; + draw( QStyle::CE_MenuBarItem, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); + } + else if (part == PART_ENTIRE_CONTROL) + { } else { - pixmap.fill(KApplication::palette().color(QPalette::Window)); + returnVal = false; } } else if (type == CTRL_MENU_POPUP) { if (part == PART_MENU_ITEM) { - QStyleOptionMenuItem styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - kapp->style()->drawControl( QStyle::CE_MenuItem, &styleOption, &painter); + QStyleOptionMenuItem option; + draw( QStyle::CE_MenuItem, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } - else if (part == PART_MENU_ITEM_CHECK_MARK) + else if (part == PART_MENU_ITEM_CHECK_MARK && (nControlState & CTRL_STATE_PRESSED) ) { - QStyleOptionButton styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - if (nControlState & CTRL_STATE_PRESSED) - { - kapp->style()->drawPrimitive( QStyle::PE_IndicatorMenuCheckMark, &styleOption, &painter); - } + QStyleOptionButton option; + draw( QStyle::PE_IndicatorMenuCheckMark, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } - else if (part == PART_MENU_ITEM_RADIO_MARK) + else if (part == PART_MENU_ITEM_RADIO_MARK && (nControlState & CTRL_STATE_PRESSED) ) { - QStyleOptionButton styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - if (nControlState & CTRL_STATE_PRESSED) - { - kapp->style()->drawPrimitive( QStyle::PE_IndicatorRadioButton, &styleOption, &painter); - } + QStyleOptionButton option; + draw( QStyle::PE_IndicatorRadioButton, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else { - pixmap.fill(KApplication::palette().color(QPalette::Window)); - #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) - QStyleOptionFrameV3 styleOption; + QStyleOptionFrameV3 option; + option.frameShape = QFrame::StyledPanel; #else - QStyleOptionFrameV2 styleOption; - #endif - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) - styleOption.frameShape = QFrame::StyledPanel; + QStyleOptionFrameV2 option; #endif - - kapp->style()->drawPrimitive( QStyle::PE_FrameMenu, &styleOption, &painter); + draw( QStyle::PE_FrameMenu, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } } else if ( (type == CTRL_TOOLBAR) && (part == PART_BUTTON) ) { - QStyleOptionToolButton styleOption; + QStyleOptionToolButton option; - styleOption.arrowType = Qt::NoArrow; - styleOption.subControls = QStyle::SC_ToolButton; + option.arrowType = Qt::NoArrow; + option.subControls = QStyle::SC_ToolButton; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - styleOption.state |= QStyle::State_Raised | QStyle::State_Enabled | QStyle::State_AutoRaise; + option.state = vclStateValue2StateFlag( nControlState, value ); + option.state |= QStyle::State_Raised | QStyle::State_Enabled | QStyle::State_AutoRaise; - kapp->style()->drawComplexControl( QStyle::CC_ToolButton, &styleOption, &painter); + draw( QStyle::CC_ToolButton, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if ( (type == CTRL_TOOLBAR) && (part == PART_ENTIRE_CONTROL) ) { - QStyleOptionToolBar styleOption; + QStyleOptionToolBar option; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); + option.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + option.state = vclStateValue2StateFlag( nControlState, value ); - kapp->style()->drawControl( QStyle::CE_ToolBar, &styleOption, &painter); + draw( QStyle::CE_ToolBar, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if ( (type == CTRL_TOOLBAR) && (part == PART_THUMB_VERT) ) { - QStyleOption styleOption; + const int tw = widgetRect.width(); + widgetRect.setWidth(kapp->style()->pixelMetric(QStyle::PM_ToolBarHandleExtent)); - int width = kapp->style()->pixelMetric(QStyle::PM_ToolBarHandleExtent); + QStyleOption option; + option.state = QStyle::State_Horizontal; - styleOption.rect = QRect(0, 0, width, widgetRect.height()); - styleOption.state = QStyle::State_Horizontal; + draw( QStyle::PE_IndicatorToolBarHandle, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); - kapp->style()->drawPrimitive( QStyle::PE_IndicatorToolBarHandle, &styleOption, &painter); + widgetRect.setWidth(tw); } else if (type == CTRL_EDITBOX) { - pixmap.fill(KApplication::palette().color(QPalette::Window)); - - //TODO hover?? OO does not seem to do this for line edits + QStyleOptionFrameV2 option; + draw( QStyle::PE_PanelLineEdit, &option, m_image, + vclStateValue2StateFlag(nControlState, value), 2 ); - #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) - QStyleOptionFrameV3 styleOption; - #else - QStyleOptionFrameV2 styleOption; - #endif - - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - //TODO...how does the line edit draw itself internally?? - styleOption.rect = QRect(2, 2, widgetRect.width()-4, widgetRect.height()-4); - kapp->style()->drawPrimitive( QStyle::PE_PanelLineEdit, &styleOption, &painter); - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - kapp->style()->drawPrimitive( QStyle::PE_FrameLineEdit, &styleOption, &painter); + draw( QStyle::PE_FrameLineEdit, &option, m_image, + vclStateValue2StateFlag(nControlState, value), 0 ); } else if (type == CTRL_COMBOBOX) { - pixmap.fill(KApplication::palette().color(QPalette::Window)); - - QStyleOptionComboBox styleOption; + QStyleOptionComboBox option; + option.editable = true; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - styleOption.editable = true; - - kapp->style()->drawComplexControl(QStyle::CC_ComboBox, &styleOption, &painter); + draw( QStyle::CC_ComboBox, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_LISTBOX) { if( part == PART_WINDOW ) { - lcl_drawFrame( widgetRect, painter, QStyle::PE_Frame, nControlState, value ); + lcl_drawFrame( QStyle::PE_Frame, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else { - QStyleOptionComboBox styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - + QStyleOptionComboBox option; if (part == PART_SUB_EDIT) { - kapp->style()->drawControl(QStyle::CE_ComboBoxLabel, &styleOption, &painter); + draw( QStyle::CE_ComboBoxLabel, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else { - kapp->style()->drawComplexControl(QStyle::CC_ComboBox, &styleOption, &painter); + draw( QStyle::CC_ComboBox, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } } } else if (type == CTRL_LISTNODE) { - QStyleOption styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - styleOption.state |= QStyle::State_Item; - styleOption.state |= QStyle::State_Children; + QStyleOption option; + option.state = QStyle::State_Item | QStyle::State_Children; if (nControlState & CTRL_STATE_PRESSED) - { - styleOption.state |= QStyle::State_Open; - } + option.state |= QStyle::State_Open; - kapp->style()->drawPrimitive(QStyle::PE_IndicatorBranch, &styleOption, &painter); + draw( QStyle::PE_IndicatorBranch, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_CHECKBOX) { - QStyleOptionButton styleOption; - - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - kapp->style()->drawControl(QStyle::CE_CheckBox, &styleOption, &painter); + QStyleOptionButton option; + draw( QStyle::CE_CheckBox, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_SCROLLBAR) { - pixmap.fill(KApplication::palette().color(QPalette::Window)); - if ((part == PART_DRAW_BACKGROUND_VERT) || (part == PART_DRAW_BACKGROUND_HORZ)) { + QStyleOptionSlider option; ScrollbarValue* sbVal = static_cast<ScrollbarValue *> ( value.getOptionalVal() ); - QStyleOptionSlider styleOption; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - //if the scroll bar is active (aka not degenrate...allow for hover events if (sbVal->mnVisibleSize < sbVal->mnMax) - { - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - styleOption.state |= QStyle::State_MouseOver; - } + option.state = QStyle::State_MouseOver; //horizontal or vertical if (part == PART_DRAW_BACKGROUND_VERT) - { - styleOption.orientation = Qt::Vertical; - } + option.orientation = Qt::Vertical; else - { - styleOption.state |= QStyle::State_Horizontal; - } + option.state |= QStyle::State_Horizontal; //setup parameters from the OO values - styleOption.minimum = sbVal->mnMin; - styleOption.maximum = sbVal->mnMax - sbVal->mnVisibleSize; - styleOption.sliderValue = sbVal->mnCur; - styleOption.sliderPosition = sbVal->mnCur; - styleOption.pageStep = sbVal->mnVisibleSize; + option.minimum = sbVal->mnMin; + option.maximum = sbVal->mnMax - sbVal->mnVisibleSize; + option.sliderValue = sbVal->mnCur; + option.sliderPosition = sbVal->mnCur; + option.pageStep = sbVal->mnVisibleSize; //setup the active control...always the slider if (sbVal->mnThumbState & CTRL_STATE_ROLLOVER) - { - styleOption.activeSubControls = QStyle::SC_ScrollBarSlider; - } + option.activeSubControls = QStyle::SC_ScrollBarSlider; - kapp->style()->drawComplexControl(QStyle::CC_ScrollBar, &styleOption, &painter); + draw( QStyle::CC_ScrollBar, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); + } + else + { + returnVal = false; } } else if (type == CTRL_SPINBOX) { - pixmap.fill(KApplication::palette().color(QPalette::Window)); + QStyleOptionSpinBox option; - QStyleOptionSpinBox styleOption; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); // determine active control SpinbuttonValue* pSpinVal = (SpinbuttonValue *)(value.getOptionalVal()); if( pSpinVal ) { if( (pSpinVal->mnUpperState & CTRL_STATE_PRESSED) ) - styleOption.activeSubControls |= QStyle::SC_SpinBoxUp; + option.activeSubControls |= QStyle::SC_SpinBoxUp; if( (pSpinVal->mnLowerState & CTRL_STATE_PRESSED) ) - styleOption.activeSubControls |= QStyle::SC_SpinBoxDown; + option.activeSubControls |= QStyle::SC_SpinBoxDown; } - kapp->style()->drawComplexControl(QStyle::CC_SpinBox, &styleOption, &painter); + draw( QStyle::CC_SpinBox, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_GROUPBOX) { - QStyleOptionGroupBox styleOption; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - kapp->style()->drawComplexControl(QStyle::CC_GroupBox, &styleOption, &painter); + QStyleOptionGroupBox option; + draw( QStyle::CC_GroupBox, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_RADIOBUTTON) { - QStyleOptionButton styleOption; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - kapp->style()->drawControl(QStyle::CE_RadioButton, &styleOption, &painter); + QStyleOptionButton option; + draw( QStyle::CE_RadioButton, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_TOOLTIP) { - QStyleOption styleOption; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - - kapp->style()->drawPrimitive(QStyle::PE_PanelTipLabel, &styleOption, &painter); + QStyleOption option; + draw( QStyle::PE_PanelTipLabel, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_FRAME) { - pixmap.fill(KApplication::palette().color(QPalette::Window)); - lcl_drawFrame( widgetRect, painter, QStyle::PE_Frame, nControlState, value ); + lcl_drawFrame( QStyle::PE_Frame, m_image, + vclStateValue2StateFlag(nControlState, value) ); + + int size = kapp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin); + pTempClipRegion = XCreateRegion(); + XRectangle xRect = { widgetRect.left(), widgetRect.top(), widgetRect.width(), widgetRect.height() }; + XUnionRectWithRegion( &xRect, pTempClipRegion, pTempClipRegion ); + XLIB_Region pSubtract = XCreateRegion(); + xRect.x += size; + xRect.y += size; + xRect.width -= 2* size; + xRect.height -= 2*size; + XUnionRectWithRegion( &xRect, pSubtract, pSubtract ); + XSubtractRegion( pTempClipRegion, pSubtract, pTempClipRegion ); + XDestroyRegion( pSubtract ); } else if (type == CTRL_FIXEDBORDER) { - pixmap.fill(KApplication::palette().color(QPalette::Window)); - lcl_drawFrame( widgetRect, painter, QStyle::PE_FrameWindow, nControlState, value ); + lcl_drawFrame( QStyle::PE_FrameWindow, m_image, + vclStateValue2StateFlag(nControlState, value) ); } else if (type == CTRL_WINDOW_BACKGROUND) { - pixmap.fill(KApplication::palette().color(QPalette::Window)); + m_image->fill(KApplication::palette().color(QPalette::Window).rgb()); } else if (type == CTRL_FIXEDLINE) { - QStyleOptionMenuItem styleOption; + QStyleOptionMenuItem option; + option.menuItemType = QStyleOptionMenuItem::Separator; + option.state |= QStyle::State_Item; - styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); - styleOption.state = vclStateValue2StateFlag( nControlState, value ); - styleOption.menuItemType = QStyleOptionMenuItem::Separator; - styleOption.state |= QStyle::State_Item; + draw( QStyle::CE_MenuItem, &option, m_image, + vclStateValue2StateFlag(nControlState, value) ); + } + else if (type == CTRL_SLIDER && (part == PART_TRACK_HORZ_AREA || part == PART_TRACK_VERT_AREA)) + { + SliderValue* slVal = static_cast<SliderValue *> ( value.getOptionalVal() ); + QStyleOptionSlider option; - kapp->style()->drawControl( QStyle::CE_MenuItem, &styleOption, &painter); + option.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + option.state = vclStateValue2StateFlag( nControlState, value ); + option.maximum = slVal->mnMax; + option.minimum = slVal->mnMin; + option.sliderPosition = option.sliderValue = slVal->mnCur; + option.orientation = (part == PART_TRACK_HORZ_AREA) ? Qt::Horizontal : Qt::Vertical; + + draw( QStyle::CC_Slider, &option, m_image, vclStateValue2StateFlag(nControlState, value) ); } else { @@ -543,11 +532,35 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, if (returnVal) { - X11SalGraphics::CopyScreenArea( dpy, - pixmap.handle(), pixmap.x11Info().screen(), pixmap.x11Info().depth(), - drawable, GetScreenNumber(), GetVisual().GetDepth(), gc, - 0, 0, widgetRect.width(), widgetRect.height(), widgetRect.left(), widgetRect.top() ); + GC gc = SelectFont(); + + if( gc ) + { + if( pTempClipRegion ) + { + if( pClipRegion_ ) + XIntersectRegion( pTempClipRegion, pClipRegion_, pTempClipRegion ); + XSetRegion( GetXDisplay(), gc, pTempClipRegion ); + } + QPixmap pixmap = QPixmap::fromImage(*m_image, Qt::ColorOnly | Qt::OrderedDither | Qt::OrderedAlphaDither); + X11SalGraphics::CopyScreenArea( GetXDisplay(), + pixmap.handle(), pixmap.x11Info().screen(), pixmap.x11Info().depth(), + GetDrawable(), GetScreenNumber(), GetVisual().GetDepth(), + gc, 0, 0, widgetRect.width(), widgetRect.height(), widgetRect.left(), widgetRect.top()); + + if( pTempClipRegion ) + { + if( pClipRegion_ ) + XSetRegion( GetXDisplay(), gc, pClipRegion_ ); + else + XSetClipMask( GetXDisplay(), gc, None ); + } + } + else + returnVal = false; } + if( pTempClipRegion ) + XDestroyRegion( pTempClipRegion ); return returnVal; } @@ -759,6 +772,24 @@ BOOL KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart part, boundingRect = contentRect; retVal = true; + break; + } + case CTRL_SLIDER: + { + const int w = kapp->style()->pixelMetric(QStyle::PM_SliderLength); + if( part == PART_THUMB_HORZ ) + { + contentRect = QRect(boundingRect.left(), boundingRect.top(), w, boundingRect.height()); + boundingRect = contentRect; + retVal = true; + } + else if( part == PART_THUMB_VERT ) + { + contentRect = QRect(boundingRect.left(), boundingRect.top(), boundingRect.width(), w); + boundingRect = contentRect; + retVal = true; + } + break; } default: break; diff --git a/vcl/unx/kde4/KDESalGraphics.hxx b/vcl/unx/kde4/KDESalGraphics.hxx index 3e9ac44e4981..b5328f462a16 100644 --- a/vcl/unx/kde4/KDESalGraphics.hxx +++ b/vcl/unx/kde4/KDESalGraphics.hxx @@ -31,12 +31,18 @@ #include <saldisp.hxx> #include <salgdi.h> +#define Region QtXRegion +#include <QImage> +#undef Region + /** handles graphics drawings requests and performs the needed drawing operations */ class KDESalGraphics : public X11SalGraphics { + QImage* m_image; + public: - KDESalGraphics() {} - virtual ~KDESalGraphics() {} + KDESalGraphics(); + virtual ~KDESalGraphics(); /** What widgets can be drawn the native way. diff --git a/vcl/unx/source/app/saldata.cxx b/vcl/unx/source/app/saldata.cxx index 4155887a9875..75d18de0787a 100644 --- a/vcl/unx/source/app/saldata.cxx +++ b/vcl/unx/source/app/saldata.cxx @@ -276,6 +276,7 @@ X11SalData::X11SalData() m_pPlugin = NULL; hMainThread_ = pthread_self(); + osl_getLocalHostname( &maLocalHostName.pData ); } X11SalData::~X11SalData() diff --git a/vcl/unx/source/app/saldisp.cxx b/vcl/unx/source/app/saldisp.cxx index 97116626894e..aa2afab93657 100644 --- a/vcl/unx/source/app/saldisp.cxx +++ b/vcl/unx/source/app/saldisp.cxx @@ -322,12 +322,12 @@ sal_IsLocalDisplay( Display *pDisplay ) if( pPtr != NULL ) { - OUString aLocalHostname; - if( osl_getLocalHostname( &aLocalHostname.pData ) == osl_Socket_Ok) + const OUString& rLocalHostname( GetX11SalData()->GetLocalHostName() ); + if( rLocalHostname.getLength() ) { *pPtr = '\0'; OUString aDisplayHostname( pDisplayHost, strlen( pDisplayHost ), osl_getThreadTextEncoding() ); - bEqual = sal_EqualHosts( aLocalHostname, aDisplayHostname ); + bEqual = sal_EqualHosts( rLocalHostname, aDisplayHostname ); bEqual = bEqual && sal_IsDisplayNumber( pPtr + 1 ); } } @@ -2594,6 +2594,28 @@ void SalDisplay::PrintInfo() const sal::static_int_cast< unsigned int >(GetVisual(m_nDefaultScreen).GetVisualId()) ); } +void SalDisplay::addXineramaScreenUnique( long i_nX, long i_nY, long i_nWidth, long i_nHeight ) +{ + // see if any frame buffers are at the same coordinates + // this can happen with weird configuration e.g. on + // XFree86 and Clone displays + const size_t nScreens = m_aXineramaScreens.size(); + for( size_t n = 0; n < nScreens; n++ ) + { + if( m_aXineramaScreens[n].Left() == i_nX && + m_aXineramaScreens[n].Top() == i_nY ) + { + if( m_aXineramaScreens[n].GetWidth() < i_nWidth || + m_aXineramaScreens[n].GetHeight() < i_nHeight ) + { + m_aXineramaScreens[n].SetSize( Size( i_nWidth, i_nHeight ) ); + } + return; + } + } + m_aXineramaScreens.push_back( Rectangle( Point( i_nX, i_nY ), Size( i_nWidth, i_nHeight ) ) ); +} + void SalDisplay::InitXinerama() { if( m_aScreens.size() > 1 ) @@ -2618,10 +2640,10 @@ void SalDisplay::InitXinerama() m_bXinerama = true; m_aXineramaScreens = std::vector<Rectangle>( nFramebuffers ); for( int i = 0; i < nFramebuffers; i++ ) - m_aXineramaScreens[i] = Rectangle( Point( pFramebuffers[i].x, - pFramebuffers[i].y ), - Size( pFramebuffers[i].width, - pFramebuffers[i].height ) ); + addXineramaScreenUnique( pFramebuffers[i].x, + pFramebuffers[i].y, + pFramebuffers[i].width, + pFramebuffers[i].height ); } } #elif defined(USE_XINERAMA_XORG) @@ -2637,30 +2659,10 @@ if( XineramaIsActive( pDisp_ ) ) m_aXineramaScreens = std::vector<Rectangle>(); for( int i = 0; i < nFramebuffers; i++ ) { - // see if any frame buffers are at the same coordinates - // this can happen with weird configuration e.g. on - // XFree86 and Clone displays - bool bDuplicate = false; - for( int n = 0; n < i; n++ ) - { - if( m_aXineramaScreens[n].Left() == pScreens[i].x_org && - m_aXineramaScreens[n].Top() == pScreens[i].y_org ) - { - bDuplicate = true; - if( m_aXineramaScreens[n].GetWidth() < pScreens[i].width || - m_aXineramaScreens[n].GetHeight() < pScreens[i].height ) - { - m_aXineramaScreens[n].SetSize( Size( pScreens[i].width, - pScreens[i].height ) ); - } - break; - } - } - if( ! bDuplicate ) - m_aXineramaScreens.push_back( Rectangle( Point( pScreens[i].x_org, - pScreens[i].y_org ), - Size( pScreens[i].width, - pScreens[i].height ) ) ); + addXineramaScreenUnique( pScreens[i].x_org, + pScreens[i].y_org, + pScreens[i].width, + pScreens[i].height ); } m_bXinerama = m_aXineramaScreens.size() > 1; } diff --git a/vcl/unx/source/app/wmadaptor.cxx b/vcl/unx/source/app/wmadaptor.cxx index 89c8bb56291c..fb2317e19573 100644 --- a/vcl/unx/source/app/wmadaptor.cxx +++ b/vcl/unx/source/app/wmadaptor.cxx @@ -34,6 +34,7 @@ #include <sal/alloca.h> #include <wmadaptor.hxx> #include <saldisp.hxx> +#include <saldata.hxx> #include <salframe.h> #include <vcl/salgdi.hxx> #include <osl/thread.h> @@ -118,6 +119,7 @@ static const WMAdaptorProtocol aProtocolTab[] = { "_NET_NUMBER_OF_DESKTOPS", WMAdaptor::NET_NUMBER_OF_DESKTOPS }, { "_NET_WM_DESKTOP", WMAdaptor::NET_WM_DESKTOP }, { "_NET_WM_ICON_NAME", WMAdaptor::NET_WM_ICON_NAME }, + { "_NET_WM_PING", WMAdaptor::NET_WM_PING }, { "_NET_WM_STATE", WMAdaptor::NET_WM_STATE }, { "_NET_WM_STATE_ABOVE", WMAdaptor::NET_WM_STATE_STAYS_ON_TOP }, { "_NET_WM_STATE_FULLSCREEN", WMAdaptor::NET_WM_STATE_FULLSCREEN }, @@ -179,7 +181,8 @@ static const WMAdaptorProtocol aAtomTab[] = { "_XSETTINGS_SETTINGS", WMAdaptor::XSETTINGS }, { "_XEMBED", WMAdaptor::XEMBED }, { "_XEMBED_INFO", WMAdaptor::XEMBED_INFO }, - { "_NET_WM_USER_TIME", WMAdaptor::NET_WM_USER_TIME } + { "_NET_WM_USER_TIME", WMAdaptor::NET_WM_USER_TIME }, + { "_NET_WM_PID", WMAdaptor::NET_WM_PID } }; extern "C" { @@ -233,6 +236,7 @@ WMAdaptor::WMAdaptor( SalDisplay* pDisplay ) : m_pSalDisplay( pDisplay ), m_bTransientBehaviour( true ), m_bEnableAlwaysOnTopWorks( false ), + m_bLegacyPartialFullscreen( false ), m_nWinGravity( StaticGravity ), m_nInitWinGravity( StaticGravity ) { @@ -909,6 +913,40 @@ bool WMAdaptor::getNetWmName() XFree( pProperty ); pProperty = NULL; } + // if this is metacity, check for version to enable a legacy workaround + if( m_aWMName.EqualsAscii( "Metacity" ) ) + { + int nVersionMajor = 0, nVersionMinor = 0; + Atom nVersionAtom = XInternAtom( m_pDisplay, "_METACITY_VERSION", True ); + if( nVersionAtom ) + { + if( XGetWindowProperty( m_pDisplay, + aWMChild, + nVersionAtom, + 0, 256, + False, + m_aWMAtoms[ UTF8_STRING ], + &aRealType, + &nFormat, + &nItems, + &nBytesLeft, + &pProperty ) == 0 + && nItems != 0 + ) + { + String aMetaVersion( (sal_Char*)pProperty, nItems, RTL_TEXTENCODING_UTF8 ); + nVersionMajor = aMetaVersion.GetToken( 0, '.' ).ToInt32(); + nVersionMinor = aMetaVersion.GetToken( 1, '.' ).ToInt32(); + } + if( pProperty ) + { + XFree( pProperty ); + pProperty = NULL; + } + } + if( nVersionMajor < 2 || (nVersionMajor == 2 && nVersionMinor < 12) ) + m_bLegacyPartialFullscreen = true; + } } } else if( pProperty ) @@ -2412,3 +2450,52 @@ void NetWMAdaptor::setUserTime( X11SalFrame* i_pFrame, long i_nUserTime ) const ); } } + +/* + * WMAdaptor::setPID + */ +void WMAdaptor::setPID( X11SalFrame* i_pFrame ) const +{ + if( m_aWMAtoms[NET_WM_PID] ) + { + long nPID = (long)getpid(); + XChangeProperty( m_pDisplay, + i_pFrame->GetShellWindow(), + m_aWMAtoms[NET_WM_PID], + XA_CARDINAL, + 32, + PropModeReplace, + (unsigned char*)&nPID, + 1 + ); + } +} + +/* +* WMAdaptor::setClientMachine +*/ +void WMAdaptor::setClientMachine( X11SalFrame* i_pFrame ) const +{ + rtl::OString aWmClient( rtl::OUStringToOString( GetX11SalData()->GetLocalHostName(), RTL_TEXTENCODING_ASCII_US ) ); + XTextProperty aClientProp = { (unsigned char*)aWmClient.getStr(), XA_STRING, 8, aWmClient.getLength() }; + XSetWMClientMachine( m_pDisplay, i_pFrame->GetShellWindow(), &aClientProp ); +} + +void WMAdaptor::answerPing( X11SalFrame* i_pFrame, XClientMessageEvent* i_pEvent ) const +{ + if( m_aWMAtoms[NET_WM_PING] && + i_pEvent->message_type == m_aWMAtoms[ WM_PROTOCOLS ] && + (Atom)i_pEvent->data.l[0] == m_aWMAtoms[ NET_WM_PING ] ) + { + XEvent aEvent; + aEvent.xclient = *i_pEvent; + aEvent.xclient.window = m_pSalDisplay->GetRootWindow( i_pFrame->GetScreenNumber() ); + XSendEvent( m_pDisplay, + m_pSalDisplay->GetRootWindow( i_pFrame->GetScreenNumber() ), + False, + SubstructureNotifyMask | SubstructureRedirectMask, + &aEvent + ); + XFlush( m_pDisplay ); + } +} diff --git a/vcl/unx/source/fontmanager/fontconfig.cxx b/vcl/unx/source/fontmanager/fontconfig.cxx index 18d8a8d85a43..bc6de4fbc94a 100644 --- a/vcl/unx/source/fontmanager/fontconfig.cxx +++ b/vcl/unx/source/fontmanager/fontconfig.cxx @@ -643,7 +643,7 @@ namespace } } -int PrintFontManager::countFontconfigFonts() +int PrintFontManager::countFontconfigFonts( std::hash_map<rtl::OString, int, rtl::OStringHash>& o_rVisitedPaths ) { int nFonts = 0; @@ -704,6 +704,9 @@ int PrintFontManager::countFontconfigFonts() std::list< PrintFont* > aFonts; OString aDir, aBase, aOrgPath( (sal_Char*)file ); splitPath( aOrgPath, aDir, aBase ); + + o_rVisitedPaths[aDir] = 1; + int nDirID = getDirectoryAtom( aDir, true ); if( ! m_pFontCache->getFontCacheFile( nDirID, aBase, aFonts ) ) { @@ -1183,7 +1186,7 @@ bool PrintFontManager::initFontconfig() return false; } -int PrintFontManager::countFontconfigFonts() +int PrintFontManager::countFontconfigFonts( std::hash_map<rtl::OString, int, rtl::OStringHash>& ) { return 0; } diff --git a/vcl/unx/source/fontmanager/fontmanager.cxx b/vcl/unx/source/fontmanager/fontmanager.cxx index 7d5224707f72..93e3eef53ab3 100644 --- a/vcl/unx/source/fontmanager/fontmanager.cxx +++ b/vcl/unx/source/fontmanager/fontmanager.cxx @@ -2149,10 +2149,14 @@ void PrintFontManager::initialize() } while( nIndex >= 0 ); } + // protect against duplicate paths + std::hash_map< OString, int, OStringHash > visited_dirs; + // now that all global and local font dirs are known to fontconfig // check that there are fonts actually managed by fontconfig + // also don't search directories that fontconfig already did if( m_bFontconfigSuccess ) - m_bFontconfigSuccess = (countFontconfigFonts() > 0); + m_bFontconfigSuccess = (countFontconfigFonts( visited_dirs ) > 0); // don't search through many directories fontconfig already told us about if( ! m_bFontconfigSuccess ) @@ -2163,8 +2167,6 @@ void PrintFontManager::initialize() // search for font files in each path std::list< OString >::iterator dir_it; - // protect against duplicate paths - std::hash_map< OString, int, OStringHash > visited_dirs; for( dir_it = m_aFontDirectories.begin(); dir_it != m_aFontDirectories.end(); ++dir_it ) { OString aPath( *dir_it ); diff --git a/vcl/unx/source/fontmanager/parseAFM.cxx b/vcl/unx/source/fontmanager/parseAFM.cxx index fd131121cbb5..e1a33b4d1b5d 100644 --- a/vcl/unx/source/fontmanager/parseAFM.cxx +++ b/vcl/unx/source/fontmanager/parseAFM.cxx @@ -403,89 +403,91 @@ static int parseGlobals( FileInputStream* fp, register GlobalFontInfo* gfi ) switch(recognize(keyword, tokenlen)) { case STARTFONTMETRICS: - keyword = token(fp,tokenlen); - gfi->afmVersion = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->afmVersion = strdup( keyword ); break; case COMMENT: keyword = linetoken(fp); break; case FONTNAME: - keyword = token(fp, tokenlen); - gfi->fontName = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->fontName = strdup( keyword ); break; case ENCODINGSCHEME: - keyword = token(fp, tokenlen); - gfi->encodingScheme = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->encodingScheme = strdup( keyword ); break; case FULLNAME: - keyword = linetoken(fp); - gfi->fullName = strdup( keyword ); + if ((keyword = linetoken(fp)) != NULL) + gfi->fullName = strdup( keyword ); break; case FAMILYNAME: - keyword = linetoken(fp); - gfi->familyName = strdup( keyword ); + if ((keyword = linetoken(fp)) != NULL) + gfi->familyName = strdup( keyword ); break; case WEIGHT: - keyword = token(fp, tokenlen); - gfi->weight = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->weight = strdup( keyword ); break; case ITALICANGLE: - keyword = token(fp,tokenlen); - gfi->italicAngle = StringToDouble( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->italicAngle = StringToDouble( keyword ); break; case ISFIXEDPITCH: - keyword = token(fp,tokenlen); - if (MATCH(keyword, False)) - gfi->isFixedPitch = 0; - else - gfi->isFixedPitch = 1; + if ((keyword = token(fp,tokenlen)) != NULL) + { + if (MATCH(keyword, False)) + gfi->isFixedPitch = 0; + else + gfi->isFixedPitch = 1; + } break; case UNDERLINEPOSITION: - keyword = token(fp,tokenlen); - gfi->underlinePosition = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->underlinePosition = atoi(keyword); break; case UNDERLINETHICKNESS: - keyword = token(fp,tokenlen); - gfi->underlineThickness = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->underlineThickness = atoi(keyword); break; case VERSION: - keyword = token(fp,tokenlen); - gfi->version = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->version = strdup( keyword ); break; case NOTICE: - keyword = linetoken(fp); - gfi->notice = strdup( keyword ); + if ((keyword = linetoken(fp)) != NULL) + gfi->notice = strdup( keyword ); break; case FONTBBOX: - keyword = token(fp,tokenlen); - gfi->fontBBox.llx = atoi(keyword); - keyword = token(fp,tokenlen); - gfi->fontBBox.lly = atoi(keyword); - keyword = token(fp,tokenlen); - gfi->fontBBox.urx = atoi(keyword); - keyword = token(fp,tokenlen); - gfi->fontBBox.ury = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->fontBBox.llx = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->fontBBox.lly = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->fontBBox.urx = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->fontBBox.ury = atoi(keyword); break; case CAPHEIGHT: - keyword = token(fp,tokenlen); - gfi->capHeight = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->capHeight = atoi(keyword); break; case XHEIGHT: - keyword = token(fp,tokenlen); - gfi->xHeight = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->xHeight = atoi(keyword); break; case DESCENT: - keyword = token(fp,tokenlen); - gfi->descender = -atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->descender = -atoi(keyword); break; case DESCENDER: - keyword = token(fp,tokenlen); - gfi->descender = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->descender = atoi(keyword); break; case ASCENT: case ASCENDER: - keyword = token(fp,tokenlen); - gfi->ascender = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + gfi->ascender = atoi(keyword); break; case STARTCHARMETRICS: cont = false; @@ -499,8 +501,8 @@ static int parseGlobals( FileInputStream* fp, register GlobalFontInfo* gfi ) keyword = token(fp,tokenlen); break; case STARTDIRECTION: - keyword = token(fp,tokenlen); - direction = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + direction = atoi(keyword); break; /* ignore this for now */ case ENDDIRECTION: break; /* ignore this for now */ @@ -523,9 +525,11 @@ static int parseGlobals( FileInputStream* fp, register GlobalFontInfo* gfi ) keyword=token(fp,tokenlen); //ignore break; case CHARWIDTH: - keyword = token(fp,tokenlen); - if (direction == 0) - gfi->charwidth = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + { + if (direction == 0) + gfi->charwidth = atoi(keyword); + } keyword = token(fp,tokenlen); /* ignore y-width for now */ break; @@ -584,24 +588,27 @@ static int initializeArray( FileInputStream* fp, register int* cwi) keyword = linetoken(fp); break; case CODE: - code = atoi(token(fp,tokenlen)); + if ((keyword = token(fp,tokenlen)) != NULL) + code = atoi(keyword); break; case CODEHEX: - sscanf(token(fp,tokenlen),"<%x>", &code); + if ((keyword = token(fp,tokenlen)) != NULL) + sscanf(keyword,"<%x>", &code); break; case XWIDTH: - width = atoi(token(fp,tokenlen)); + if ((keyword = token(fp,tokenlen)) != NULL) + width = atoi(keyword); break; case X0WIDTH: (void) token(fp,tokenlen); break; case CHARNAME: - keyword = token(fp,tokenlen); - if (MATCH(keyword, Space)) - { - cont = false; - found = true; - } + if ((keyword = token(fp,tokenlen)) != NULL) + if (MATCH(keyword, Space)) + { + cont = false; + found = true; + } break; case ENDCHARMETRICS: cont = false; @@ -690,8 +697,8 @@ static int parseCharWidths( FileInputStream* fp, register int* cwi) keyword = linetoken(fp); break; case CODE: - keyword = token(fp,tokenlen); - pos = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + pos = atoi(keyword); break; case XYWIDTH: /* PROBLEM: Should be no Y-WIDTH when doing "quick & dirty" */ @@ -699,16 +706,16 @@ static int parseCharWidths( FileInputStream* fp, register int* cwi) error = parseError; break; case CODEHEX: - keyword = token(fp,tokenlen); - sscanf(keyword, "<%x>", &pos); + if ((keyword = token(fp,tokenlen)) != NULL) + sscanf(keyword, "<%x>", &pos); break; case X0WIDTH: (void) token(fp,tokenlen); break; case XWIDTH: - keyword = token(fp,tokenlen); - if (pos >= 0) /* ignore unmapped chars */ - cwi[pos] = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + if (pos >= 0) /* ignore unmapped chars */ + cwi[pos] = atoi(keyword); break; case ENDCHARMETRICS: cont = false; @@ -835,7 +842,8 @@ static int parseCharMetrics( FileInputStream* fp, register FontInfo* fi) { if (firstTime) firstTime = false; else temp++; - temp->code = atoi(token(fp,tokenlen)); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->code = atoi(keyword); if (fi->gfi && fi->gfi->charwidth) temp->wx = fi->gfi->charwidth; count++; @@ -859,7 +867,8 @@ static int parseCharMetrics( FileInputStream* fp, register FontInfo* fi) firstTime = false; else temp++; - sscanf(token(fp,tokenlen),"<%x>", &temp->code); + if ((keyword = token(fp,tokenlen)) != NULL) + sscanf(keyword,"<%x>", &temp->code); if (fi->gfi && fi->gfi->charwidth) temp->wx = fi->gfi->charwidth; count++; @@ -870,24 +879,32 @@ static int parseCharMetrics( FileInputStream* fp, register FontInfo* fi) } break; case XYWIDTH: - temp->wx = atoi(token(fp,tokenlen)); - temp->wy = atoi(token(fp,tokenlen)); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->wx = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->wy = atoi(keyword); break; case X0WIDTH: - temp->wx = atoi(token(fp,tokenlen)); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->wx = atoi(keyword); break; case XWIDTH: - temp->wx = atoi(token(fp,tokenlen)); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->wx = atoi(keyword); break; case CHARNAME: - keyword = token(fp,tokenlen); - temp->name = (char *)strdup(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->name = (char *)strdup(keyword); break; case CHARBBOX: - temp->charBBox.llx = atoi(token(fp,tokenlen)); - temp->charBBox.lly = atoi(token(fp,tokenlen)); - temp->charBBox.urx = atoi(token(fp,tokenlen)); - temp->charBBox.ury = atoi(token(fp,tokenlen)); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->charBBox.llx = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->charBBox.lly = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->charBBox.urx = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + temp->charBBox.ury = atoi(keyword); break; case LIGATURE: { Ligature **tail = &(temp->ligs); @@ -901,10 +918,10 @@ static int parseCharMetrics( FileInputStream* fp, register FontInfo* fi) } *tail = (Ligature *) calloc(1, sizeof(Ligature)); - keyword = token(fp,tokenlen); - (*tail)->succ = (char *)strdup(keyword); - keyword = token(fp,tokenlen); - (*tail)->lig = (char *)strdup(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + (*tail)->succ = (char *)strdup(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + (*tail)->lig = (char *)strdup(keyword); break; } case ENDCHARMETRICS: cont = false;; @@ -1000,16 +1017,16 @@ static int parseTrackKernData( FileInputStream* fp, register FontInfo* fi) if (tcount < fi->numOfTracks) { - keyword = token(fp,tokenlen); - fi->tkd[pos].degree = atoi(keyword); - keyword = token(fp,tokenlen); - fi->tkd[pos].minPtSize = StringToDouble(keyword); - keyword = token(fp,tokenlen); - fi->tkd[pos].minKernAmt = StringToDouble(keyword); - keyword = token(fp,tokenlen); - fi->tkd[pos].maxPtSize = StringToDouble(keyword); - keyword = token(fp,tokenlen); - fi->tkd[pos++].maxKernAmt = StringToDouble(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->tkd[pos].degree = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->tkd[pos].minPtSize = StringToDouble(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->tkd[pos].minKernAmt = StringToDouble(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->tkd[pos].maxPtSize = StringToDouble(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->tkd[pos++].maxKernAmt = StringToDouble(keyword); tcount++; } else @@ -1107,14 +1124,14 @@ static int parsePairKernData( FileInputStream* fp, register FontInfo* fi) } if (pcount < fi->numOfPairs) { - keyword = token(fp,tokenlen); - fi->pkd[pos].name1 = strdup( keyword ); - keyword = token(fp,tokenlen); - fi->pkd[pos].name2 = strdup( keyword ); - keyword = token(fp,tokenlen); - fi->pkd[pos].xamt = atoi(keyword); - keyword = token(fp,tokenlen); - fi->pkd[pos++].yamt = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->pkd[pos].name1 = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->pkd[pos].name2 = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->pkd[pos].xamt = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->pkd[pos++].yamt = atoi(keyword); pcount++; } else @@ -1131,12 +1148,12 @@ static int parsePairKernData( FileInputStream* fp, register FontInfo* fi) } if (pcount < fi->numOfPairs) { - keyword = token(fp,tokenlen); - fi->pkd[pos].name1 = strdup( keyword ); - keyword = token(fp,tokenlen); - fi->pkd[pos].name2 = strdup( keyword ); - keyword = token(fp,tokenlen); - fi->pkd[pos++].xamt = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->pkd[pos].name1 = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->pkd[pos].name2 = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->pkd[pos++].xamt = atoi(keyword); pcount++; } else @@ -1258,8 +1275,8 @@ static int parseCompCharData( FileInputStream* fp, register FontInfo* fi) if (firstTime) firstTime = false; else pos++; fi->ccd[pos].ccName = strdup( keyword ); - keyword = token(fp,tokenlen); - fi->ccd[pos].numOfPieces = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->ccd[pos].numOfPieces = atoi(keyword); fi->ccd[pos].pieces = (Pcc *) calloc(fi->ccd[pos].numOfPieces, sizeof(Pcc)); j = 0; @@ -1274,12 +1291,12 @@ static int parseCompCharData( FileInputStream* fp, register FontInfo* fi) case COMPCHARPIECE: if (pcount < fi->ccd[pos].numOfPieces) { - keyword = token(fp,tokenlen); - fi->ccd[pos].pieces[j].pccName = strdup( keyword ); - keyword = token(fp,tokenlen); - fi->ccd[pos].pieces[j].deltax = atoi(keyword); - keyword = token(fp,tokenlen); - fi->ccd[pos].pieces[j++].deltay = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->ccd[pos].pieces[j].pccName = strdup( keyword ); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->ccd[pos].pieces[j].deltax = atoi(keyword); + if ((keyword = token(fp,tokenlen)) != NULL) + fi->ccd[pos].pieces[j++].deltay = atoi(keyword); pcount++; } else @@ -1373,7 +1390,8 @@ int parseFile( const char* pFilename, FontInfo** fi, FLAGS flags) if ((code != normalEOF) && (code != earlyEOF)) { - (*fi)->numOfChars = atoi(token(&aFile,tokenlen)); + if ((keyword = token(&aFile,tokenlen)) != NULL) + (*fi)->numOfChars = atoi(keyword); if (flags & (P_M ^ P_W)) { (*fi)->cmi = (CharMetricInfo *) @@ -1423,7 +1441,7 @@ int parseFile( const char* pFilename, FontInfo** fi, FLAGS flags) break; case STARTTRACKKERN: keyword = token(&aFile,tokenlen); - if (flags & P_T) + if ((flags & P_T) && keyword) { (*fi)->numOfTracks = atoi(keyword); (*fi)->tkd = (TrackKernData *) @@ -1438,7 +1456,7 @@ int parseFile( const char* pFilename, FontInfo** fi, FLAGS flags) break; case STARTKERNPAIRS: keyword = token(&aFile,tokenlen); - if (flags & P_P) + if ((flags & P_P) && keyword) { (*fi)->numOfPairs = atoi(keyword); (*fi)->pkd = (PairKernData *) @@ -1453,7 +1471,7 @@ int parseFile( const char* pFilename, FontInfo** fi, FLAGS flags) break; case STARTCOMPOSITES: keyword = token(&aFile,tokenlen); - if (flags & P_C) + if ((flags & P_C) && keyword) { (*fi)->numOfComps = atoi(keyword); (*fi)->ccd = (CompCharData *) diff --git a/vcl/unx/source/gdi/gcach_xpeer.cxx b/vcl/unx/source/gdi/gcach_xpeer.cxx index 634f79d3e002..a69a2426b519 100644 --- a/vcl/unx/source/gdi/gcach_xpeer.cxx +++ b/vcl/unx/source/gdi/gcach_xpeer.cxx @@ -119,7 +119,7 @@ void X11GlyphPeer::InitAntialiasing() // enable XRENDER accelerated aliasing on screens that support it // unless it explicitly disabled by an environment variable if( (nEnvAntiAlias & 2) == 0 ) - mnUsingXRender = XRenderPeer::GetInstance().InitRenderText( mnMaxScreens ); + mnUsingXRender = XRenderPeer::GetInstance().InitRenderText(); // else enable client side antialiasing for these screens // unless it is explicitly disabled by an environment variable diff --git a/vcl/unx/source/gdi/salgdi3.cxx b/vcl/unx/source/gdi/salgdi3.cxx index 0c1fcd7c77bd..f00ee26c0d4d 100644 --- a/vcl/unx/source/gdi/salgdi3.cxx +++ b/vcl/unx/source/gdi/salgdi3.cxx @@ -641,13 +641,11 @@ bool X11SalGraphics::setFont( const ImplFontSelectData *pEntry, int nFallbackLev mpServerFont[ nFallbackLevel ] = pServerFont; // apply font specific-hint settings if needed + // TODO: also disable it for reference devices if( !bPrinter_ ) { - // TODO: is it worth it to cache the hint settings, e.g. in the ImplFontEntry? - ImplFontOptions aFontOptions; - bool GetFCFontOptions( const ImplFontAttributes&, int nSize, ImplFontOptions&); - if( GetFCFontOptions( *pEntry->mpFontData, pEntry->mnHeight, aFontOptions ) ) - pServerFont->SetFontOptions( aFontOptions ); + ImplServerFontEntry* pSFE = static_cast<ImplServerFontEntry*>( pEntry->mpFontEntry ); + pSFE->HandleFontOptions(); } return true; @@ -656,6 +654,24 @@ bool X11SalGraphics::setFont( const ImplFontSelectData *pEntry, int nFallbackLev return false; } +void ImplServerFontEntry::HandleFontOptions( void ) +{ + bool GetFCFontOptions( const ImplFontAttributes&, int nSize, ImplFontOptions& ); + + if( !mpServerFont ) + return; + if( !mbGotFontOptions ) + { + // get and cache the font options + mbGotFontOptions = true; + mbValidFontOptions = GetFCFontOptions( *maFontSelData.mpFontData, + maFontSelData.mnHeight, maFontOptions ); + } + // apply the font options + if( mbValidFontOptions ) + mpServerFont->SetFontOptions( maFontOptions ); +} + //-------------------------------------------------------------------------- inline sal_Unicode SwapBytes( const sal_Unicode nIn ) @@ -1088,7 +1104,7 @@ void X11SalGraphics::DrawServerAAFontString( const ServerFontLayout& rLayout ) } // set font foreground color and opacity - XRenderColor aRenderColor = GetXRenderColor( nTextPixel_ ); + XRenderColor aRenderColor = GetXRenderColor( nTextColor_ ); rRenderPeer.FillRectangle( PictOpSrc, rEntry.m_aPicture, &aRenderColor, 0, 0, 1, 1 ); // set clipping @@ -1633,11 +1649,13 @@ void X11SalGraphics::GetDevFontSubstList( OutputDevice* ) void cairosubcallback( void* pPattern ) { CairoWrapper& rCairo = CairoWrapper::get(); - if( rCairo.isValid() ) - { + if( !rCairo.isValid() ) + return; const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); - rCairo.ft_font_options_substitute( rStyleSettings.GetCairoFontOptions(), pPattern); - } + const void* pFontOptions = rStyleSettings.GetCairoFontOptions(); + if( !pFontOptions ) + return; + rCairo.ft_font_options_substitute( pFontOptions, pPattern ); } bool GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize, @@ -1664,7 +1682,6 @@ bool GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize, default: aInfo.m_eItalic = psp::italic::Unknown; break; - } // set weight switch( rFontAttributes.GetWeight() ) @@ -1740,7 +1757,6 @@ bool GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize, const psp::PrintFontManager& rPFM = psp::PrintFontManager::get(); bool bOK = rPFM.getFontOptions( aInfo, nSize, cairosubcallback, rFontOptions); - return bOK; } diff --git a/vcl/unx/source/gdi/xrender_peer.cxx b/vcl/unx/source/gdi/xrender_peer.cxx index c5d84cffab58..8d24e4098df4 100644 --- a/vcl/unx/source/gdi/xrender_peer.cxx +++ b/vcl/unx/source/gdi/xrender_peer.cxx @@ -25,6 +25,9 @@ * ************************************************************************/ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + #include <stdio.h> #include <rtl/ustring.hxx> #include <osl/module.h> @@ -172,7 +175,7 @@ void XRenderPeer::InitRenderLib() #if 0 // not having trapezoid support is supported if( !pFunc ) return; #endif - mpXRenderAddTraps = (void(*)(Display*,Picture,int,int,const XTrap*,int))pFunc; + mpXRenderAddTraps = (void(*)(Display*,Picture,int,int,const _XTrap*,int))pFunc; #endif // XRENDER_LINK @@ -190,12 +193,16 @@ void XRenderPeer::InitRenderLib() (*mpXRenderQueryVersion)( mpDisplay, &nMajor, &nMinor ); #endif mnRenderVersion = 16*nMajor + nMinor; + + // the 8bit alpha mask format must be there + XRenderPictFormat aPictFormat={0,0,8,{0,0,0,0,0,0,0,0xFF},0}; + mpStandardFormatA8 = FindPictureFormat( PictFormatAlphaMask|PictFormatDepth, aPictFormat ); } // --------------------------------------------------------------------------- // return mask of screens capable of XRENDER text -sal_uInt32 XRenderPeer::InitRenderText( int nMaxDepth ) +sal_uInt32 XRenderPeer::InitRenderText() { if( mnRenderVersion < 0x01 ) return 0; @@ -206,9 +213,6 @@ sal_uInt32 XRenderPeer::InitRenderText( int nMaxDepth ) if( mnRenderVersion < 0x02 ) return 0; - // the 8bit alpha mask format must be there - XRenderPictFormat aPictFormat={0,0,8,{0,0,0,0,0,0,0,0xFF},0}; - mpStandardFormatA8 = FindPictureFormat( PictFormatAlphaMask|PictFormatDepth, aPictFormat ); if( !mpStandardFormatA8 ) return 0; @@ -217,18 +221,24 @@ sal_uInt32 XRenderPeer::InitRenderText( int nMaxDepth ) SalDisplay* pSalDisp = GetX11SalData()->GetDisplay(); const int nScreenCount = pSalDisp->GetScreenCount(); XRenderPictFormat* pVisualFormat = NULL; + int nMaxDepth = 0; for( int nScreen = 0; nScreen < nScreenCount; ++nScreen ) { Visual* pXVisual = pSalDisp->GetVisual( nScreen ).GetVisual(); pVisualFormat = FindVisualFormat( pXVisual ); if( pVisualFormat != NULL ) + { + int nVDepth = pSalDisp->GetVisual( nScreen ).GetDepth(); + if( nVDepth > nMaxDepth ) + nMaxDepth = nVDepth; nRetMask |= 1U << nScreen; + } } // #97763# disable XRENDER on <15bit displays for XFree<=4.2.0 if( mnRenderVersion <= 0x02 ) if( nMaxDepth < 15 ) - return 0; + nRetMask = 0; return nRetMask; } diff --git a/vcl/unx/source/gdi/xrender_peer.hxx b/vcl/unx/source/gdi/xrender_peer.hxx index 6d40015ee94d..89dccfcef40b 100644 --- a/vcl/unx/source/gdi/xrender_peer.hxx +++ b/vcl/unx/source/gdi/xrender_peer.hxx @@ -29,6 +29,7 @@ #define _SV_XRENDER_PEER_HXX #include <tools/prex.h> +struct _XTrap; // on some older systems this is not declared within Xrender.h #include <X11/extensions/Xrender.h> #include <tools/postx.h> @@ -41,7 +42,7 @@ public: static XRenderPeer& GetInstance(); int GetVersion() const; - sal_uInt32 InitRenderText( int nMaxDepth ); + sal_uInt32 InitRenderText(); protected: XRenderPeer(); @@ -84,7 +85,7 @@ public: const XRenderPictFormat*, int nXSrc, int nYSrc, const XTrapezoid*, int nCount ) const; bool AddTraps( Picture aDst, int nXOfs, int nYOfs, - const XTrap*, int nCount ) const; + const _XTrap*, int nCount ) const; bool AreTrapezoidsSupported() const #ifdef XRENDER_LINK @@ -120,7 +121,7 @@ private: const XRenderColor*,int,int,unsigned int,unsigned int); void (*mpXRenderCompositeTrapezoids)(Display*,int,Picture,Picture, const XRenderPictFormat*,int,int,const XTrapezoid*,int); - void (*mpXRenderAddTraps)(Display*,Picture,int,int,const XTrap*,int); + void (*mpXRenderAddTraps)(Display*,Picture,int,int,const _XTrap*,int); #endif // XRENDER_LINK }; @@ -326,7 +327,7 @@ inline void XRenderPeer::CompositeTrapezoids( int nOp, } inline bool XRenderPeer::AddTraps( Picture aDst, int nXOfs, int nYOfs, - const XTrap* pTraps, int nCount ) const + const _XTrap* pTraps, int nCount ) const { #ifdef XRENDER_LINK XRenderAddTraps( mpDisplay, aDst, nXOfs, nYOfs, pTraps, nCount ); diff --git a/vcl/unx/source/plugadapt/salplug.cxx b/vcl/unx/source/plugadapt/salplug.cxx index c42c22bc0592..a438760cffba 100644 --- a/vcl/unx/source/plugadapt/salplug.cxx +++ b/vcl/unx/source/plugadapt/salplug.cxx @@ -98,6 +98,14 @@ static SalInstance* tryInstance( const OUString& rModuleBase ) { pCloseModule = NULL; } + /* + * #i109007# KDE3 seems to have the same problem; an atexit cleanup + * handler, which cannot be resolved anymore if the plugin is already unloaded. + */ + else if( rModuleBase.equalsAscii("kde") ) + { + pCloseModule = NULL; + } GetSalData()->m_pPlugin = aMod; } diff --git a/vcl/unx/source/printer/ppdparser.cxx b/vcl/unx/source/printer/ppdparser.cxx index 971db860cf42..b2549573d099 100644 --- a/vcl/unx/source/printer/ppdparser.cxx +++ b/vcl/unx/source/printer/ppdparser.cxx @@ -258,7 +258,6 @@ using namespace rtl; std::list< PPDParser* > PPDParser::aAllParsers; std::hash_map< OUString, OUString, OUStringHash >* PPDParser::pAllPPDFiles = NULL; -static String aEmptyString; class PPDDecompressStream { @@ -1284,12 +1283,12 @@ void PPDParser::parseConstraint( const ByteString& rLine ) m_aConstraints.push_back( aConstraint ); } -const String& PPDParser::getDefaultPaperDimension() const +String PPDParser::getDefaultPaperDimension() const { if( m_pDefaultPaperDimension ) return m_pDefaultPaperDimension->m_aOption; - return aEmptyString; + return String(); } bool PPDParser::getMargins( @@ -1356,10 +1355,10 @@ bool PPDParser::getPaperDimension( return true; } -const String& PPDParser::matchPaper( int nWidth, int nHeight ) const +String PPDParser::matchPaper( int nWidth, int nHeight ) const { if( ! m_pPaperDimensions ) - return aEmptyString; + return String(); int nPDim = -1; double PDWidth, PDHeight; @@ -1393,51 +1392,51 @@ const String& PPDParser::matchPaper( int nWidth, int nHeight ) const { // swap portrait/landscape and try again bDontSwap = true; - const String& rRet = matchPaper( nHeight, nWidth ); + String rRet = matchPaper( nHeight, nWidth ); bDontSwap = false; return rRet; } - return nPDim != -1 ? m_pPaperDimensions->getValue( nPDim )->m_aOption : aEmptyString; + return nPDim != -1 ? m_pPaperDimensions->getValue( nPDim )->m_aOption : String(); } -const String& PPDParser::getDefaultInputSlot() const +String PPDParser::getDefaultInputSlot() const { if( m_pDefaultInputSlot ) return m_pDefaultInputSlot->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getSlot( int nSlot ) const +String PPDParser::getSlot( int nSlot ) const { if( ! m_pInputSlots ) - return aEmptyString; + return String(); if( nSlot > 0 && nSlot < m_pInputSlots->countValues() ) return m_pInputSlots->getValue( nSlot )->m_aOption; else if( m_pInputSlots->countValues() > 0 ) return m_pInputSlots->getValue( (ULONG)0 )->m_aOption; - return aEmptyString; + return String(); } -const String& PPDParser::getSlotCommand( int nSlot ) const +String PPDParser::getSlotCommand( int nSlot ) const { if( ! m_pInputSlots ) - return aEmptyString; + return String(); if( nSlot > 0 && nSlot < m_pInputSlots->countValues() ) return m_pInputSlots->getValue( nSlot )->m_aValue; else if( m_pInputSlots->countValues() > 0 ) return m_pInputSlots->getValue( (ULONG)0 )->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getSlotCommand( const String& rSlot ) const +String PPDParser::getSlotCommand( const String& rSlot ) const { if( ! m_pInputSlots ) - return aEmptyString; + return String(); for( int i=0; i < m_pInputSlots->countValues(); i++ ) { @@ -1445,39 +1444,39 @@ const String& PPDParser::getSlotCommand( const String& rSlot ) const if( pValue->m_aOption == rSlot ) return pValue->m_aValue; } - return aEmptyString; + return String(); } -const String& PPDParser::getPaperDimension( int nPaperDimension ) const +String PPDParser::getPaperDimension( int nPaperDimension ) const { if( ! m_pPaperDimensions ) - return aEmptyString; + return String(); if( nPaperDimension > 0 && nPaperDimension < m_pPaperDimensions->countValues() ) return m_pPaperDimensions->getValue( nPaperDimension )->m_aOption; else if( m_pPaperDimensions->countValues() > 0 ) return m_pPaperDimensions->getValue( (ULONG)0 )->m_aOption; - return aEmptyString; + return String(); } -const String& PPDParser::getPaperDimensionCommand( int nPaperDimension ) const +String PPDParser::getPaperDimensionCommand( int nPaperDimension ) const { if( ! m_pPaperDimensions ) - return aEmptyString; + return String(); if( nPaperDimension > 0 && nPaperDimension < m_pPaperDimensions->countValues() ) return m_pPaperDimensions->getValue( nPaperDimension )->m_aValue; else if( m_pPaperDimensions->countValues() > 0 ) return m_pPaperDimensions->getValue( (ULONG)0 )->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getPaperDimensionCommand( const String& rPaperDimension ) const +String PPDParser::getPaperDimensionCommand( const String& rPaperDimension ) const { if( ! m_pPaperDimensions ) - return aEmptyString; + return String(); for( int i=0; i < m_pPaperDimensions->countValues(); i++ ) { @@ -1485,7 +1484,7 @@ const String& PPDParser::getPaperDimensionCommand( const String& rPaperDimension if( pValue->m_aOption == rPaperDimension ) return pValue->m_aValue; } - return aEmptyString; + return String(); } void PPDParser::getResolutionFromString( @@ -1543,13 +1542,13 @@ void PPDParser::getResolution( int nNr, int& rXRes, int& rYRes ) const rXRes, rYRes ); } -const String& PPDParser::getResolutionCommand( int nXRes, int nYRes ) const +String PPDParser::getResolutionCommand( int nXRes, int nYRes ) const { if( ( ! m_pResolutions || m_pResolutions->countValues() == 0 ) && m_pDefaultResolution ) return m_pDefaultResolution->m_aValue; if( ! m_pResolutions ) - return aEmptyString; + return String(); int nX, nY; for( int i = 0; i < m_pResolutions->countValues(); i++ ) @@ -1559,46 +1558,46 @@ const String& PPDParser::getResolutionCommand( int nXRes, int nYRes ) const if( nX == nXRes && nY == nYRes ) return m_pResolutions->getValue( i )->m_aValue; } - return aEmptyString; + return String(); } -const String& PPDParser::getDefaultDuplexType() const +String PPDParser::getDefaultDuplexType() const { if( m_pDefaultDuplexType ) return m_pDefaultDuplexType->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getDuplex( int nDuplex ) const +String PPDParser::getDuplex( int nDuplex ) const { if( ! m_pDuplexTypes ) - return aEmptyString; + return String(); if( nDuplex > 0 && nDuplex < m_pDuplexTypes->countValues() ) return m_pDuplexTypes->getValue( nDuplex )->m_aOption; else if( m_pDuplexTypes->countValues() > 0 ) return m_pDuplexTypes->getValue( (ULONG)0 )->m_aOption; - return aEmptyString; + return String(); } -const String& PPDParser::getDuplexCommand( int nDuplex ) const +String PPDParser::getDuplexCommand( int nDuplex ) const { if( ! m_pDuplexTypes ) - return aEmptyString; + return String(); if( nDuplex > 0 && nDuplex < m_pDuplexTypes->countValues() ) return m_pDuplexTypes->getValue( nDuplex )->m_aValue; else if( m_pDuplexTypes->countValues() > 0 ) return m_pDuplexTypes->getValue( (ULONG)0 )->m_aValue; - return aEmptyString; + return String(); } -const String& PPDParser::getDuplexCommand( const String& rDuplex ) const +String PPDParser::getDuplexCommand( const String& rDuplex ) const { if( ! m_pDuplexTypes ) - return aEmptyString; + return String(); for( int i=0; i < m_pDuplexTypes->countValues(); i++ ) { @@ -1606,7 +1605,7 @@ const String& PPDParser::getDuplexCommand( const String& rDuplex ) const if( pValue->m_aOption == rDuplex ) return pValue->m_aValue; } - return aEmptyString; + return String(); } void PPDParser::getFontAttributes( @@ -1636,14 +1635,14 @@ void PPDParser::getFontAttributes( } } -const String& PPDParser::getFont( int nFont ) const +String PPDParser::getFont( int nFont ) const { if( ! m_pFontList ) - return aEmptyString; + return String(); if( nFont >=0 && nFont < m_pFontList->countValues() ) return m_pFontList->getValue( nFont )->m_aOption; - return aEmptyString; + return String(); } rtl::OUString PPDParser::translateKey( const rtl::OUString& i_rKey, diff --git a/vcl/unx/source/window/salframe.cxx b/vcl/unx/source/window/salframe.cxx index 5b538626a634..6d243e41db8c 100644 --- a/vcl/unx/source/window/salframe.cxx +++ b/vcl/unx/source/window/salframe.cxx @@ -528,6 +528,8 @@ void X11SalFrame::Init( ULONG nSalFrameStyle, int nScreen, SystemParentData* pPa Atom a[4]; int n = 0; a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_DELETE_WINDOW ); + if( pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING ) ) + a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING ); if( ! s_pSaveYourselfFrame && ! mpParent) { // at all times have only one frame with SaveYourself @@ -549,11 +551,23 @@ void X11SalFrame::Init( ULONG nSalFrameStyle, int nScreen, SystemParentData* pPa pHints->win_gravity = GetDisplay()->getWMAdaptor()->getPositionWinGravity(); pHints->x = 0; pHints->y = 0; + if( mbFullScreen ) + { + pHints->flags |= PMaxSize | PMinSize; + pHints->max_width = w+100; + pHints->max_height = h+100; + pHints->min_width = w; + pHints->min_height = h; + } XSetWMNormalHints( GetXDisplay(), GetShellWindow(), pHints ); XFree (pHints); + // set PID and WM_CLIENT_MACHINE + pDisplay_->getWMAdaptor()->setClientMachine( this ); + pDisplay_->getWMAdaptor()->setPID( this ); + // set client leader if( aClientLeader ) { @@ -605,7 +619,8 @@ void X11SalFrame::Init( ULONG nSalFrameStyle, int nScreen, SystemParentData* pPa eType = WMAdaptor::windowType_Utility; if( nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION ) eType = WMAdaptor::windowType_Toolbar; - if( nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) + if( (nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) + && GetDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) eType = WMAdaptor::windowType_Dock; GetDisplay()->getWMAdaptor()-> @@ -735,6 +750,8 @@ void X11SalFrame::passOnSaveYourSelf() int n = 0; a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_DELETE_WINDOW ); a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_SAVE_YOURSELF ); + if( pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING ) ) + a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING ); XSetWMProtocols( GetXDisplay(), s_pSaveYourselfFrame->GetShellWindow(), a, n ); } } @@ -1130,7 +1147,7 @@ void X11SalFrame::Show( BOOL bVisible, BOOL bNoActivate ) // even though transient frames should be kept above their parent // this does not necessarily hold true for DOCK type windows // so artificially set ABOVE and remove it again on hide - if( mpParent && (mpParent->nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) ) + if( mpParent && (mpParent->nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) && pDisplay_->getWMAdaptor()->isLegacyPartialFullscreen()) pDisplay_->getWMAdaptor()->enableAlwaysOnTop( this, bVisible ); bMapped_ = bVisible; @@ -1322,11 +1339,6 @@ void X11SalFrame::Show( BOOL bVisible, BOOL bNoActivate ) } else { -#if OSL_DEBUG_LEVEL > 1 - if( nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION ) - fprintf( stderr, "hide on ownerdraw\n" ); -#endif - if( getInputContext() ) getInputContext()->Unmap( this ); @@ -1616,6 +1628,7 @@ void X11SalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, USHOR } else SetPosSize( aPosSize ); + bDefaultPosition_ = False; } @@ -2042,6 +2055,12 @@ void X11SalFrame::SetPosSize( const Rectangle &rPosSize ) pHints->y = values.y; pHints->win_gravity = pDisplay_->getWMAdaptor()->getPositionWinGravity(); } + if( mbFullScreen ) + { + pHints->max_width = 10000; + pHints->max_height = 10000; + pHints->flags |= PMaxSize; + } XSetWMNormalHints( GetXDisplay(), GetShellWindow(), pHints ); @@ -2199,28 +2218,15 @@ void X11SalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nScreen ) maGeometry.nWidth = aRect.GetWidth(); maGeometry.nHeight = aRect.GetHeight(); mbMaximizedHorz = mbMaximizedVert = false; + mbFullScreen = true; createNewWindow( None, m_nScreen ); - GetDisplay()->getWMAdaptor()->enableAlwaysOnTop( this, true ); - #if 0 - // this would give additional intent to the window - // manager to force the positioning of the window; - // alas all other windows will be expunged from that - // region, leaving us in a pity state afterwards - Size aScreenSize = pDisplay_->GetScreenSize( m_nScreen ); - pDisplay_->getWMAdaptor()->setFrameStruts( this, - aRect.Left(), aRect.Top(), - aScreenSize.Width() - aRect.Right(), - aScreenSize.Height() - aRect.Bottom(), - aRect.Left(), aRect.Right(), - aRect.Top(), aRect.Bottom(), - aRect.Left(), aRect.Right(), - aRect.Top(), aRect.Bottom() - ); - #endif - + if( GetDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + GetDisplay()->getWMAdaptor()->enableAlwaysOnTop( this, true ); + else + GetDisplay()->getWMAdaptor()->showFullScreen( this, true ); if( bVisible ) Show(TRUE); - mbFullScreen = true; + } else { @@ -3927,52 +3933,56 @@ long X11SalFrame::HandleClientMessage( XClientMessageEvent *pEvent ) Close(); // ??? return 1; } - else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::WM_PROTOCOLS ) - && ! ( nStyle_ & SAL_FRAME_STYLE_PLUG ) - && ! (( nStyle_ & SAL_FRAME_STYLE_FLOAT ) && (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION)) - ) + else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::WM_PROTOCOLS ) ) { - if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_DELETE_WINDOW ) ) - { - Close(); - return 1; - } - else if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_TAKE_FOCUS ) ) - { - // do nothing, we set the input focus in ToTop() if necessary -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "got WM_TAKE_FOCUS on %s window\n", - (nStyle_&SAL_FRAME_STYLE_OWNERDRAWDECORATION) ? - "ownerdraw" : "NON OWNERDRAW" ); -#endif - } - else if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_SAVE_YOURSELF ) ) + if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::NET_WM_PING ) ) + rWMAdaptor.answerPing( this, pEvent ); + else if( ! ( nStyle_ & SAL_FRAME_STYLE_PLUG ) + && ! (( nStyle_ & SAL_FRAME_STYLE_FLOAT ) && (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION)) + ) { - bool bSession = rWMAdaptor.getWindowManagerName().EqualsAscii( "Dtwm" ); - - if( ! bSession ) + if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_DELETE_WINDOW ) ) + { + Close(); + return 1; + } + else if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_TAKE_FOCUS ) ) { - if( this == s_pSaveYourselfFrame ) + // do nothing, we set the input focus in ToTop() if necessary + #if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "got WM_TAKE_FOCUS on %s window\n", + (nStyle_&SAL_FRAME_STYLE_OWNERDRAWDECORATION) ? + "ownerdraw" : "NON OWNERDRAW" ); + #endif + } + else if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_SAVE_YOURSELF ) ) + { + bool bSession = rWMAdaptor.getWindowManagerName().EqualsAscii( "Dtwm" ); + + if( ! bSession ) { - ByteString aExec( SessionManagerClient::getExecName(), osl_getThreadTextEncoding() ); - const char* argv[2]; - argv[0] = "/bin/sh"; - argv[1] = const_cast<char*>(aExec.GetBuffer()); -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "SaveYourself request, setting command: %s %s\n", argv[0], argv[1] ); -#endif - XSetCommand( GetXDisplay(), GetShellWindow(), (char**)argv, 2 ); + if( this == s_pSaveYourselfFrame ) + { + ByteString aExec( SessionManagerClient::getExecName(), osl_getThreadTextEncoding() ); + const char* argv[2]; + argv[0] = "/bin/sh"; + argv[1] = const_cast<char*>(aExec.GetBuffer()); + #if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "SaveYourself request, setting command: %s %s\n", argv[0], argv[1] ); + #endif + XSetCommand( GetXDisplay(), GetShellWindow(), (char**)argv, 2 ); + } + else + // can only happen in race between WM and window closing + XChangeProperty( GetXDisplay(), GetShellWindow(), rWMAdaptor.getAtom( WMAdaptor::WM_COMMAND ), XA_STRING, 8, PropModeReplace, (unsigned char*)"", 0 ); } else - // can only happen in race between WM and window closing - XChangeProperty( GetXDisplay(), GetShellWindow(), rWMAdaptor.getAtom( WMAdaptor::WM_COMMAND ), XA_STRING, 8, PropModeReplace, (unsigned char*)"", 0 ); - } - else - { - // save open documents; would be good for non Dtwm, too, - // but there is no real Shutdown message in the ancient - // SM protocol; on Dtwm SaveYourself really means Shutdown, too. - IceSalSession::handleOldX11SaveYourself( this ); + { + // save open documents; would be good for non Dtwm, too, + // but there is no real Shutdown message in the ancient + // SM protocol; on Dtwm SaveYourself really means Shutdown, too. + IceSalSession::handleOldX11SaveYourself( this ); + } } } } |