1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_vcl.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <unx/gtk/gtkframe.hxx> 32*cdf0e10cSrcweir #include <unx/gtk/gtkdata.hxx> 33*cdf0e10cSrcweir #include <unx/gtk/gtkinst.hxx> 34*cdf0e10cSrcweir #include <unx/gtk/gtkgdi.hxx> 35*cdf0e10cSrcweir #include <vcl/keycodes.hxx> 36*cdf0e10cSrcweir #include <unx/wmadaptor.hxx> 37*cdf0e10cSrcweir #include <unx/sm.hxx> 38*cdf0e10cSrcweir #include <unx/salbmp.h> 39*cdf0e10cSrcweir #include <unx/salprn.h> 40*cdf0e10cSrcweir #include <vcl/floatwin.hxx> 41*cdf0e10cSrcweir #include <vcl/svapp.hxx> 42*cdf0e10cSrcweir #include <vcl/window.hxx> 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir #include <tools/prex.h> 45*cdf0e10cSrcweir #include <X11/Xatom.h> 46*cdf0e10cSrcweir #include <tools/postx.h> 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir #include <dlfcn.h> 49*cdf0e10cSrcweir #include <vcl/salbtype.hxx> 50*cdf0e10cSrcweir #include <vcl/bitmapex.hxx> 51*cdf0e10cSrcweir #include <impbmp.hxx> 52*cdf0e10cSrcweir #include <svids.hrc> 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir #include <algorithm> 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 57*cdf0e10cSrcweir #include <cstdio> 58*cdf0e10cSrcweir #endif 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleContext.hpp> 61*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp> 62*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleStateSet.hpp> 63*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp> 64*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleEditableText.hpp> 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir #ifdef ENABLE_DBUS 67*cdf0e10cSrcweir #include <dbus/dbus-glib.h> 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir #define GSM_DBUS_SERVICE "org.gnome.SessionManager" 70*cdf0e10cSrcweir #define GSM_DBUS_PATH "/org/gnome/SessionManager" 71*cdf0e10cSrcweir #define GSM_DBUS_INTERFACE "org.gnome.SessionManager" 72*cdf0e10cSrcweir #endif 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir // make compile on gtk older than 2.10 75*cdf0e10cSrcweir #if GTK_MINOR_VERSION < 10 76*cdf0e10cSrcweir #define GDK_SUPER_MASK (1 << 26) 77*cdf0e10cSrcweir #define GDK_HYPER_MASK (1 << 27) 78*cdf0e10cSrcweir #define GDK_META_MASK (1 << 28) 79*cdf0e10cSrcweir #endif 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir using namespace com::sun::star; 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir int GtkSalFrame::m_nFloats = 0; 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir static sal_uInt16 GetKeyModCode( guint state ) 86*cdf0e10cSrcweir { 87*cdf0e10cSrcweir sal_uInt16 nCode = 0; 88*cdf0e10cSrcweir if( (state & GDK_SHIFT_MASK) ) 89*cdf0e10cSrcweir nCode |= KEY_SHIFT; 90*cdf0e10cSrcweir if( (state & GDK_CONTROL_MASK) ) 91*cdf0e10cSrcweir nCode |= KEY_MOD1; 92*cdf0e10cSrcweir if( (state & GDK_MOD1_MASK) ) 93*cdf0e10cSrcweir nCode |= KEY_MOD2; 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir // Map Meta/Super keys to MOD3 modifier on all Unix systems 96*cdf0e10cSrcweir // except Mac OS X 97*cdf0e10cSrcweir if ( (state & GDK_META_MASK ) || ( state & GDK_SUPER_MASK ) ) 98*cdf0e10cSrcweir nCode |= KEY_MOD3; 99*cdf0e10cSrcweir return nCode; 100*cdf0e10cSrcweir } 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir static sal_uInt16 GetMouseModCode( guint state ) 103*cdf0e10cSrcweir { 104*cdf0e10cSrcweir sal_uInt16 nCode = GetKeyModCode( state ); 105*cdf0e10cSrcweir if( (state & GDK_BUTTON1_MASK) ) 106*cdf0e10cSrcweir nCode |= MOUSE_LEFT; 107*cdf0e10cSrcweir if( (state & GDK_BUTTON2_MASK) ) 108*cdf0e10cSrcweir nCode |= MOUSE_MIDDLE; 109*cdf0e10cSrcweir if( (state & GDK_BUTTON3_MASK) ) 110*cdf0e10cSrcweir nCode |= MOUSE_RIGHT; 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir return nCode; 113*cdf0e10cSrcweir } 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir static sal_uInt16 GetKeyCode( guint keyval ) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir sal_uInt16 nCode = 0; 118*cdf0e10cSrcweir if( keyval >= GDK_0 && keyval <= GDK_9 ) 119*cdf0e10cSrcweir nCode = KEY_0 + (keyval-GDK_0); 120*cdf0e10cSrcweir else if( keyval >= GDK_KP_0 && keyval <= GDK_KP_9 ) 121*cdf0e10cSrcweir nCode = KEY_0 + (keyval-GDK_KP_0); 122*cdf0e10cSrcweir else if( keyval >= GDK_A && keyval <= GDK_Z ) 123*cdf0e10cSrcweir nCode = KEY_A + (keyval-GDK_A ); 124*cdf0e10cSrcweir else if( keyval >= GDK_a && keyval <= GDK_z ) 125*cdf0e10cSrcweir nCode = KEY_A + (keyval-GDK_a ); 126*cdf0e10cSrcweir else if( keyval >= GDK_F1 && keyval <= GDK_F26 ) 127*cdf0e10cSrcweir { 128*cdf0e10cSrcweir if( GetX11SalData()->GetDisplay()->IsNumLockFromXS() ) 129*cdf0e10cSrcweir { 130*cdf0e10cSrcweir nCode = KEY_F1 + (keyval-GDK_F1); 131*cdf0e10cSrcweir } 132*cdf0e10cSrcweir else 133*cdf0e10cSrcweir { 134*cdf0e10cSrcweir switch( keyval ) 135*cdf0e10cSrcweir { 136*cdf0e10cSrcweir // - - - - - Sun keyboard, see vcl/unx/source/app/saldisp.cxx 137*cdf0e10cSrcweir case GDK_L2: 138*cdf0e10cSrcweir if( GetX11SalData()->GetDisplay()->GetServerVendor() == vendor_sun ) 139*cdf0e10cSrcweir nCode = KEY_REPEAT; 140*cdf0e10cSrcweir else 141*cdf0e10cSrcweir nCode = KEY_F12; 142*cdf0e10cSrcweir break; 143*cdf0e10cSrcweir case GDK_L3: nCode = KEY_PROPERTIES; break; 144*cdf0e10cSrcweir case GDK_L4: nCode = KEY_UNDO; break; 145*cdf0e10cSrcweir case GDK_L6: nCode = KEY_COPY; break; // KEY_F16 146*cdf0e10cSrcweir case GDK_L8: nCode = KEY_PASTE; break; // KEY_F18 147*cdf0e10cSrcweir case GDK_L10: nCode = KEY_CUT; break; // KEY_F20 148*cdf0e10cSrcweir default: 149*cdf0e10cSrcweir nCode = KEY_F1 + (keyval-GDK_F1); break; 150*cdf0e10cSrcweir } 151*cdf0e10cSrcweir } 152*cdf0e10cSrcweir } 153*cdf0e10cSrcweir else 154*cdf0e10cSrcweir { 155*cdf0e10cSrcweir switch( keyval ) 156*cdf0e10cSrcweir { 157*cdf0e10cSrcweir case GDK_KP_Down: 158*cdf0e10cSrcweir case GDK_Down: nCode = KEY_DOWN; break; 159*cdf0e10cSrcweir case GDK_KP_Up: 160*cdf0e10cSrcweir case GDK_Up: nCode = KEY_UP; break; 161*cdf0e10cSrcweir case GDK_KP_Left: 162*cdf0e10cSrcweir case GDK_Left: nCode = KEY_LEFT; break; 163*cdf0e10cSrcweir case GDK_KP_Right: 164*cdf0e10cSrcweir case GDK_Right: nCode = KEY_RIGHT; break; 165*cdf0e10cSrcweir case GDK_KP_Begin: 166*cdf0e10cSrcweir case GDK_KP_Home: 167*cdf0e10cSrcweir case GDK_Begin: 168*cdf0e10cSrcweir case GDK_Home: nCode = KEY_HOME; break; 169*cdf0e10cSrcweir case GDK_KP_End: 170*cdf0e10cSrcweir case GDK_End: nCode = KEY_END; break; 171*cdf0e10cSrcweir case GDK_KP_Page_Up: 172*cdf0e10cSrcweir case GDK_Page_Up: nCode = KEY_PAGEUP; break; 173*cdf0e10cSrcweir case GDK_KP_Page_Down: 174*cdf0e10cSrcweir case GDK_Page_Down: nCode = KEY_PAGEDOWN; break; 175*cdf0e10cSrcweir case GDK_KP_Enter: 176*cdf0e10cSrcweir case GDK_Return: nCode = KEY_RETURN; break; 177*cdf0e10cSrcweir case GDK_Escape: nCode = KEY_ESCAPE; break; 178*cdf0e10cSrcweir case GDK_ISO_Left_Tab: 179*cdf0e10cSrcweir case GDK_KP_Tab: 180*cdf0e10cSrcweir case GDK_Tab: nCode = KEY_TAB; break; 181*cdf0e10cSrcweir case GDK_BackSpace: nCode = KEY_BACKSPACE; break; 182*cdf0e10cSrcweir case GDK_KP_Space: 183*cdf0e10cSrcweir case GDK_space: nCode = KEY_SPACE; break; 184*cdf0e10cSrcweir case GDK_KP_Insert: 185*cdf0e10cSrcweir case GDK_Insert: nCode = KEY_INSERT; break; 186*cdf0e10cSrcweir case GDK_KP_Delete: 187*cdf0e10cSrcweir case GDK_Delete: nCode = KEY_DELETE; break; 188*cdf0e10cSrcweir case GDK_plus: 189*cdf0e10cSrcweir case GDK_KP_Add: nCode = KEY_ADD; break; 190*cdf0e10cSrcweir case GDK_minus: 191*cdf0e10cSrcweir case GDK_KP_Subtract: nCode = KEY_SUBTRACT; break; 192*cdf0e10cSrcweir case GDK_asterisk: 193*cdf0e10cSrcweir case GDK_KP_Multiply: nCode = KEY_MULTIPLY; break; 194*cdf0e10cSrcweir case GDK_slash: 195*cdf0e10cSrcweir case GDK_KP_Divide: nCode = KEY_DIVIDE; break; 196*cdf0e10cSrcweir case GDK_period: 197*cdf0e10cSrcweir case GDK_decimalpoint: nCode = KEY_POINT; break; 198*cdf0e10cSrcweir case GDK_comma: nCode = KEY_COMMA; break; 199*cdf0e10cSrcweir case GDK_less: nCode = KEY_LESS; break; 200*cdf0e10cSrcweir case GDK_greater: nCode = KEY_GREATER; break; 201*cdf0e10cSrcweir case GDK_KP_Equal: 202*cdf0e10cSrcweir case GDK_equal: nCode = KEY_EQUAL; break; 203*cdf0e10cSrcweir case GDK_Find: nCode = KEY_FIND; break; 204*cdf0e10cSrcweir case GDK_Menu: nCode = KEY_CONTEXTMENU;break; 205*cdf0e10cSrcweir case GDK_Help: nCode = KEY_HELP; break; 206*cdf0e10cSrcweir case GDK_Undo: nCode = KEY_UNDO; break; 207*cdf0e10cSrcweir case GDK_Redo: nCode = KEY_REPEAT; break; 208*cdf0e10cSrcweir case GDK_KP_Decimal: 209*cdf0e10cSrcweir case GDK_KP_Separator: nCode = KEY_DECIMAL; break; 210*cdf0e10cSrcweir case GDK_asciitilde: nCode = KEY_TILDE; break; 211*cdf0e10cSrcweir case GDK_leftsinglequotemark: 212*cdf0e10cSrcweir case GDK_quoteleft: nCode = KEY_QUOTELEFT; break; 213*cdf0e10cSrcweir // some special cases, also see saldisp.cxx 214*cdf0e10cSrcweir // - - - - - - - - - - - - - Apollo - - - - - - - - - - - - - 0x1000 215*cdf0e10cSrcweir case 0x1000FF02: // apXK_Copy 216*cdf0e10cSrcweir nCode = KEY_COPY; 217*cdf0e10cSrcweir break; 218*cdf0e10cSrcweir case 0x1000FF03: // apXK_Cut 219*cdf0e10cSrcweir nCode = KEY_CUT; 220*cdf0e10cSrcweir break; 221*cdf0e10cSrcweir case 0x1000FF04: // apXK_Paste 222*cdf0e10cSrcweir nCode = KEY_PASTE; 223*cdf0e10cSrcweir break; 224*cdf0e10cSrcweir case 0x1000FF14: // apXK_Repeat 225*cdf0e10cSrcweir nCode = KEY_REPEAT; 226*cdf0e10cSrcweir break; 227*cdf0e10cSrcweir // Exit, Save 228*cdf0e10cSrcweir // - - - - - - - - - - - - - - D E C - - - - - - - - - - - - - 0x1000 229*cdf0e10cSrcweir case 0x1000FF00: 230*cdf0e10cSrcweir nCode = KEY_DELETE; 231*cdf0e10cSrcweir break; 232*cdf0e10cSrcweir // - - - - - - - - - - - - - - H P - - - - - - - - - - - - - 0x1000 233*cdf0e10cSrcweir case 0x1000FF73: // hpXK_DeleteChar 234*cdf0e10cSrcweir nCode = KEY_DELETE; 235*cdf0e10cSrcweir break; 236*cdf0e10cSrcweir case 0x1000FF74: // hpXK_BackTab 237*cdf0e10cSrcweir case 0x1000FF75: // hpXK_KP_BackTab 238*cdf0e10cSrcweir nCode = KEY_TAB; 239*cdf0e10cSrcweir break; 240*cdf0e10cSrcweir // - - - - - - - - - - - - - - I B M - - - - - - - - - - - - - 241*cdf0e10cSrcweir // - - - - - - - - - - - - - - O S F - - - - - - - - - - - - - 0x1004 242*cdf0e10cSrcweir case 0x1004FF02: // osfXK_Copy 243*cdf0e10cSrcweir nCode = KEY_COPY; 244*cdf0e10cSrcweir break; 245*cdf0e10cSrcweir case 0x1004FF03: // osfXK_Cut 246*cdf0e10cSrcweir nCode = KEY_CUT; 247*cdf0e10cSrcweir break; 248*cdf0e10cSrcweir case 0x1004FF04: // osfXK_Paste 249*cdf0e10cSrcweir nCode = KEY_PASTE; 250*cdf0e10cSrcweir break; 251*cdf0e10cSrcweir case 0x1004FF07: // osfXK_BackTab 252*cdf0e10cSrcweir nCode = KEY_TAB; 253*cdf0e10cSrcweir break; 254*cdf0e10cSrcweir case 0x1004FF08: // osfXK_BackSpace 255*cdf0e10cSrcweir nCode = KEY_BACKSPACE; 256*cdf0e10cSrcweir break; 257*cdf0e10cSrcweir case 0x1004FF1B: // osfXK_Escape 258*cdf0e10cSrcweir nCode = KEY_ESCAPE; 259*cdf0e10cSrcweir break; 260*cdf0e10cSrcweir // Up, Down, Left, Right, PageUp, PageDown 261*cdf0e10cSrcweir // - - - - - - - - - - - - - - S C O - - - - - - - - - - - - - 262*cdf0e10cSrcweir // - - - - - - - - - - - - - - S G I - - - - - - - - - - - - - 0x1007 263*cdf0e10cSrcweir // - - - - - - - - - - - - - - S N I - - - - - - - - - - - - - 264*cdf0e10cSrcweir // - - - - - - - - - - - - - - S U N - - - - - - - - - - - - - 0x1005 265*cdf0e10cSrcweir case 0x1005FF10: // SunXK_F36 266*cdf0e10cSrcweir nCode = KEY_F11; 267*cdf0e10cSrcweir break; 268*cdf0e10cSrcweir case 0x1005FF11: // SunXK_F37 269*cdf0e10cSrcweir nCode = KEY_F12; 270*cdf0e10cSrcweir break; 271*cdf0e10cSrcweir case 0x1005FF70: // SunXK_Props 272*cdf0e10cSrcweir nCode = KEY_PROPERTIES; 273*cdf0e10cSrcweir break; 274*cdf0e10cSrcweir case 0x1005FF71: // SunXK_Front 275*cdf0e10cSrcweir nCode = KEY_FRONT; 276*cdf0e10cSrcweir break; 277*cdf0e10cSrcweir case 0x1005FF72: // SunXK_Copy 278*cdf0e10cSrcweir nCode = KEY_COPY; 279*cdf0e10cSrcweir break; 280*cdf0e10cSrcweir case 0x1005FF73: // SunXK_Open 281*cdf0e10cSrcweir nCode = KEY_OPEN; 282*cdf0e10cSrcweir break; 283*cdf0e10cSrcweir case 0x1005FF74: // SunXK_Paste 284*cdf0e10cSrcweir nCode = KEY_PASTE; 285*cdf0e10cSrcweir break; 286*cdf0e10cSrcweir case 0x1005FF75: // SunXK_Cut 287*cdf0e10cSrcweir nCode = KEY_CUT; 288*cdf0e10cSrcweir break; 289*cdf0e10cSrcweir } 290*cdf0e10cSrcweir } 291*cdf0e10cSrcweir 292*cdf0e10cSrcweir return nCode; 293*cdf0e10cSrcweir } 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir // F10 means either KEY_F10 or KEY_MENU, which has to be decided 296*cdf0e10cSrcweir // in the independent part. 297*cdf0e10cSrcweir struct KeyAlternate 298*cdf0e10cSrcweir { 299*cdf0e10cSrcweir sal_uInt16 nKeyCode; 300*cdf0e10cSrcweir sal_Unicode nCharCode; 301*cdf0e10cSrcweir KeyAlternate() : nKeyCode( 0 ), nCharCode( 0 ) {} 302*cdf0e10cSrcweir KeyAlternate( sal_uInt16 nKey, sal_Unicode nChar = 0 ) : nKeyCode( nKey ), nCharCode( nChar ) {} 303*cdf0e10cSrcweir }; 304*cdf0e10cSrcweir 305*cdf0e10cSrcweir inline KeyAlternate 306*cdf0e10cSrcweir GetAlternateKeyCode( const sal_uInt16 nKeyCode ) 307*cdf0e10cSrcweir { 308*cdf0e10cSrcweir KeyAlternate aAlternate; 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir switch( nKeyCode ) 311*cdf0e10cSrcweir { 312*cdf0e10cSrcweir case KEY_F10: aAlternate = KeyAlternate( KEY_MENU );break; 313*cdf0e10cSrcweir case KEY_F24: aAlternate = KeyAlternate( KEY_SUBTRACT, '-' );break; 314*cdf0e10cSrcweir } 315*cdf0e10cSrcweir 316*cdf0e10cSrcweir return aAlternate; 317*cdf0e10cSrcweir } 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir void GtkSalFrame::doKeyCallback( guint state, 320*cdf0e10cSrcweir guint keyval, 321*cdf0e10cSrcweir guint16 hardware_keycode, 322*cdf0e10cSrcweir guint8 /*group*/, 323*cdf0e10cSrcweir guint32 time, 324*cdf0e10cSrcweir sal_Unicode aOrigCode, 325*cdf0e10cSrcweir bool bDown, 326*cdf0e10cSrcweir bool bSendRelease 327*cdf0e10cSrcweir ) 328*cdf0e10cSrcweir { 329*cdf0e10cSrcweir SalKeyEvent aEvent; 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir aEvent.mnTime = time; 332*cdf0e10cSrcweir aEvent.mnCharCode = aOrigCode; 333*cdf0e10cSrcweir aEvent.mnRepeat = 0; 334*cdf0e10cSrcweir 335*cdf0e10cSrcweir vcl::DeletionListener aDel( this ); 336*cdf0e10cSrcweir /* #i42122# translate all keys with Ctrl and/or Alt to group 0 337*cdf0e10cSrcweir * else shortcuts (e.g. Ctrl-o) will not work but be inserted by 338*cdf0e10cSrcweir * the application 339*cdf0e10cSrcweir */ 340*cdf0e10cSrcweir /* #i52338# do this for all keys that the independent part has no key code for 341*cdf0e10cSrcweir */ 342*cdf0e10cSrcweir aEvent.mnCode = GetKeyCode( keyval ); 343*cdf0e10cSrcweir if( aEvent.mnCode == 0 ) 344*cdf0e10cSrcweir { 345*cdf0e10cSrcweir // check other mapping 346*cdf0e10cSrcweir gint eff_group, level; 347*cdf0e10cSrcweir GdkModifierType consumed; 348*cdf0e10cSrcweir guint updated_keyval = 0; 349*cdf0e10cSrcweir // use gdk_keymap_get_default instead of NULL; 350*cdf0e10cSrcweir // workaround a crahs fixed in gtk 2.4 351*cdf0e10cSrcweir if( gdk_keymap_translate_keyboard_state( gdk_keymap_get_default(), 352*cdf0e10cSrcweir hardware_keycode, 353*cdf0e10cSrcweir (GdkModifierType)0, 354*cdf0e10cSrcweir 0, 355*cdf0e10cSrcweir &updated_keyval, 356*cdf0e10cSrcweir &eff_group, 357*cdf0e10cSrcweir &level, 358*cdf0e10cSrcweir &consumed ) ) 359*cdf0e10cSrcweir { 360*cdf0e10cSrcweir aEvent.mnCode = GetKeyCode( updated_keyval ); 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir } 363*cdf0e10cSrcweir aEvent.mnCode |= GetKeyModCode( state ); 364*cdf0e10cSrcweir 365*cdf0e10cSrcweir if( bDown ) 366*cdf0e10cSrcweir { 367*cdf0e10cSrcweir bool bHandled = CallCallback( SALEVENT_KEYINPUT, &aEvent ); 368*cdf0e10cSrcweir // #i46889# copy AlternatKeyCode handling from generic plugin 369*cdf0e10cSrcweir if( ! bHandled ) 370*cdf0e10cSrcweir { 371*cdf0e10cSrcweir KeyAlternate aAlternate = GetAlternateKeyCode( aEvent.mnCode ); 372*cdf0e10cSrcweir if( aAlternate.nKeyCode ) 373*cdf0e10cSrcweir { 374*cdf0e10cSrcweir aEvent.mnCode = aAlternate.nKeyCode; 375*cdf0e10cSrcweir if( aAlternate.nCharCode ) 376*cdf0e10cSrcweir aEvent.mnCharCode = aAlternate.nCharCode; 377*cdf0e10cSrcweir bHandled = CallCallback( SALEVENT_KEYINPUT, &aEvent ); 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir if( bSendRelease && ! aDel.isDeleted() ) 381*cdf0e10cSrcweir { 382*cdf0e10cSrcweir CallCallback( SALEVENT_KEYUP, &aEvent ); 383*cdf0e10cSrcweir } 384*cdf0e10cSrcweir } 385*cdf0e10cSrcweir else 386*cdf0e10cSrcweir CallCallback( SALEVENT_KEYUP, &aEvent ); 387*cdf0e10cSrcweir } 388*cdf0e10cSrcweir 389*cdf0e10cSrcweir GtkSalFrame::GraphicsHolder::~GraphicsHolder() 390*cdf0e10cSrcweir { 391*cdf0e10cSrcweir delete pGraphics; 392*cdf0e10cSrcweir } 393*cdf0e10cSrcweir 394*cdf0e10cSrcweir GtkSalFrame::GtkSalFrame( SalFrame* pParent, sal_uLong nStyle ) 395*cdf0e10cSrcweir { 396*cdf0e10cSrcweir m_nScreen = getDisplay()->GetDefaultScreenNumber(); 397*cdf0e10cSrcweir getDisplay()->registerFrame( this ); 398*cdf0e10cSrcweir m_bDefaultPos = true; 399*cdf0e10cSrcweir m_bDefaultSize = ( (nStyle & SAL_FRAME_STYLE_SIZEABLE) && ! pParent ); 400*cdf0e10cSrcweir m_bWindowIsGtkPlug = false; 401*cdf0e10cSrcweir Init( pParent, nStyle ); 402*cdf0e10cSrcweir } 403*cdf0e10cSrcweir 404*cdf0e10cSrcweir GtkSalFrame::GtkSalFrame( SystemParentData* pSysData ) 405*cdf0e10cSrcweir { 406*cdf0e10cSrcweir m_nScreen = getDisplay()->GetDefaultScreenNumber(); 407*cdf0e10cSrcweir getDisplay()->registerFrame( this ); 408*cdf0e10cSrcweir getDisplay()->setHaveSystemChildFrame(); 409*cdf0e10cSrcweir m_bDefaultPos = true; 410*cdf0e10cSrcweir m_bDefaultSize = true; 411*cdf0e10cSrcweir Init( pSysData ); 412*cdf0e10cSrcweir } 413*cdf0e10cSrcweir 414*cdf0e10cSrcweir GtkSalFrame::~GtkSalFrame() 415*cdf0e10cSrcweir { 416*cdf0e10cSrcweir for( unsigned int i = 0; i < sizeof(m_aGraphics)/sizeof(m_aGraphics[0]); ++i ) 417*cdf0e10cSrcweir { 418*cdf0e10cSrcweir if( !m_aGraphics[i].pGraphics ) 419*cdf0e10cSrcweir continue; 420*cdf0e10cSrcweir m_aGraphics[i].pGraphics->SetDrawable( None, m_nScreen ); 421*cdf0e10cSrcweir m_aGraphics[i].bInUse = false; 422*cdf0e10cSrcweir } 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir if( m_pParent ) 425*cdf0e10cSrcweir m_pParent->m_aChildren.remove( this ); 426*cdf0e10cSrcweir 427*cdf0e10cSrcweir getDisplay()->deregisterFrame( this ); 428*cdf0e10cSrcweir 429*cdf0e10cSrcweir if( m_pRegion ) 430*cdf0e10cSrcweir gdk_region_destroy( m_pRegion ); 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir if( m_hBackgroundPixmap ) 433*cdf0e10cSrcweir { 434*cdf0e10cSrcweir XSetWindowBackgroundPixmap( getDisplay()->GetDisplay(), 435*cdf0e10cSrcweir GDK_WINDOW_XWINDOW(m_pWindow->window), 436*cdf0e10cSrcweir None ); 437*cdf0e10cSrcweir XFreePixmap( getDisplay()->GetDisplay(), m_hBackgroundPixmap ); 438*cdf0e10cSrcweir } 439*cdf0e10cSrcweir 440*cdf0e10cSrcweir if( m_pIMHandler ) 441*cdf0e10cSrcweir delete m_pIMHandler; 442*cdf0e10cSrcweir 443*cdf0e10cSrcweir if( m_pFixedContainer ) 444*cdf0e10cSrcweir gtk_widget_destroy( GTK_WIDGET(m_pFixedContainer) ); 445*cdf0e10cSrcweir if( m_pWindow ) 446*cdf0e10cSrcweir { 447*cdf0e10cSrcweir g_object_set_data( G_OBJECT( m_pWindow ), "SalFrame", NULL ); 448*cdf0e10cSrcweir gtk_widget_destroy( m_pWindow ); 449*cdf0e10cSrcweir } 450*cdf0e10cSrcweir if( m_pForeignParent ) 451*cdf0e10cSrcweir g_object_unref( G_OBJECT(m_pForeignParent) ); 452*cdf0e10cSrcweir if( m_pForeignTopLevel ) 453*cdf0e10cSrcweir g_object_unref(G_OBJECT( m_pForeignTopLevel) ); 454*cdf0e10cSrcweir } 455*cdf0e10cSrcweir 456*cdf0e10cSrcweir void GtkSalFrame::moveWindow( long nX, long nY ) 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir if( isChild( false, true ) ) 459*cdf0e10cSrcweir { 460*cdf0e10cSrcweir if( m_pParent ) 461*cdf0e10cSrcweir gtk_fixed_move( m_pParent->getFixedContainer(), 462*cdf0e10cSrcweir m_pWindow, 463*cdf0e10cSrcweir nX - m_pParent->maGeometry.nX, nY - m_pParent->maGeometry.nY ); 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir else 466*cdf0e10cSrcweir gtk_window_move( GTK_WINDOW(m_pWindow), nX, nY ); 467*cdf0e10cSrcweir } 468*cdf0e10cSrcweir 469*cdf0e10cSrcweir void GtkSalFrame::resizeWindow( long nWidth, long nHeight ) 470*cdf0e10cSrcweir { 471*cdf0e10cSrcweir if( isChild( false, true ) ) 472*cdf0e10cSrcweir gtk_widget_set_size_request( m_pWindow, nWidth, nHeight ); 473*cdf0e10cSrcweir else if( ! isChild( true, false ) ) 474*cdf0e10cSrcweir gtk_window_resize( GTK_WINDOW(m_pWindow), nWidth, nHeight ); 475*cdf0e10cSrcweir } 476*cdf0e10cSrcweir 477*cdf0e10cSrcweir /* 478*cdf0e10cSrcweir * Always use a sub-class of GtkFixed we can tag for a11y. This allows us to 479*cdf0e10cSrcweir * utilize GAIL for the toplevel window and toolkit implementation incl. 480*cdf0e10cSrcweir * key event listener support .. 481*cdf0e10cSrcweir */ 482*cdf0e10cSrcweir 483*cdf0e10cSrcweir GType 484*cdf0e10cSrcweir ooo_fixed_get_type() 485*cdf0e10cSrcweir { 486*cdf0e10cSrcweir static GType type = 0; 487*cdf0e10cSrcweir 488*cdf0e10cSrcweir if (!type) { 489*cdf0e10cSrcweir static const GTypeInfo tinfo = 490*cdf0e10cSrcweir { 491*cdf0e10cSrcweir sizeof (GtkFixedClass), 492*cdf0e10cSrcweir (GBaseInitFunc) NULL, /* base init */ 493*cdf0e10cSrcweir (GBaseFinalizeFunc) NULL, /* base finalize */ 494*cdf0e10cSrcweir (GClassInitFunc) NULL, /* class init */ 495*cdf0e10cSrcweir (GClassFinalizeFunc) NULL, /* class finalize */ 496*cdf0e10cSrcweir NULL, /* class data */ 497*cdf0e10cSrcweir sizeof (GtkFixed), /* instance size */ 498*cdf0e10cSrcweir 0, /* nb preallocs */ 499*cdf0e10cSrcweir (GInstanceInitFunc) NULL, /* instance init */ 500*cdf0e10cSrcweir NULL /* value table */ 501*cdf0e10cSrcweir }; 502*cdf0e10cSrcweir 503*cdf0e10cSrcweir type = g_type_register_static( GTK_TYPE_FIXED, "OOoFixed", 504*cdf0e10cSrcweir &tinfo, (GTypeFlags) 0); 505*cdf0e10cSrcweir } 506*cdf0e10cSrcweir 507*cdf0e10cSrcweir return type; 508*cdf0e10cSrcweir } 509*cdf0e10cSrcweir 510*cdf0e10cSrcweir void GtkSalFrame::updateScreenNumber() 511*cdf0e10cSrcweir { 512*cdf0e10cSrcweir if( getDisplay()->IsXinerama() && getDisplay()->GetXineramaScreens().size() > 1 ) 513*cdf0e10cSrcweir { 514*cdf0e10cSrcweir Point aPoint( maGeometry.nX, maGeometry.nY ); 515*cdf0e10cSrcweir const std::vector<Rectangle>& rScreenRects( getDisplay()->GetXineramaScreens() ); 516*cdf0e10cSrcweir size_t nScreens = rScreenRects.size(); 517*cdf0e10cSrcweir for( size_t i = 0; i < nScreens; i++ ) 518*cdf0e10cSrcweir { 519*cdf0e10cSrcweir if( rScreenRects[i].IsInside( aPoint ) ) 520*cdf0e10cSrcweir { 521*cdf0e10cSrcweir maGeometry.nScreenNumber = static_cast<unsigned int>(i); 522*cdf0e10cSrcweir break; 523*cdf0e10cSrcweir } 524*cdf0e10cSrcweir } 525*cdf0e10cSrcweir } 526*cdf0e10cSrcweir else 527*cdf0e10cSrcweir maGeometry.nScreenNumber = static_cast<unsigned int>(m_nScreen); 528*cdf0e10cSrcweir } 529*cdf0e10cSrcweir 530*cdf0e10cSrcweir void GtkSalFrame::InitCommon() 531*cdf0e10cSrcweir { 532*cdf0e10cSrcweir // connect signals 533*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "style-set", G_CALLBACK(signalStyleSet), this ); 534*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "button-press-event", G_CALLBACK(signalButton), this ); 535*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "button-release-event", G_CALLBACK(signalButton), this ); 536*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "expose-event", G_CALLBACK(signalExpose), this ); 537*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "focus-in-event", G_CALLBACK(signalFocus), this ); 538*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "focus-out-event", G_CALLBACK(signalFocus), this ); 539*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "map-event", G_CALLBACK(signalMap), this ); 540*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "unmap-event", G_CALLBACK(signalUnmap), this ); 541*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "configure-event", G_CALLBACK(signalConfigure), this ); 542*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "motion-notify-event", G_CALLBACK(signalMotion), this ); 543*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "key-press-event", G_CALLBACK(signalKey), this ); 544*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "key-release-event", G_CALLBACK(signalKey), this ); 545*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "delete-event", G_CALLBACK(signalDelete), this ); 546*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "window-state-event", G_CALLBACK(signalState), this ); 547*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "scroll-event", G_CALLBACK(signalScroll), this ); 548*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "leave-notify-event", G_CALLBACK(signalCrossing), this ); 549*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "enter-notify-event", G_CALLBACK(signalCrossing), this ); 550*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "visibility-notify-event", G_CALLBACK(signalVisibility), this ); 551*cdf0e10cSrcweir g_signal_connect( G_OBJECT(m_pWindow), "destroy", G_CALLBACK(signalDestroy), this ); 552*cdf0e10cSrcweir 553*cdf0e10cSrcweir // init members 554*cdf0e10cSrcweir m_pCurrentCursor = NULL; 555*cdf0e10cSrcweir m_nKeyModifiers = 0; 556*cdf0e10cSrcweir m_bSingleAltPress = false; 557*cdf0e10cSrcweir m_bFullscreen = false; 558*cdf0e10cSrcweir m_nState = GDK_WINDOW_STATE_WITHDRAWN; 559*cdf0e10cSrcweir m_nVisibility = GDK_VISIBILITY_FULLY_OBSCURED; 560*cdf0e10cSrcweir m_bSendModChangeOnRelease = false; 561*cdf0e10cSrcweir m_pIMHandler = NULL; 562*cdf0e10cSrcweir m_hBackgroundPixmap = None; 563*cdf0e10cSrcweir m_nSavedScreenSaverTimeout = 0; 564*cdf0e10cSrcweir m_nGSMCookie = 0; 565*cdf0e10cSrcweir m_nExtStyle = 0; 566*cdf0e10cSrcweir m_pRegion = NULL; 567*cdf0e10cSrcweir m_ePointerStyle = 0xffff; 568*cdf0e10cSrcweir m_bSetFocusOnMap = false; 569*cdf0e10cSrcweir 570*cdf0e10cSrcweir gtk_widget_set_app_paintable( m_pWindow, sal_True ); 571*cdf0e10cSrcweir gtk_widget_set_double_buffered( m_pWindow, FALSE ); 572*cdf0e10cSrcweir gtk_widget_set_redraw_on_allocate( m_pWindow, FALSE ); 573*cdf0e10cSrcweir gtk_widget_add_events( m_pWindow, 574*cdf0e10cSrcweir GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | 575*cdf0e10cSrcweir GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | 576*cdf0e10cSrcweir GDK_VISIBILITY_NOTIFY_MASK 577*cdf0e10cSrcweir ); 578*cdf0e10cSrcweir 579*cdf0e10cSrcweir // add the fixed container child, 580*cdf0e10cSrcweir // fixed is needed since we have to position plugin windows 581*cdf0e10cSrcweir m_pFixedContainer = GTK_FIXED(g_object_new( ooo_fixed_get_type(), NULL )); 582*cdf0e10cSrcweir gtk_container_add( GTK_CONTAINER(m_pWindow), GTK_WIDGET(m_pFixedContainer) ); 583*cdf0e10cSrcweir 584*cdf0e10cSrcweir // show the widgets 585*cdf0e10cSrcweir gtk_widget_show( GTK_WIDGET(m_pFixedContainer) ); 586*cdf0e10cSrcweir 587*cdf0e10cSrcweir // realize the window, we need an XWindow id 588*cdf0e10cSrcweir gtk_widget_realize( m_pWindow ); 589*cdf0e10cSrcweir 590*cdf0e10cSrcweir //system data 591*cdf0e10cSrcweir SalDisplay* pDisp = GetX11SalData()->GetDisplay(); 592*cdf0e10cSrcweir m_aSystemData.nSize = sizeof( SystemChildData ); 593*cdf0e10cSrcweir m_aSystemData.pDisplay = pDisp->GetDisplay(); 594*cdf0e10cSrcweir m_aSystemData.aWindow = GDK_WINDOW_XWINDOW(m_pWindow->window); 595*cdf0e10cSrcweir m_aSystemData.pSalFrame = this; 596*cdf0e10cSrcweir m_aSystemData.pWidget = m_pWindow; 597*cdf0e10cSrcweir m_aSystemData.pVisual = pDisp->GetVisual( m_nScreen ).GetVisual(); 598*cdf0e10cSrcweir m_aSystemData.nScreen = m_nScreen; 599*cdf0e10cSrcweir m_aSystemData.nDepth = pDisp->GetVisual( m_nScreen ).GetDepth(); 600*cdf0e10cSrcweir m_aSystemData.aColormap = pDisp->GetColormap( m_nScreen ).GetXColormap(); 601*cdf0e10cSrcweir m_aSystemData.pAppContext = NULL; 602*cdf0e10cSrcweir m_aSystemData.aShellWindow = m_aSystemData.aWindow; 603*cdf0e10cSrcweir m_aSystemData.pShellWidget = m_aSystemData.pWidget; 604*cdf0e10cSrcweir 605*cdf0e10cSrcweir 606*cdf0e10cSrcweir // fake an initial geometry, gets updated via configure event or SetPosSize 607*cdf0e10cSrcweir if( m_bDefaultPos || m_bDefaultSize ) 608*cdf0e10cSrcweir { 609*cdf0e10cSrcweir Size aDefSize = calcDefaultSize(); 610*cdf0e10cSrcweir maGeometry.nX = -1; 611*cdf0e10cSrcweir maGeometry.nY = -1; 612*cdf0e10cSrcweir maGeometry.nWidth = aDefSize.Width(); 613*cdf0e10cSrcweir maGeometry.nHeight = aDefSize.Height(); 614*cdf0e10cSrcweir if( m_pParent ) 615*cdf0e10cSrcweir { 616*cdf0e10cSrcweir // approximation 617*cdf0e10cSrcweir maGeometry.nTopDecoration = m_pParent->maGeometry.nTopDecoration; 618*cdf0e10cSrcweir maGeometry.nBottomDecoration = m_pParent->maGeometry.nBottomDecoration; 619*cdf0e10cSrcweir maGeometry.nLeftDecoration = m_pParent->maGeometry.nLeftDecoration; 620*cdf0e10cSrcweir maGeometry.nRightDecoration = m_pParent->maGeometry.nRightDecoration; 621*cdf0e10cSrcweir } 622*cdf0e10cSrcweir else 623*cdf0e10cSrcweir { 624*cdf0e10cSrcweir maGeometry.nTopDecoration = 0; 625*cdf0e10cSrcweir maGeometry.nBottomDecoration = 0; 626*cdf0e10cSrcweir maGeometry.nLeftDecoration = 0; 627*cdf0e10cSrcweir maGeometry.nRightDecoration = 0; 628*cdf0e10cSrcweir } 629*cdf0e10cSrcweir } 630*cdf0e10cSrcweir else 631*cdf0e10cSrcweir { 632*cdf0e10cSrcweir resizeWindow( maGeometry.nWidth, maGeometry.nHeight ); 633*cdf0e10cSrcweir moveWindow( maGeometry.nX, maGeometry.nY ); 634*cdf0e10cSrcweir } 635*cdf0e10cSrcweir updateScreenNumber(); 636*cdf0e10cSrcweir 637*cdf0e10cSrcweir SetIcon(1); 638*cdf0e10cSrcweir m_nWorkArea = pDisp->getWMAdaptor()->getCurrentWorkArea(); 639*cdf0e10cSrcweir 640*cdf0e10cSrcweir /* #i64117# gtk sets a nice background pixmap 641*cdf0e10cSrcweir * but we actually don't really want that, so save 642*cdf0e10cSrcweir * some time on the Xserver as well as prevent 643*cdf0e10cSrcweir * some paint issues 644*cdf0e10cSrcweir */ 645*cdf0e10cSrcweir XSetWindowBackgroundPixmap( getDisplay()->GetDisplay(), 646*cdf0e10cSrcweir GDK_WINDOW_XWINDOW(m_pWindow->window), 647*cdf0e10cSrcweir m_hBackgroundPixmap ); 648*cdf0e10cSrcweir } 649*cdf0e10cSrcweir 650*cdf0e10cSrcweir /* Sadly gtk_window_set_accept_focus exists only since gtk 2.4 651*cdf0e10cSrcweir * for achieving the same effect we will remove the WM_TAKE_FOCUS 652*cdf0e10cSrcweir * protocol from the window and set the input hint to false. 653*cdf0e10cSrcweir * But gtk_window_set_accept_focus needs to be called before 654*cdf0e10cSrcweir * window realization whereas the removal obviously can only happen 655*cdf0e10cSrcweir * after realization. 656*cdf0e10cSrcweir */ 657*cdf0e10cSrcweir 658*cdf0e10cSrcweir extern "C" { 659*cdf0e10cSrcweir typedef void(*setAcceptFn)( GtkWindow*, gboolean ); 660*cdf0e10cSrcweir static setAcceptFn p_gtk_window_set_accept_focus = NULL; 661*cdf0e10cSrcweir static bool bGetAcceptFocusFn = true; 662*cdf0e10cSrcweir 663*cdf0e10cSrcweir typedef void(*setUserTimeFn)( GdkWindow*, guint32 ); 664*cdf0e10cSrcweir static setUserTimeFn p_gdk_x11_window_set_user_time = NULL; 665*cdf0e10cSrcweir static bool bGetSetUserTimeFn = true; 666*cdf0e10cSrcweir } 667*cdf0e10cSrcweir 668*cdf0e10cSrcweir static void lcl_set_accept_focus( GtkWindow* pWindow, gboolean bAccept, bool bBeforeRealize ) 669*cdf0e10cSrcweir { 670*cdf0e10cSrcweir if( bGetAcceptFocusFn ) 671*cdf0e10cSrcweir { 672*cdf0e10cSrcweir bGetAcceptFocusFn = false; 673*cdf0e10cSrcweir p_gtk_window_set_accept_focus = (setAcceptFn)osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gtk_window_set_accept_focus" ); 674*cdf0e10cSrcweir } 675*cdf0e10cSrcweir if( p_gtk_window_set_accept_focus && bBeforeRealize ) 676*cdf0e10cSrcweir p_gtk_window_set_accept_focus( pWindow, bAccept ); 677*cdf0e10cSrcweir else if( ! bBeforeRealize ) 678*cdf0e10cSrcweir { 679*cdf0e10cSrcweir Display* pDisplay = GetX11SalData()->GetDisplay()->GetDisplay(); 680*cdf0e10cSrcweir XLIB_Window aWindow = GDK_WINDOW_XWINDOW( GTK_WIDGET(pWindow)->window ); 681*cdf0e10cSrcweir XWMHints* pHints = XGetWMHints( pDisplay, aWindow ); 682*cdf0e10cSrcweir if( ! pHints ) 683*cdf0e10cSrcweir { 684*cdf0e10cSrcweir pHints = XAllocWMHints(); 685*cdf0e10cSrcweir pHints->flags = 0; 686*cdf0e10cSrcweir } 687*cdf0e10cSrcweir pHints->flags |= InputHint; 688*cdf0e10cSrcweir pHints->input = bAccept ? True : False; 689*cdf0e10cSrcweir XSetWMHints( pDisplay, aWindow, pHints ); 690*cdf0e10cSrcweir XFree( pHints ); 691*cdf0e10cSrcweir 692*cdf0e10cSrcweir if (GetX11SalData()->GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii("compiz")) 693*cdf0e10cSrcweir return; 694*cdf0e10cSrcweir 695*cdf0e10cSrcweir /* remove WM_TAKE_FOCUS protocol; this would usually be the 696*cdf0e10cSrcweir * right thing, but gtk handles it internally whereas we 697*cdf0e10cSrcweir * want to handle it ourselves (as to sometimes not get 698*cdf0e10cSrcweir * the focus) 699*cdf0e10cSrcweir */ 700*cdf0e10cSrcweir Atom* pProtocols = NULL; 701*cdf0e10cSrcweir int nProtocols = 0; 702*cdf0e10cSrcweir XGetWMProtocols( pDisplay, 703*cdf0e10cSrcweir aWindow, 704*cdf0e10cSrcweir &pProtocols, &nProtocols ); 705*cdf0e10cSrcweir if( pProtocols ) 706*cdf0e10cSrcweir { 707*cdf0e10cSrcweir bool bSet = false; 708*cdf0e10cSrcweir Atom nTakeFocus = XInternAtom( pDisplay, "WM_TAKE_FOCUS", True ); 709*cdf0e10cSrcweir if( nTakeFocus ) 710*cdf0e10cSrcweir { 711*cdf0e10cSrcweir for( int i = 0; i < nProtocols; i++ ) 712*cdf0e10cSrcweir { 713*cdf0e10cSrcweir if( pProtocols[i] == nTakeFocus ) 714*cdf0e10cSrcweir { 715*cdf0e10cSrcweir for( int n = i; n < nProtocols-1; n++ ) 716*cdf0e10cSrcweir pProtocols[n] = pProtocols[n+1]; 717*cdf0e10cSrcweir nProtocols--; 718*cdf0e10cSrcweir i--; 719*cdf0e10cSrcweir bSet = true; 720*cdf0e10cSrcweir } 721*cdf0e10cSrcweir } 722*cdf0e10cSrcweir } 723*cdf0e10cSrcweir if( bSet ) 724*cdf0e10cSrcweir XSetWMProtocols( pDisplay, aWindow, pProtocols, nProtocols ); 725*cdf0e10cSrcweir XFree( pProtocols ); 726*cdf0e10cSrcweir } 727*cdf0e10cSrcweir } 728*cdf0e10cSrcweir } 729*cdf0e10cSrcweir static void lcl_set_user_time( GdkWindow* i_pWindow, guint32 i_nTime ) 730*cdf0e10cSrcweir { 731*cdf0e10cSrcweir if( bGetSetUserTimeFn ) 732*cdf0e10cSrcweir { 733*cdf0e10cSrcweir bGetSetUserTimeFn = false; 734*cdf0e10cSrcweir p_gdk_x11_window_set_user_time = (setUserTimeFn)osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gdk_x11_window_set_user_time" ); 735*cdf0e10cSrcweir } 736*cdf0e10cSrcweir if( p_gdk_x11_window_set_user_time ) 737*cdf0e10cSrcweir p_gdk_x11_window_set_user_time( i_pWindow, i_nTime ); 738*cdf0e10cSrcweir else 739*cdf0e10cSrcweir { 740*cdf0e10cSrcweir Display* pDisplay = GetX11SalData()->GetDisplay()->GetDisplay(); 741*cdf0e10cSrcweir XLIB_Window aWindow = GDK_WINDOW_XWINDOW( i_pWindow ); 742*cdf0e10cSrcweir Atom nUserTime = XInternAtom( pDisplay, "_NET_WM_USER_TIME", True ); 743*cdf0e10cSrcweir if( nUserTime ) 744*cdf0e10cSrcweir { 745*cdf0e10cSrcweir XChangeProperty( pDisplay, aWindow, 746*cdf0e10cSrcweir nUserTime, XA_CARDINAL, 32, 747*cdf0e10cSrcweir PropModeReplace, (unsigned char*)&i_nTime, 1 ); 748*cdf0e10cSrcweir } 749*cdf0e10cSrcweir } 750*cdf0e10cSrcweir }; 751*cdf0e10cSrcweir 752*cdf0e10cSrcweir GtkSalFrame *GtkSalFrame::getFromWindow( GtkWindow *pWindow ) 753*cdf0e10cSrcweir { 754*cdf0e10cSrcweir return (GtkSalFrame *) g_object_get_data( G_OBJECT( pWindow ), "SalFrame" ); 755*cdf0e10cSrcweir } 756*cdf0e10cSrcweir 757*cdf0e10cSrcweir void GtkSalFrame::Init( SalFrame* pParent, sal_uLong nStyle ) 758*cdf0e10cSrcweir { 759*cdf0e10cSrcweir if( nStyle & SAL_FRAME_STYLE_DEFAULT ) // ensure default style 760*cdf0e10cSrcweir { 761*cdf0e10cSrcweir nStyle |= SAL_FRAME_STYLE_MOVEABLE | SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_CLOSEABLE; 762*cdf0e10cSrcweir nStyle &= ~SAL_FRAME_STYLE_FLOAT; 763*cdf0e10cSrcweir } 764*cdf0e10cSrcweir 765*cdf0e10cSrcweir m_pParent = static_cast<GtkSalFrame*>(pParent); 766*cdf0e10cSrcweir m_pForeignParent = NULL; 767*cdf0e10cSrcweir m_aForeignParentWindow = None; 768*cdf0e10cSrcweir m_pForeignTopLevel = NULL; 769*cdf0e10cSrcweir m_aForeignTopLevelWindow = None; 770*cdf0e10cSrcweir m_nStyle = nStyle; 771*cdf0e10cSrcweir 772*cdf0e10cSrcweir GtkWindowType eWinType = ( (nStyle & SAL_FRAME_STYLE_FLOAT) && 773*cdf0e10cSrcweir ! (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION| 774*cdf0e10cSrcweir SAL_FRAME_STYLE_FLOAT_FOCUSABLE)) 775*cdf0e10cSrcweir ) 776*cdf0e10cSrcweir ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL; 777*cdf0e10cSrcweir 778*cdf0e10cSrcweir if( nStyle & SAL_FRAME_STYLE_SYSTEMCHILD ) 779*cdf0e10cSrcweir { 780*cdf0e10cSrcweir m_pWindow = gtk_event_box_new(); 781*cdf0e10cSrcweir if( m_pParent ) 782*cdf0e10cSrcweir { 783*cdf0e10cSrcweir // insert into container 784*cdf0e10cSrcweir gtk_fixed_put( m_pParent->getFixedContainer(), 785*cdf0e10cSrcweir m_pWindow, 0, 0 ); 786*cdf0e10cSrcweir 787*cdf0e10cSrcweir } 788*cdf0e10cSrcweir } 789*cdf0e10cSrcweir else 790*cdf0e10cSrcweir m_pWindow = gtk_widget_new( GTK_TYPE_WINDOW, "type", eWinType, "visible", FALSE, NULL ); 791*cdf0e10cSrcweir g_object_set_data( G_OBJECT( m_pWindow ), "SalFrame", this ); 792*cdf0e10cSrcweir 793*cdf0e10cSrcweir // force wm class hint 794*cdf0e10cSrcweir m_nExtStyle = ~0; 795*cdf0e10cSrcweir SetExtendedFrameStyle( 0 ); 796*cdf0e10cSrcweir 797*cdf0e10cSrcweir if( m_pParent && m_pParent->m_pWindow && ! isChild() ) 798*cdf0e10cSrcweir gtk_window_set_screen( GTK_WINDOW(m_pWindow), gtk_window_get_screen( GTK_WINDOW(m_pParent->m_pWindow) ) ); 799*cdf0e10cSrcweir 800*cdf0e10cSrcweir // set window type 801*cdf0e10cSrcweir bool bDecoHandling = 802*cdf0e10cSrcweir ! isChild() && 803*cdf0e10cSrcweir ( ! (nStyle & SAL_FRAME_STYLE_FLOAT) || 804*cdf0e10cSrcweir (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) ); 805*cdf0e10cSrcweir 806*cdf0e10cSrcweir if( bDecoHandling ) 807*cdf0e10cSrcweir { 808*cdf0e10cSrcweir bool bNoDecor = ! (nStyle & (SAL_FRAME_STYLE_MOVEABLE | SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_CLOSEABLE ) ); 809*cdf0e10cSrcweir GdkWindowTypeHint eType = GDK_WINDOW_TYPE_HINT_NORMAL; 810*cdf0e10cSrcweir if( (nStyle & SAL_FRAME_STYLE_DIALOG) && m_pParent != 0 ) 811*cdf0e10cSrcweir eType = GDK_WINDOW_TYPE_HINT_DIALOG; 812*cdf0e10cSrcweir if( (nStyle & SAL_FRAME_STYLE_INTRO) ) 813*cdf0e10cSrcweir { 814*cdf0e10cSrcweir gtk_window_set_role( GTK_WINDOW(m_pWindow), "splashscreen" ); 815*cdf0e10cSrcweir eType = GDK_WINDOW_TYPE_HINT_SPLASHSCREEN; 816*cdf0e10cSrcweir } 817*cdf0e10cSrcweir else if( (nStyle & SAL_FRAME_STYLE_TOOLWINDOW ) ) 818*cdf0e10cSrcweir { 819*cdf0e10cSrcweir eType = GDK_WINDOW_TYPE_HINT_UTILITY; 820*cdf0e10cSrcweir gtk_window_set_skip_taskbar_hint( GTK_WINDOW(m_pWindow), true ); 821*cdf0e10cSrcweir } 822*cdf0e10cSrcweir else if( (nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) 823*cdf0e10cSrcweir { 824*cdf0e10cSrcweir eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; 825*cdf0e10cSrcweir lcl_set_accept_focus( GTK_WINDOW(m_pWindow), sal_False, true ); 826*cdf0e10cSrcweir bNoDecor = true; 827*cdf0e10cSrcweir } 828*cdf0e10cSrcweir else if( (nStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) 829*cdf0e10cSrcweir { 830*cdf0e10cSrcweir eType = GDK_WINDOW_TYPE_HINT_UTILITY; 831*cdf0e10cSrcweir } 832*cdf0e10cSrcweir 833*cdf0e10cSrcweir if( (nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) 834*cdf0e10cSrcweir && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) 835*cdf0e10cSrcweir { 836*cdf0e10cSrcweir eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; 837*cdf0e10cSrcweir gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), true ); 838*cdf0e10cSrcweir } 839*cdf0e10cSrcweir 840*cdf0e10cSrcweir gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), eType ); 841*cdf0e10cSrcweir if( bNoDecor ) 842*cdf0e10cSrcweir gtk_window_set_decorated( GTK_WINDOW(m_pWindow), FALSE ); 843*cdf0e10cSrcweir gtk_window_set_gravity( GTK_WINDOW(m_pWindow), GDK_GRAVITY_STATIC ); 844*cdf0e10cSrcweir if( m_pParent && ! (m_pParent->m_nStyle & SAL_FRAME_STYLE_PLUG) ) 845*cdf0e10cSrcweir gtk_window_set_transient_for( GTK_WINDOW(m_pWindow), GTK_WINDOW(m_pParent->m_pWindow) ); 846*cdf0e10cSrcweir } 847*cdf0e10cSrcweir else if( (nStyle & SAL_FRAME_STYLE_FLOAT) ) 848*cdf0e10cSrcweir { 849*cdf0e10cSrcweir gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), GDK_WINDOW_TYPE_HINT_UTILITY ); 850*cdf0e10cSrcweir } 851*cdf0e10cSrcweir if( m_pParent ) 852*cdf0e10cSrcweir m_pParent->m_aChildren.push_back( this ); 853*cdf0e10cSrcweir 854*cdf0e10cSrcweir InitCommon(); 855*cdf0e10cSrcweir 856*cdf0e10cSrcweir if( eWinType == GTK_WINDOW_TOPLEVEL ) 857*cdf0e10cSrcweir { 858*cdf0e10cSrcweir guint32 nUserTime = 0; 859*cdf0e10cSrcweir if( (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_TOOLWINDOW)) == 0 ) 860*cdf0e10cSrcweir { 861*cdf0e10cSrcweir /* #i99360# ugly workaround an X11 library bug */ 862*cdf0e10cSrcweir nUserTime= getDisplay()->GetLastUserEventTime( true ); 863*cdf0e10cSrcweir // nUserTime = gdk_x11_get_server_time(GTK_WIDGET (m_pWindow)->window); 864*cdf0e10cSrcweir } 865*cdf0e10cSrcweir lcl_set_user_time(GTK_WIDGET(m_pWindow)->window, nUserTime); 866*cdf0e10cSrcweir } 867*cdf0e10cSrcweir 868*cdf0e10cSrcweir if( bDecoHandling ) 869*cdf0e10cSrcweir { 870*cdf0e10cSrcweir gtk_window_set_resizable( GTK_WINDOW(m_pWindow), (nStyle & SAL_FRAME_STYLE_SIZEABLE) ? sal_True : FALSE ); 871*cdf0e10cSrcweir if( ( (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION)) ) ) 872*cdf0e10cSrcweir lcl_set_accept_focus( GTK_WINDOW(m_pWindow), sal_False, false ); 873*cdf0e10cSrcweir } 874*cdf0e10cSrcweir 875*cdf0e10cSrcweir } 876*cdf0e10cSrcweir 877*cdf0e10cSrcweir GdkNativeWindow GtkSalFrame::findTopLevelSystemWindow( GdkNativeWindow aWindow ) 878*cdf0e10cSrcweir { 879*cdf0e10cSrcweir XLIB_Window aRoot, aParent; 880*cdf0e10cSrcweir XLIB_Window* pChildren; 881*cdf0e10cSrcweir unsigned int nChildren; 882*cdf0e10cSrcweir bool bBreak = false; 883*cdf0e10cSrcweir do 884*cdf0e10cSrcweir { 885*cdf0e10cSrcweir pChildren = NULL; 886*cdf0e10cSrcweir nChildren = 0; 887*cdf0e10cSrcweir aParent = aRoot = None; 888*cdf0e10cSrcweir XQueryTree( getDisplay()->GetDisplay(), aWindow, 889*cdf0e10cSrcweir &aRoot, &aParent, &pChildren, &nChildren ); 890*cdf0e10cSrcweir XFree( pChildren ); 891*cdf0e10cSrcweir if( aParent != aRoot ) 892*cdf0e10cSrcweir aWindow = aParent; 893*cdf0e10cSrcweir int nCount = 0; 894*cdf0e10cSrcweir Atom* pProps = XListProperties( getDisplay()->GetDisplay(), 895*cdf0e10cSrcweir aWindow, 896*cdf0e10cSrcweir &nCount ); 897*cdf0e10cSrcweir for( int i = 0; i < nCount && ! bBreak; ++i ) 898*cdf0e10cSrcweir bBreak = (pProps[i] == XA_WM_HINTS); 899*cdf0e10cSrcweir if( pProps ) 900*cdf0e10cSrcweir XFree( pProps ); 901*cdf0e10cSrcweir } while( aParent != aRoot && ! bBreak ); 902*cdf0e10cSrcweir 903*cdf0e10cSrcweir return aWindow; 904*cdf0e10cSrcweir } 905*cdf0e10cSrcweir 906*cdf0e10cSrcweir void GtkSalFrame::Init( SystemParentData* pSysData ) 907*cdf0e10cSrcweir { 908*cdf0e10cSrcweir m_pParent = NULL; 909*cdf0e10cSrcweir m_aForeignParentWindow = (GdkNativeWindow)pSysData->aWindow; 910*cdf0e10cSrcweir m_pForeignParent = NULL; 911*cdf0e10cSrcweir m_aForeignTopLevelWindow = findTopLevelSystemWindow( (GdkNativeWindow)pSysData->aWindow ); 912*cdf0e10cSrcweir m_pForeignTopLevel = gdk_window_foreign_new_for_display( getGdkDisplay(), m_aForeignTopLevelWindow ); 913*cdf0e10cSrcweir gdk_window_set_events( m_pForeignTopLevel, GDK_STRUCTURE_MASK ); 914*cdf0e10cSrcweir 915*cdf0e10cSrcweir if( pSysData->nSize > sizeof(pSysData->nSize)+sizeof(pSysData->aWindow) && pSysData->bXEmbedSupport ) 916*cdf0e10cSrcweir { 917*cdf0e10cSrcweir m_pWindow = gtk_plug_new( pSysData->aWindow ); 918*cdf0e10cSrcweir m_bWindowIsGtkPlug = true; 919*cdf0e10cSrcweir GTK_WIDGET_SET_FLAGS( m_pWindow, GTK_CAN_FOCUS | GTK_SENSITIVE | GTK_CAN_DEFAULT ); 920*cdf0e10cSrcweir gtk_widget_set_sensitive( m_pWindow, true ); 921*cdf0e10cSrcweir } 922*cdf0e10cSrcweir else 923*cdf0e10cSrcweir { 924*cdf0e10cSrcweir m_pWindow = gtk_window_new( GTK_WINDOW_POPUP ); 925*cdf0e10cSrcweir m_bWindowIsGtkPlug = false; 926*cdf0e10cSrcweir } 927*cdf0e10cSrcweir m_nStyle = SAL_FRAME_STYLE_PLUG; 928*cdf0e10cSrcweir InitCommon(); 929*cdf0e10cSrcweir 930*cdf0e10cSrcweir m_pForeignParent = gdk_window_foreign_new_for_display( getGdkDisplay(), m_aForeignParentWindow ); 931*cdf0e10cSrcweir gdk_window_set_events( m_pForeignParent, GDK_STRUCTURE_MASK ); 932*cdf0e10cSrcweir int x_ret, y_ret; 933*cdf0e10cSrcweir unsigned int w, h, bw, d; 934*cdf0e10cSrcweir XLIB_Window aRoot; 935*cdf0e10cSrcweir XGetGeometry( getDisplay()->GetDisplay(), pSysData->aWindow, 936*cdf0e10cSrcweir &aRoot, &x_ret, &y_ret, &w, &h, &bw, &d ); 937*cdf0e10cSrcweir maGeometry.nWidth = w; 938*cdf0e10cSrcweir maGeometry.nHeight = h; 939*cdf0e10cSrcweir gtk_window_resize( GTK_WINDOW(m_pWindow), w, h ); 940*cdf0e10cSrcweir gtk_window_move( GTK_WINDOW(m_pWindow), 0, 0 ); 941*cdf0e10cSrcweir if( ! m_bWindowIsGtkPlug ) 942*cdf0e10cSrcweir { 943*cdf0e10cSrcweir XReparentWindow( getDisplay()->GetDisplay(), 944*cdf0e10cSrcweir GDK_WINDOW_XWINDOW(m_pWindow->window), 945*cdf0e10cSrcweir (XLIB_Window)pSysData->aWindow, 946*cdf0e10cSrcweir 0, 0 ); 947*cdf0e10cSrcweir } 948*cdf0e10cSrcweir } 949*cdf0e10cSrcweir 950*cdf0e10cSrcweir void GtkSalFrame::askForXEmbedFocus( sal_Int32 i_nTimeCode ) 951*cdf0e10cSrcweir { 952*cdf0e10cSrcweir XEvent aEvent; 953*cdf0e10cSrcweir 954*cdf0e10cSrcweir rtl_zeroMemory( &aEvent, sizeof(aEvent) ); 955*cdf0e10cSrcweir aEvent.xclient.window = m_aForeignParentWindow; 956*cdf0e10cSrcweir aEvent.xclient.type = ClientMessage; 957*cdf0e10cSrcweir aEvent.xclient.message_type = getDisplay()->getWMAdaptor()->getAtom( vcl_sal::WMAdaptor::XEMBED ); 958*cdf0e10cSrcweir aEvent.xclient.format = 32; 959*cdf0e10cSrcweir aEvent.xclient.data.l[0] = i_nTimeCode ? i_nTimeCode : CurrentTime; 960*cdf0e10cSrcweir aEvent.xclient.data.l[1] = 3; // XEMBED_REQUEST_FOCUS 961*cdf0e10cSrcweir aEvent.xclient.data.l[2] = 0; 962*cdf0e10cSrcweir aEvent.xclient.data.l[3] = 0; 963*cdf0e10cSrcweir aEvent.xclient.data.l[4] = 0; 964*cdf0e10cSrcweir 965*cdf0e10cSrcweir getDisplay()->GetXLib()->PushXErrorLevel( true ); 966*cdf0e10cSrcweir XSendEvent( getDisplay()->GetDisplay(), 967*cdf0e10cSrcweir m_aForeignParentWindow, 968*cdf0e10cSrcweir False, NoEventMask, &aEvent ); 969*cdf0e10cSrcweir XSync( getDisplay()->GetDisplay(), False ); 970*cdf0e10cSrcweir getDisplay()->GetXLib()->PopXErrorLevel(); 971*cdf0e10cSrcweir } 972*cdf0e10cSrcweir 973*cdf0e10cSrcweir void GtkSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle ) 974*cdf0e10cSrcweir { 975*cdf0e10cSrcweir if( nStyle != m_nExtStyle && ! isChild() ) 976*cdf0e10cSrcweir { 977*cdf0e10cSrcweir m_nExtStyle = nStyle; 978*cdf0e10cSrcweir if( GTK_WIDGET_REALIZED( m_pWindow ) ) 979*cdf0e10cSrcweir { 980*cdf0e10cSrcweir XClassHint* pClass = XAllocClassHint(); 981*cdf0e10cSrcweir rtl::OString aResHint = X11SalData::getFrameResName( m_nExtStyle ); 982*cdf0e10cSrcweir pClass->res_name = const_cast<char*>(aResHint.getStr()); 983*cdf0e10cSrcweir pClass->res_class = const_cast<char*>(X11SalData::getFrameClassName()); 984*cdf0e10cSrcweir XSetClassHint( getDisplay()->GetDisplay(), 985*cdf0e10cSrcweir GDK_WINDOW_XWINDOW(m_pWindow->window), 986*cdf0e10cSrcweir pClass ); 987*cdf0e10cSrcweir XFree( pClass ); 988*cdf0e10cSrcweir } 989*cdf0e10cSrcweir else 990*cdf0e10cSrcweir gtk_window_set_wmclass( GTK_WINDOW(m_pWindow), 991*cdf0e10cSrcweir X11SalData::getFrameResName( m_nExtStyle ), 992*cdf0e10cSrcweir X11SalData::getFrameClassName() ); 993*cdf0e10cSrcweir } 994*cdf0e10cSrcweir } 995*cdf0e10cSrcweir 996*cdf0e10cSrcweir 997*cdf0e10cSrcweir SalGraphics* GtkSalFrame::GetGraphics() 998*cdf0e10cSrcweir { 999*cdf0e10cSrcweir if( m_pWindow ) 1000*cdf0e10cSrcweir { 1001*cdf0e10cSrcweir for( int i = 0; i < nMaxGraphics; i++ ) 1002*cdf0e10cSrcweir { 1003*cdf0e10cSrcweir if( ! m_aGraphics[i].bInUse ) 1004*cdf0e10cSrcweir { 1005*cdf0e10cSrcweir m_aGraphics[i].bInUse = true; 1006*cdf0e10cSrcweir if( ! m_aGraphics[i].pGraphics ) 1007*cdf0e10cSrcweir { 1008*cdf0e10cSrcweir m_aGraphics[i].pGraphics = new GtkSalGraphics( m_pWindow ); 1009*cdf0e10cSrcweir m_aGraphics[i].pGraphics->Init( this, GDK_WINDOW_XWINDOW(m_pWindow->window), m_nScreen ); 1010*cdf0e10cSrcweir } 1011*cdf0e10cSrcweir return m_aGraphics[i].pGraphics; 1012*cdf0e10cSrcweir } 1013*cdf0e10cSrcweir } 1014*cdf0e10cSrcweir } 1015*cdf0e10cSrcweir 1016*cdf0e10cSrcweir return NULL; 1017*cdf0e10cSrcweir } 1018*cdf0e10cSrcweir 1019*cdf0e10cSrcweir void GtkSalFrame::ReleaseGraphics( SalGraphics* pGraphics ) 1020*cdf0e10cSrcweir { 1021*cdf0e10cSrcweir for( int i = 0; i < nMaxGraphics; i++ ) 1022*cdf0e10cSrcweir { 1023*cdf0e10cSrcweir if( m_aGraphics[i].pGraphics == pGraphics ) 1024*cdf0e10cSrcweir { 1025*cdf0e10cSrcweir m_aGraphics[i].bInUse = false; 1026*cdf0e10cSrcweir break; 1027*cdf0e10cSrcweir } 1028*cdf0e10cSrcweir } 1029*cdf0e10cSrcweir } 1030*cdf0e10cSrcweir 1031*cdf0e10cSrcweir sal_Bool GtkSalFrame::PostEvent( void* pData ) 1032*cdf0e10cSrcweir { 1033*cdf0e10cSrcweir getDisplay()->SendInternalEvent( this, pData ); 1034*cdf0e10cSrcweir return sal_True; 1035*cdf0e10cSrcweir } 1036*cdf0e10cSrcweir 1037*cdf0e10cSrcweir void GtkSalFrame::SetTitle( const String& rTitle ) 1038*cdf0e10cSrcweir { 1039*cdf0e10cSrcweir m_aTitle = rTitle; 1040*cdf0e10cSrcweir if( m_pWindow && ! isChild() ) 1041*cdf0e10cSrcweir gtk_window_set_title( GTK_WINDOW(m_pWindow), rtl::OUStringToOString( rTitle, RTL_TEXTENCODING_UTF8 ).getStr() ); 1042*cdf0e10cSrcweir } 1043*cdf0e10cSrcweir 1044*cdf0e10cSrcweir static inline sal_uInt8 * 1045*cdf0e10cSrcweir getRow( BitmapBuffer *pBuffer, sal_uLong nRow ) 1046*cdf0e10cSrcweir { 1047*cdf0e10cSrcweir if( BMP_SCANLINE_ADJUSTMENT( pBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN ) 1048*cdf0e10cSrcweir return pBuffer->mpBits + nRow * pBuffer->mnScanlineSize; 1049*cdf0e10cSrcweir else 1050*cdf0e10cSrcweir return pBuffer->mpBits + ( pBuffer->mnHeight - nRow - 1 ) * pBuffer->mnScanlineSize; 1051*cdf0e10cSrcweir } 1052*cdf0e10cSrcweir 1053*cdf0e10cSrcweir static GdkPixbuf * 1054*cdf0e10cSrcweir bitmapToPixbuf( SalBitmap *pSalBitmap, SalBitmap *pSalAlpha ) 1055*cdf0e10cSrcweir { 1056*cdf0e10cSrcweir g_return_val_if_fail( pSalBitmap != NULL, NULL ); 1057*cdf0e10cSrcweir g_return_val_if_fail( pSalAlpha != NULL, NULL ); 1058*cdf0e10cSrcweir 1059*cdf0e10cSrcweir BitmapBuffer *pBitmap = pSalBitmap->AcquireBuffer( sal_True ); 1060*cdf0e10cSrcweir g_return_val_if_fail( pBitmap != NULL, NULL ); 1061*cdf0e10cSrcweir g_return_val_if_fail( pBitmap->mnBitCount == 24, NULL ); 1062*cdf0e10cSrcweir 1063*cdf0e10cSrcweir BitmapBuffer *pAlpha = pSalAlpha->AcquireBuffer( sal_True ); 1064*cdf0e10cSrcweir g_return_val_if_fail( pAlpha != NULL, NULL ); 1065*cdf0e10cSrcweir g_return_val_if_fail( pAlpha->mnBitCount == 8, NULL ); 1066*cdf0e10cSrcweir 1067*cdf0e10cSrcweir Size aSize = pSalBitmap->GetSize(); 1068*cdf0e10cSrcweir g_return_val_if_fail( pSalAlpha->GetSize() == aSize, NULL ); 1069*cdf0e10cSrcweir 1070*cdf0e10cSrcweir int nX, nY; 1071*cdf0e10cSrcweir guchar *pPixbufData = (guchar *)g_malloc (4 * aSize.Width() * aSize.Height() ); 1072*cdf0e10cSrcweir guchar *pDestData = pPixbufData; 1073*cdf0e10cSrcweir 1074*cdf0e10cSrcweir for( nY = 0; nY < pBitmap->mnHeight; nY++ ) 1075*cdf0e10cSrcweir { 1076*cdf0e10cSrcweir sal_uInt8 *pData = getRow( pBitmap, nY ); 1077*cdf0e10cSrcweir sal_uInt8 *pAlphaData = getRow( pAlpha, nY ); 1078*cdf0e10cSrcweir 1079*cdf0e10cSrcweir for( nX = 0; nX < pBitmap->mnWidth; nX++ ) 1080*cdf0e10cSrcweir { 1081*cdf0e10cSrcweir if( pBitmap->mnFormat == BMP_FORMAT_24BIT_TC_BGR ) 1082*cdf0e10cSrcweir { 1083*cdf0e10cSrcweir pDestData[2] = *pData++; 1084*cdf0e10cSrcweir pDestData[1] = *pData++; 1085*cdf0e10cSrcweir pDestData[0] = *pData++; 1086*cdf0e10cSrcweir } 1087*cdf0e10cSrcweir else // BMP_FORMAT_24BIT_TC_RGB 1088*cdf0e10cSrcweir { 1089*cdf0e10cSrcweir pDestData[0] = *pData++; 1090*cdf0e10cSrcweir pDestData[1] = *pData++; 1091*cdf0e10cSrcweir pDestData[2] = *pData++; 1092*cdf0e10cSrcweir } 1093*cdf0e10cSrcweir pDestData += 3; 1094*cdf0e10cSrcweir *pDestData++ = 255 - *pAlphaData++; 1095*cdf0e10cSrcweir } 1096*cdf0e10cSrcweir } 1097*cdf0e10cSrcweir 1098*cdf0e10cSrcweir pSalBitmap->ReleaseBuffer( pBitmap, sal_True ); 1099*cdf0e10cSrcweir pSalAlpha->ReleaseBuffer( pAlpha, sal_True ); 1100*cdf0e10cSrcweir 1101*cdf0e10cSrcweir return gdk_pixbuf_new_from_data( pPixbufData, 1102*cdf0e10cSrcweir GDK_COLORSPACE_RGB, sal_True, 8, 1103*cdf0e10cSrcweir aSize.Width(), aSize.Height(), 1104*cdf0e10cSrcweir aSize.Width() * 4, 1105*cdf0e10cSrcweir (GdkPixbufDestroyNotify) g_free, 1106*cdf0e10cSrcweir NULL ); 1107*cdf0e10cSrcweir } 1108*cdf0e10cSrcweir 1109*cdf0e10cSrcweir void GtkSalFrame::SetIcon( sal_uInt16 nIcon ) 1110*cdf0e10cSrcweir { 1111*cdf0e10cSrcweir if( (m_nStyle & (SAL_FRAME_STYLE_PLUG|SAL_FRAME_STYLE_SYSTEMCHILD|SAL_FRAME_STYLE_FLOAT|SAL_FRAME_STYLE_INTRO|SAL_FRAME_STYLE_OWNERDRAWDECORATION)) 1112*cdf0e10cSrcweir || ! m_pWindow ) 1113*cdf0e10cSrcweir return; 1114*cdf0e10cSrcweir 1115*cdf0e10cSrcweir if( !ImplGetResMgr() ) 1116*cdf0e10cSrcweir return; 1117*cdf0e10cSrcweir 1118*cdf0e10cSrcweir GdkPixbuf *pBuf; 1119*cdf0e10cSrcweir GList *pIcons = NULL; 1120*cdf0e10cSrcweir 1121*cdf0e10cSrcweir sal_uInt16 nOffsets[2] = { SV_ICON_SMALL_START, SV_ICON_LARGE_START }; 1122*cdf0e10cSrcweir sal_uInt16 nIndex; 1123*cdf0e10cSrcweir 1124*cdf0e10cSrcweir // Use high contrast icons where appropriate 1125*cdf0e10cSrcweir if( Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 1126*cdf0e10cSrcweir { 1127*cdf0e10cSrcweir nOffsets[0] = SV_ICON_LARGE_HC_START; 1128*cdf0e10cSrcweir nOffsets[1] = SV_ICON_SMALL_HC_START; 1129*cdf0e10cSrcweir } 1130*cdf0e10cSrcweir 1131*cdf0e10cSrcweir for( nIndex = 0; nIndex < sizeof(nOffsets)/ sizeof(sal_uInt16); nIndex++ ) 1132*cdf0e10cSrcweir { 1133*cdf0e10cSrcweir // #i44723# workaround gcc temporary problem 1134*cdf0e10cSrcweir ResId aResId( nOffsets[nIndex] + nIcon, *ImplGetResMgr() ); 1135*cdf0e10cSrcweir BitmapEx aIcon( aResId ); 1136*cdf0e10cSrcweir 1137*cdf0e10cSrcweir // #i81083# convert to 24bit/8bit alpha bitmap 1138*cdf0e10cSrcweir Bitmap aBmp = aIcon.GetBitmap(); 1139*cdf0e10cSrcweir if( aBmp.GetBitCount() != 24 || ! aIcon.IsAlpha() ) 1140*cdf0e10cSrcweir { 1141*cdf0e10cSrcweir if( aBmp.GetBitCount() != 24 ) 1142*cdf0e10cSrcweir aBmp.Convert( BMP_CONVERSION_24BIT ); 1143*cdf0e10cSrcweir AlphaMask aMask; 1144*cdf0e10cSrcweir if( ! aIcon.IsAlpha() ) 1145*cdf0e10cSrcweir { 1146*cdf0e10cSrcweir switch( aIcon.GetTransparentType() ) 1147*cdf0e10cSrcweir { 1148*cdf0e10cSrcweir case TRANSPARENT_NONE: 1149*cdf0e10cSrcweir { 1150*cdf0e10cSrcweir sal_uInt8 nTrans = 0; 1151*cdf0e10cSrcweir aMask = AlphaMask( aBmp.GetSizePixel(), &nTrans ); 1152*cdf0e10cSrcweir } 1153*cdf0e10cSrcweir break; 1154*cdf0e10cSrcweir case TRANSPARENT_COLOR: 1155*cdf0e10cSrcweir aMask = AlphaMask( aBmp.CreateMask( aIcon.GetTransparentColor() ) ); 1156*cdf0e10cSrcweir break; 1157*cdf0e10cSrcweir case TRANSPARENT_BITMAP: 1158*cdf0e10cSrcweir aMask = AlphaMask( aIcon.GetMask() ); 1159*cdf0e10cSrcweir break; 1160*cdf0e10cSrcweir default: 1161*cdf0e10cSrcweir DBG_ERROR( "unhandled transparent type" ); 1162*cdf0e10cSrcweir break; 1163*cdf0e10cSrcweir } 1164*cdf0e10cSrcweir } 1165*cdf0e10cSrcweir else 1166*cdf0e10cSrcweir aMask = aIcon.GetAlpha(); 1167*cdf0e10cSrcweir aIcon = BitmapEx( aBmp, aMask ); 1168*cdf0e10cSrcweir } 1169*cdf0e10cSrcweir 1170*cdf0e10cSrcweir ImpBitmap *pIconImpBitmap = aIcon.ImplGetBitmapImpBitmap(); 1171*cdf0e10cSrcweir ImpBitmap *pIconImpMask = aIcon.ImplGetMaskImpBitmap(); 1172*cdf0e10cSrcweir 1173*cdf0e10cSrcweir 1174*cdf0e10cSrcweir if( pIconImpBitmap && pIconImpMask ) 1175*cdf0e10cSrcweir { 1176*cdf0e10cSrcweir SalBitmap *pIconBitmap = 1177*cdf0e10cSrcweir pIconImpBitmap->ImplGetSalBitmap(); 1178*cdf0e10cSrcweir SalBitmap *pIconMask = 1179*cdf0e10cSrcweir pIconImpMask->ImplGetSalBitmap(); 1180*cdf0e10cSrcweir 1181*cdf0e10cSrcweir if( ( pBuf = bitmapToPixbuf( pIconBitmap, pIconMask ) ) ) 1182*cdf0e10cSrcweir pIcons = g_list_prepend( pIcons, pBuf ); 1183*cdf0e10cSrcweir } 1184*cdf0e10cSrcweir } 1185*cdf0e10cSrcweir 1186*cdf0e10cSrcweir gtk_window_set_icon_list( GTK_WINDOW(m_pWindow), pIcons ); 1187*cdf0e10cSrcweir 1188*cdf0e10cSrcweir g_list_foreach( pIcons, (GFunc) g_object_unref, NULL ); 1189*cdf0e10cSrcweir g_list_free( pIcons ); 1190*cdf0e10cSrcweir } 1191*cdf0e10cSrcweir 1192*cdf0e10cSrcweir void GtkSalFrame::SetMenu( SalMenu* ) 1193*cdf0e10cSrcweir { 1194*cdf0e10cSrcweir } 1195*cdf0e10cSrcweir 1196*cdf0e10cSrcweir void GtkSalFrame::DrawMenuBar() 1197*cdf0e10cSrcweir { 1198*cdf0e10cSrcweir } 1199*cdf0e10cSrcweir 1200*cdf0e10cSrcweir void GtkSalFrame::Center() 1201*cdf0e10cSrcweir { 1202*cdf0e10cSrcweir long nX, nY; 1203*cdf0e10cSrcweir 1204*cdf0e10cSrcweir if( m_pParent ) 1205*cdf0e10cSrcweir { 1206*cdf0e10cSrcweir nX = ((long)m_pParent->maGeometry.nWidth - (long)maGeometry.nWidth)/2; 1207*cdf0e10cSrcweir nY = ((long)m_pParent->maGeometry.nHeight - (long)maGeometry.nHeight)/2; 1208*cdf0e10cSrcweir 1209*cdf0e10cSrcweir } 1210*cdf0e10cSrcweir else 1211*cdf0e10cSrcweir { 1212*cdf0e10cSrcweir long nScreenWidth, nScreenHeight; 1213*cdf0e10cSrcweir long nScreenX = 0, nScreenY = 0; 1214*cdf0e10cSrcweir 1215*cdf0e10cSrcweir Size aScreenSize = GetX11SalData()->GetDisplay()->GetScreenSize( m_nScreen ); 1216*cdf0e10cSrcweir nScreenWidth = aScreenSize.Width(); 1217*cdf0e10cSrcweir nScreenHeight = aScreenSize.Height(); 1218*cdf0e10cSrcweir if( GetX11SalData()->GetDisplay()->IsXinerama() ) 1219*cdf0e10cSrcweir { 1220*cdf0e10cSrcweir // get xinerama screen we are on 1221*cdf0e10cSrcweir // if there is a parent, use its center for screen determination 1222*cdf0e10cSrcweir // else use the pointer 1223*cdf0e10cSrcweir GdkScreen* pScreen; 1224*cdf0e10cSrcweir gint x, y; 1225*cdf0e10cSrcweir GdkModifierType aMask; 1226*cdf0e10cSrcweir gdk_display_get_pointer( getGdkDisplay(), &pScreen, &x, &y, &aMask ); 1227*cdf0e10cSrcweir 1228*cdf0e10cSrcweir const std::vector< Rectangle >& rScreens = GetX11SalData()->GetDisplay()->GetXineramaScreens(); 1229*cdf0e10cSrcweir for( unsigned int i = 0; i < rScreens.size(); i++ ) 1230*cdf0e10cSrcweir if( rScreens[i].IsInside( Point( x, y ) ) ) 1231*cdf0e10cSrcweir { 1232*cdf0e10cSrcweir nScreenX = rScreens[i].Left(); 1233*cdf0e10cSrcweir nScreenY = rScreens[i].Top(); 1234*cdf0e10cSrcweir nScreenWidth = rScreens[i].GetWidth(); 1235*cdf0e10cSrcweir nScreenHeight = rScreens[i].GetHeight(); 1236*cdf0e10cSrcweir break; 1237*cdf0e10cSrcweir } 1238*cdf0e10cSrcweir } 1239*cdf0e10cSrcweir nX = nScreenX + (nScreenWidth - (long)maGeometry.nWidth)/2; 1240*cdf0e10cSrcweir nY = nScreenY + (nScreenHeight - (long)maGeometry.nHeight)/2; 1241*cdf0e10cSrcweir } 1242*cdf0e10cSrcweir SetPosSize( nX, nY, 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ); 1243*cdf0e10cSrcweir } 1244*cdf0e10cSrcweir 1245*cdf0e10cSrcweir Size GtkSalFrame::calcDefaultSize() 1246*cdf0e10cSrcweir { 1247*cdf0e10cSrcweir Size aScreenSize = GetX11SalData()->GetDisplay()->GetScreenSize( m_nScreen ); 1248*cdf0e10cSrcweir long w = aScreenSize.Width(); 1249*cdf0e10cSrcweir long h = aScreenSize.Height(); 1250*cdf0e10cSrcweir 1251*cdf0e10cSrcweir // fill in holy default values brought to us by product management 1252*cdf0e10cSrcweir if( aScreenSize.Width() >= 800 ) 1253*cdf0e10cSrcweir w = 785; 1254*cdf0e10cSrcweir if( aScreenSize.Width() >= 1024 ) 1255*cdf0e10cSrcweir w = 920; 1256*cdf0e10cSrcweir 1257*cdf0e10cSrcweir if( aScreenSize.Height() >= 600 ) 1258*cdf0e10cSrcweir h = 550; 1259*cdf0e10cSrcweir if( aScreenSize.Height() >= 768 ) 1260*cdf0e10cSrcweir h = 630; 1261*cdf0e10cSrcweir if( aScreenSize.Height() >= 1024 ) 1262*cdf0e10cSrcweir h = 875; 1263*cdf0e10cSrcweir 1264*cdf0e10cSrcweir return Size( w, h ); 1265*cdf0e10cSrcweir } 1266*cdf0e10cSrcweir 1267*cdf0e10cSrcweir void GtkSalFrame::SetDefaultSize() 1268*cdf0e10cSrcweir { 1269*cdf0e10cSrcweir Size aDefSize = calcDefaultSize(); 1270*cdf0e10cSrcweir 1271*cdf0e10cSrcweir SetPosSize( 0, 0, aDefSize.Width(), aDefSize.Height(), 1272*cdf0e10cSrcweir SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT ); 1273*cdf0e10cSrcweir 1274*cdf0e10cSrcweir if( (m_nStyle & SAL_FRAME_STYLE_DEFAULT) && m_pWindow ) 1275*cdf0e10cSrcweir gtk_window_maximize( GTK_WINDOW(m_pWindow) ); 1276*cdf0e10cSrcweir } 1277*cdf0e10cSrcweir 1278*cdf0e10cSrcweir static void initClientId() 1279*cdf0e10cSrcweir { 1280*cdf0e10cSrcweir static bool bOnce = false; 1281*cdf0e10cSrcweir if( ! bOnce ) 1282*cdf0e10cSrcweir { 1283*cdf0e10cSrcweir bOnce = true; 1284*cdf0e10cSrcweir const ByteString& rID = SessionManagerClient::getSessionID(); 1285*cdf0e10cSrcweir if( rID.Len() > 0 ) 1286*cdf0e10cSrcweir gdk_set_sm_client_id(rID.GetBuffer()); 1287*cdf0e10cSrcweir } 1288*cdf0e10cSrcweir } 1289*cdf0e10cSrcweir 1290*cdf0e10cSrcweir void GtkSalFrame::Show( sal_Bool bVisible, sal_Bool bNoActivate ) 1291*cdf0e10cSrcweir { 1292*cdf0e10cSrcweir if( m_pWindow ) 1293*cdf0e10cSrcweir { 1294*cdf0e10cSrcweir if( m_pParent && (m_pParent->m_nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) 1295*cdf0e10cSrcweir && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) 1296*cdf0e10cSrcweir gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), bVisible ); 1297*cdf0e10cSrcweir if( bVisible ) 1298*cdf0e10cSrcweir { 1299*cdf0e10cSrcweir SessionManagerClient::open(); // will simply return after the first time 1300*cdf0e10cSrcweir initClientId(); 1301*cdf0e10cSrcweir getDisplay()->startupNotificationCompleted(); 1302*cdf0e10cSrcweir 1303*cdf0e10cSrcweir if( m_bDefaultPos ) 1304*cdf0e10cSrcweir Center(); 1305*cdf0e10cSrcweir if( m_bDefaultSize ) 1306*cdf0e10cSrcweir SetDefaultSize(); 1307*cdf0e10cSrcweir setMinMaxSize(); 1308*cdf0e10cSrcweir 1309*cdf0e10cSrcweir // #i45160# switch to desktop where a dialog with parent will appear 1310*cdf0e10cSrcweir if( m_pParent && m_pParent->m_nWorkArea != m_nWorkArea && GTK_WIDGET_MAPPED(m_pParent->m_pWindow) ) 1311*cdf0e10cSrcweir getDisplay()->getWMAdaptor()->switchToWorkArea( m_pParent->m_nWorkArea ); 1312*cdf0e10cSrcweir 1313*cdf0e10cSrcweir if( isFloatGrabWindow() && 1314*cdf0e10cSrcweir m_pParent && 1315*cdf0e10cSrcweir m_nFloats == 0 && 1316*cdf0e10cSrcweir ! getDisplay()->GetCaptureFrame() ) 1317*cdf0e10cSrcweir { 1318*cdf0e10cSrcweir /* #i63086# 1319*cdf0e10cSrcweir * outsmart Metacity's "focus:mouse" mode 1320*cdf0e10cSrcweir * which insists on taking the focus from the document 1321*cdf0e10cSrcweir * to the new float. Grab focus to parent frame BEFORE 1322*cdf0e10cSrcweir * showing the float (cannot grab it to the float 1323*cdf0e10cSrcweir * before show). 1324*cdf0e10cSrcweir */ 1325*cdf0e10cSrcweir m_pParent->grabPointer( sal_True, sal_True ); 1326*cdf0e10cSrcweir } 1327*cdf0e10cSrcweir 1328*cdf0e10cSrcweir guint32 nUserTime = 0; 1329*cdf0e10cSrcweir if( ! bNoActivate && (m_nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_TOOLWINDOW)) == 0 ) 1330*cdf0e10cSrcweir /* #i99360# ugly workaround an X11 library bug */ 1331*cdf0e10cSrcweir nUserTime= getDisplay()->GetLastUserEventTime( true ); 1332*cdf0e10cSrcweir //nUserTime = gdk_x11_get_server_time(GTK_WIDGET (m_pWindow)->window); 1333*cdf0e10cSrcweir 1334*cdf0e10cSrcweir //For these floating windows we don't want the main window to lose focus, and metacity has... 1335*cdf0e10cSrcweir // metacity-2.24.0/src/core/window.c 1336*cdf0e10cSrcweir // 1337*cdf0e10cSrcweir // if ((focus_window != NULL) && XSERVER_TIME_IS_BEFORE (compare, focus_window->net_wm_user_time)) 1338*cdf0e10cSrcweir // "compare" window focus prevented by other activity 1339*cdf0e10cSrcweir // 1340*cdf0e10cSrcweir // where "compare" is this window 1341*cdf0e10cSrcweir 1342*cdf0e10cSrcweir // which leads to... 1343*cdf0e10cSrcweir 1344*cdf0e10cSrcweir // /* This happens for error dialogs or alerts; these need to remain on 1345*cdf0e10cSrcweir // * top, but it would be confusing to have its ancestor remain 1346*cdf0e10cSrcweir // * focused. 1347*cdf0e10cSrcweir // */ 1348*cdf0e10cSrcweir // if (meta_window_is_ancestor_of_transient (focus_window, window)) 1349*cdf0e10cSrcweir // "The focus window %s is an ancestor of the newly mapped " 1350*cdf0e10cSrcweir // "window %s which isn't being focused. Unfocusing the " 1351*cdf0e10cSrcweir // "ancestor.\n", 1352*cdf0e10cSrcweir // 1353*cdf0e10cSrcweir // i.e. having a time < that of the toplevel frame means that the toplevel frame gets unfocused. 1354*cdf0e10cSrcweir // awesome. 1355*cdf0e10cSrcweir if( nUserTime == 0 ) 1356*cdf0e10cSrcweir { 1357*cdf0e10cSrcweir /* #i99360# ugly workaround an X11 library bug */ 1358*cdf0e10cSrcweir nUserTime= getDisplay()->GetLastUserEventTime( true ); 1359*cdf0e10cSrcweir //nUserTime = gdk_x11_get_server_time(GTK_WIDGET (m_pWindow)->window); 1360*cdf0e10cSrcweir } 1361*cdf0e10cSrcweir lcl_set_user_time( GTK_WIDGET(m_pWindow)->window, nUserTime ); 1362*cdf0e10cSrcweir 1363*cdf0e10cSrcweir if( ! bNoActivate && (m_nStyle & SAL_FRAME_STYLE_TOOLWINDOW) ) 1364*cdf0e10cSrcweir m_bSetFocusOnMap = true; 1365*cdf0e10cSrcweir 1366*cdf0e10cSrcweir gtk_widget_show( m_pWindow ); 1367*cdf0e10cSrcweir 1368*cdf0e10cSrcweir if( isFloatGrabWindow() ) 1369*cdf0e10cSrcweir { 1370*cdf0e10cSrcweir m_nFloats++; 1371*cdf0e10cSrcweir if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 1 ) 1372*cdf0e10cSrcweir grabPointer( sal_True, sal_True ); 1373*cdf0e10cSrcweir // #i44068# reset parent's IM context 1374*cdf0e10cSrcweir if( m_pParent ) 1375*cdf0e10cSrcweir m_pParent->EndExtTextInput(0); 1376*cdf0e10cSrcweir } 1377*cdf0e10cSrcweir if( m_bWindowIsGtkPlug ) 1378*cdf0e10cSrcweir askForXEmbedFocus( 0 ); 1379*cdf0e10cSrcweir } 1380*cdf0e10cSrcweir else 1381*cdf0e10cSrcweir { 1382*cdf0e10cSrcweir if( isFloatGrabWindow() ) 1383*cdf0e10cSrcweir { 1384*cdf0e10cSrcweir m_nFloats--; 1385*cdf0e10cSrcweir if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 0) 1386*cdf0e10cSrcweir grabPointer( sal_False ); 1387*cdf0e10cSrcweir } 1388*cdf0e10cSrcweir gtk_widget_hide( m_pWindow ); 1389*cdf0e10cSrcweir if( m_pIMHandler ) 1390*cdf0e10cSrcweir m_pIMHandler->focusChanged( false ); 1391*cdf0e10cSrcweir // flush here; there may be a very seldom race between 1392*cdf0e10cSrcweir // the display connection used for clipboard and our connection 1393*cdf0e10cSrcweir Flush(); 1394*cdf0e10cSrcweir } 1395*cdf0e10cSrcweir CallCallback( SALEVENT_RESIZE, NULL ); 1396*cdf0e10cSrcweir } 1397*cdf0e10cSrcweir } 1398*cdf0e10cSrcweir 1399*cdf0e10cSrcweir void GtkSalFrame::Enable( sal_Bool /*bEnable*/ ) 1400*cdf0e10cSrcweir { 1401*cdf0e10cSrcweir // Not implemented by X11SalFrame either 1402*cdf0e10cSrcweir } 1403*cdf0e10cSrcweir 1404*cdf0e10cSrcweir void GtkSalFrame::setMinMaxSize() 1405*cdf0e10cSrcweir { 1406*cdf0e10cSrcweir /* FIXME: for yet unknown reasons the reported size is a little smaller 1407*cdf0e10cSrcweir * than the max size hint; one would guess that this was due to the border 1408*cdf0e10cSrcweir * sizes of the widgets involved (GtkWindow and GtkFixed), but setting the 1409*cdf0e10cSrcweir * their border to 0 (which is the default anyway) does not change the 1410*cdf0e10cSrcweir * behaviour. Until the reason is known we'll add some pixels here. 1411*cdf0e10cSrcweir */ 1412*cdf0e10cSrcweir #define CONTAINER_ADJUSTMENT 6 1413*cdf0e10cSrcweir 1414*cdf0e10cSrcweir /* #i34504# metacity (and possibly others) do not treat 1415*cdf0e10cSrcweir * _NET_WM_STATE_FULLSCREEN and max_width/heigth independently; 1416*cdf0e10cSrcweir * whether they should is undefined. So don't set the max size hint 1417*cdf0e10cSrcweir * for a full screen window. 1418*cdf0e10cSrcweir */ 1419*cdf0e10cSrcweir if( m_pWindow && ! isChild() ) 1420*cdf0e10cSrcweir { 1421*cdf0e10cSrcweir GdkGeometry aGeo; 1422*cdf0e10cSrcweir int aHints = 0; 1423*cdf0e10cSrcweir if( m_nStyle & SAL_FRAME_STYLE_SIZEABLE ) 1424*cdf0e10cSrcweir { 1425*cdf0e10cSrcweir if( m_aMinSize.Width() && m_aMinSize.Height() ) 1426*cdf0e10cSrcweir { 1427*cdf0e10cSrcweir aGeo.min_width = m_aMinSize.Width()+CONTAINER_ADJUSTMENT; 1428*cdf0e10cSrcweir aGeo.min_height = m_aMinSize.Height()+CONTAINER_ADJUSTMENT; 1429*cdf0e10cSrcweir aHints |= GDK_HINT_MIN_SIZE; 1430*cdf0e10cSrcweir } 1431*cdf0e10cSrcweir if( m_aMaxSize.Width() && m_aMaxSize.Height() && ! m_bFullscreen ) 1432*cdf0e10cSrcweir { 1433*cdf0e10cSrcweir aGeo.max_width = m_aMaxSize.Width()+CONTAINER_ADJUSTMENT; 1434*cdf0e10cSrcweir aGeo.max_height = m_aMaxSize.Height()+CONTAINER_ADJUSTMENT; 1435*cdf0e10cSrcweir aHints |= GDK_HINT_MAX_SIZE; 1436*cdf0e10cSrcweir } 1437*cdf0e10cSrcweir } 1438*cdf0e10cSrcweir else 1439*cdf0e10cSrcweir { 1440*cdf0e10cSrcweir aGeo.min_width = maGeometry.nWidth; 1441*cdf0e10cSrcweir aGeo.min_height = maGeometry.nHeight; 1442*cdf0e10cSrcweir aHints |= GDK_HINT_MIN_SIZE; 1443*cdf0e10cSrcweir if( ! m_bFullscreen ) 1444*cdf0e10cSrcweir { 1445*cdf0e10cSrcweir aGeo.max_width = maGeometry.nWidth; 1446*cdf0e10cSrcweir aGeo.max_height = maGeometry.nHeight; 1447*cdf0e10cSrcweir aHints |= GDK_HINT_MAX_SIZE; 1448*cdf0e10cSrcweir } 1449*cdf0e10cSrcweir } 1450*cdf0e10cSrcweir if( m_bFullscreen && m_aMaxSize.Width() && m_aMaxSize.Height() ) 1451*cdf0e10cSrcweir { 1452*cdf0e10cSrcweir aGeo.max_width = m_aMaxSize.Width(); 1453*cdf0e10cSrcweir aGeo.max_height = m_aMaxSize.Height(); 1454*cdf0e10cSrcweir aHints |= GDK_HINT_MAX_SIZE; 1455*cdf0e10cSrcweir } 1456*cdf0e10cSrcweir if( aHints ) 1457*cdf0e10cSrcweir gtk_window_set_geometry_hints( GTK_WINDOW(m_pWindow), 1458*cdf0e10cSrcweir NULL, 1459*cdf0e10cSrcweir &aGeo, 1460*cdf0e10cSrcweir GdkWindowHints( aHints ) ); 1461*cdf0e10cSrcweir } 1462*cdf0e10cSrcweir } 1463*cdf0e10cSrcweir 1464*cdf0e10cSrcweir void GtkSalFrame::SetMaxClientSize( long nWidth, long nHeight ) 1465*cdf0e10cSrcweir { 1466*cdf0e10cSrcweir if( ! isChild() ) 1467*cdf0e10cSrcweir { 1468*cdf0e10cSrcweir m_aMaxSize = Size( nWidth, nHeight ); 1469*cdf0e10cSrcweir // Show does a setMinMaxSize 1470*cdf0e10cSrcweir if( GTK_WIDGET_MAPPED( m_pWindow ) ) 1471*cdf0e10cSrcweir setMinMaxSize(); 1472*cdf0e10cSrcweir } 1473*cdf0e10cSrcweir } 1474*cdf0e10cSrcweir void GtkSalFrame::SetMinClientSize( long nWidth, long nHeight ) 1475*cdf0e10cSrcweir { 1476*cdf0e10cSrcweir if( ! isChild() ) 1477*cdf0e10cSrcweir { 1478*cdf0e10cSrcweir m_aMinSize = Size( nWidth, nHeight ); 1479*cdf0e10cSrcweir if( m_pWindow ) 1480*cdf0e10cSrcweir { 1481*cdf0e10cSrcweir gtk_widget_set_size_request( m_pWindow, nWidth, nHeight ); 1482*cdf0e10cSrcweir // Show does a setMinMaxSize 1483*cdf0e10cSrcweir if( GTK_WIDGET_MAPPED( m_pWindow ) ) 1484*cdf0e10cSrcweir setMinMaxSize(); 1485*cdf0e10cSrcweir } 1486*cdf0e10cSrcweir } 1487*cdf0e10cSrcweir } 1488*cdf0e10cSrcweir 1489*cdf0e10cSrcweir void GtkSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags ) 1490*cdf0e10cSrcweir { 1491*cdf0e10cSrcweir if( !m_pWindow || isChild( true, false ) ) 1492*cdf0e10cSrcweir return; 1493*cdf0e10cSrcweir 1494*cdf0e10cSrcweir bool bSized = false, bMoved = false; 1495*cdf0e10cSrcweir 1496*cdf0e10cSrcweir if( (nFlags & ( SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT )) && 1497*cdf0e10cSrcweir (nWidth > 0 && nHeight > 0 ) // sometimes stupid things happen 1498*cdf0e10cSrcweir ) 1499*cdf0e10cSrcweir { 1500*cdf0e10cSrcweir m_bDefaultSize = false; 1501*cdf0e10cSrcweir 1502*cdf0e10cSrcweir if( (unsigned long)nWidth != maGeometry.nWidth || (unsigned long)nHeight != maGeometry.nHeight ) 1503*cdf0e10cSrcweir bSized = true; 1504*cdf0e10cSrcweir maGeometry.nWidth = nWidth; 1505*cdf0e10cSrcweir maGeometry.nHeight = nHeight; 1506*cdf0e10cSrcweir 1507*cdf0e10cSrcweir if( isChild( false, true ) ) 1508*cdf0e10cSrcweir gtk_widget_set_size_request( m_pWindow, nWidth, nHeight ); 1509*cdf0e10cSrcweir else if( ! ( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) ) 1510*cdf0e10cSrcweir gtk_window_resize( GTK_WINDOW(m_pWindow), nWidth, nHeight ); 1511*cdf0e10cSrcweir setMinMaxSize(); 1512*cdf0e10cSrcweir } 1513*cdf0e10cSrcweir else if( m_bDefaultSize ) 1514*cdf0e10cSrcweir SetDefaultSize(); 1515*cdf0e10cSrcweir 1516*cdf0e10cSrcweir m_bDefaultSize = false; 1517*cdf0e10cSrcweir 1518*cdf0e10cSrcweir if( nFlags & ( SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ) ) 1519*cdf0e10cSrcweir { 1520*cdf0e10cSrcweir if( m_pParent ) 1521*cdf0e10cSrcweir { 1522*cdf0e10cSrcweir if( Application::GetSettings().GetLayoutRTL() ) 1523*cdf0e10cSrcweir nX = m_pParent->maGeometry.nWidth-maGeometry.nWidth-1-nX; 1524*cdf0e10cSrcweir nX += m_pParent->maGeometry.nX; 1525*cdf0e10cSrcweir nY += m_pParent->maGeometry.nY; 1526*cdf0e10cSrcweir } 1527*cdf0e10cSrcweir 1528*cdf0e10cSrcweir // adjust position to avoid off screen windows 1529*cdf0e10cSrcweir // but allow toolbars to be positioned partly off screen by the user 1530*cdf0e10cSrcweir Size aScreenSize = GetX11SalData()->GetDisplay()->GetScreenSize( m_nScreen ); 1531*cdf0e10cSrcweir if( ! (m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) 1532*cdf0e10cSrcweir { 1533*cdf0e10cSrcweir if( nX < (long)maGeometry.nLeftDecoration ) 1534*cdf0e10cSrcweir nX = maGeometry.nLeftDecoration; 1535*cdf0e10cSrcweir if( nY < (long)maGeometry.nTopDecoration ) 1536*cdf0e10cSrcweir nY = maGeometry.nTopDecoration; 1537*cdf0e10cSrcweir if( (nX + (long)maGeometry.nWidth + (long)maGeometry.nRightDecoration) > (long)aScreenSize.Width() ) 1538*cdf0e10cSrcweir nX = aScreenSize.Width() - maGeometry.nWidth - maGeometry.nRightDecoration; 1539*cdf0e10cSrcweir if( (nY + (long)maGeometry.nHeight + (long)maGeometry.nBottomDecoration) > (long)aScreenSize.Height() ) 1540*cdf0e10cSrcweir nY = aScreenSize.Height() - maGeometry.nHeight - maGeometry.nBottomDecoration; 1541*cdf0e10cSrcweir } 1542*cdf0e10cSrcweir else 1543*cdf0e10cSrcweir { 1544*cdf0e10cSrcweir if( nX + (long)maGeometry.nWidth < 10 ) 1545*cdf0e10cSrcweir nX = 10 - (long)maGeometry.nWidth; 1546*cdf0e10cSrcweir if( nY + (long)maGeometry.nHeight < 10 ) 1547*cdf0e10cSrcweir nY = 10 - (long)maGeometry.nHeight; 1548*cdf0e10cSrcweir if( nX > (long)aScreenSize.Width() - 10 ) 1549*cdf0e10cSrcweir nX = (long)aScreenSize.Width() - 10; 1550*cdf0e10cSrcweir if( nY > (long)aScreenSize.Height() - 10 ) 1551*cdf0e10cSrcweir nY = (long)aScreenSize.Height() - 10; 1552*cdf0e10cSrcweir } 1553*cdf0e10cSrcweir 1554*cdf0e10cSrcweir if( nX != maGeometry.nX || nY != maGeometry.nY ) 1555*cdf0e10cSrcweir bMoved = true; 1556*cdf0e10cSrcweir maGeometry.nX = nX; 1557*cdf0e10cSrcweir maGeometry.nY = nY; 1558*cdf0e10cSrcweir 1559*cdf0e10cSrcweir m_bDefaultPos = false; 1560*cdf0e10cSrcweir 1561*cdf0e10cSrcweir moveWindow( maGeometry.nX, maGeometry.nY ); 1562*cdf0e10cSrcweir 1563*cdf0e10cSrcweir updateScreenNumber(); 1564*cdf0e10cSrcweir } 1565*cdf0e10cSrcweir else if( m_bDefaultPos ) 1566*cdf0e10cSrcweir Center(); 1567*cdf0e10cSrcweir 1568*cdf0e10cSrcweir m_bDefaultPos = false; 1569*cdf0e10cSrcweir 1570*cdf0e10cSrcweir if( bSized && ! bMoved ) 1571*cdf0e10cSrcweir CallCallback( SALEVENT_RESIZE, NULL ); 1572*cdf0e10cSrcweir else if( bMoved && ! bSized ) 1573*cdf0e10cSrcweir CallCallback( SALEVENT_MOVE, NULL ); 1574*cdf0e10cSrcweir else if( bMoved && bSized ) 1575*cdf0e10cSrcweir CallCallback( SALEVENT_MOVERESIZE, NULL ); 1576*cdf0e10cSrcweir } 1577*cdf0e10cSrcweir 1578*cdf0e10cSrcweir void GtkSalFrame::GetClientSize( long& rWidth, long& rHeight ) 1579*cdf0e10cSrcweir { 1580*cdf0e10cSrcweir if( m_pWindow && !(m_nState & GDK_WINDOW_STATE_ICONIFIED) ) 1581*cdf0e10cSrcweir { 1582*cdf0e10cSrcweir rWidth = maGeometry.nWidth; 1583*cdf0e10cSrcweir rHeight = maGeometry.nHeight; 1584*cdf0e10cSrcweir } 1585*cdf0e10cSrcweir else 1586*cdf0e10cSrcweir rWidth = rHeight = 0; 1587*cdf0e10cSrcweir } 1588*cdf0e10cSrcweir 1589*cdf0e10cSrcweir void GtkSalFrame::GetWorkArea( Rectangle& rRect ) 1590*cdf0e10cSrcweir { 1591*cdf0e10cSrcweir rRect = GetX11SalData()->GetDisplay()->getWMAdaptor()->getWorkArea( 0 ); 1592*cdf0e10cSrcweir } 1593*cdf0e10cSrcweir 1594*cdf0e10cSrcweir SalFrame* GtkSalFrame::GetParent() const 1595*cdf0e10cSrcweir { 1596*cdf0e10cSrcweir return m_pParent; 1597*cdf0e10cSrcweir } 1598*cdf0e10cSrcweir 1599*cdf0e10cSrcweir void GtkSalFrame::SetWindowState( const SalFrameState* pState ) 1600*cdf0e10cSrcweir { 1601*cdf0e10cSrcweir if( ! m_pWindow || ! pState || isChild( true, false ) ) 1602*cdf0e10cSrcweir return; 1603*cdf0e10cSrcweir 1604*cdf0e10cSrcweir const sal_uLong nMaxGeometryMask = 1605*cdf0e10cSrcweir SAL_FRAMESTATE_MASK_X | SAL_FRAMESTATE_MASK_Y | 1606*cdf0e10cSrcweir SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT | 1607*cdf0e10cSrcweir SAL_FRAMESTATE_MASK_MAXIMIZED_X | SAL_FRAMESTATE_MASK_MAXIMIZED_Y | 1608*cdf0e10cSrcweir SAL_FRAMESTATE_MASK_MAXIMIZED_WIDTH | SAL_FRAMESTATE_MASK_MAXIMIZED_HEIGHT; 1609*cdf0e10cSrcweir 1610*cdf0e10cSrcweir if( (pState->mnMask & SAL_FRAMESTATE_MASK_STATE) && 1611*cdf0e10cSrcweir ! ( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) && 1612*cdf0e10cSrcweir (pState->mnState & SAL_FRAMESTATE_MAXIMIZED) && 1613*cdf0e10cSrcweir (pState->mnMask & nMaxGeometryMask) == nMaxGeometryMask ) 1614*cdf0e10cSrcweir { 1615*cdf0e10cSrcweir resizeWindow( pState->mnWidth, pState->mnHeight ); 1616*cdf0e10cSrcweir moveWindow( pState->mnX, pState->mnY ); 1617*cdf0e10cSrcweir m_bDefaultPos = m_bDefaultSize = false; 1618*cdf0e10cSrcweir 1619*cdf0e10cSrcweir maGeometry.nX = pState->mnMaximizedX; 1620*cdf0e10cSrcweir maGeometry.nY = pState->mnMaximizedY; 1621*cdf0e10cSrcweir maGeometry.nWidth = pState->mnMaximizedWidth; 1622*cdf0e10cSrcweir maGeometry.nHeight = pState->mnMaximizedHeight; 1623*cdf0e10cSrcweir updateScreenNumber(); 1624*cdf0e10cSrcweir 1625*cdf0e10cSrcweir m_nState = GdkWindowState( m_nState | GDK_WINDOW_STATE_MAXIMIZED ); 1626*cdf0e10cSrcweir m_aRestorePosSize = Rectangle( Point( pState->mnX, pState->mnY ), 1627*cdf0e10cSrcweir Size( pState->mnWidth, pState->mnHeight ) ); 1628*cdf0e10cSrcweir } 1629*cdf0e10cSrcweir else if( pState->mnMask & (SAL_FRAMESTATE_MASK_X | SAL_FRAMESTATE_MASK_Y | 1630*cdf0e10cSrcweir SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT ) ) 1631*cdf0e10cSrcweir { 1632*cdf0e10cSrcweir sal_uInt16 nPosSizeFlags = 0; 1633*cdf0e10cSrcweir long nX = pState->mnX - (m_pParent ? m_pParent->maGeometry.nX : 0); 1634*cdf0e10cSrcweir long nY = pState->mnY - (m_pParent ? m_pParent->maGeometry.nY : 0); 1635*cdf0e10cSrcweir long nWidth = pState->mnWidth; 1636*cdf0e10cSrcweir long nHeight = pState->mnHeight; 1637*cdf0e10cSrcweir if( pState->mnMask & SAL_FRAMESTATE_MASK_X ) 1638*cdf0e10cSrcweir nPosSizeFlags |= SAL_FRAME_POSSIZE_X; 1639*cdf0e10cSrcweir else 1640*cdf0e10cSrcweir nX = maGeometry.nX - (m_pParent ? m_pParent->maGeometry.nX : 0); 1641*cdf0e10cSrcweir if( pState->mnMask & SAL_FRAMESTATE_MASK_Y ) 1642*cdf0e10cSrcweir nPosSizeFlags |= SAL_FRAME_POSSIZE_Y; 1643*cdf0e10cSrcweir else 1644*cdf0e10cSrcweir nY = maGeometry.nY - (m_pParent ? m_pParent->maGeometry.nY : 0); 1645*cdf0e10cSrcweir if( pState->mnMask & SAL_FRAMESTATE_MASK_WIDTH ) 1646*cdf0e10cSrcweir nPosSizeFlags |= SAL_FRAME_POSSIZE_WIDTH; 1647*cdf0e10cSrcweir else 1648*cdf0e10cSrcweir nWidth = maGeometry.nWidth; 1649*cdf0e10cSrcweir if( pState->mnMask & SAL_FRAMESTATE_MASK_HEIGHT ) 1650*cdf0e10cSrcweir nPosSizeFlags |= SAL_FRAME_POSSIZE_HEIGHT; 1651*cdf0e10cSrcweir else 1652*cdf0e10cSrcweir nHeight = maGeometry.nHeight; 1653*cdf0e10cSrcweir SetPosSize( nX, nY, pState->mnWidth, pState->mnHeight, nPosSizeFlags ); 1654*cdf0e10cSrcweir } 1655*cdf0e10cSrcweir if( pState->mnMask & SAL_FRAMESTATE_MASK_STATE && ! isChild() ) 1656*cdf0e10cSrcweir { 1657*cdf0e10cSrcweir if( pState->mnState & SAL_FRAMESTATE_MAXIMIZED ) 1658*cdf0e10cSrcweir gtk_window_maximize( GTK_WINDOW(m_pWindow) ); 1659*cdf0e10cSrcweir else 1660*cdf0e10cSrcweir gtk_window_unmaximize( GTK_WINDOW(m_pWindow) ); 1661*cdf0e10cSrcweir /* #i42379# there is no rollup state in GDK; and rolled up windows are 1662*cdf0e10cSrcweir * (probably depending on the WM) reported as iconified. If we iconify a 1663*cdf0e10cSrcweir * window here that was e.g. a dialog, then it will be unmapped but still 1664*cdf0e10cSrcweir * not be displayed in the task list, so it's an iconified window that 1665*cdf0e10cSrcweir * the user cannot get out of this state. So do not set the iconified state 1666*cdf0e10cSrcweir * on windows with a parent (that is transient frames) since these tend 1667*cdf0e10cSrcweir * to not be represented in an icon task list. 1668*cdf0e10cSrcweir */ 1669*cdf0e10cSrcweir if( (pState->mnState & SAL_FRAMESTATE_MINIMIZED) 1670*cdf0e10cSrcweir && ! m_pParent ) 1671*cdf0e10cSrcweir gtk_window_iconify( GTK_WINDOW(m_pWindow) ); 1672*cdf0e10cSrcweir else 1673*cdf0e10cSrcweir gtk_window_deiconify( GTK_WINDOW(m_pWindow) ); 1674*cdf0e10cSrcweir } 1675*cdf0e10cSrcweir } 1676*cdf0e10cSrcweir 1677*cdf0e10cSrcweir sal_Bool GtkSalFrame::GetWindowState( SalFrameState* pState ) 1678*cdf0e10cSrcweir { 1679*cdf0e10cSrcweir pState->mnState = SAL_FRAMESTATE_NORMAL; 1680*cdf0e10cSrcweir pState->mnMask = SAL_FRAMESTATE_MASK_STATE; 1681*cdf0e10cSrcweir // rollup ? gtk 2.2 does not seem to support the shaded state 1682*cdf0e10cSrcweir if( (m_nState & GDK_WINDOW_STATE_ICONIFIED) ) 1683*cdf0e10cSrcweir pState->mnState |= SAL_FRAMESTATE_MINIMIZED; 1684*cdf0e10cSrcweir if( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) 1685*cdf0e10cSrcweir { 1686*cdf0e10cSrcweir pState->mnState |= SAL_FRAMESTATE_MAXIMIZED; 1687*cdf0e10cSrcweir pState->mnX = m_aRestorePosSize.Left(); 1688*cdf0e10cSrcweir pState->mnY = m_aRestorePosSize.Top(); 1689*cdf0e10cSrcweir pState->mnWidth = m_aRestorePosSize.GetWidth(); 1690*cdf0e10cSrcweir pState->mnHeight = m_aRestorePosSize.GetHeight(); 1691*cdf0e10cSrcweir pState->mnMaximizedX = maGeometry.nX; 1692*cdf0e10cSrcweir pState->mnMaximizedY = maGeometry.nY; 1693*cdf0e10cSrcweir pState->mnMaximizedWidth = maGeometry.nWidth; 1694*cdf0e10cSrcweir pState->mnMaximizedHeight = maGeometry.nHeight; 1695*cdf0e10cSrcweir pState->mnMask |= SAL_FRAMESTATE_MASK_MAXIMIZED_X | 1696*cdf0e10cSrcweir SAL_FRAMESTATE_MASK_MAXIMIZED_Y | 1697*cdf0e10cSrcweir SAL_FRAMESTATE_MASK_MAXIMIZED_WIDTH | 1698*cdf0e10cSrcweir SAL_FRAMESTATE_MASK_MAXIMIZED_HEIGHT; 1699*cdf0e10cSrcweir } 1700*cdf0e10cSrcweir else 1701*cdf0e10cSrcweir { 1702*cdf0e10cSrcweir 1703*cdf0e10cSrcweir pState->mnX = maGeometry.nX; 1704*cdf0e10cSrcweir pState->mnY = maGeometry.nY; 1705*cdf0e10cSrcweir pState->mnWidth = maGeometry.nWidth; 1706*cdf0e10cSrcweir pState->mnHeight = maGeometry.nHeight; 1707*cdf0e10cSrcweir } 1708*cdf0e10cSrcweir pState->mnMask |= SAL_FRAMESTATE_MASK_X | 1709*cdf0e10cSrcweir SAL_FRAMESTATE_MASK_Y | 1710*cdf0e10cSrcweir SAL_FRAMESTATE_MASK_WIDTH | 1711*cdf0e10cSrcweir SAL_FRAMESTATE_MASK_HEIGHT; 1712*cdf0e10cSrcweir 1713*cdf0e10cSrcweir return sal_True; 1714*cdf0e10cSrcweir } 1715*cdf0e10cSrcweir 1716*cdf0e10cSrcweir void GtkSalFrame::moveToScreen( int nScreen ) 1717*cdf0e10cSrcweir { 1718*cdf0e10cSrcweir if( isChild() ) 1719*cdf0e10cSrcweir return; 1720*cdf0e10cSrcweir 1721*cdf0e10cSrcweir if( nScreen < 0 || nScreen >= gdk_display_get_n_screens( getGdkDisplay() ) ) 1722*cdf0e10cSrcweir nScreen = m_nScreen; 1723*cdf0e10cSrcweir if( nScreen == m_nScreen ) 1724*cdf0e10cSrcweir return; 1725*cdf0e10cSrcweir 1726*cdf0e10cSrcweir GdkScreen* pScreen = gdk_display_get_screen( getGdkDisplay(), nScreen ); 1727*cdf0e10cSrcweir if( pScreen ) 1728*cdf0e10cSrcweir { 1729*cdf0e10cSrcweir m_nScreen = nScreen; 1730*cdf0e10cSrcweir gtk_window_set_screen( GTK_WINDOW(m_pWindow), pScreen ); 1731*cdf0e10cSrcweir // realize the window, we need an XWindow id 1732*cdf0e10cSrcweir gtk_widget_realize( m_pWindow ); 1733*cdf0e10cSrcweir // update system data 1734*cdf0e10cSrcweir GtkSalDisplay* pDisp = getDisplay(); 1735*cdf0e10cSrcweir m_aSystemData.aWindow = GDK_WINDOW_XWINDOW(m_pWindow->window); 1736*cdf0e10cSrcweir m_aSystemData.pVisual = pDisp->GetVisual( m_nScreen ).GetVisual(); 1737*cdf0e10cSrcweir m_aSystemData.nScreen = nScreen; 1738*cdf0e10cSrcweir m_aSystemData.nDepth = pDisp->GetVisual( m_nScreen ).GetDepth(); 1739*cdf0e10cSrcweir m_aSystemData.aColormap = pDisp->GetColormap( m_nScreen ).GetXColormap(); 1740*cdf0e10cSrcweir m_aSystemData.pAppContext = NULL; 1741*cdf0e10cSrcweir m_aSystemData.aShellWindow = m_aSystemData.aWindow; 1742*cdf0e10cSrcweir // update graphics if necessary 1743*cdf0e10cSrcweir for( unsigned int i = 0; i < sizeof(m_aGraphics)/sizeof(m_aGraphics[0]); i++ ) 1744*cdf0e10cSrcweir { 1745*cdf0e10cSrcweir if( m_aGraphics[i].bInUse ) 1746*cdf0e10cSrcweir m_aGraphics[i].pGraphics->SetDrawable( GDK_WINDOW_XWINDOW(m_pWindow->window), m_nScreen ); 1747*cdf0e10cSrcweir } 1748*cdf0e10cSrcweir updateScreenNumber(); 1749*cdf0e10cSrcweir } 1750*cdf0e10cSrcweir 1751*cdf0e10cSrcweir if( m_pParent && m_pParent->m_nScreen != m_nScreen ) 1752*cdf0e10cSrcweir SetParent( NULL ); 1753*cdf0e10cSrcweir std::list< GtkSalFrame* > aChildren = m_aChildren; 1754*cdf0e10cSrcweir for( std::list< GtkSalFrame* >::iterator it = aChildren.begin(); it != aChildren.end(); ++it ) 1755*cdf0e10cSrcweir (*it)->moveToScreen( m_nScreen ); 1756*cdf0e10cSrcweir 1757*cdf0e10cSrcweir // FIXME: SalObjects 1758*cdf0e10cSrcweir } 1759*cdf0e10cSrcweir 1760*cdf0e10cSrcweir void GtkSalFrame::SetScreenNumber( unsigned int nNewScreen ) 1761*cdf0e10cSrcweir { 1762*cdf0e10cSrcweir if( nNewScreen == maGeometry.nScreenNumber ) 1763*cdf0e10cSrcweir return; 1764*cdf0e10cSrcweir 1765*cdf0e10cSrcweir if( m_pWindow && ! isChild() ) 1766*cdf0e10cSrcweir { 1767*cdf0e10cSrcweir GtkSalDisplay* pDisp = getDisplay(); 1768*cdf0e10cSrcweir if( pDisp->IsXinerama() && pDisp->GetXineramaScreens().size() > 1 ) 1769*cdf0e10cSrcweir { 1770*cdf0e10cSrcweir if( nNewScreen >= pDisp->GetXineramaScreens().size() ) 1771*cdf0e10cSrcweir return; 1772*cdf0e10cSrcweir 1773*cdf0e10cSrcweir Rectangle aOldScreenRect( pDisp->GetXineramaScreens()[maGeometry.nScreenNumber] ); 1774*cdf0e10cSrcweir Rectangle aNewScreenRect( pDisp->GetXineramaScreens()[nNewScreen] ); 1775*cdf0e10cSrcweir bool bVisible = GTK_WIDGET_MAPPED(m_pWindow); 1776*cdf0e10cSrcweir if( bVisible ) 1777*cdf0e10cSrcweir Show( sal_False ); 1778*cdf0e10cSrcweir maGeometry.nX = aNewScreenRect.Left() + (maGeometry.nX - aOldScreenRect.Left()); 1779*cdf0e10cSrcweir maGeometry.nY = aNewScreenRect.Top() + (maGeometry.nY - aOldScreenRect.Top()); 1780*cdf0e10cSrcweir createNewWindow( None, false, m_nScreen ); 1781*cdf0e10cSrcweir gtk_window_move( GTK_WINDOW(m_pWindow), maGeometry.nX, maGeometry.nY ); 1782*cdf0e10cSrcweir if( bVisible ) 1783*cdf0e10cSrcweir Show( sal_True ); 1784*cdf0e10cSrcweir maGeometry.nScreenNumber = nNewScreen; 1785*cdf0e10cSrcweir } 1786*cdf0e10cSrcweir else if( sal_Int32(nNewScreen) < pDisp->GetScreenCount() ) 1787*cdf0e10cSrcweir { 1788*cdf0e10cSrcweir moveToScreen( (int)nNewScreen ); 1789*cdf0e10cSrcweir maGeometry.nScreenNumber = nNewScreen; 1790*cdf0e10cSrcweir gtk_window_move( GTK_WINDOW(m_pWindow), maGeometry.nX, maGeometry.nY ); 1791*cdf0e10cSrcweir } 1792*cdf0e10cSrcweir } 1793*cdf0e10cSrcweir } 1794*cdf0e10cSrcweir 1795*cdf0e10cSrcweir void GtkSalFrame::ShowFullScreen( sal_Bool bFullScreen, sal_Int32 nScreen ) 1796*cdf0e10cSrcweir { 1797*cdf0e10cSrcweir if( m_pWindow && ! isChild() ) 1798*cdf0e10cSrcweir { 1799*cdf0e10cSrcweir GtkSalDisplay* pDisp = getDisplay(); 1800*cdf0e10cSrcweir // xinerama ? 1801*cdf0e10cSrcweir if( pDisp->IsXinerama() && pDisp->GetXineramaScreens().size() > 1 ) 1802*cdf0e10cSrcweir { 1803*cdf0e10cSrcweir if( bFullScreen ) 1804*cdf0e10cSrcweir { 1805*cdf0e10cSrcweir m_aRestorePosSize = Rectangle( Point( maGeometry.nX, maGeometry.nY ), 1806*cdf0e10cSrcweir Size( maGeometry.nWidth, maGeometry.nHeight ) ); 1807*cdf0e10cSrcweir bool bVisible = GTK_WIDGET_MAPPED(m_pWindow); 1808*cdf0e10cSrcweir if( bVisible ) 1809*cdf0e10cSrcweir Show( sal_False ); 1810*cdf0e10cSrcweir m_nStyle |= SAL_FRAME_STYLE_PARTIAL_FULLSCREEN; 1811*cdf0e10cSrcweir createNewWindow( None, false, m_nScreen ); 1812*cdf0e10cSrcweir Rectangle aNewPosSize; 1813*cdf0e10cSrcweir if( nScreen < 0 || nScreen >= static_cast<int>(pDisp->GetXineramaScreens().size()) ) 1814*cdf0e10cSrcweir aNewPosSize = Rectangle( Point( 0, 0 ), pDisp->GetScreenSize(m_nScreen) ); 1815*cdf0e10cSrcweir else 1816*cdf0e10cSrcweir aNewPosSize = pDisp->GetXineramaScreens()[ nScreen ]; 1817*cdf0e10cSrcweir 1818*cdf0e10cSrcweir gtk_window_resize( GTK_WINDOW(m_pWindow), 1819*cdf0e10cSrcweir maGeometry.nWidth = aNewPosSize.GetWidth(), 1820*cdf0e10cSrcweir maGeometry.nHeight = aNewPosSize.GetHeight() ); 1821*cdf0e10cSrcweir gtk_window_move( GTK_WINDOW(m_pWindow), 1822*cdf0e10cSrcweir maGeometry.nX = aNewPosSize.Left(), 1823*cdf0e10cSrcweir maGeometry.nY = aNewPosSize.Top() ); 1824*cdf0e10cSrcweir // #i110881# for the benefit of compiz set a max size here 1825*cdf0e10cSrcweir // else setting to fullscreen fails for unknown reasons 1826*cdf0e10cSrcweir m_aMaxSize.Width() = aNewPosSize.GetWidth()+100; 1827*cdf0e10cSrcweir m_aMaxSize.Height() = aNewPosSize.GetHeight()+100; 1828*cdf0e10cSrcweir // workaround different legacy version window managers have different opinions about 1829*cdf0e10cSrcweir // _NET_WM_STATE_FULLSCREEN (Metacity <-> KWin) 1830*cdf0e10cSrcweir if( ! getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) 1831*cdf0e10cSrcweir { 1832*cdf0e10cSrcweir pDisp->getWMAdaptor()->setFullScreenMonitors( GDK_WINDOW_XWINDOW( GTK_WIDGET(m_pWindow)->window ), nScreen ); 1833*cdf0e10cSrcweir if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) 1834*cdf0e10cSrcweir gtk_window_set_resizable( GTK_WINDOW(m_pWindow), sal_True ); 1835*cdf0e10cSrcweir gtk_window_fullscreen( GTK_WINDOW( m_pWindow ) ); 1836*cdf0e10cSrcweir } 1837*cdf0e10cSrcweir if( bVisible ) 1838*cdf0e10cSrcweir Show( sal_True ); 1839*cdf0e10cSrcweir } 1840*cdf0e10cSrcweir else 1841*cdf0e10cSrcweir { 1842*cdf0e10cSrcweir bool bVisible = GTK_WIDGET_MAPPED(m_pWindow); 1843*cdf0e10cSrcweir if( ! getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) 1844*cdf0e10cSrcweir gtk_window_unfullscreen( GTK_WINDOW(m_pWindow) ); 1845*cdf0e10cSrcweir if( bVisible ) 1846*cdf0e10cSrcweir Show( sal_False ); 1847*cdf0e10cSrcweir m_nStyle &= ~SAL_FRAME_STYLE_PARTIAL_FULLSCREEN; 1848*cdf0e10cSrcweir createNewWindow( None, false, m_nScreen ); 1849*cdf0e10cSrcweir if( ! m_aRestorePosSize.IsEmpty() ) 1850*cdf0e10cSrcweir { 1851*cdf0e10cSrcweir gtk_window_resize( GTK_WINDOW(m_pWindow), 1852*cdf0e10cSrcweir maGeometry.nWidth = m_aRestorePosSize.GetWidth(), 1853*cdf0e10cSrcweir maGeometry.nHeight = m_aRestorePosSize.GetHeight() ); 1854*cdf0e10cSrcweir gtk_window_move( GTK_WINDOW(m_pWindow), 1855*cdf0e10cSrcweir maGeometry.nX = m_aRestorePosSize.Left(), 1856*cdf0e10cSrcweir maGeometry.nY = m_aRestorePosSize.Top() ); 1857*cdf0e10cSrcweir m_aRestorePosSize = Rectangle(); 1858*cdf0e10cSrcweir } 1859*cdf0e10cSrcweir if( bVisible ) 1860*cdf0e10cSrcweir Show( sal_True ); 1861*cdf0e10cSrcweir } 1862*cdf0e10cSrcweir } 1863*cdf0e10cSrcweir else 1864*cdf0e10cSrcweir { 1865*cdf0e10cSrcweir if( bFullScreen ) 1866*cdf0e10cSrcweir { 1867*cdf0e10cSrcweir if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) 1868*cdf0e10cSrcweir gtk_window_set_resizable( GTK_WINDOW(m_pWindow), TRUE ); 1869*cdf0e10cSrcweir gtk_window_fullscreen( GTK_WINDOW(m_pWindow) ); 1870*cdf0e10cSrcweir moveToScreen( nScreen ); 1871*cdf0e10cSrcweir Size aScreenSize = pDisp->GetScreenSize( m_nScreen ); 1872*cdf0e10cSrcweir maGeometry.nX = 0; 1873*cdf0e10cSrcweir maGeometry.nY = 0; 1874*cdf0e10cSrcweir maGeometry.nWidth = aScreenSize.Width(); 1875*cdf0e10cSrcweir maGeometry.nHeight = aScreenSize.Height(); 1876*cdf0e10cSrcweir } 1877*cdf0e10cSrcweir else 1878*cdf0e10cSrcweir { 1879*cdf0e10cSrcweir gtk_window_unfullscreen( GTK_WINDOW(m_pWindow) ); 1880*cdf0e10cSrcweir if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) 1881*cdf0e10cSrcweir gtk_window_set_resizable( GTK_WINDOW(m_pWindow), FALSE ); 1882*cdf0e10cSrcweir moveToScreen( nScreen ); 1883*cdf0e10cSrcweir } 1884*cdf0e10cSrcweir } 1885*cdf0e10cSrcweir m_bDefaultPos = m_bDefaultSize = false; 1886*cdf0e10cSrcweir updateScreenNumber(); 1887*cdf0e10cSrcweir CallCallback( SALEVENT_MOVERESIZE, NULL ); 1888*cdf0e10cSrcweir } 1889*cdf0e10cSrcweir m_bFullscreen = bFullScreen; 1890*cdf0e10cSrcweir } 1891*cdf0e10cSrcweir 1892*cdf0e10cSrcweir /* definitions from xautolock.c (pl15) */ 1893*cdf0e10cSrcweir #define XAUTOLOCK_DISABLE 1 1894*cdf0e10cSrcweir #define XAUTOLOCK_ENABLE 2 1895*cdf0e10cSrcweir 1896*cdf0e10cSrcweir void GtkSalFrame::setAutoLock( bool bLock ) 1897*cdf0e10cSrcweir { 1898*cdf0e10cSrcweir if( isChild() ) 1899*cdf0e10cSrcweir return; 1900*cdf0e10cSrcweir 1901*cdf0e10cSrcweir GdkScreen *pScreen = gtk_window_get_screen( GTK_WINDOW(m_pWindow) ); 1902*cdf0e10cSrcweir GdkDisplay *pDisplay = gdk_screen_get_display( pScreen ); 1903*cdf0e10cSrcweir GdkWindow *pRootWin = gdk_screen_get_root_window( pScreen ); 1904*cdf0e10cSrcweir 1905*cdf0e10cSrcweir Atom nAtom = XInternAtom( GDK_DISPLAY_XDISPLAY( pDisplay ), 1906*cdf0e10cSrcweir "XAUTOLOCK_MESSAGE", False ); 1907*cdf0e10cSrcweir 1908*cdf0e10cSrcweir int nMessage = bLock ? XAUTOLOCK_ENABLE : XAUTOLOCK_DISABLE; 1909*cdf0e10cSrcweir 1910*cdf0e10cSrcweir XChangeProperty( GDK_DISPLAY_XDISPLAY( pDisplay ), 1911*cdf0e10cSrcweir GDK_WINDOW_XID( pRootWin ), 1912*cdf0e10cSrcweir nAtom, XA_INTEGER, 1913*cdf0e10cSrcweir 8, PropModeReplace, 1914*cdf0e10cSrcweir (unsigned char*)&nMessage, 1915*cdf0e10cSrcweir sizeof( nMessage ) ); 1916*cdf0e10cSrcweir } 1917*cdf0e10cSrcweir 1918*cdf0e10cSrcweir #ifdef ENABLE_DBUS 1919*cdf0e10cSrcweir /** cookie is returned as an unsigned integer */ 1920*cdf0e10cSrcweir static guint 1921*cdf0e10cSrcweir dbus_inhibit_gsm (const gchar *appname, 1922*cdf0e10cSrcweir const gchar *reason, 1923*cdf0e10cSrcweir guint xid) 1924*cdf0e10cSrcweir { 1925*cdf0e10cSrcweir gboolean res; 1926*cdf0e10cSrcweir guint cookie; 1927*cdf0e10cSrcweir GError *error = NULL; 1928*cdf0e10cSrcweir DBusGProxy *proxy = NULL; 1929*cdf0e10cSrcweir DBusGConnection *session_connection = NULL; 1930*cdf0e10cSrcweir 1931*cdf0e10cSrcweir /* get the DBUS session connection */ 1932*cdf0e10cSrcweir session_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); 1933*cdf0e10cSrcweir if (error != NULL) { 1934*cdf0e10cSrcweir g_warning ("DBUS cannot connect : %s", error->message); 1935*cdf0e10cSrcweir g_error_free (error); 1936*cdf0e10cSrcweir return -1; 1937*cdf0e10cSrcweir } 1938*cdf0e10cSrcweir 1939*cdf0e10cSrcweir /* get the proxy with gnome-session-manager */ 1940*cdf0e10cSrcweir proxy = dbus_g_proxy_new_for_name (session_connection, 1941*cdf0e10cSrcweir GSM_DBUS_SERVICE, 1942*cdf0e10cSrcweir GSM_DBUS_PATH, 1943*cdf0e10cSrcweir GSM_DBUS_INTERFACE); 1944*cdf0e10cSrcweir if (proxy == NULL) { 1945*cdf0e10cSrcweir g_warning ("Could not get DBUS proxy: %s", GSM_DBUS_SERVICE); 1946*cdf0e10cSrcweir return -1; 1947*cdf0e10cSrcweir } 1948*cdf0e10cSrcweir 1949*cdf0e10cSrcweir res = dbus_g_proxy_call (proxy, 1950*cdf0e10cSrcweir "Inhibit", &error, 1951*cdf0e10cSrcweir G_TYPE_STRING, appname, 1952*cdf0e10cSrcweir G_TYPE_UINT, xid, 1953*cdf0e10cSrcweir G_TYPE_STRING, reason, 1954*cdf0e10cSrcweir G_TYPE_UINT, 8, //Inhibit the session being marked as idle 1955*cdf0e10cSrcweir G_TYPE_INVALID, 1956*cdf0e10cSrcweir G_TYPE_UINT, &cookie, 1957*cdf0e10cSrcweir G_TYPE_INVALID); 1958*cdf0e10cSrcweir 1959*cdf0e10cSrcweir /* check the return value */ 1960*cdf0e10cSrcweir if (! res) { 1961*cdf0e10cSrcweir cookie = -1; 1962*cdf0e10cSrcweir g_warning ("Inhibit method failed"); 1963*cdf0e10cSrcweir } 1964*cdf0e10cSrcweir 1965*cdf0e10cSrcweir /* check the error value */ 1966*cdf0e10cSrcweir if (error != NULL) { 1967*cdf0e10cSrcweir g_warning ("Inhibit problem : %s", error->message); 1968*cdf0e10cSrcweir g_error_free (error); 1969*cdf0e10cSrcweir cookie = -1; 1970*cdf0e10cSrcweir } 1971*cdf0e10cSrcweir 1972*cdf0e10cSrcweir g_object_unref (G_OBJECT (proxy)); 1973*cdf0e10cSrcweir return cookie; 1974*cdf0e10cSrcweir } 1975*cdf0e10cSrcweir 1976*cdf0e10cSrcweir static void 1977*cdf0e10cSrcweir dbus_uninhibit_gsm (guint cookie) 1978*cdf0e10cSrcweir { 1979*cdf0e10cSrcweir gboolean res; 1980*cdf0e10cSrcweir GError *error = NULL; 1981*cdf0e10cSrcweir DBusGProxy *proxy = NULL; 1982*cdf0e10cSrcweir DBusGConnection *session_connection = NULL; 1983*cdf0e10cSrcweir 1984*cdf0e10cSrcweir if (cookie == guint(-1)) { 1985*cdf0e10cSrcweir g_warning ("Invalid cookie"); 1986*cdf0e10cSrcweir return; 1987*cdf0e10cSrcweir } 1988*cdf0e10cSrcweir 1989*cdf0e10cSrcweir /* get the DBUS session connection */ 1990*cdf0e10cSrcweir session_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); 1991*cdf0e10cSrcweir if (error) { 1992*cdf0e10cSrcweir g_warning ("DBUS cannot connect : %s", error->message); 1993*cdf0e10cSrcweir g_error_free (error); 1994*cdf0e10cSrcweir return; 1995*cdf0e10cSrcweir } 1996*cdf0e10cSrcweir 1997*cdf0e10cSrcweir /* get the proxy with gnome-session-manager */ 1998*cdf0e10cSrcweir proxy = dbus_g_proxy_new_for_name (session_connection, 1999*cdf0e10cSrcweir GSM_DBUS_SERVICE, 2000*cdf0e10cSrcweir GSM_DBUS_PATH, 2001*cdf0e10cSrcweir GSM_DBUS_INTERFACE); 2002*cdf0e10cSrcweir if (proxy == NULL) { 2003*cdf0e10cSrcweir g_warning ("Could not get DBUS proxy: %s", GSM_DBUS_SERVICE); 2004*cdf0e10cSrcweir return; 2005*cdf0e10cSrcweir } 2006*cdf0e10cSrcweir 2007*cdf0e10cSrcweir res = dbus_g_proxy_call (proxy, 2008*cdf0e10cSrcweir "Uninhibit", 2009*cdf0e10cSrcweir &error, 2010*cdf0e10cSrcweir G_TYPE_UINT, cookie, 2011*cdf0e10cSrcweir G_TYPE_INVALID, 2012*cdf0e10cSrcweir G_TYPE_INVALID); 2013*cdf0e10cSrcweir 2014*cdf0e10cSrcweir /* check the return value */ 2015*cdf0e10cSrcweir if (! res) { 2016*cdf0e10cSrcweir g_warning ("Uninhibit method failed"); 2017*cdf0e10cSrcweir } 2018*cdf0e10cSrcweir 2019*cdf0e10cSrcweir /* check the error value */ 2020*cdf0e10cSrcweir if (error != NULL) { 2021*cdf0e10cSrcweir g_warning ("Uninhibit problem : %s", error->message); 2022*cdf0e10cSrcweir g_error_free (error); 2023*cdf0e10cSrcweir cookie = -1; 2024*cdf0e10cSrcweir } 2025*cdf0e10cSrcweir g_object_unref (G_OBJECT (proxy)); 2026*cdf0e10cSrcweir } 2027*cdf0e10cSrcweir #endif 2028*cdf0e10cSrcweir 2029*cdf0e10cSrcweir void GtkSalFrame::StartPresentation( sal_Bool bStart ) 2030*cdf0e10cSrcweir { 2031*cdf0e10cSrcweir Display *pDisplay = GDK_DISPLAY_XDISPLAY( getGdkDisplay() ); 2032*cdf0e10cSrcweir 2033*cdf0e10cSrcweir setAutoLock( !bStart ); 2034*cdf0e10cSrcweir 2035*cdf0e10cSrcweir int nTimeout, nInterval, bPreferBlanking, bAllowExposures; 2036*cdf0e10cSrcweir 2037*cdf0e10cSrcweir XGetScreenSaver( pDisplay, &nTimeout, &nInterval, 2038*cdf0e10cSrcweir &bPreferBlanking, &bAllowExposures ); 2039*cdf0e10cSrcweir if( bStart ) 2040*cdf0e10cSrcweir { 2041*cdf0e10cSrcweir if ( nTimeout ) 2042*cdf0e10cSrcweir { 2043*cdf0e10cSrcweir m_nSavedScreenSaverTimeout = nTimeout; 2044*cdf0e10cSrcweir XResetScreenSaver( pDisplay ); 2045*cdf0e10cSrcweir XSetScreenSaver( pDisplay, 0, nInterval, 2046*cdf0e10cSrcweir bPreferBlanking, bAllowExposures ); 2047*cdf0e10cSrcweir } 2048*cdf0e10cSrcweir #ifdef ENABLE_DBUS 2049*cdf0e10cSrcweir m_nGSMCookie = dbus_inhibit_gsm(g_get_application_name(), "presentation", 2050*cdf0e10cSrcweir GDK_WINDOW_XID(m_pWindow->window)); 2051*cdf0e10cSrcweir #endif 2052*cdf0e10cSrcweir } 2053*cdf0e10cSrcweir else 2054*cdf0e10cSrcweir { 2055*cdf0e10cSrcweir if( m_nSavedScreenSaverTimeout ) 2056*cdf0e10cSrcweir XSetScreenSaver( pDisplay, m_nSavedScreenSaverTimeout, 2057*cdf0e10cSrcweir nInterval, bPreferBlanking, 2058*cdf0e10cSrcweir bAllowExposures ); 2059*cdf0e10cSrcweir m_nSavedScreenSaverTimeout = 0; 2060*cdf0e10cSrcweir #ifdef ENABLE_DBUS 2061*cdf0e10cSrcweir dbus_uninhibit_gsm(m_nGSMCookie); 2062*cdf0e10cSrcweir #endif 2063*cdf0e10cSrcweir } 2064*cdf0e10cSrcweir } 2065*cdf0e10cSrcweir 2066*cdf0e10cSrcweir void GtkSalFrame::SetAlwaysOnTop( sal_Bool /*bOnTop*/ ) 2067*cdf0e10cSrcweir { 2068*cdf0e10cSrcweir } 2069*cdf0e10cSrcweir 2070*cdf0e10cSrcweir void GtkSalFrame::ToTop( sal_uInt16 nFlags ) 2071*cdf0e10cSrcweir { 2072*cdf0e10cSrcweir if( m_pWindow ) 2073*cdf0e10cSrcweir { 2074*cdf0e10cSrcweir if( isChild( false, true ) ) 2075*cdf0e10cSrcweir gtk_widget_grab_focus( m_pWindow ); 2076*cdf0e10cSrcweir else if( GTK_WIDGET_MAPPED( m_pWindow ) ) 2077*cdf0e10cSrcweir { 2078*cdf0e10cSrcweir if( ! (nFlags & SAL_FRAME_TOTOP_GRABFOCUS_ONLY) ) 2079*cdf0e10cSrcweir gtk_window_present( GTK_WINDOW(m_pWindow) ); 2080*cdf0e10cSrcweir else 2081*cdf0e10cSrcweir { 2082*cdf0e10cSrcweir // gdk_window_focus( m_pWindow->window, gdk_x11_get_server_time(GTK_WIDGET (m_pWindow)->window) ); 2083*cdf0e10cSrcweir /* #i99360# ugly workaround an X11 library bug */ 2084*cdf0e10cSrcweir guint32 nUserTime= getDisplay()->GetLastUserEventTime( true ); 2085*cdf0e10cSrcweir gdk_window_focus( m_pWindow->window, nUserTime ); 2086*cdf0e10cSrcweir } 2087*cdf0e10cSrcweir /* need to do an XSetInputFocus here because 2088*cdf0e10cSrcweir * gdk_window_focus will ask a EWMH compliant WM to put the focus 2089*cdf0e10cSrcweir * to our window - which it of course won't since our input hint 2090*cdf0e10cSrcweir * is set to false. 2091*cdf0e10cSrcweir */ 2092*cdf0e10cSrcweir if( (m_nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_FLOAT_FOCUSABLE)) ) 2093*cdf0e10cSrcweir { 2094*cdf0e10cSrcweir // sad but true: this can cause an XError, we need to catch that 2095*cdf0e10cSrcweir // to do this we need to synchronize with the XServer 2096*cdf0e10cSrcweir getDisplay()->GetXLib()->PushXErrorLevel( true ); 2097*cdf0e10cSrcweir XSetInputFocus( getDisplay()->GetDisplay(), GDK_WINDOW_XWINDOW( m_pWindow->window ), RevertToParent, CurrentTime ); 2098*cdf0e10cSrcweir XSync( getDisplay()->GetDisplay(), False ); 2099*cdf0e10cSrcweir getDisplay()->GetXLib()->PopXErrorLevel(); 2100*cdf0e10cSrcweir } 2101*cdf0e10cSrcweir } 2102*cdf0e10cSrcweir else 2103*cdf0e10cSrcweir { 2104*cdf0e10cSrcweir if( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN ) 2105*cdf0e10cSrcweir gtk_window_present( GTK_WINDOW(m_pWindow) ); 2106*cdf0e10cSrcweir } 2107*cdf0e10cSrcweir } 2108*cdf0e10cSrcweir } 2109*cdf0e10cSrcweir 2110*cdf0e10cSrcweir void GtkSalFrame::SetPointer( PointerStyle ePointerStyle ) 2111*cdf0e10cSrcweir { 2112*cdf0e10cSrcweir if( m_pWindow && ePointerStyle != m_ePointerStyle ) 2113*cdf0e10cSrcweir { 2114*cdf0e10cSrcweir m_ePointerStyle = ePointerStyle; 2115*cdf0e10cSrcweir GdkCursor *pCursor = getDisplay()->getCursor( ePointerStyle ); 2116*cdf0e10cSrcweir gdk_window_set_cursor( m_pWindow->window, pCursor ); 2117*cdf0e10cSrcweir m_pCurrentCursor = pCursor; 2118*cdf0e10cSrcweir 2119*cdf0e10cSrcweir // #i80791# use grabPointer the same way as CaptureMouse, respective float grab 2120*cdf0e10cSrcweir if( getDisplay()->MouseCaptured( this ) ) 2121*cdf0e10cSrcweir grabPointer( sal_True, sal_False ); 2122*cdf0e10cSrcweir else if( m_nFloats > 0 ) 2123*cdf0e10cSrcweir grabPointer( sal_True, sal_True ); 2124*cdf0e10cSrcweir } 2125*cdf0e10cSrcweir } 2126*cdf0e10cSrcweir 2127*cdf0e10cSrcweir void GtkSalFrame::grabPointer( sal_Bool bGrab, sal_Bool bOwnerEvents ) 2128*cdf0e10cSrcweir { 2129*cdf0e10cSrcweir if( m_pWindow ) 2130*cdf0e10cSrcweir { 2131*cdf0e10cSrcweir if( bGrab ) 2132*cdf0e10cSrcweir { 2133*cdf0e10cSrcweir bool bUseGdkGrab = true; 2134*cdf0e10cSrcweir if( getDisplay()->getHaveSystemChildFrame() ) 2135*cdf0e10cSrcweir { 2136*cdf0e10cSrcweir const std::list< SalFrame* >& rFrames = getDisplay()->getFrames(); 2137*cdf0e10cSrcweir for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it ) 2138*cdf0e10cSrcweir { 2139*cdf0e10cSrcweir const GtkSalFrame* pFrame = static_cast< const GtkSalFrame* >(*it); 2140*cdf0e10cSrcweir if( pFrame->m_bWindowIsGtkPlug ) 2141*cdf0e10cSrcweir { 2142*cdf0e10cSrcweir bUseGdkGrab = false; 2143*cdf0e10cSrcweir break; 2144*cdf0e10cSrcweir } 2145*cdf0e10cSrcweir } 2146*cdf0e10cSrcweir } 2147*cdf0e10cSrcweir if( bUseGdkGrab ) 2148*cdf0e10cSrcweir { 2149*cdf0e10cSrcweir const int nMask = ( GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK ); 2150*cdf0e10cSrcweir 2151*cdf0e10cSrcweir gdk_pointer_grab( m_pWindow->window, bOwnerEvents, 2152*cdf0e10cSrcweir (GdkEventMask) nMask, NULL, m_pCurrentCursor, 2153*cdf0e10cSrcweir GDK_CURRENT_TIME ); 2154*cdf0e10cSrcweir } 2155*cdf0e10cSrcweir else 2156*cdf0e10cSrcweir { 2157*cdf0e10cSrcweir // FIXME: for some unknown reason gdk_pointer_grab does not 2158*cdf0e10cSrcweir // really produce owner events for GtkPlug windows 2159*cdf0e10cSrcweir // the cause is yet unknown 2160*cdf0e10cSrcweir // 2161*cdf0e10cSrcweir // this is of course a bad hack, especially as we cannot 2162*cdf0e10cSrcweir // set the right cursor this way 2163*cdf0e10cSrcweir XGrabPointer( getDisplay()->GetDisplay(), 2164*cdf0e10cSrcweir GDK_WINDOW_XWINDOW( m_pWindow->window), 2165*cdf0e10cSrcweir bOwnerEvents, 2166*cdf0e10cSrcweir PointerMotionMask | ButtonPressMask | ButtonReleaseMask, 2167*cdf0e10cSrcweir GrabModeAsync, 2168*cdf0e10cSrcweir GrabModeAsync, 2169*cdf0e10cSrcweir None, 2170*cdf0e10cSrcweir None, 2171*cdf0e10cSrcweir CurrentTime 2172*cdf0e10cSrcweir ); 2173*cdf0e10cSrcweir 2174*cdf0e10cSrcweir } 2175*cdf0e10cSrcweir } 2176*cdf0e10cSrcweir else 2177*cdf0e10cSrcweir { 2178*cdf0e10cSrcweir // Two GdkDisplays may be open 2179*cdf0e10cSrcweir gdk_display_pointer_ungrab( getGdkDisplay(), GDK_CURRENT_TIME); 2180*cdf0e10cSrcweir } 2181*cdf0e10cSrcweir } 2182*cdf0e10cSrcweir } 2183*cdf0e10cSrcweir 2184*cdf0e10cSrcweir void GtkSalFrame::CaptureMouse( sal_Bool bCapture ) 2185*cdf0e10cSrcweir { 2186*cdf0e10cSrcweir getDisplay()->CaptureMouse( bCapture ? this : NULL ); 2187*cdf0e10cSrcweir } 2188*cdf0e10cSrcweir 2189*cdf0e10cSrcweir void GtkSalFrame::SetPointerPos( long nX, long nY ) 2190*cdf0e10cSrcweir { 2191*cdf0e10cSrcweir GtkSalFrame* pFrame = this; 2192*cdf0e10cSrcweir while( pFrame && pFrame->isChild( false, true ) ) 2193*cdf0e10cSrcweir pFrame = pFrame->m_pParent; 2194*cdf0e10cSrcweir if( ! pFrame ) 2195*cdf0e10cSrcweir return; 2196*cdf0e10cSrcweir 2197*cdf0e10cSrcweir GdkScreen *pScreen = gtk_window_get_screen( GTK_WINDOW(pFrame->m_pWindow) ); 2198*cdf0e10cSrcweir GdkDisplay *pDisplay = gdk_screen_get_display( pScreen ); 2199*cdf0e10cSrcweir 2200*cdf0e10cSrcweir /* #87921# when the application tries to center the mouse in the dialog the 2201*cdf0e10cSrcweir * window isn't mapped already. So use coordinates relative to the root window. 2202*cdf0e10cSrcweir */ 2203*cdf0e10cSrcweir unsigned int nWindowLeft = maGeometry.nX + nX; 2204*cdf0e10cSrcweir unsigned int nWindowTop = maGeometry.nY + nY; 2205*cdf0e10cSrcweir 2206*cdf0e10cSrcweir XWarpPointer( GDK_DISPLAY_XDISPLAY (pDisplay), None, 2207*cdf0e10cSrcweir GDK_WINDOW_XID (gdk_screen_get_root_window( pScreen ) ), 2208*cdf0e10cSrcweir 0, 0, 0, 0, nWindowLeft, nWindowTop); 2209*cdf0e10cSrcweir // #i38648# ask for the next motion hint 2210*cdf0e10cSrcweir gint x, y; 2211*cdf0e10cSrcweir GdkModifierType mask; 2212*cdf0e10cSrcweir gdk_window_get_pointer( pFrame->m_pWindow->window, &x, &y, &mask ); 2213*cdf0e10cSrcweir } 2214*cdf0e10cSrcweir 2215*cdf0e10cSrcweir void GtkSalFrame::Flush() 2216*cdf0e10cSrcweir { 2217*cdf0e10cSrcweir #ifdef HAVE_A_RECENT_GTK 2218*cdf0e10cSrcweir gdk_display_flush( getGdkDisplay() ); 2219*cdf0e10cSrcweir #else 2220*cdf0e10cSrcweir XFlush (GDK_DISPLAY_XDISPLAY (getGdkDisplay())); 2221*cdf0e10cSrcweir #endif 2222*cdf0e10cSrcweir } 2223*cdf0e10cSrcweir 2224*cdf0e10cSrcweir void GtkSalFrame::Sync() 2225*cdf0e10cSrcweir { 2226*cdf0e10cSrcweir gdk_display_sync( getGdkDisplay() ); 2227*cdf0e10cSrcweir } 2228*cdf0e10cSrcweir 2229*cdf0e10cSrcweir String GtkSalFrame::GetSymbolKeyName( const String&, sal_uInt16 nKeyCode ) 2230*cdf0e10cSrcweir { 2231*cdf0e10cSrcweir return getDisplay()->GetKeyName( nKeyCode ); 2232*cdf0e10cSrcweir } 2233*cdf0e10cSrcweir 2234*cdf0e10cSrcweir String GtkSalFrame::GetKeyName( sal_uInt16 nKeyCode ) 2235*cdf0e10cSrcweir { 2236*cdf0e10cSrcweir return getDisplay()->GetKeyName( nKeyCode ); 2237*cdf0e10cSrcweir } 2238*cdf0e10cSrcweir 2239*cdf0e10cSrcweir GdkDisplay *GtkSalFrame::getGdkDisplay() 2240*cdf0e10cSrcweir { 2241*cdf0e10cSrcweir return static_cast<GtkSalDisplay*>(GetX11SalData()->GetDisplay())->GetGdkDisplay(); 2242*cdf0e10cSrcweir } 2243*cdf0e10cSrcweir 2244*cdf0e10cSrcweir GtkSalDisplay *GtkSalFrame::getDisplay() 2245*cdf0e10cSrcweir { 2246*cdf0e10cSrcweir return static_cast<GtkSalDisplay*>(GetX11SalData()->GetDisplay()); 2247*cdf0e10cSrcweir } 2248*cdf0e10cSrcweir 2249*cdf0e10cSrcweir SalFrame::SalPointerState GtkSalFrame::GetPointerState() 2250*cdf0e10cSrcweir { 2251*cdf0e10cSrcweir SalPointerState aState; 2252*cdf0e10cSrcweir GdkScreen* pScreen; 2253*cdf0e10cSrcweir gint x, y; 2254*cdf0e10cSrcweir GdkModifierType aMask; 2255*cdf0e10cSrcweir gdk_display_get_pointer( getGdkDisplay(), &pScreen, &x, &y, &aMask ); 2256*cdf0e10cSrcweir aState.maPos = Point( x - maGeometry.nX, y - maGeometry.nY ); 2257*cdf0e10cSrcweir aState.mnState = GetMouseModCode( aMask ); 2258*cdf0e10cSrcweir return aState; 2259*cdf0e10cSrcweir } 2260*cdf0e10cSrcweir 2261*cdf0e10cSrcweir void GtkSalFrame::SetInputContext( SalInputContext* pContext ) 2262*cdf0e10cSrcweir { 2263*cdf0e10cSrcweir if( ! pContext ) 2264*cdf0e10cSrcweir return; 2265*cdf0e10cSrcweir 2266*cdf0e10cSrcweir if( ! (pContext->mnOptions & SAL_INPUTCONTEXT_TEXT) ) 2267*cdf0e10cSrcweir return; 2268*cdf0e10cSrcweir 2269*cdf0e10cSrcweir // create a new im context 2270*cdf0e10cSrcweir if( ! m_pIMHandler ) 2271*cdf0e10cSrcweir m_pIMHandler = new IMHandler( this ); 2272*cdf0e10cSrcweir m_pIMHandler->setInputContext( pContext ); 2273*cdf0e10cSrcweir } 2274*cdf0e10cSrcweir 2275*cdf0e10cSrcweir void GtkSalFrame::EndExtTextInput( sal_uInt16 nFlags ) 2276*cdf0e10cSrcweir { 2277*cdf0e10cSrcweir if( m_pIMHandler ) 2278*cdf0e10cSrcweir m_pIMHandler->endExtTextInput( nFlags ); 2279*cdf0e10cSrcweir } 2280*cdf0e10cSrcweir 2281*cdf0e10cSrcweir sal_Bool GtkSalFrame::MapUnicodeToKeyCode( sal_Unicode , LanguageType , KeyCode& ) 2282*cdf0e10cSrcweir { 2283*cdf0e10cSrcweir // not supported yet 2284*cdf0e10cSrcweir return sal_False; 2285*cdf0e10cSrcweir } 2286*cdf0e10cSrcweir 2287*cdf0e10cSrcweir LanguageType GtkSalFrame::GetInputLanguage() 2288*cdf0e10cSrcweir { 2289*cdf0e10cSrcweir return LANGUAGE_DONTKNOW; 2290*cdf0e10cSrcweir } 2291*cdf0e10cSrcweir 2292*cdf0e10cSrcweir SalBitmap* GtkSalFrame::SnapShot() 2293*cdf0e10cSrcweir { 2294*cdf0e10cSrcweir if( !m_pWindow ) 2295*cdf0e10cSrcweir return NULL; 2296*cdf0e10cSrcweir 2297*cdf0e10cSrcweir X11SalBitmap *pBmp = new X11SalBitmap; 2298*cdf0e10cSrcweir GdkWindow *pWin = m_pWindow->window; 2299*cdf0e10cSrcweir if( pBmp->SnapShot( GDK_DISPLAY_XDISPLAY( getGdkDisplay() ), 2300*cdf0e10cSrcweir GDK_WINDOW_XID( pWin ) ) ) 2301*cdf0e10cSrcweir return pBmp; 2302*cdf0e10cSrcweir else 2303*cdf0e10cSrcweir delete pBmp; 2304*cdf0e10cSrcweir 2305*cdf0e10cSrcweir return NULL; 2306*cdf0e10cSrcweir } 2307*cdf0e10cSrcweir 2308*cdf0e10cSrcweir void GtkSalFrame::UpdateSettings( AllSettings& rSettings ) 2309*cdf0e10cSrcweir { 2310*cdf0e10cSrcweir if( ! m_pWindow ) 2311*cdf0e10cSrcweir return; 2312*cdf0e10cSrcweir 2313*cdf0e10cSrcweir GtkSalGraphics* pGraphics = static_cast<GtkSalGraphics*>(m_aGraphics[0].pGraphics); 2314*cdf0e10cSrcweir bool bFreeGraphics = false; 2315*cdf0e10cSrcweir if( ! pGraphics ) 2316*cdf0e10cSrcweir { 2317*cdf0e10cSrcweir pGraphics = static_cast<GtkSalGraphics*>(GetGraphics()); 2318*cdf0e10cSrcweir bFreeGraphics = true; 2319*cdf0e10cSrcweir } 2320*cdf0e10cSrcweir 2321*cdf0e10cSrcweir pGraphics->updateSettings( rSettings ); 2322*cdf0e10cSrcweir 2323*cdf0e10cSrcweir if( bFreeGraphics ) 2324*cdf0e10cSrcweir ReleaseGraphics( pGraphics ); 2325*cdf0e10cSrcweir } 2326*cdf0e10cSrcweir 2327*cdf0e10cSrcweir void GtkSalFrame::Beep( SoundType eType ) 2328*cdf0e10cSrcweir { 2329*cdf0e10cSrcweir switch( eType ) 2330*cdf0e10cSrcweir { 2331*cdf0e10cSrcweir case SOUND_DEFAULT: 2332*cdf0e10cSrcweir case SOUND_ERROR: 2333*cdf0e10cSrcweir gdk_display_beep( getGdkDisplay() ); 2334*cdf0e10cSrcweir break; 2335*cdf0e10cSrcweir default: 2336*cdf0e10cSrcweir break; 2337*cdf0e10cSrcweir } 2338*cdf0e10cSrcweir } 2339*cdf0e10cSrcweir 2340*cdf0e10cSrcweir const SystemEnvData* GtkSalFrame::GetSystemData() const 2341*cdf0e10cSrcweir { 2342*cdf0e10cSrcweir return &m_aSystemData; 2343*cdf0e10cSrcweir } 2344*cdf0e10cSrcweir 2345*cdf0e10cSrcweir void GtkSalFrame::SetParent( SalFrame* pNewParent ) 2346*cdf0e10cSrcweir { 2347*cdf0e10cSrcweir if( m_pParent ) 2348*cdf0e10cSrcweir m_pParent->m_aChildren.remove( this ); 2349*cdf0e10cSrcweir m_pParent = static_cast<GtkSalFrame*>(pNewParent); 2350*cdf0e10cSrcweir if( m_pParent ) 2351*cdf0e10cSrcweir m_pParent->m_aChildren.push_back( this ); 2352*cdf0e10cSrcweir if( ! isChild() ) 2353*cdf0e10cSrcweir gtk_window_set_transient_for( GTK_WINDOW(m_pWindow), 2354*cdf0e10cSrcweir (m_pParent && ! m_pParent->isChild(true,false)) ? GTK_WINDOW(m_pParent->m_pWindow) : NULL 2355*cdf0e10cSrcweir ); 2356*cdf0e10cSrcweir } 2357*cdf0e10cSrcweir 2358*cdf0e10cSrcweir void GtkSalFrame::createNewWindow( XLIB_Window aNewParent, bool bXEmbed, int nScreen ) 2359*cdf0e10cSrcweir { 2360*cdf0e10cSrcweir bool bWasVisible = GTK_WIDGET_MAPPED(m_pWindow); 2361*cdf0e10cSrcweir if( bWasVisible ) 2362*cdf0e10cSrcweir Show( sal_False ); 2363*cdf0e10cSrcweir 2364*cdf0e10cSrcweir if( nScreen < 0 || nScreen >= getDisplay()->GetScreenCount() ) 2365*cdf0e10cSrcweir nScreen = m_nScreen; 2366*cdf0e10cSrcweir 2367*cdf0e10cSrcweir SystemParentData aParentData; 2368*cdf0e10cSrcweir aParentData.aWindow = aNewParent; 2369*cdf0e10cSrcweir aParentData.bXEmbedSupport = bXEmbed; 2370*cdf0e10cSrcweir if( aNewParent == None ) 2371*cdf0e10cSrcweir { 2372*cdf0e10cSrcweir aNewParent = getDisplay()->GetRootWindow(nScreen); 2373*cdf0e10cSrcweir aParentData.aWindow = None; 2374*cdf0e10cSrcweir aParentData.bXEmbedSupport = false; 2375*cdf0e10cSrcweir } 2376*cdf0e10cSrcweir else 2377*cdf0e10cSrcweir { 2378*cdf0e10cSrcweir // is new parent a root window ? 2379*cdf0e10cSrcweir Display* pDisp = getDisplay()->GetDisplay(); 2380*cdf0e10cSrcweir int nScreens = getDisplay()->GetScreenCount(); 2381*cdf0e10cSrcweir for( int i = 0; i < nScreens; i++ ) 2382*cdf0e10cSrcweir { 2383*cdf0e10cSrcweir if( aNewParent == RootWindow( pDisp, i ) ) 2384*cdf0e10cSrcweir { 2385*cdf0e10cSrcweir nScreen = i; 2386*cdf0e10cSrcweir aParentData.aWindow = None; 2387*cdf0e10cSrcweir aParentData.bXEmbedSupport = false; 2388*cdf0e10cSrcweir break; 2389*cdf0e10cSrcweir } 2390*cdf0e10cSrcweir } 2391*cdf0e10cSrcweir } 2392*cdf0e10cSrcweir 2393*cdf0e10cSrcweir // free xrender resources 2394*cdf0e10cSrcweir for( unsigned int i = 0; i < sizeof(m_aGraphics)/sizeof(m_aGraphics[0]); i++ ) 2395*cdf0e10cSrcweir if( m_aGraphics[i].bInUse ) 2396*cdf0e10cSrcweir m_aGraphics[i].pGraphics->SetDrawable( None, m_nScreen ); 2397*cdf0e10cSrcweir 2398*cdf0e10cSrcweir // first deinit frame 2399*cdf0e10cSrcweir if( m_pIMHandler ) 2400*cdf0e10cSrcweir { 2401*cdf0e10cSrcweir delete m_pIMHandler; 2402*cdf0e10cSrcweir m_pIMHandler = NULL; 2403*cdf0e10cSrcweir } 2404*cdf0e10cSrcweir if( m_pRegion ) 2405*cdf0e10cSrcweir gdk_region_destroy( m_pRegion ); 2406*cdf0e10cSrcweir if( m_pFixedContainer ) 2407*cdf0e10cSrcweir gtk_widget_destroy( GTK_WIDGET(m_pFixedContainer) ); 2408*cdf0e10cSrcweir if( m_pWindow ) 2409*cdf0e10cSrcweir gtk_widget_destroy( m_pWindow ); 2410*cdf0e10cSrcweir if( m_pForeignParent ) 2411*cdf0e10cSrcweir g_object_unref( G_OBJECT(m_pForeignParent) ); 2412*cdf0e10cSrcweir if( m_pForeignTopLevel ) 2413*cdf0e10cSrcweir g_object_unref( G_OBJECT(m_pForeignTopLevel) ); 2414*cdf0e10cSrcweir 2415*cdf0e10cSrcweir // init new window 2416*cdf0e10cSrcweir m_bDefaultPos = m_bDefaultSize = false; 2417*cdf0e10cSrcweir if( aParentData.aWindow != None ) 2418*cdf0e10cSrcweir { 2419*cdf0e10cSrcweir m_nStyle |= SAL_FRAME_STYLE_PLUG; 2420*cdf0e10cSrcweir Init( &aParentData ); 2421*cdf0e10cSrcweir } 2422*cdf0e10cSrcweir else 2423*cdf0e10cSrcweir { 2424*cdf0e10cSrcweir m_nStyle &= ~SAL_FRAME_STYLE_PLUG; 2425*cdf0e10cSrcweir Init( (m_pParent && m_pParent->m_nScreen == m_nScreen) ? m_pParent : NULL, m_nStyle ); 2426*cdf0e10cSrcweir } 2427*cdf0e10cSrcweir 2428*cdf0e10cSrcweir // update graphics 2429*cdf0e10cSrcweir for( unsigned int i = 0; i < sizeof(m_aGraphics)/sizeof(m_aGraphics[0]); i++ ) 2430*cdf0e10cSrcweir { 2431*cdf0e10cSrcweir if( m_aGraphics[i].bInUse ) 2432*cdf0e10cSrcweir { 2433*cdf0e10cSrcweir m_aGraphics[i].pGraphics->SetDrawable( GDK_WINDOW_XWINDOW(m_pWindow->window), m_nScreen ); 2434*cdf0e10cSrcweir m_aGraphics[i].pGraphics->SetWindow( m_pWindow ); 2435*cdf0e10cSrcweir } 2436*cdf0e10cSrcweir } 2437*cdf0e10cSrcweir 2438*cdf0e10cSrcweir if( m_aTitle.Len() ) 2439*cdf0e10cSrcweir SetTitle( m_aTitle ); 2440*cdf0e10cSrcweir 2441*cdf0e10cSrcweir if( bWasVisible ) 2442*cdf0e10cSrcweir Show( sal_True ); 2443*cdf0e10cSrcweir 2444*cdf0e10cSrcweir std::list< GtkSalFrame* > aChildren = m_aChildren; 2445*cdf0e10cSrcweir m_aChildren.clear(); 2446*cdf0e10cSrcweir for( std::list< GtkSalFrame* >::iterator it = aChildren.begin(); it != aChildren.end(); ++it ) 2447*cdf0e10cSrcweir (*it)->createNewWindow( None, false, m_nScreen ); 2448*cdf0e10cSrcweir 2449*cdf0e10cSrcweir // FIXME: SalObjects 2450*cdf0e10cSrcweir } 2451*cdf0e10cSrcweir 2452*cdf0e10cSrcweir bool GtkSalFrame::SetPluginParent( SystemParentData* pSysParent ) 2453*cdf0e10cSrcweir { 2454*cdf0e10cSrcweir if( pSysParent ) // this may be the first system child frame now 2455*cdf0e10cSrcweir getDisplay()->setHaveSystemChildFrame(); 2456*cdf0e10cSrcweir createNewWindow( pSysParent->aWindow, (pSysParent->nSize > sizeof(long)) ? pSysParent->bXEmbedSupport : false, m_nScreen ); 2457*cdf0e10cSrcweir return true; 2458*cdf0e10cSrcweir } 2459*cdf0e10cSrcweir 2460*cdf0e10cSrcweir void GtkSalFrame::ResetClipRegion() 2461*cdf0e10cSrcweir { 2462*cdf0e10cSrcweir if( m_pWindow ) 2463*cdf0e10cSrcweir gdk_window_shape_combine_region( m_pWindow->window, NULL, 0, 0 ); 2464*cdf0e10cSrcweir } 2465*cdf0e10cSrcweir 2466*cdf0e10cSrcweir void GtkSalFrame::BeginSetClipRegion( sal_uLong ) 2467*cdf0e10cSrcweir { 2468*cdf0e10cSrcweir if( m_pRegion ) 2469*cdf0e10cSrcweir gdk_region_destroy( m_pRegion ); 2470*cdf0e10cSrcweir m_pRegion = gdk_region_new(); 2471*cdf0e10cSrcweir } 2472*cdf0e10cSrcweir 2473*cdf0e10cSrcweir void GtkSalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) 2474*cdf0e10cSrcweir { 2475*cdf0e10cSrcweir if( m_pRegion ) 2476*cdf0e10cSrcweir { 2477*cdf0e10cSrcweir GdkRectangle aRect; 2478*cdf0e10cSrcweir aRect.x = nX; 2479*cdf0e10cSrcweir aRect.y = nY; 2480*cdf0e10cSrcweir aRect.width = nWidth; 2481*cdf0e10cSrcweir aRect.height = nHeight; 2482*cdf0e10cSrcweir 2483*cdf0e10cSrcweir gdk_region_union_with_rect( m_pRegion, &aRect ); 2484*cdf0e10cSrcweir } 2485*cdf0e10cSrcweir } 2486*cdf0e10cSrcweir 2487*cdf0e10cSrcweir void GtkSalFrame::EndSetClipRegion() 2488*cdf0e10cSrcweir { 2489*cdf0e10cSrcweir if( m_pWindow && m_pRegion ) 2490*cdf0e10cSrcweir gdk_window_shape_combine_region( m_pWindow->window, m_pRegion, 0, 0 ); 2491*cdf0e10cSrcweir } 2492*cdf0e10cSrcweir 2493*cdf0e10cSrcweir bool GtkSalFrame::Dispatch( const XEvent* pEvent ) 2494*cdf0e10cSrcweir { 2495*cdf0e10cSrcweir bool bContinueDispatch = true; 2496*cdf0e10cSrcweir 2497*cdf0e10cSrcweir if( pEvent->type == PropertyNotify ) 2498*cdf0e10cSrcweir { 2499*cdf0e10cSrcweir vcl_sal::WMAdaptor* pAdaptor = getDisplay()->getWMAdaptor(); 2500*cdf0e10cSrcweir Atom nDesktopAtom = pAdaptor->getAtom( vcl_sal::WMAdaptor::NET_WM_DESKTOP ); 2501*cdf0e10cSrcweir if( pEvent->xproperty.atom == nDesktopAtom && 2502*cdf0e10cSrcweir pEvent->xproperty.state == PropertyNewValue ) 2503*cdf0e10cSrcweir { 2504*cdf0e10cSrcweir m_nWorkArea = pAdaptor->getWindowWorkArea( GDK_WINDOW_XWINDOW( m_pWindow->window) ); 2505*cdf0e10cSrcweir } 2506*cdf0e10cSrcweir } 2507*cdf0e10cSrcweir else if( pEvent->type == ConfigureNotify ) 2508*cdf0e10cSrcweir { 2509*cdf0e10cSrcweir if( m_pForeignParent && pEvent->xconfigure.window == m_aForeignParentWindow ) 2510*cdf0e10cSrcweir { 2511*cdf0e10cSrcweir bContinueDispatch = false; 2512*cdf0e10cSrcweir gtk_window_resize( GTK_WINDOW(m_pWindow), pEvent->xconfigure.width, pEvent->xconfigure.height ); 2513*cdf0e10cSrcweir if( ( sal::static_int_cast< int >(maGeometry.nWidth) != 2514*cdf0e10cSrcweir pEvent->xconfigure.width ) || 2515*cdf0e10cSrcweir ( sal::static_int_cast< int >(maGeometry.nHeight) != 2516*cdf0e10cSrcweir pEvent->xconfigure.height ) ) 2517*cdf0e10cSrcweir { 2518*cdf0e10cSrcweir maGeometry.nWidth = pEvent->xconfigure.width; 2519*cdf0e10cSrcweir maGeometry.nHeight = pEvent->xconfigure.height; 2520*cdf0e10cSrcweir setMinMaxSize(); 2521*cdf0e10cSrcweir getDisplay()->SendInternalEvent( this, NULL, SALEVENT_RESIZE ); 2522*cdf0e10cSrcweir } 2523*cdf0e10cSrcweir } 2524*cdf0e10cSrcweir else if( m_pForeignTopLevel && pEvent->xconfigure.window == m_aForeignTopLevelWindow ) 2525*cdf0e10cSrcweir { 2526*cdf0e10cSrcweir bContinueDispatch = false; 2527*cdf0e10cSrcweir // update position 2528*cdf0e10cSrcweir int x = 0, y = 0; 2529*cdf0e10cSrcweir XLIB_Window aChild; 2530*cdf0e10cSrcweir XTranslateCoordinates( getDisplay()->GetDisplay(), 2531*cdf0e10cSrcweir GDK_WINDOW_XWINDOW( m_pWindow->window), 2532*cdf0e10cSrcweir getDisplay()->GetRootWindow( getDisplay()->GetDefaultScreenNumber() ), 2533*cdf0e10cSrcweir 0, 0, 2534*cdf0e10cSrcweir &x, &y, 2535*cdf0e10cSrcweir &aChild ); 2536*cdf0e10cSrcweir if( x != maGeometry.nX || y != maGeometry.nY ) 2537*cdf0e10cSrcweir { 2538*cdf0e10cSrcweir maGeometry.nX = x; 2539*cdf0e10cSrcweir maGeometry.nY = y; 2540*cdf0e10cSrcweir getDisplay()->SendInternalEvent( this, NULL, SALEVENT_MOVE ); 2541*cdf0e10cSrcweir } 2542*cdf0e10cSrcweir } 2543*cdf0e10cSrcweir } 2544*cdf0e10cSrcweir else if( pEvent->type == ClientMessage && 2545*cdf0e10cSrcweir pEvent->xclient.message_type == getDisplay()->getWMAdaptor()->getAtom( vcl_sal::WMAdaptor::XEMBED ) && 2546*cdf0e10cSrcweir pEvent->xclient.window == GDK_WINDOW_XWINDOW(m_pWindow->window) && 2547*cdf0e10cSrcweir m_bWindowIsGtkPlug 2548*cdf0e10cSrcweir ) 2549*cdf0e10cSrcweir { 2550*cdf0e10cSrcweir // FIXME: this should not be necessary, GtkPlug should do this 2551*cdf0e10cSrcweir // transparently for us 2552*cdf0e10cSrcweir if( pEvent->xclient.data.l[1] == 1 || // XEMBED_WINDOW_ACTIVATE 2553*cdf0e10cSrcweir pEvent->xclient.data.l[1] == 2 // XEMBED_WINDOW_DEACTIVATE 2554*cdf0e10cSrcweir ) 2555*cdf0e10cSrcweir { 2556*cdf0e10cSrcweir GdkEventFocus aEvent; 2557*cdf0e10cSrcweir aEvent.type = GDK_FOCUS_CHANGE; 2558*cdf0e10cSrcweir aEvent.window = m_pWindow->window; 2559*cdf0e10cSrcweir aEvent.send_event = sal_True; 2560*cdf0e10cSrcweir aEvent.in = (pEvent->xclient.data.l[1] == 1); 2561*cdf0e10cSrcweir signalFocus( m_pWindow, &aEvent, this ); 2562*cdf0e10cSrcweir } 2563*cdf0e10cSrcweir } 2564*cdf0e10cSrcweir 2565*cdf0e10cSrcweir return bContinueDispatch; 2566*cdf0e10cSrcweir } 2567*cdf0e10cSrcweir 2568*cdf0e10cSrcweir void GtkSalFrame::SetBackgroundBitmap( SalBitmap* pBitmap ) 2569*cdf0e10cSrcweir { 2570*cdf0e10cSrcweir if( m_hBackgroundPixmap ) 2571*cdf0e10cSrcweir { 2572*cdf0e10cSrcweir XSetWindowBackgroundPixmap( getDisplay()->GetDisplay(), 2573*cdf0e10cSrcweir GDK_WINDOW_XWINDOW(m_pWindow->window), 2574*cdf0e10cSrcweir None ); 2575*cdf0e10cSrcweir XFreePixmap( getDisplay()->GetDisplay(), m_hBackgroundPixmap ); 2576*cdf0e10cSrcweir m_hBackgroundPixmap = None; 2577*cdf0e10cSrcweir } 2578*cdf0e10cSrcweir if( pBitmap ) 2579*cdf0e10cSrcweir { 2580*cdf0e10cSrcweir X11SalBitmap* pBM = static_cast<X11SalBitmap*>(pBitmap); 2581*cdf0e10cSrcweir Size aSize = pBM->GetSize(); 2582*cdf0e10cSrcweir if( aSize.Width() && aSize.Height() ) 2583*cdf0e10cSrcweir { 2584*cdf0e10cSrcweir m_hBackgroundPixmap = 2585*cdf0e10cSrcweir XCreatePixmap( getDisplay()->GetDisplay(), 2586*cdf0e10cSrcweir GDK_WINDOW_XWINDOW(m_pWindow->window), 2587*cdf0e10cSrcweir aSize.Width(), 2588*cdf0e10cSrcweir aSize.Height(), 2589*cdf0e10cSrcweir getDisplay()->GetVisual(m_nScreen).GetDepth() ); 2590*cdf0e10cSrcweir if( m_hBackgroundPixmap ) 2591*cdf0e10cSrcweir { 2592*cdf0e10cSrcweir SalTwoRect aTwoRect; 2593*cdf0e10cSrcweir aTwoRect.mnSrcX = aTwoRect.mnSrcY = aTwoRect.mnDestX = aTwoRect.mnDestY = 0; 2594*cdf0e10cSrcweir aTwoRect.mnSrcWidth = aTwoRect.mnDestWidth = aSize.Width(); 2595*cdf0e10cSrcweir aTwoRect.mnSrcHeight = aTwoRect.mnDestHeight = aSize.Height(); 2596*cdf0e10cSrcweir pBM->ImplDraw( m_hBackgroundPixmap, 2597*cdf0e10cSrcweir m_nScreen, 2598*cdf0e10cSrcweir getDisplay()->GetVisual(m_nScreen).GetDepth(), 2599*cdf0e10cSrcweir aTwoRect, 2600*cdf0e10cSrcweir getDisplay()->GetCopyGC(m_nScreen) ); 2601*cdf0e10cSrcweir XSetWindowBackgroundPixmap( getDisplay()->GetDisplay(), 2602*cdf0e10cSrcweir GDK_WINDOW_XWINDOW(m_pWindow->window), 2603*cdf0e10cSrcweir m_hBackgroundPixmap ); 2604*cdf0e10cSrcweir } 2605*cdf0e10cSrcweir } 2606*cdf0e10cSrcweir } 2607*cdf0e10cSrcweir } 2608*cdf0e10cSrcweir 2609*cdf0e10cSrcweir gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer frame ) 2610*cdf0e10cSrcweir { 2611*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 2612*cdf0e10cSrcweir SalMouseEvent aEvent; 2613*cdf0e10cSrcweir sal_uInt16 nEventType = 0; 2614*cdf0e10cSrcweir switch( pEvent->type ) 2615*cdf0e10cSrcweir { 2616*cdf0e10cSrcweir case GDK_BUTTON_PRESS: 2617*cdf0e10cSrcweir nEventType = SALEVENT_MOUSEBUTTONDOWN; 2618*cdf0e10cSrcweir break; 2619*cdf0e10cSrcweir case GDK_BUTTON_RELEASE: 2620*cdf0e10cSrcweir nEventType = SALEVENT_MOUSEBUTTONUP; 2621*cdf0e10cSrcweir break; 2622*cdf0e10cSrcweir default: 2623*cdf0e10cSrcweir return sal_False; 2624*cdf0e10cSrcweir } 2625*cdf0e10cSrcweir switch( pEvent->button ) 2626*cdf0e10cSrcweir { 2627*cdf0e10cSrcweir case 1: aEvent.mnButton = MOUSE_LEFT; break; 2628*cdf0e10cSrcweir case 2: aEvent.mnButton = MOUSE_MIDDLE; break; 2629*cdf0e10cSrcweir case 3: aEvent.mnButton = MOUSE_RIGHT; break; 2630*cdf0e10cSrcweir default: return sal_False; 2631*cdf0e10cSrcweir } 2632*cdf0e10cSrcweir aEvent.mnTime = pEvent->time; 2633*cdf0e10cSrcweir aEvent.mnX = (long)pEvent->x_root - pThis->maGeometry.nX; 2634*cdf0e10cSrcweir aEvent.mnY = (long)pEvent->y_root - pThis->maGeometry.nY; 2635*cdf0e10cSrcweir aEvent.mnCode = GetMouseModCode( pEvent->state ); 2636*cdf0e10cSrcweir 2637*cdf0e10cSrcweir bool bClosePopups = false; 2638*cdf0e10cSrcweir if( pEvent->type == GDK_BUTTON_PRESS && 2639*cdf0e10cSrcweir (pThis->m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) == 0 2640*cdf0e10cSrcweir ) 2641*cdf0e10cSrcweir { 2642*cdf0e10cSrcweir if( m_nFloats > 0 ) 2643*cdf0e10cSrcweir { 2644*cdf0e10cSrcweir // close popups if user clicks outside our application 2645*cdf0e10cSrcweir gint x, y; 2646*cdf0e10cSrcweir bClosePopups = (gdk_display_get_window_at_pointer( pThis->getGdkDisplay(), &x, &y ) == NULL); 2647*cdf0e10cSrcweir } 2648*cdf0e10cSrcweir /* #i30306# release implicit pointer grab if no popups are open; else 2649*cdf0e10cSrcweir * Drag cannot grab the pointer and will fail. 2650*cdf0e10cSrcweir */ 2651*cdf0e10cSrcweir if( m_nFloats < 1 || bClosePopups ) 2652*cdf0e10cSrcweir gdk_display_pointer_ungrab( pThis->getGdkDisplay(), GDK_CURRENT_TIME ); 2653*cdf0e10cSrcweir } 2654*cdf0e10cSrcweir 2655*cdf0e10cSrcweir GTK_YIELD_GRAB(); 2656*cdf0e10cSrcweir 2657*cdf0e10cSrcweir if( pThis->m_bWindowIsGtkPlug && 2658*cdf0e10cSrcweir pEvent->type == GDK_BUTTON_PRESS && 2659*cdf0e10cSrcweir pEvent->button == 1 ) 2660*cdf0e10cSrcweir { 2661*cdf0e10cSrcweir pThis->askForXEmbedFocus( pEvent->time ); 2662*cdf0e10cSrcweir } 2663*cdf0e10cSrcweir 2664*cdf0e10cSrcweir // --- RTL --- (mirror mouse pos) 2665*cdf0e10cSrcweir if( Application::GetSettings().GetLayoutRTL() ) 2666*cdf0e10cSrcweir aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; 2667*cdf0e10cSrcweir 2668*cdf0e10cSrcweir vcl::DeletionListener aDel( pThis ); 2669*cdf0e10cSrcweir 2670*cdf0e10cSrcweir pThis->CallCallback( nEventType, &aEvent ); 2671*cdf0e10cSrcweir 2672*cdf0e10cSrcweir if( ! aDel.isDeleted() ) 2673*cdf0e10cSrcweir { 2674*cdf0e10cSrcweir if( bClosePopups ) 2675*cdf0e10cSrcweir { 2676*cdf0e10cSrcweir ImplSVData* pSVData = ImplGetSVData(); 2677*cdf0e10cSrcweir if ( pSVData->maWinData.mpFirstFloat ) 2678*cdf0e10cSrcweir { 2679*cdf0e10cSrcweir static const char* pEnv = getenv( "SAL_FLOATWIN_NOAPPFOCUSCLOSE" ); 2680*cdf0e10cSrcweir if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) && !(pEnv && *pEnv) ) 2681*cdf0e10cSrcweir pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL ); 2682*cdf0e10cSrcweir } 2683*cdf0e10cSrcweir } 2684*cdf0e10cSrcweir 2685*cdf0e10cSrcweir if( ! aDel.isDeleted() ) 2686*cdf0e10cSrcweir { 2687*cdf0e10cSrcweir int frame_x = (int)(pEvent->x_root - pEvent->x); 2688*cdf0e10cSrcweir int frame_y = (int)(pEvent->y_root - pEvent->y); 2689*cdf0e10cSrcweir if( frame_x != pThis->maGeometry.nX || frame_y != pThis->maGeometry.nY ) 2690*cdf0e10cSrcweir { 2691*cdf0e10cSrcweir pThis->maGeometry.nX = frame_x; 2692*cdf0e10cSrcweir pThis->maGeometry.nY = frame_y; 2693*cdf0e10cSrcweir pThis->CallCallback( SALEVENT_MOVE, NULL ); 2694*cdf0e10cSrcweir } 2695*cdf0e10cSrcweir } 2696*cdf0e10cSrcweir } 2697*cdf0e10cSrcweir 2698*cdf0e10cSrcweir return sal_False; 2699*cdf0e10cSrcweir } 2700*cdf0e10cSrcweir 2701*cdf0e10cSrcweir gboolean GtkSalFrame::signalScroll( GtkWidget*, GdkEvent* pEvent, gpointer frame ) 2702*cdf0e10cSrcweir { 2703*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 2704*cdf0e10cSrcweir GdkEventScroll* pSEvent = (GdkEventScroll*)pEvent; 2705*cdf0e10cSrcweir 2706*cdf0e10cSrcweir static sal_uLong nLines = 0; 2707*cdf0e10cSrcweir if( ! nLines ) 2708*cdf0e10cSrcweir { 2709*cdf0e10cSrcweir char* pEnv = getenv( "SAL_WHEELLINES" ); 2710*cdf0e10cSrcweir nLines = pEnv ? atoi( pEnv ) : 3; 2711*cdf0e10cSrcweir if( nLines > 10 ) 2712*cdf0e10cSrcweir nLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; 2713*cdf0e10cSrcweir } 2714*cdf0e10cSrcweir 2715*cdf0e10cSrcweir bool bNeg = (pSEvent->direction == GDK_SCROLL_DOWN || pSEvent->direction == GDK_SCROLL_RIGHT ); 2716*cdf0e10cSrcweir SalWheelMouseEvent aEvent; 2717*cdf0e10cSrcweir aEvent.mnTime = pSEvent->time; 2718*cdf0e10cSrcweir aEvent.mnX = (sal_uLong)pSEvent->x; 2719*cdf0e10cSrcweir aEvent.mnY = (sal_uLong)pSEvent->y; 2720*cdf0e10cSrcweir aEvent.mnDelta = bNeg ? -120 : 120; 2721*cdf0e10cSrcweir aEvent.mnNotchDelta = bNeg ? -1 : 1; 2722*cdf0e10cSrcweir aEvent.mnScrollLines = nLines; 2723*cdf0e10cSrcweir aEvent.mnCode = GetMouseModCode( pSEvent->state ); 2724*cdf0e10cSrcweir aEvent.mbHorz = (pSEvent->direction == GDK_SCROLL_LEFT || pSEvent->direction == GDK_SCROLL_RIGHT); 2725*cdf0e10cSrcweir 2726*cdf0e10cSrcweir GTK_YIELD_GRAB(); 2727*cdf0e10cSrcweir 2728*cdf0e10cSrcweir // --- RTL --- (mirror mouse pos) 2729*cdf0e10cSrcweir if( Application::GetSettings().GetLayoutRTL() ) 2730*cdf0e10cSrcweir aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; 2731*cdf0e10cSrcweir 2732*cdf0e10cSrcweir pThis->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 2733*cdf0e10cSrcweir 2734*cdf0e10cSrcweir return sal_False; 2735*cdf0e10cSrcweir } 2736*cdf0e10cSrcweir 2737*cdf0e10cSrcweir gboolean GtkSalFrame::signalMotion( GtkWidget*, GdkEventMotion* pEvent, gpointer frame ) 2738*cdf0e10cSrcweir { 2739*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 2740*cdf0e10cSrcweir 2741*cdf0e10cSrcweir SalMouseEvent aEvent; 2742*cdf0e10cSrcweir aEvent.mnTime = pEvent->time; 2743*cdf0e10cSrcweir aEvent.mnX = (long)pEvent->x_root - pThis->maGeometry.nX; 2744*cdf0e10cSrcweir aEvent.mnY = (long)pEvent->y_root - pThis->maGeometry.nY; 2745*cdf0e10cSrcweir aEvent.mnCode = GetMouseModCode( pEvent->state ); 2746*cdf0e10cSrcweir aEvent.mnButton = 0; 2747*cdf0e10cSrcweir 2748*cdf0e10cSrcweir 2749*cdf0e10cSrcweir GTK_YIELD_GRAB(); 2750*cdf0e10cSrcweir 2751*cdf0e10cSrcweir // --- RTL --- (mirror mouse pos) 2752*cdf0e10cSrcweir if( Application::GetSettings().GetLayoutRTL() ) 2753*cdf0e10cSrcweir aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; 2754*cdf0e10cSrcweir 2755*cdf0e10cSrcweir vcl::DeletionListener aDel( pThis ); 2756*cdf0e10cSrcweir 2757*cdf0e10cSrcweir pThis->CallCallback( SALEVENT_MOUSEMOVE, &aEvent ); 2758*cdf0e10cSrcweir 2759*cdf0e10cSrcweir if( ! aDel.isDeleted() ) 2760*cdf0e10cSrcweir { 2761*cdf0e10cSrcweir int frame_x = (int)(pEvent->x_root - pEvent->x); 2762*cdf0e10cSrcweir int frame_y = (int)(pEvent->y_root - pEvent->y); 2763*cdf0e10cSrcweir if( frame_x != pThis->maGeometry.nX || frame_y != pThis->maGeometry.nY ) 2764*cdf0e10cSrcweir { 2765*cdf0e10cSrcweir pThis->maGeometry.nX = frame_x; 2766*cdf0e10cSrcweir pThis->maGeometry.nY = frame_y; 2767*cdf0e10cSrcweir pThis->CallCallback( SALEVENT_MOVE, NULL ); 2768*cdf0e10cSrcweir } 2769*cdf0e10cSrcweir 2770*cdf0e10cSrcweir if( ! aDel.isDeleted() ) 2771*cdf0e10cSrcweir { 2772*cdf0e10cSrcweir // ask for the next hint 2773*cdf0e10cSrcweir gint x, y; 2774*cdf0e10cSrcweir GdkModifierType mask; 2775*cdf0e10cSrcweir gdk_window_get_pointer( GTK_WIDGET(pThis->m_pWindow)->window, &x, &y, &mask ); 2776*cdf0e10cSrcweir } 2777*cdf0e10cSrcweir } 2778*cdf0e10cSrcweir 2779*cdf0e10cSrcweir return sal_True; 2780*cdf0e10cSrcweir } 2781*cdf0e10cSrcweir 2782*cdf0e10cSrcweir gboolean GtkSalFrame::signalCrossing( GtkWidget*, GdkEventCrossing* pEvent, gpointer frame ) 2783*cdf0e10cSrcweir { 2784*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 2785*cdf0e10cSrcweir SalMouseEvent aEvent; 2786*cdf0e10cSrcweir aEvent.mnTime = pEvent->time; 2787*cdf0e10cSrcweir aEvent.mnX = (long)pEvent->x_root - pThis->maGeometry.nX; 2788*cdf0e10cSrcweir aEvent.mnY = (long)pEvent->y_root - pThis->maGeometry.nY; 2789*cdf0e10cSrcweir aEvent.mnCode = GetMouseModCode( pEvent->state ); 2790*cdf0e10cSrcweir aEvent.mnButton = 0; 2791*cdf0e10cSrcweir 2792*cdf0e10cSrcweir GTK_YIELD_GRAB(); 2793*cdf0e10cSrcweir pThis->CallCallback( (pEvent->type == GDK_ENTER_NOTIFY) ? SALEVENT_MOUSEMOVE : SALEVENT_MOUSELEAVE, &aEvent ); 2794*cdf0e10cSrcweir 2795*cdf0e10cSrcweir return sal_True; 2796*cdf0e10cSrcweir } 2797*cdf0e10cSrcweir 2798*cdf0e10cSrcweir 2799*cdf0e10cSrcweir gboolean GtkSalFrame::signalExpose( GtkWidget*, GdkEventExpose* pEvent, gpointer frame ) 2800*cdf0e10cSrcweir { 2801*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 2802*cdf0e10cSrcweir 2803*cdf0e10cSrcweir struct SalPaintEvent aEvent( pEvent->area.x, pEvent->area.y, pEvent->area.width, pEvent->area.height ); 2804*cdf0e10cSrcweir 2805*cdf0e10cSrcweir GTK_YIELD_GRAB(); 2806*cdf0e10cSrcweir pThis->CallCallback( SALEVENT_PAINT, &aEvent ); 2807*cdf0e10cSrcweir 2808*cdf0e10cSrcweir return sal_False; 2809*cdf0e10cSrcweir } 2810*cdf0e10cSrcweir 2811*cdf0e10cSrcweir gboolean GtkSalFrame::signalFocus( GtkWidget*, GdkEventFocus* pEvent, gpointer frame ) 2812*cdf0e10cSrcweir { 2813*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 2814*cdf0e10cSrcweir 2815*cdf0e10cSrcweir GTK_YIELD_GRAB(); 2816*cdf0e10cSrcweir 2817*cdf0e10cSrcweir // check if printers have changed (analogous to salframe focus handler) 2818*cdf0e10cSrcweir vcl_sal::PrinterUpdate::update(); 2819*cdf0e10cSrcweir 2820*cdf0e10cSrcweir if( !pEvent->in ) 2821*cdf0e10cSrcweir { 2822*cdf0e10cSrcweir pThis->m_nKeyModifiers = 0; 2823*cdf0e10cSrcweir pThis->m_bSingleAltPress = false; 2824*cdf0e10cSrcweir pThis->m_bSendModChangeOnRelease = false; 2825*cdf0e10cSrcweir } 2826*cdf0e10cSrcweir 2827*cdf0e10cSrcweir if( pThis->m_pIMHandler ) 2828*cdf0e10cSrcweir pThis->m_pIMHandler->focusChanged( pEvent->in ); 2829*cdf0e10cSrcweir 2830*cdf0e10cSrcweir // ask for changed printers like generic implementation 2831*cdf0e10cSrcweir if( pEvent->in ) 2832*cdf0e10cSrcweir if( static_cast< X11SalInstance* >(GetSalData()->m_pInstance)->isPrinterInit() ) 2833*cdf0e10cSrcweir vcl_sal::PrinterUpdate::update(); 2834*cdf0e10cSrcweir 2835*cdf0e10cSrcweir // FIXME: find out who the hell steals the focus from our frame 2836*cdf0e10cSrcweir // while we have the pointer grabbed, this should not come from 2837*cdf0e10cSrcweir // the window manager. Is this an event that was still queued ? 2838*cdf0e10cSrcweir // The focus does not seem to get set inside our process 2839*cdf0e10cSrcweir // 2840*cdf0e10cSrcweir // in the meantime do not propagate focus get/lose if floats are open 2841*cdf0e10cSrcweir if( m_nFloats == 0 ) 2842*cdf0e10cSrcweir pThis->CallCallback( pEvent->in ? SALEVENT_GETFOCUS : SALEVENT_LOSEFOCUS, NULL ); 2843*cdf0e10cSrcweir 2844*cdf0e10cSrcweir return sal_False; 2845*cdf0e10cSrcweir } 2846*cdf0e10cSrcweir 2847*cdf0e10cSrcweir IMPL_LINK( GtkSalFrame, ImplDelayedFullScreenHdl, void*, EMPTYARG ) 2848*cdf0e10cSrcweir { 2849*cdf0e10cSrcweir Atom nStateAtom = getDisplay()->getWMAdaptor()->getAtom(vcl_sal::WMAdaptor::NET_WM_STATE); 2850*cdf0e10cSrcweir Atom nFSAtom = getDisplay()->getWMAdaptor()->getAtom(vcl_sal::WMAdaptor::NET_WM_STATE_FULLSCREEN ); 2851*cdf0e10cSrcweir if( nStateAtom && nFSAtom ) 2852*cdf0e10cSrcweir { 2853*cdf0e10cSrcweir /* #i110881# workaround a gtk issue (see https://bugzilla.redhat.com/show_bug.cgi?id=623191#c8) 2854*cdf0e10cSrcweir gtk_window_fullscreen can fail due to a race condition, request an additional status change 2855*cdf0e10cSrcweir to fullscreen to be safe 2856*cdf0e10cSrcweir */ 2857*cdf0e10cSrcweir XEvent aEvent; 2858*cdf0e10cSrcweir aEvent.type = ClientMessage; 2859*cdf0e10cSrcweir aEvent.xclient.display = getDisplay()->GetDisplay(); 2860*cdf0e10cSrcweir aEvent.xclient.window = GDK_WINDOW_XWINDOW(m_pWindow->window); 2861*cdf0e10cSrcweir aEvent.xclient.message_type = nStateAtom; 2862*cdf0e10cSrcweir aEvent.xclient.format = 32; 2863*cdf0e10cSrcweir aEvent.xclient.data.l[0] = 1; 2864*cdf0e10cSrcweir aEvent.xclient.data.l[1] = nFSAtom; 2865*cdf0e10cSrcweir aEvent.xclient.data.l[2] = 0; 2866*cdf0e10cSrcweir aEvent.xclient.data.l[3] = 0; 2867*cdf0e10cSrcweir aEvent.xclient.data.l[4] = 0; 2868*cdf0e10cSrcweir XSendEvent( getDisplay()->GetDisplay(), 2869*cdf0e10cSrcweir getDisplay()->GetRootWindow( m_nScreen ), 2870*cdf0e10cSrcweir False, 2871*cdf0e10cSrcweir SubstructureNotifyMask | SubstructureRedirectMask, 2872*cdf0e10cSrcweir &aEvent 2873*cdf0e10cSrcweir ); 2874*cdf0e10cSrcweir } 2875*cdf0e10cSrcweir 2876*cdf0e10cSrcweir return 0; 2877*cdf0e10cSrcweir } 2878*cdf0e10cSrcweir 2879*cdf0e10cSrcweir gboolean GtkSalFrame::signalMap( GtkWidget*, GdkEvent*, gpointer frame ) 2880*cdf0e10cSrcweir { 2881*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 2882*cdf0e10cSrcweir 2883*cdf0e10cSrcweir GTK_YIELD_GRAB(); 2884*cdf0e10cSrcweir 2885*cdf0e10cSrcweir if( pThis->m_bFullscreen ) 2886*cdf0e10cSrcweir { 2887*cdf0e10cSrcweir /* #i110881# workaorund a gtk issue (see https://bugzilla.redhat.com/show_bug.cgi?id=623191#c8) 2888*cdf0e10cSrcweir gtk_window_fullscreen can run into a race condition with the window's showstate 2889*cdf0e10cSrcweir */ 2890*cdf0e10cSrcweir Application::PostUserEvent( LINK( pThis, GtkSalFrame, ImplDelayedFullScreenHdl ) ); 2891*cdf0e10cSrcweir } 2892*cdf0e10cSrcweir 2893*cdf0e10cSrcweir bool bSetFocus = pThis->m_bSetFocusOnMap; 2894*cdf0e10cSrcweir pThis->m_bSetFocusOnMap = false; 2895*cdf0e10cSrcweir if( ImplGetSVData()->mbIsTestTool ) 2896*cdf0e10cSrcweir { 2897*cdf0e10cSrcweir /* #i76541# testtool needs the focus to be in a new document 2898*cdf0e10cSrcweir * however e.g. metacity does not necessarily put the focus into 2899*cdf0e10cSrcweir * a newly shown window. An extra little hint seems to help here. 2900*cdf0e10cSrcweir * however we don't want to interfere with the normal user experience 2901*cdf0e10cSrcweir * so this is done when running in testtool only 2902*cdf0e10cSrcweir */ 2903*cdf0e10cSrcweir if( ! pThis->m_pParent && (pThis->m_nStyle & SAL_FRAME_STYLE_MOVEABLE) != 0 ) 2904*cdf0e10cSrcweir bSetFocus = true; 2905*cdf0e10cSrcweir } 2906*cdf0e10cSrcweir 2907*cdf0e10cSrcweir if( bSetFocus ) 2908*cdf0e10cSrcweir { 2909*cdf0e10cSrcweir XSetInputFocus( pThis->getDisplay()->GetDisplay(), 2910*cdf0e10cSrcweir GDK_WINDOW_XWINDOW( GTK_WIDGET(pThis->m_pWindow)->window), 2911*cdf0e10cSrcweir RevertToParent, CurrentTime ); 2912*cdf0e10cSrcweir } 2913*cdf0e10cSrcweir 2914*cdf0e10cSrcweir pThis->CallCallback( SALEVENT_RESIZE, NULL ); 2915*cdf0e10cSrcweir 2916*cdf0e10cSrcweir return sal_False; 2917*cdf0e10cSrcweir } 2918*cdf0e10cSrcweir 2919*cdf0e10cSrcweir gboolean GtkSalFrame::signalUnmap( GtkWidget*, GdkEvent*, gpointer frame ) 2920*cdf0e10cSrcweir { 2921*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 2922*cdf0e10cSrcweir 2923*cdf0e10cSrcweir GTK_YIELD_GRAB(); 2924*cdf0e10cSrcweir pThis->CallCallback( SALEVENT_RESIZE, NULL ); 2925*cdf0e10cSrcweir 2926*cdf0e10cSrcweir return sal_False; 2927*cdf0e10cSrcweir } 2928*cdf0e10cSrcweir 2929*cdf0e10cSrcweir gboolean GtkSalFrame::signalConfigure( GtkWidget*, GdkEventConfigure* pEvent, gpointer frame ) 2930*cdf0e10cSrcweir { 2931*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 2932*cdf0e10cSrcweir 2933*cdf0e10cSrcweir bool bMoved = false, bSized = false; 2934*cdf0e10cSrcweir int x = pEvent->x, y = pEvent->y; 2935*cdf0e10cSrcweir 2936*cdf0e10cSrcweir /* HACK: during sizing/moving a toolbar pThis->maGeometry is actually 2937*cdf0e10cSrcweir * already exact; even worse: due to the asynchronicity of configure 2938*cdf0e10cSrcweir * events the borderwindow which would evaluate this event 2939*cdf0e10cSrcweir * would size/move based on wrong data if we would actually evaluate 2940*cdf0e10cSrcweir * this event. So let's swallow it; this is also a performance 2941*cdf0e10cSrcweir * improvement as one can omit the synchronous XTranslateCoordinates 2942*cdf0e10cSrcweir * call below. 2943*cdf0e10cSrcweir */ 2944*cdf0e10cSrcweir if( (pThis->m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) && 2945*cdf0e10cSrcweir pThis->getDisplay()->GetCaptureFrame() == pThis ) 2946*cdf0e10cSrcweir return sal_False; 2947*cdf0e10cSrcweir 2948*cdf0e10cSrcweir 2949*cdf0e10cSrcweir // in child case the coordinates are not root coordinates, 2950*cdf0e10cSrcweir // need to transform 2951*cdf0e10cSrcweir 2952*cdf0e10cSrcweir /* #i31785# sadly one cannot really trust the x,y members of the event; 2953*cdf0e10cSrcweir * they are e.g. not set correctly on maximize/demaximize; this rather 2954*cdf0e10cSrcweir * sounds like a bug in gtk we have to workaround. 2955*cdf0e10cSrcweir */ 2956*cdf0e10cSrcweir XLIB_Window aChild; 2957*cdf0e10cSrcweir XTranslateCoordinates( pThis->getDisplay()->GetDisplay(), 2958*cdf0e10cSrcweir GDK_WINDOW_XWINDOW(GTK_WIDGET(pThis->m_pWindow)->window), 2959*cdf0e10cSrcweir pThis->getDisplay()->GetRootWindow( pThis->getDisplay()->GetDefaultScreenNumber() ), 2960*cdf0e10cSrcweir 0, 0, 2961*cdf0e10cSrcweir &x, &y, 2962*cdf0e10cSrcweir &aChild ); 2963*cdf0e10cSrcweir 2964*cdf0e10cSrcweir if( x != pThis->maGeometry.nX || y != pThis->maGeometry.nY ) 2965*cdf0e10cSrcweir { 2966*cdf0e10cSrcweir bMoved = true; 2967*cdf0e10cSrcweir pThis->maGeometry.nX = x; 2968*cdf0e10cSrcweir pThis->maGeometry.nY = y; 2969*cdf0e10cSrcweir } 2970*cdf0e10cSrcweir /* #i86302# 2971*cdf0e10cSrcweir * for non sizeable windows we set the min and max hint for the window manager to 2972*cdf0e10cSrcweir * achieve correct sizing. However this is asynchronous and e.g. on Compiz 2973*cdf0e10cSrcweir * it sometimes happens that the window gets resized to another size (some default) 2974*cdf0e10cSrcweir * if we update the size here, subsequent setMinMaxSize will use this wrong size 2975*cdf0e10cSrcweir * - which is not good since the window manager will now size the window back to this 2976*cdf0e10cSrcweir * wrong size at some point. 2977*cdf0e10cSrcweir */ 2978*cdf0e10cSrcweir if( (pThis->m_nStyle & (SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_PLUG)) == SAL_FRAME_STYLE_SIZEABLE ) 2979*cdf0e10cSrcweir { 2980*cdf0e10cSrcweir if( pEvent->width != (int)pThis->maGeometry.nWidth || pEvent->height != (int)pThis->maGeometry.nHeight ) 2981*cdf0e10cSrcweir { 2982*cdf0e10cSrcweir bSized = true; 2983*cdf0e10cSrcweir pThis->maGeometry.nWidth = pEvent->width; 2984*cdf0e10cSrcweir pThis->maGeometry.nHeight = pEvent->height; 2985*cdf0e10cSrcweir } 2986*cdf0e10cSrcweir } 2987*cdf0e10cSrcweir 2988*cdf0e10cSrcweir // update decoration hints 2989*cdf0e10cSrcweir if( ! (pThis->m_nStyle & SAL_FRAME_STYLE_PLUG) ) 2990*cdf0e10cSrcweir { 2991*cdf0e10cSrcweir GdkRectangle aRect; 2992*cdf0e10cSrcweir gdk_window_get_frame_extents( GTK_WIDGET(pThis->m_pWindow)->window, &aRect ); 2993*cdf0e10cSrcweir pThis->maGeometry.nTopDecoration = y - aRect.y; 2994*cdf0e10cSrcweir pThis->maGeometry.nBottomDecoration = aRect.y + aRect.height - y - pEvent->height; 2995*cdf0e10cSrcweir pThis->maGeometry.nLeftDecoration = x - aRect.x; 2996*cdf0e10cSrcweir pThis->maGeometry.nRightDecoration = aRect.x + aRect.width - x - pEvent->width; 2997*cdf0e10cSrcweir } 2998*cdf0e10cSrcweir else 2999*cdf0e10cSrcweir { 3000*cdf0e10cSrcweir pThis->maGeometry.nTopDecoration = 3001*cdf0e10cSrcweir pThis->maGeometry.nBottomDecoration = 3002*cdf0e10cSrcweir pThis->maGeometry.nLeftDecoration = 3003*cdf0e10cSrcweir pThis->maGeometry.nRightDecoration = 0; 3004*cdf0e10cSrcweir } 3005*cdf0e10cSrcweir 3006*cdf0e10cSrcweir GTK_YIELD_GRAB(); 3007*cdf0e10cSrcweir pThis->updateScreenNumber(); 3008*cdf0e10cSrcweir if( bMoved && bSized ) 3009*cdf0e10cSrcweir pThis->CallCallback( SALEVENT_MOVERESIZE, NULL ); 3010*cdf0e10cSrcweir else if( bMoved ) 3011*cdf0e10cSrcweir pThis->CallCallback( SALEVENT_MOVE, NULL ); 3012*cdf0e10cSrcweir else if( bSized ) 3013*cdf0e10cSrcweir pThis->CallCallback( SALEVENT_RESIZE, NULL ); 3014*cdf0e10cSrcweir 3015*cdf0e10cSrcweir return sal_False; 3016*cdf0e10cSrcweir } 3017*cdf0e10cSrcweir 3018*cdf0e10cSrcweir gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame ) 3019*cdf0e10cSrcweir { 3020*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 3021*cdf0e10cSrcweir 3022*cdf0e10cSrcweir vcl::DeletionListener aDel( pThis ); 3023*cdf0e10cSrcweir 3024*cdf0e10cSrcweir if( pThis->m_pIMHandler ) 3025*cdf0e10cSrcweir { 3026*cdf0e10cSrcweir if( pThis->m_pIMHandler->handleKeyEvent( pEvent ) ) 3027*cdf0e10cSrcweir { 3028*cdf0e10cSrcweir pThis->m_bSingleAltPress = false; 3029*cdf0e10cSrcweir return sal_True; 3030*cdf0e10cSrcweir } 3031*cdf0e10cSrcweir } 3032*cdf0e10cSrcweir GTK_YIELD_GRAB(); 3033*cdf0e10cSrcweir 3034*cdf0e10cSrcweir // handle modifiers 3035*cdf0e10cSrcweir if( pEvent->keyval == GDK_Shift_L || pEvent->keyval == GDK_Shift_R || 3036*cdf0e10cSrcweir pEvent->keyval == GDK_Control_L || pEvent->keyval == GDK_Control_R || 3037*cdf0e10cSrcweir pEvent->keyval == GDK_Alt_L || pEvent->keyval == GDK_Alt_R || 3038*cdf0e10cSrcweir pEvent->keyval == GDK_Meta_L || pEvent->keyval == GDK_Meta_R || 3039*cdf0e10cSrcweir pEvent->keyval == GDK_Super_L || pEvent->keyval == GDK_Super_R ) 3040*cdf0e10cSrcweir { 3041*cdf0e10cSrcweir SalKeyModEvent aModEvt; 3042*cdf0e10cSrcweir 3043*cdf0e10cSrcweir sal_uInt16 nModCode = GetKeyModCode( pEvent->state ); 3044*cdf0e10cSrcweir 3045*cdf0e10cSrcweir aModEvt.mnModKeyCode = 0; // emit no MODKEYCHANGE events 3046*cdf0e10cSrcweir if( pEvent->type == GDK_KEY_PRESS && !pThis->m_nKeyModifiers ) 3047*cdf0e10cSrcweir pThis->m_bSendModChangeOnRelease = true; 3048*cdf0e10cSrcweir 3049*cdf0e10cSrcweir else if( pEvent->type == GDK_KEY_RELEASE && 3050*cdf0e10cSrcweir pThis->m_bSendModChangeOnRelease ) 3051*cdf0e10cSrcweir { 3052*cdf0e10cSrcweir aModEvt.mnModKeyCode = pThis->m_nKeyModifiers; 3053*cdf0e10cSrcweir pThis->m_nKeyModifiers = 0; 3054*cdf0e10cSrcweir } 3055*cdf0e10cSrcweir 3056*cdf0e10cSrcweir sal_uInt16 nExtModMask = 0; 3057*cdf0e10cSrcweir sal_uInt16 nModMask = 0; 3058*cdf0e10cSrcweir // pressing just the ctrl key leads to a keysym of XK_Control but 3059*cdf0e10cSrcweir // the event state does not contain ControlMask. In the release 3060*cdf0e10cSrcweir // event its the other way round: it does contain the Control mask. 3061*cdf0e10cSrcweir // The modifier mode therefore has to be adapted manually. 3062*cdf0e10cSrcweir switch( pEvent->keyval ) 3063*cdf0e10cSrcweir { 3064*cdf0e10cSrcweir case GDK_Control_L: 3065*cdf0e10cSrcweir nExtModMask = MODKEY_LMOD1; 3066*cdf0e10cSrcweir nModMask = KEY_MOD1; 3067*cdf0e10cSrcweir break; 3068*cdf0e10cSrcweir case GDK_Control_R: 3069*cdf0e10cSrcweir nExtModMask = MODKEY_RMOD1; 3070*cdf0e10cSrcweir nModMask = KEY_MOD1; 3071*cdf0e10cSrcweir break; 3072*cdf0e10cSrcweir case GDK_Alt_L: 3073*cdf0e10cSrcweir nExtModMask = MODKEY_LMOD2; 3074*cdf0e10cSrcweir nModMask = KEY_MOD2; 3075*cdf0e10cSrcweir break; 3076*cdf0e10cSrcweir case GDK_Alt_R: 3077*cdf0e10cSrcweir nExtModMask = MODKEY_RMOD2; 3078*cdf0e10cSrcweir nModMask = KEY_MOD2; 3079*cdf0e10cSrcweir break; 3080*cdf0e10cSrcweir case GDK_Shift_L: 3081*cdf0e10cSrcweir nExtModMask = MODKEY_LSHIFT; 3082*cdf0e10cSrcweir nModMask = KEY_SHIFT; 3083*cdf0e10cSrcweir break; 3084*cdf0e10cSrcweir case GDK_Shift_R: 3085*cdf0e10cSrcweir nExtModMask = MODKEY_RSHIFT; 3086*cdf0e10cSrcweir nModMask = KEY_SHIFT; 3087*cdf0e10cSrcweir break; 3088*cdf0e10cSrcweir // Map Meta/Super to MOD3 modifier on all Unix systems 3089*cdf0e10cSrcweir // except Mac OS X 3090*cdf0e10cSrcweir case GDK_Meta_L: 3091*cdf0e10cSrcweir case GDK_Super_L: 3092*cdf0e10cSrcweir nExtModMask = MODKEY_LMOD3; 3093*cdf0e10cSrcweir nModMask = KEY_MOD3; 3094*cdf0e10cSrcweir break; 3095*cdf0e10cSrcweir case GDK_Meta_R: 3096*cdf0e10cSrcweir case GDK_Super_R: 3097*cdf0e10cSrcweir nExtModMask = MODKEY_RMOD3; 3098*cdf0e10cSrcweir nModMask = KEY_MOD3; 3099*cdf0e10cSrcweir break; 3100*cdf0e10cSrcweir } 3101*cdf0e10cSrcweir if( pEvent->type == GDK_KEY_RELEASE ) 3102*cdf0e10cSrcweir { 3103*cdf0e10cSrcweir nModCode &= ~nModMask; 3104*cdf0e10cSrcweir pThis->m_nKeyModifiers &= ~nExtModMask; 3105*cdf0e10cSrcweir } 3106*cdf0e10cSrcweir else 3107*cdf0e10cSrcweir { 3108*cdf0e10cSrcweir nModCode |= nModMask; 3109*cdf0e10cSrcweir pThis->m_nKeyModifiers |= nExtModMask; 3110*cdf0e10cSrcweir } 3111*cdf0e10cSrcweir 3112*cdf0e10cSrcweir aModEvt.mnCode = nModCode; 3113*cdf0e10cSrcweir aModEvt.mnTime = pEvent->time; 3114*cdf0e10cSrcweir 3115*cdf0e10cSrcweir pThis->CallCallback( SALEVENT_KEYMODCHANGE, &aModEvt ); 3116*cdf0e10cSrcweir 3117*cdf0e10cSrcweir if( ! aDel.isDeleted() ) 3118*cdf0e10cSrcweir { 3119*cdf0e10cSrcweir // emulate KEY_MENU 3120*cdf0e10cSrcweir if( ( pEvent->keyval == GDK_Alt_L || pEvent->keyval == GDK_Alt_R ) && 3121*cdf0e10cSrcweir ( nModCode & ~(KEY_MOD3|KEY_MOD2)) == 0 ) 3122*cdf0e10cSrcweir { 3123*cdf0e10cSrcweir if( pEvent->type == GDK_KEY_PRESS ) 3124*cdf0e10cSrcweir pThis->m_bSingleAltPress = true; 3125*cdf0e10cSrcweir 3126*cdf0e10cSrcweir else if( pThis->m_bSingleAltPress ) 3127*cdf0e10cSrcweir { 3128*cdf0e10cSrcweir SalKeyEvent aKeyEvt; 3129*cdf0e10cSrcweir 3130*cdf0e10cSrcweir aKeyEvt.mnCode = KEY_MENU | nModCode; 3131*cdf0e10cSrcweir aKeyEvt.mnRepeat = 0; 3132*cdf0e10cSrcweir aKeyEvt.mnTime = pEvent->time; 3133*cdf0e10cSrcweir aKeyEvt.mnCharCode = 0; 3134*cdf0e10cSrcweir 3135*cdf0e10cSrcweir // simulate KEY_MENU 3136*cdf0e10cSrcweir pThis->CallCallback( SALEVENT_KEYINPUT, &aKeyEvt ); 3137*cdf0e10cSrcweir if( ! aDel.isDeleted() ) 3138*cdf0e10cSrcweir { 3139*cdf0e10cSrcweir pThis->CallCallback( SALEVENT_KEYUP, &aKeyEvt ); 3140*cdf0e10cSrcweir pThis->m_bSingleAltPress = false; 3141*cdf0e10cSrcweir } 3142*cdf0e10cSrcweir } 3143*cdf0e10cSrcweir } 3144*cdf0e10cSrcweir else 3145*cdf0e10cSrcweir pThis->m_bSingleAltPress = false; 3146*cdf0e10cSrcweir } 3147*cdf0e10cSrcweir } 3148*cdf0e10cSrcweir else 3149*cdf0e10cSrcweir { 3150*cdf0e10cSrcweir pThis->doKeyCallback( pEvent->state, 3151*cdf0e10cSrcweir pEvent->keyval, 3152*cdf0e10cSrcweir pEvent->hardware_keycode, 3153*cdf0e10cSrcweir pEvent->group, 3154*cdf0e10cSrcweir pEvent->time, 3155*cdf0e10cSrcweir sal_Unicode(gdk_keyval_to_unicode( pEvent->keyval )), 3156*cdf0e10cSrcweir (pEvent->type == GDK_KEY_PRESS), 3157*cdf0e10cSrcweir false ); 3158*cdf0e10cSrcweir if( ! aDel.isDeleted() ) 3159*cdf0e10cSrcweir { 3160*cdf0e10cSrcweir pThis->m_bSendModChangeOnRelease = false; 3161*cdf0e10cSrcweir pThis->m_bSingleAltPress = false; 3162*cdf0e10cSrcweir } 3163*cdf0e10cSrcweir } 3164*cdf0e10cSrcweir 3165*cdf0e10cSrcweir if( !aDel.isDeleted() && pThis->m_pIMHandler ) 3166*cdf0e10cSrcweir pThis->m_pIMHandler->updateIMSpotLocation(); 3167*cdf0e10cSrcweir 3168*cdf0e10cSrcweir return sal_True; 3169*cdf0e10cSrcweir } 3170*cdf0e10cSrcweir 3171*cdf0e10cSrcweir gboolean GtkSalFrame::signalDelete( GtkWidget*, GdkEvent*, gpointer frame ) 3172*cdf0e10cSrcweir { 3173*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 3174*cdf0e10cSrcweir 3175*cdf0e10cSrcweir GTK_YIELD_GRAB(); 3176*cdf0e10cSrcweir pThis->CallCallback( SALEVENT_CLOSE, NULL ); 3177*cdf0e10cSrcweir 3178*cdf0e10cSrcweir return sal_True; 3179*cdf0e10cSrcweir } 3180*cdf0e10cSrcweir 3181*cdf0e10cSrcweir void GtkSalFrame::signalStyleSet( GtkWidget*, GtkStyle* pPrevious, gpointer frame ) 3182*cdf0e10cSrcweir { 3183*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 3184*cdf0e10cSrcweir 3185*cdf0e10cSrcweir // every frame gets an initial style set on creation 3186*cdf0e10cSrcweir // do not post these as the whole application tends to 3187*cdf0e10cSrcweir // redraw itself to adjust to the new style 3188*cdf0e10cSrcweir // where there IS no new style resulting in tremendous unnecessary flickering 3189*cdf0e10cSrcweir if( pPrevious != NULL ) 3190*cdf0e10cSrcweir { 3191*cdf0e10cSrcweir // signalStyleSet does NOT usually have the gdk lock 3192*cdf0e10cSrcweir // so post user event to safely dispatch the SALEVENT_SETTINGSCHANGED 3193*cdf0e10cSrcweir // note: settings changed for multiple frames is avoided in winproc.cxx ImplHandleSettings 3194*cdf0e10cSrcweir pThis->getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_SETTINGSCHANGED ); 3195*cdf0e10cSrcweir pThis->getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_FONTCHANGED ); 3196*cdf0e10cSrcweir } 3197*cdf0e10cSrcweir 3198*cdf0e10cSrcweir /* #i64117# gtk sets a nice background pixmap 3199*cdf0e10cSrcweir * but we actually don't really want that, so save 3200*cdf0e10cSrcweir * some time on the Xserver as well as prevent 3201*cdf0e10cSrcweir * some paint issues 3202*cdf0e10cSrcweir */ 3203*cdf0e10cSrcweir GdkWindow* pWin = GTK_WIDGET(pThis->getWindow())->window; 3204*cdf0e10cSrcweir if( pWin ) 3205*cdf0e10cSrcweir { 3206*cdf0e10cSrcweir XLIB_Window aWin = GDK_WINDOW_XWINDOW(pWin); 3207*cdf0e10cSrcweir if( aWin != None ) 3208*cdf0e10cSrcweir XSetWindowBackgroundPixmap( pThis->getDisplay()->GetDisplay(), 3209*cdf0e10cSrcweir aWin, 3210*cdf0e10cSrcweir pThis->m_hBackgroundPixmap ); 3211*cdf0e10cSrcweir } 3212*cdf0e10cSrcweir 3213*cdf0e10cSrcweir if( ! pThis->m_pParent ) 3214*cdf0e10cSrcweir { 3215*cdf0e10cSrcweir // signalize theme changed for NWF caches 3216*cdf0e10cSrcweir // FIXME: should be called only once for a style change 3217*cdf0e10cSrcweir GtkSalGraphics::bThemeChanged = sal_True; 3218*cdf0e10cSrcweir } 3219*cdf0e10cSrcweir } 3220*cdf0e10cSrcweir 3221*cdf0e10cSrcweir gboolean GtkSalFrame::signalState( GtkWidget*, GdkEvent* pEvent, gpointer frame ) 3222*cdf0e10cSrcweir { 3223*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 3224*cdf0e10cSrcweir if( (pThis->m_nState & GDK_WINDOW_STATE_ICONIFIED) != (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_ICONIFIED ) ) 3225*cdf0e10cSrcweir pThis->getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_RESIZE ); 3226*cdf0e10cSrcweir 3227*cdf0e10cSrcweir if( (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_MAXIMIZED) && 3228*cdf0e10cSrcweir ! (pThis->m_nState & GDK_WINDOW_STATE_MAXIMIZED) ) 3229*cdf0e10cSrcweir { 3230*cdf0e10cSrcweir pThis->m_aRestorePosSize = 3231*cdf0e10cSrcweir Rectangle( Point( pThis->maGeometry.nX, pThis->maGeometry.nY ), 3232*cdf0e10cSrcweir Size( pThis->maGeometry.nWidth, pThis->maGeometry.nHeight ) ); 3233*cdf0e10cSrcweir } 3234*cdf0e10cSrcweir pThis->m_nState = pEvent->window_state.new_window_state; 3235*cdf0e10cSrcweir 3236*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 3237*cdf0e10cSrcweir if( (pEvent->window_state.changed_mask & GDK_WINDOW_STATE_FULLSCREEN) ) 3238*cdf0e10cSrcweir { 3239*cdf0e10cSrcweir fprintf( stderr, "window %p %s full screen state\n", 3240*cdf0e10cSrcweir pThis, 3241*cdf0e10cSrcweir (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ? "enters" : "leaves"); 3242*cdf0e10cSrcweir } 3243*cdf0e10cSrcweir #endif 3244*cdf0e10cSrcweir 3245*cdf0e10cSrcweir return sal_False; 3246*cdf0e10cSrcweir } 3247*cdf0e10cSrcweir 3248*cdf0e10cSrcweir gboolean GtkSalFrame::signalVisibility( GtkWidget*, GdkEventVisibility* pEvent, gpointer frame ) 3249*cdf0e10cSrcweir { 3250*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 3251*cdf0e10cSrcweir pThis->m_nVisibility = pEvent->state; 3252*cdf0e10cSrcweir 3253*cdf0e10cSrcweir return sal_False; 3254*cdf0e10cSrcweir } 3255*cdf0e10cSrcweir 3256*cdf0e10cSrcweir void GtkSalFrame::signalDestroy( GtkObject* pObj, gpointer frame ) 3257*cdf0e10cSrcweir { 3258*cdf0e10cSrcweir GtkSalFrame* pThis = (GtkSalFrame*)frame; 3259*cdf0e10cSrcweir if( GTK_WIDGET( pObj ) == pThis->m_pWindow ) 3260*cdf0e10cSrcweir { 3261*cdf0e10cSrcweir pThis->m_pFixedContainer = NULL; 3262*cdf0e10cSrcweir pThis->m_pWindow = NULL; 3263*cdf0e10cSrcweir } 3264*cdf0e10cSrcweir } 3265*cdf0e10cSrcweir 3266*cdf0e10cSrcweir // ---------------------------------------------------------------------- 3267*cdf0e10cSrcweir // GtkSalFrame::IMHandler 3268*cdf0e10cSrcweir // ---------------------------------------------------------------------- 3269*cdf0e10cSrcweir 3270*cdf0e10cSrcweir GtkSalFrame::IMHandler::IMHandler( GtkSalFrame* pFrame ) 3271*cdf0e10cSrcweir : m_pFrame(pFrame), 3272*cdf0e10cSrcweir m_nPrevKeyPresses( 0 ), 3273*cdf0e10cSrcweir m_pIMContext( NULL ), 3274*cdf0e10cSrcweir m_bFocused( true ), 3275*cdf0e10cSrcweir m_bPreeditJustChanged( false ) 3276*cdf0e10cSrcweir { 3277*cdf0e10cSrcweir m_aInputEvent.mpTextAttr = NULL; 3278*cdf0e10cSrcweir createIMContext(); 3279*cdf0e10cSrcweir } 3280*cdf0e10cSrcweir 3281*cdf0e10cSrcweir GtkSalFrame::IMHandler::~IMHandler() 3282*cdf0e10cSrcweir { 3283*cdf0e10cSrcweir // cancel an eventual event posted to begin preedit again 3284*cdf0e10cSrcweir m_pFrame->getDisplay()->CancelInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); 3285*cdf0e10cSrcweir deleteIMContext(); 3286*cdf0e10cSrcweir } 3287*cdf0e10cSrcweir 3288*cdf0e10cSrcweir void GtkSalFrame::IMHandler::createIMContext() 3289*cdf0e10cSrcweir { 3290*cdf0e10cSrcweir if( ! m_pIMContext ) 3291*cdf0e10cSrcweir { 3292*cdf0e10cSrcweir m_pIMContext = gtk_im_multicontext_new (); 3293*cdf0e10cSrcweir g_signal_connect( m_pIMContext, "commit", 3294*cdf0e10cSrcweir G_CALLBACK (signalIMCommit), this ); 3295*cdf0e10cSrcweir g_signal_connect( m_pIMContext, "preedit_changed", 3296*cdf0e10cSrcweir G_CALLBACK (signalIMPreeditChanged), this ); 3297*cdf0e10cSrcweir g_signal_connect( m_pIMContext, "retrieve_surrounding", 3298*cdf0e10cSrcweir G_CALLBACK (signalIMRetrieveSurrounding), this ); 3299*cdf0e10cSrcweir g_signal_connect( m_pIMContext, "delete_surrounding", 3300*cdf0e10cSrcweir G_CALLBACK (signalIMDeleteSurrounding), this ); 3301*cdf0e10cSrcweir g_signal_connect( m_pIMContext, "preedit_start", 3302*cdf0e10cSrcweir G_CALLBACK (signalIMPreeditStart), this ); 3303*cdf0e10cSrcweir g_signal_connect( m_pIMContext, "preedit_end", 3304*cdf0e10cSrcweir G_CALLBACK (signalIMPreeditEnd), this ); 3305*cdf0e10cSrcweir 3306*cdf0e10cSrcweir m_pFrame->getDisplay()->GetXLib()->PushXErrorLevel( true ); 3307*cdf0e10cSrcweir gtk_im_context_set_client_window( m_pIMContext, GTK_WIDGET(m_pFrame->m_pWindow)->window ); 3308*cdf0e10cSrcweir gtk_im_context_focus_in( m_pIMContext ); 3309*cdf0e10cSrcweir m_pFrame->getDisplay()->GetXLib()->PopXErrorLevel(); 3310*cdf0e10cSrcweir m_bFocused = true; 3311*cdf0e10cSrcweir } 3312*cdf0e10cSrcweir } 3313*cdf0e10cSrcweir 3314*cdf0e10cSrcweir void GtkSalFrame::IMHandler::deleteIMContext() 3315*cdf0e10cSrcweir { 3316*cdf0e10cSrcweir if( m_pIMContext ) 3317*cdf0e10cSrcweir { 3318*cdf0e10cSrcweir // first give IC a chance to deinitialize 3319*cdf0e10cSrcweir m_pFrame->getDisplay()->GetXLib()->PushXErrorLevel( true ); 3320*cdf0e10cSrcweir gtk_im_context_set_client_window( m_pIMContext, NULL ); 3321*cdf0e10cSrcweir m_pFrame->getDisplay()->GetXLib()->PopXErrorLevel(); 3322*cdf0e10cSrcweir // destroy old IC 3323*cdf0e10cSrcweir g_object_unref( m_pIMContext ); 3324*cdf0e10cSrcweir m_pIMContext = NULL; 3325*cdf0e10cSrcweir } 3326*cdf0e10cSrcweir } 3327*cdf0e10cSrcweir 3328*cdf0e10cSrcweir void GtkSalFrame::IMHandler::doCallEndExtTextInput() 3329*cdf0e10cSrcweir { 3330*cdf0e10cSrcweir m_aInputEvent.mpTextAttr = NULL; 3331*cdf0e10cSrcweir m_pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, NULL ); 3332*cdf0e10cSrcweir } 3333*cdf0e10cSrcweir 3334*cdf0e10cSrcweir void GtkSalFrame::IMHandler::updateIMSpotLocation() 3335*cdf0e10cSrcweir { 3336*cdf0e10cSrcweir SalExtTextInputPosEvent aPosEvent; 3337*cdf0e10cSrcweir m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void*)&aPosEvent ); 3338*cdf0e10cSrcweir GdkRectangle aArea; 3339*cdf0e10cSrcweir aArea.x = aPosEvent.mnX; 3340*cdf0e10cSrcweir aArea.y = aPosEvent.mnY; 3341*cdf0e10cSrcweir aArea.width = aPosEvent.mnWidth; 3342*cdf0e10cSrcweir aArea.height = aPosEvent.mnHeight; 3343*cdf0e10cSrcweir m_pFrame->getDisplay()->GetXLib()->PushXErrorLevel( true ); 3344*cdf0e10cSrcweir gtk_im_context_set_cursor_location( m_pIMContext, &aArea ); 3345*cdf0e10cSrcweir m_pFrame->getDisplay()->GetXLib()->PopXErrorLevel(); 3346*cdf0e10cSrcweir } 3347*cdf0e10cSrcweir 3348*cdf0e10cSrcweir void GtkSalFrame::IMHandler::setInputContext( SalInputContext* ) 3349*cdf0e10cSrcweir { 3350*cdf0e10cSrcweir } 3351*cdf0e10cSrcweir 3352*cdf0e10cSrcweir void GtkSalFrame::IMHandler::sendEmptyCommit() 3353*cdf0e10cSrcweir { 3354*cdf0e10cSrcweir vcl::DeletionListener aDel( m_pFrame ); 3355*cdf0e10cSrcweir 3356*cdf0e10cSrcweir SalExtTextInputEvent aEmptyEv; 3357*cdf0e10cSrcweir aEmptyEv.mnTime = 0; 3358*cdf0e10cSrcweir aEmptyEv.mpTextAttr = 0; 3359*cdf0e10cSrcweir aEmptyEv.maText = String(); 3360*cdf0e10cSrcweir aEmptyEv.mnCursorPos = 0; 3361*cdf0e10cSrcweir aEmptyEv.mnCursorFlags = 0; 3362*cdf0e10cSrcweir aEmptyEv.mnDeltaStart = 0; 3363*cdf0e10cSrcweir aEmptyEv.mbOnlyCursor = False; 3364*cdf0e10cSrcweir m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEmptyEv ); 3365*cdf0e10cSrcweir if( ! aDel.isDeleted() ) 3366*cdf0e10cSrcweir m_pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, NULL ); 3367*cdf0e10cSrcweir } 3368*cdf0e10cSrcweir 3369*cdf0e10cSrcweir void GtkSalFrame::IMHandler::endExtTextInput( sal_uInt16 /*nFlags*/ ) 3370*cdf0e10cSrcweir { 3371*cdf0e10cSrcweir gtk_im_context_reset ( m_pIMContext ); 3372*cdf0e10cSrcweir 3373*cdf0e10cSrcweir if( m_aInputEvent.mpTextAttr ) 3374*cdf0e10cSrcweir { 3375*cdf0e10cSrcweir vcl::DeletionListener aDel( m_pFrame ); 3376*cdf0e10cSrcweir // delete preedit in sal (commit an empty string) 3377*cdf0e10cSrcweir sendEmptyCommit(); 3378*cdf0e10cSrcweir if( ! aDel.isDeleted() ) 3379*cdf0e10cSrcweir { 3380*cdf0e10cSrcweir // mark previous preedit state again (will e.g. be sent at focus gain) 3381*cdf0e10cSrcweir m_aInputEvent.mpTextAttr = &m_aInputFlags[0]; 3382*cdf0e10cSrcweir if( m_bFocused ) 3383*cdf0e10cSrcweir { 3384*cdf0e10cSrcweir // begin preedit again 3385*cdf0e10cSrcweir m_pFrame->getDisplay()->SendInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); 3386*cdf0e10cSrcweir } 3387*cdf0e10cSrcweir } 3388*cdf0e10cSrcweir } 3389*cdf0e10cSrcweir } 3390*cdf0e10cSrcweir 3391*cdf0e10cSrcweir void GtkSalFrame::IMHandler::focusChanged( bool bFocusIn ) 3392*cdf0e10cSrcweir { 3393*cdf0e10cSrcweir m_bFocused = bFocusIn; 3394*cdf0e10cSrcweir if( bFocusIn ) 3395*cdf0e10cSrcweir { 3396*cdf0e10cSrcweir m_pFrame->getDisplay()->GetXLib()->PushXErrorLevel( true ); 3397*cdf0e10cSrcweir gtk_im_context_focus_in( m_pIMContext ); 3398*cdf0e10cSrcweir m_pFrame->getDisplay()->GetXLib()->PopXErrorLevel(); 3399*cdf0e10cSrcweir if( m_aInputEvent.mpTextAttr ) 3400*cdf0e10cSrcweir { 3401*cdf0e10cSrcweir sendEmptyCommit(); 3402*cdf0e10cSrcweir // begin preedit again 3403*cdf0e10cSrcweir m_pFrame->getDisplay()->SendInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); 3404*cdf0e10cSrcweir } 3405*cdf0e10cSrcweir } 3406*cdf0e10cSrcweir else 3407*cdf0e10cSrcweir { 3408*cdf0e10cSrcweir m_pFrame->getDisplay()->GetXLib()->PushXErrorLevel( true ); 3409*cdf0e10cSrcweir gtk_im_context_focus_out( m_pIMContext ); 3410*cdf0e10cSrcweir m_pFrame->getDisplay()->GetXLib()->PopXErrorLevel(); 3411*cdf0e10cSrcweir // cancel an eventual event posted to begin preedit again 3412*cdf0e10cSrcweir m_pFrame->getDisplay()->CancelInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); 3413*cdf0e10cSrcweir } 3414*cdf0e10cSrcweir } 3415*cdf0e10cSrcweir 3416*cdf0e10cSrcweir bool GtkSalFrame::IMHandler::handleKeyEvent( GdkEventKey* pEvent ) 3417*cdf0e10cSrcweir { 3418*cdf0e10cSrcweir vcl::DeletionListener aDel( m_pFrame ); 3419*cdf0e10cSrcweir 3420*cdf0e10cSrcweir if( pEvent->type == GDK_KEY_PRESS ) 3421*cdf0e10cSrcweir { 3422*cdf0e10cSrcweir // Add this key press event to the list of previous key presses 3423*cdf0e10cSrcweir // to which we compare key release events. If a later key release 3424*cdf0e10cSrcweir // event has a matching key press event in this list, we swallow 3425*cdf0e10cSrcweir // the key release because some GTK Input Methods don't swallow it 3426*cdf0e10cSrcweir // for us. 3427*cdf0e10cSrcweir m_aPrevKeyPresses.push_back( PreviousKeyPress(pEvent) ); 3428*cdf0e10cSrcweir m_nPrevKeyPresses++; 3429*cdf0e10cSrcweir 3430*cdf0e10cSrcweir // Also pop off the earliest key press event if there are more than 10 3431*cdf0e10cSrcweir // already. 3432*cdf0e10cSrcweir while (m_nPrevKeyPresses > 10) 3433*cdf0e10cSrcweir { 3434*cdf0e10cSrcweir m_aPrevKeyPresses.pop_front(); 3435*cdf0e10cSrcweir m_nPrevKeyPresses--; 3436*cdf0e10cSrcweir } 3437*cdf0e10cSrcweir 3438*cdf0e10cSrcweir GObject* pRef = G_OBJECT( g_object_ref( G_OBJECT( m_pIMContext ) ) ); 3439*cdf0e10cSrcweir 3440*cdf0e10cSrcweir // #i51353# update spot location on every key input since we cannot 3441*cdf0e10cSrcweir // know which key may activate a preedit choice window 3442*cdf0e10cSrcweir updateIMSpotLocation(); 3443*cdf0e10cSrcweir if( aDel.isDeleted() ) 3444*cdf0e10cSrcweir return true; 3445*cdf0e10cSrcweir 3446*cdf0e10cSrcweir gboolean bResult = gtk_im_context_filter_keypress( m_pIMContext, pEvent ); 3447*cdf0e10cSrcweir g_object_unref( pRef ); 3448*cdf0e10cSrcweir 3449*cdf0e10cSrcweir if( aDel.isDeleted() ) 3450*cdf0e10cSrcweir return true; 3451*cdf0e10cSrcweir 3452*cdf0e10cSrcweir m_bPreeditJustChanged = false; 3453*cdf0e10cSrcweir 3454*cdf0e10cSrcweir if( bResult ) 3455*cdf0e10cSrcweir return true; 3456*cdf0e10cSrcweir else 3457*cdf0e10cSrcweir { 3458*cdf0e10cSrcweir DBG_ASSERT( m_nPrevKeyPresses > 0, "key press has vanished !" ); 3459*cdf0e10cSrcweir if( ! m_aPrevKeyPresses.empty() ) // sanity check 3460*cdf0e10cSrcweir { 3461*cdf0e10cSrcweir // event was not swallowed, do not filter a following 3462*cdf0e10cSrcweir // key release event 3463*cdf0e10cSrcweir // note: this relies on gtk_im_context_filter_keypress 3464*cdf0e10cSrcweir // returning without calling a handler (in the "not swallowed" 3465*cdf0e10cSrcweir // case ) which might change the previous key press list so 3466*cdf0e10cSrcweir // we would pop the wrong event here 3467*cdf0e10cSrcweir m_aPrevKeyPresses.pop_back(); 3468*cdf0e10cSrcweir m_nPrevKeyPresses--; 3469*cdf0e10cSrcweir } 3470*cdf0e10cSrcweir } 3471*cdf0e10cSrcweir } 3472*cdf0e10cSrcweir 3473*cdf0e10cSrcweir // Determine if we got an earlier key press event corresponding to this key release 3474*cdf0e10cSrcweir if (pEvent->type == GDK_KEY_RELEASE) 3475*cdf0e10cSrcweir { 3476*cdf0e10cSrcweir GObject* pRef = G_OBJECT( g_object_ref( G_OBJECT( m_pIMContext ) ) ); 3477*cdf0e10cSrcweir gboolean bResult = gtk_im_context_filter_keypress( m_pIMContext, pEvent ); 3478*cdf0e10cSrcweir g_object_unref( pRef ); 3479*cdf0e10cSrcweir 3480*cdf0e10cSrcweir if( aDel.isDeleted() ) 3481*cdf0e10cSrcweir return true; 3482*cdf0e10cSrcweir 3483*cdf0e10cSrcweir m_bPreeditJustChanged = false; 3484*cdf0e10cSrcweir 3485*cdf0e10cSrcweir std::list<PreviousKeyPress>::iterator iter = m_aPrevKeyPresses.begin(); 3486*cdf0e10cSrcweir std::list<PreviousKeyPress>::iterator iter_end = m_aPrevKeyPresses.end(); 3487*cdf0e10cSrcweir while (iter != iter_end) 3488*cdf0e10cSrcweir { 3489*cdf0e10cSrcweir // If we found a corresponding previous key press event, swallow the release 3490*cdf0e10cSrcweir // and remove the earlier key press from our list 3491*cdf0e10cSrcweir if (*iter == pEvent) 3492*cdf0e10cSrcweir { 3493*cdf0e10cSrcweir m_aPrevKeyPresses.erase(iter); 3494*cdf0e10cSrcweir m_nPrevKeyPresses--; 3495*cdf0e10cSrcweir return true; 3496*cdf0e10cSrcweir } 3497*cdf0e10cSrcweir ++iter; 3498*cdf0e10cSrcweir } 3499*cdf0e10cSrcweir 3500*cdf0e10cSrcweir if( bResult ) 3501*cdf0e10cSrcweir return true; 3502*cdf0e10cSrcweir } 3503*cdf0e10cSrcweir 3504*cdf0e10cSrcweir return false; 3505*cdf0e10cSrcweir } 3506*cdf0e10cSrcweir 3507*cdf0e10cSrcweir /* FIXME: 3508*cdf0e10cSrcweir * #122282# still more hacking: some IMEs never start a preedit but simply commit 3509*cdf0e10cSrcweir * in this case we cannot commit a single character. Workaround: do not do the 3510*cdf0e10cSrcweir * single key hack for enter or space if the unicode commited does not match 3511*cdf0e10cSrcweir */ 3512*cdf0e10cSrcweir 3513*cdf0e10cSrcweir static bool checkSingleKeyCommitHack( guint keyval, sal_Unicode cCode ) 3514*cdf0e10cSrcweir { 3515*cdf0e10cSrcweir bool bRet = true; 3516*cdf0e10cSrcweir switch( keyval ) 3517*cdf0e10cSrcweir { 3518*cdf0e10cSrcweir case GDK_KP_Enter: 3519*cdf0e10cSrcweir case GDK_Return: 3520*cdf0e10cSrcweir if( cCode != '\n' && cCode != '\r' ) 3521*cdf0e10cSrcweir bRet = false; 3522*cdf0e10cSrcweir break; 3523*cdf0e10cSrcweir case GDK_space: 3524*cdf0e10cSrcweir case GDK_KP_Space: 3525*cdf0e10cSrcweir if( cCode != ' ' ) 3526*cdf0e10cSrcweir bRet = false; 3527*cdf0e10cSrcweir break; 3528*cdf0e10cSrcweir default: 3529*cdf0e10cSrcweir break; 3530*cdf0e10cSrcweir } 3531*cdf0e10cSrcweir return bRet; 3532*cdf0e10cSrcweir } 3533*cdf0e10cSrcweir 3534*cdf0e10cSrcweir #ifdef SOLARIS 3535*cdf0e10cSrcweir #define CONTEXT_ARG pContext 3536*cdf0e10cSrcweir #else 3537*cdf0e10cSrcweir #define CONTEXT_ARG EMPTYARG 3538*cdf0e10cSrcweir #endif 3539*cdf0e10cSrcweir void GtkSalFrame::IMHandler::signalIMCommit( GtkIMContext* CONTEXT_ARG, gchar* pText, gpointer im_handler ) 3540*cdf0e10cSrcweir { 3541*cdf0e10cSrcweir GtkSalFrame::IMHandler* pThis = (GtkSalFrame::IMHandler*)im_handler; 3542*cdf0e10cSrcweir 3543*cdf0e10cSrcweir vcl::DeletionListener aDel( pThis->m_pFrame ); 3544*cdf0e10cSrcweir // open a block that will end the GTK_YIELD_GRAB before calling preedit changed again 3545*cdf0e10cSrcweir { 3546*cdf0e10cSrcweir GTK_YIELD_GRAB(); 3547*cdf0e10cSrcweir 3548*cdf0e10cSrcweir pThis->m_aInputEvent.mnTime = 0; 3549*cdf0e10cSrcweir pThis->m_aInputEvent.mpTextAttr = 0; 3550*cdf0e10cSrcweir pThis->m_aInputEvent.maText = String( pText, RTL_TEXTENCODING_UTF8 ); 3551*cdf0e10cSrcweir pThis->m_aInputEvent.mnCursorPos = pThis->m_aInputEvent.maText.Len(); 3552*cdf0e10cSrcweir pThis->m_aInputEvent.mnCursorFlags = 0; 3553*cdf0e10cSrcweir pThis->m_aInputEvent.mnDeltaStart = 0; 3554*cdf0e10cSrcweir pThis->m_aInputEvent.mbOnlyCursor = False; 3555*cdf0e10cSrcweir 3556*cdf0e10cSrcweir pThis->m_aInputFlags.clear(); 3557*cdf0e10cSrcweir 3558*cdf0e10cSrcweir /* necessary HACK: all keyboard input comes in here as soon as a IMContext is set 3559*cdf0e10cSrcweir * which is logical and consequent. But since even simple input like 3560*cdf0e10cSrcweir * <space> comes through the commit signal instead of signalKey 3561*cdf0e10cSrcweir * and all kinds of windows only implement KeyInput (e.g. PushButtons, 3562*cdf0e10cSrcweir * RadioButtons and a lot of other Controls), will send a single 3563*cdf0e10cSrcweir * KeyInput/KeyUp sequence instead of an ExtText event if there 3564*cdf0e10cSrcweir * never was a preedit and the text is only one character. 3565*cdf0e10cSrcweir * 3566*cdf0e10cSrcweir * In this case there the last ExtText event must have been 3567*cdf0e10cSrcweir * SALEVENT_ENDEXTTEXTINPUT, either because of a regular commit 3568*cdf0e10cSrcweir * or because there never was a preedit. 3569*cdf0e10cSrcweir */ 3570*cdf0e10cSrcweir bool bSingleCommit = false; 3571*cdf0e10cSrcweir bool bWasPreedit = 3572*cdf0e10cSrcweir (pThis->m_aInputEvent.mpTextAttr != 0) || 3573*cdf0e10cSrcweir pThis->m_bPreeditJustChanged; 3574*cdf0e10cSrcweir if( ! bWasPreedit 3575*cdf0e10cSrcweir && pThis->m_aInputEvent.maText.Len() == 1 3576*cdf0e10cSrcweir && ! pThis->m_aPrevKeyPresses.empty() 3577*cdf0e10cSrcweir ) 3578*cdf0e10cSrcweir { 3579*cdf0e10cSrcweir const PreviousKeyPress& rKP = pThis->m_aPrevKeyPresses.back(); 3580*cdf0e10cSrcweir sal_Unicode aOrigCode = pThis->m_aInputEvent.maText.GetChar(0); 3581*cdf0e10cSrcweir 3582*cdf0e10cSrcweir if( checkSingleKeyCommitHack( rKP.keyval, aOrigCode ) ) 3583*cdf0e10cSrcweir { 3584*cdf0e10cSrcweir pThis->m_pFrame->doKeyCallback( rKP.state, rKP.keyval, rKP.hardware_keycode, rKP.group, rKP.time, aOrigCode, true, true ); 3585*cdf0e10cSrcweir bSingleCommit = true; 3586*cdf0e10cSrcweir } 3587*cdf0e10cSrcweir } 3588*cdf0e10cSrcweir if( ! bSingleCommit ) 3589*cdf0e10cSrcweir { 3590*cdf0e10cSrcweir pThis->m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&pThis->m_aInputEvent); 3591*cdf0e10cSrcweir if( ! aDel.isDeleted() ) 3592*cdf0e10cSrcweir pThis->doCallEndExtTextInput(); 3593*cdf0e10cSrcweir } 3594*cdf0e10cSrcweir if( ! aDel.isDeleted() ) 3595*cdf0e10cSrcweir { 3596*cdf0e10cSrcweir // reset input event 3597*cdf0e10cSrcweir pThis->m_aInputEvent.maText = String(); 3598*cdf0e10cSrcweir pThis->m_aInputEvent.mnCursorPos = 0; 3599*cdf0e10cSrcweir pThis->updateIMSpotLocation(); 3600*cdf0e10cSrcweir } 3601*cdf0e10cSrcweir } 3602*cdf0e10cSrcweir #ifdef SOLARIS 3603*cdf0e10cSrcweir // #i51356# workaround a solaris IIIMP bug 3604*cdf0e10cSrcweir // in case of partial commits the preedit changed signal 3605*cdf0e10cSrcweir // and commit signal come in wrong order 3606*cdf0e10cSrcweir if( ! aDel.isDeleted() ) 3607*cdf0e10cSrcweir signalIMPreeditChanged( pContext, im_handler ); 3608*cdf0e10cSrcweir #endif 3609*cdf0e10cSrcweir } 3610*cdf0e10cSrcweir 3611*cdf0e10cSrcweir void GtkSalFrame::IMHandler::signalIMPreeditChanged( GtkIMContext*, gpointer im_handler ) 3612*cdf0e10cSrcweir { 3613*cdf0e10cSrcweir GtkSalFrame::IMHandler* pThis = (GtkSalFrame::IMHandler*)im_handler; 3614*cdf0e10cSrcweir 3615*cdf0e10cSrcweir char* pText = NULL; 3616*cdf0e10cSrcweir PangoAttrList* pAttrs = NULL; 3617*cdf0e10cSrcweir gint nCursorPos = 0; 3618*cdf0e10cSrcweir 3619*cdf0e10cSrcweir gtk_im_context_get_preedit_string( pThis->m_pIMContext, 3620*cdf0e10cSrcweir &pText, 3621*cdf0e10cSrcweir &pAttrs, 3622*cdf0e10cSrcweir &nCursorPos ); 3623*cdf0e10cSrcweir if( pText && ! *pText ) // empty string 3624*cdf0e10cSrcweir { 3625*cdf0e10cSrcweir // change from nothing to nothing -> do not start preedit 3626*cdf0e10cSrcweir // e.g. this will activate input into a calc cell without 3627*cdf0e10cSrcweir // user input 3628*cdf0e10cSrcweir if( pThis->m_aInputEvent.maText.Len() == 0 ) 3629*cdf0e10cSrcweir { 3630*cdf0e10cSrcweir g_free( pText ); 3631*cdf0e10cSrcweir return; 3632*cdf0e10cSrcweir } 3633*cdf0e10cSrcweir } 3634*cdf0e10cSrcweir 3635*cdf0e10cSrcweir pThis->m_bPreeditJustChanged = true; 3636*cdf0e10cSrcweir 3637*cdf0e10cSrcweir bool bEndPreedit = (!pText || !*pText) && pThis->m_aInputEvent.mpTextAttr != NULL; 3638*cdf0e10cSrcweir pThis->m_aInputEvent.mnTime = 0; 3639*cdf0e10cSrcweir pThis->m_aInputEvent.maText = String( pText, RTL_TEXTENCODING_UTF8 ); 3640*cdf0e10cSrcweir pThis->m_aInputEvent.mnCursorPos = nCursorPos; 3641*cdf0e10cSrcweir pThis->m_aInputEvent.mnCursorFlags = 0; 3642*cdf0e10cSrcweir pThis->m_aInputEvent.mnDeltaStart = 0; 3643*cdf0e10cSrcweir pThis->m_aInputEvent.mbOnlyCursor = False; 3644*cdf0e10cSrcweir 3645*cdf0e10cSrcweir pThis->m_aInputFlags = std::vector<sal_uInt16>( std::max( 1, (int)pThis->m_aInputEvent.maText.Len() ), 0 ); 3646*cdf0e10cSrcweir 3647*cdf0e10cSrcweir PangoAttrIterator *iter = pango_attr_list_get_iterator (pAttrs); 3648*cdf0e10cSrcweir do 3649*cdf0e10cSrcweir { 3650*cdf0e10cSrcweir GSList *attr_list = NULL; 3651*cdf0e10cSrcweir GSList *tmp_list = NULL; 3652*cdf0e10cSrcweir gint start, end; 3653*cdf0e10cSrcweir guint sal_attr = 0; 3654*cdf0e10cSrcweir 3655*cdf0e10cSrcweir pango_attr_iterator_range (iter, &start, &end); 3656*cdf0e10cSrcweir if (end == G_MAXINT) 3657*cdf0e10cSrcweir end = pText ? strlen (pText) : 0; 3658*cdf0e10cSrcweir if (end == start) 3659*cdf0e10cSrcweir continue; 3660*cdf0e10cSrcweir 3661*cdf0e10cSrcweir start = g_utf8_pointer_to_offset (pText, pText + start); 3662*cdf0e10cSrcweir end = g_utf8_pointer_to_offset (pText, pText + end); 3663*cdf0e10cSrcweir 3664*cdf0e10cSrcweir tmp_list = attr_list = pango_attr_iterator_get_attrs (iter); 3665*cdf0e10cSrcweir while (tmp_list) 3666*cdf0e10cSrcweir { 3667*cdf0e10cSrcweir PangoAttribute *pango_attr = (PangoAttribute *)(tmp_list->data); 3668*cdf0e10cSrcweir 3669*cdf0e10cSrcweir switch (pango_attr->klass->type) 3670*cdf0e10cSrcweir { 3671*cdf0e10cSrcweir case PANGO_ATTR_BACKGROUND: 3672*cdf0e10cSrcweir sal_attr |= (SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT | SAL_EXTTEXTINPUT_CURSOR_INVISIBLE); 3673*cdf0e10cSrcweir break; 3674*cdf0e10cSrcweir case PANGO_ATTR_UNDERLINE: 3675*cdf0e10cSrcweir sal_attr |= SAL_EXTTEXTINPUT_ATTR_UNDERLINE; 3676*cdf0e10cSrcweir break; 3677*cdf0e10cSrcweir case PANGO_ATTR_STRIKETHROUGH: 3678*cdf0e10cSrcweir sal_attr |= SAL_EXTTEXTINPUT_ATTR_REDTEXT; 3679*cdf0e10cSrcweir break; 3680*cdf0e10cSrcweir default: 3681*cdf0e10cSrcweir break; 3682*cdf0e10cSrcweir } 3683*cdf0e10cSrcweir pango_attribute_destroy (pango_attr); 3684*cdf0e10cSrcweir tmp_list = tmp_list->next; 3685*cdf0e10cSrcweir } 3686*cdf0e10cSrcweir if (sal_attr == 0) 3687*cdf0e10cSrcweir sal_attr |= SAL_EXTTEXTINPUT_ATTR_UNDERLINE; 3688*cdf0e10cSrcweir g_slist_free (attr_list); 3689*cdf0e10cSrcweir 3690*cdf0e10cSrcweir // Set the sal attributes on our text 3691*cdf0e10cSrcweir for (int i = start; i < end; i++) 3692*cdf0e10cSrcweir pThis->m_aInputFlags[i] |= sal_attr; 3693*cdf0e10cSrcweir } while (pango_attr_iterator_next (iter)); 3694*cdf0e10cSrcweir 3695*cdf0e10cSrcweir pThis->m_aInputEvent.mpTextAttr = &pThis->m_aInputFlags[0]; 3696*cdf0e10cSrcweir 3697*cdf0e10cSrcweir g_free( pText ); 3698*cdf0e10cSrcweir pango_attr_list_unref( pAttrs ); 3699*cdf0e10cSrcweir 3700*cdf0e10cSrcweir GTK_YIELD_GRAB(); 3701*cdf0e10cSrcweir 3702*cdf0e10cSrcweir vcl::DeletionListener aDel( pThis->m_pFrame ); 3703*cdf0e10cSrcweir 3704*cdf0e10cSrcweir pThis->m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&pThis->m_aInputEvent); 3705*cdf0e10cSrcweir if( bEndPreedit && ! aDel.isDeleted() ) 3706*cdf0e10cSrcweir pThis->doCallEndExtTextInput(); 3707*cdf0e10cSrcweir if( ! aDel.isDeleted() ) 3708*cdf0e10cSrcweir pThis->updateIMSpotLocation(); 3709*cdf0e10cSrcweir } 3710*cdf0e10cSrcweir 3711*cdf0e10cSrcweir void GtkSalFrame::IMHandler::signalIMPreeditStart( GtkIMContext*, gpointer /*im_handler*/ ) 3712*cdf0e10cSrcweir { 3713*cdf0e10cSrcweir } 3714*cdf0e10cSrcweir 3715*cdf0e10cSrcweir void GtkSalFrame::IMHandler::signalIMPreeditEnd( GtkIMContext*, gpointer im_handler ) 3716*cdf0e10cSrcweir { 3717*cdf0e10cSrcweir GtkSalFrame::IMHandler* pThis = (GtkSalFrame::IMHandler*)im_handler; 3718*cdf0e10cSrcweir GTK_YIELD_GRAB(); 3719*cdf0e10cSrcweir 3720*cdf0e10cSrcweir pThis->m_bPreeditJustChanged = true; 3721*cdf0e10cSrcweir 3722*cdf0e10cSrcweir vcl::DeletionListener aDel( pThis->m_pFrame ); 3723*cdf0e10cSrcweir pThis->doCallEndExtTextInput(); 3724*cdf0e10cSrcweir if( ! aDel.isDeleted() ) 3725*cdf0e10cSrcweir pThis->updateIMSpotLocation(); 3726*cdf0e10cSrcweir } 3727*cdf0e10cSrcweir 3728*cdf0e10cSrcweir uno::Reference<accessibility::XAccessibleEditableText> 3729*cdf0e10cSrcweir FindFocus(uno::Reference< accessibility::XAccessibleContext > xContext) 3730*cdf0e10cSrcweir { 3731*cdf0e10cSrcweir if (!xContext.is()) 3732*cdf0e10cSrcweir uno::Reference< accessibility::XAccessibleEditableText >(); 3733*cdf0e10cSrcweir 3734*cdf0e10cSrcweir uno::Reference<accessibility::XAccessibleStateSet> xState = xContext->getAccessibleStateSet(); 3735*cdf0e10cSrcweir if (xState.is()) 3736*cdf0e10cSrcweir { 3737*cdf0e10cSrcweir if (xState->contains(accessibility::AccessibleStateType::FOCUSED)) 3738*cdf0e10cSrcweir return uno::Reference<accessibility::XAccessibleEditableText>(xContext, uno::UNO_QUERY); 3739*cdf0e10cSrcweir } 3740*cdf0e10cSrcweir 3741*cdf0e10cSrcweir for (sal_Int32 i = 0; i < xContext->getAccessibleChildCount(); ++i) 3742*cdf0e10cSrcweir { 3743*cdf0e10cSrcweir uno::Reference< accessibility::XAccessible > xChild = xContext->getAccessibleChild(i); 3744*cdf0e10cSrcweir if (!xChild.is()) 3745*cdf0e10cSrcweir continue; 3746*cdf0e10cSrcweir uno::Reference< accessibility::XAccessibleContext > xChildContext = xChild->getAccessibleContext(); 3747*cdf0e10cSrcweir if (!xChildContext.is()) 3748*cdf0e10cSrcweir continue; 3749*cdf0e10cSrcweir uno::Reference< accessibility::XAccessibleEditableText > xText = FindFocus(xChildContext); 3750*cdf0e10cSrcweir if (xText.is()) 3751*cdf0e10cSrcweir return xText; 3752*cdf0e10cSrcweir } 3753*cdf0e10cSrcweir return uno::Reference< accessibility::XAccessibleEditableText >(); 3754*cdf0e10cSrcweir } 3755*cdf0e10cSrcweir 3756*cdf0e10cSrcweir uno::Reference<accessibility::XAccessibleEditableText> lcl_GetxText() 3757*cdf0e10cSrcweir { 3758*cdf0e10cSrcweir uno::Reference<accessibility::XAccessibleEditableText> xText; 3759*cdf0e10cSrcweir Window* pFocusWin = ImplGetSVData()->maWinData.mpFocusWin; 3760*cdf0e10cSrcweir if (!pFocusWin) 3761*cdf0e10cSrcweir return xText; 3762*cdf0e10cSrcweir 3763*cdf0e10cSrcweir uno::Reference< accessibility::XAccessible > xAccessible( pFocusWin->GetAccessible( true ) ); 3764*cdf0e10cSrcweir if (xAccessible.is()) 3765*cdf0e10cSrcweir xText = FindFocus(xAccessible->getAccessibleContext()); 3766*cdf0e10cSrcweir return xText; 3767*cdf0e10cSrcweir } 3768*cdf0e10cSrcweir 3769*cdf0e10cSrcweir gboolean GtkSalFrame::IMHandler::signalIMRetrieveSurrounding( GtkIMContext* pContext, gpointer /*im_handler*/ ) 3770*cdf0e10cSrcweir { 3771*cdf0e10cSrcweir uno::Reference<accessibility::XAccessibleEditableText> xText = lcl_GetxText(); 3772*cdf0e10cSrcweir 3773*cdf0e10cSrcweir if (xText.is()) 3774*cdf0e10cSrcweir { 3775*cdf0e10cSrcweir sal_uInt32 nPosition = xText->getCaretPosition(); 3776*cdf0e10cSrcweir rtl::OUString sAllText = xText->getText(); 3777*cdf0e10cSrcweir if (!sAllText.getLength()) 3778*cdf0e10cSrcweir return sal_False; 3779*cdf0e10cSrcweir rtl::OString sUTF = rtl::OUStringToOString(sAllText, RTL_TEXTENCODING_UTF8); 3780*cdf0e10cSrcweir rtl::OUString sCursorText(sAllText, nPosition); 3781*cdf0e10cSrcweir gtk_im_context_set_surrounding(pContext, sUTF.getStr(), sUTF.getLength(), 3782*cdf0e10cSrcweir rtl::OUStringToOString(sCursorText, RTL_TEXTENCODING_UTF8).getLength()); 3783*cdf0e10cSrcweir return sal_True; 3784*cdf0e10cSrcweir } 3785*cdf0e10cSrcweir 3786*cdf0e10cSrcweir return sal_False; 3787*cdf0e10cSrcweir } 3788*cdf0e10cSrcweir 3789*cdf0e10cSrcweir gboolean GtkSalFrame::IMHandler::signalIMDeleteSurrounding( GtkIMContext*, gint offset, gint nchars, 3790*cdf0e10cSrcweir gpointer /*im_handler*/ ) 3791*cdf0e10cSrcweir { 3792*cdf0e10cSrcweir uno::Reference<accessibility::XAccessibleEditableText> xText = lcl_GetxText(); 3793*cdf0e10cSrcweir 3794*cdf0e10cSrcweir if (xText.is()) 3795*cdf0e10cSrcweir { 3796*cdf0e10cSrcweir sal_uInt32 nPosition = xText->getCaretPosition(); 3797*cdf0e10cSrcweir // --> OD 2010-06-04 #i111768# - apply patch from kstribley: 3798*cdf0e10cSrcweir // range checking 3799*cdf0e10cSrcweir // xText->deleteText(nPosition + offset, nPosition + offset + nchars); 3800*cdf0e10cSrcweir sal_Int32 nDeletePos = nPosition + offset; 3801*cdf0e10cSrcweir sal_Int32 nDeleteEnd = nDeletePos + nchars; 3802*cdf0e10cSrcweir if (nDeletePos < 0) 3803*cdf0e10cSrcweir nDeletePos = 0; 3804*cdf0e10cSrcweir if (nDeleteEnd < 0) 3805*cdf0e10cSrcweir nDeleteEnd = 0; 3806*cdf0e10cSrcweir if (nDeleteEnd > xText->getCharacterCount()) 3807*cdf0e10cSrcweir nDeleteEnd = xText->getCharacterCount(); 3808*cdf0e10cSrcweir 3809*cdf0e10cSrcweir xText->deleteText(nDeletePos, nDeleteEnd); 3810*cdf0e10cSrcweir // <-- 3811*cdf0e10cSrcweir return sal_True; 3812*cdf0e10cSrcweir } 3813*cdf0e10cSrcweir 3814*cdf0e10cSrcweir return sal_False; 3815*cdf0e10cSrcweir } 3816