1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #ifndef INCLUDED_VCL_INC_UNX_SALDISP_HXX
21 #define INCLUDED_VCL_INC_UNX_SALDISP_HXX
22
23 class SalDisplay;
24 class SalColormap;
25 class SalVisual;
26 class SalXLib;
27
28 #include <X11/Xlib.h>
29 #include <X11/Xutil.h>
30 #include <X11/extensions/render.h>
31 #include <epoxy/glx.h>
32
33 #include <rtl/string.hxx>
34 #include <unx/saltype.h>
35 #include <vcl/opengl/OpenGLContext.hxx>
36 #include <vcl/ptrstyle.hxx>
37 #include <sal/types.h>
38 #include <cassert>
39 #include <list>
40 #include <unordered_map>
41 #include <vector>
42 #include <tools/gen.hxx>
43 #include <salwtype.hxx>
44 #include <unx/gendata.hxx>
45 #include <unx/gendisp.hxx>
46 #include <o3tl/enumarray.hxx>
47
48 #include <vclpluginapi.h>
49
50 /* From <X11/Intrinsic.h> */
51 typedef unsigned long Pixel;
52
53 class BitmapPalette;
54 class SalFrame;
55 class ColorMask;
56
57 namespace vcl_sal { class WMAdaptor; }
58
59 // server vendor
60
61 typedef enum {
62 vendor_none = 0,
63 vendor_sun,
64 vendor_unknown
65 } srv_vendor_t;
66
67 extern "C" srv_vendor_t sal_GetServerVendor( Display *p_display );
68
69 // MSB/Bigendian view (Color == RGB, r=0xFF0000, g=0xFF00, b=0xFF)
70
71 enum class SalRGB { RGB, RBG,
72 GBR, GRB,
73 BGR, BRG,
74 otherSalRGB };
75
76 class SalVisual : public XVisualInfo
77 {
78 SalRGB eRGBMode_;
79 int nRedShift_;
80 int nGreenShift_;
81 int nBlueShift_;
82 int nRedBits_;
83 int nGreenBits_;
84 int nBlueBits_;
85 public:
86 SalVisual();
87 SalVisual( const XVisualInfo* pXVI );
88
GetVisualId() const89 VisualID GetVisualId() const { return visualid; }
GetVisual() const90 Visual *GetVisual() const { return visual; }
GetClass() const91 int GetClass() const { return c_class; }
GetDepth() const92 int GetDepth() const { return depth; }
93
94 Pixel GetTCPixel( Color nColor ) const;
95 Color GetTCColor( Pixel nPixel ) const;
96 };
97
98 // A move-only flag, used by SalColormap to track ownership of its m_aVisual.visual:
99 struct OwnershipFlag {
100 bool owner = false;
101
102 OwnershipFlag() = default;
103
OwnershipFlagOwnershipFlag104 OwnershipFlag(OwnershipFlag && other) noexcept: owner(other.owner) { other.owner = false; }
105
operator =OwnershipFlag106 OwnershipFlag & operator =(OwnershipFlag && other) noexcept {
107 assert(&other != this);
108 owner = other.owner;
109 other.owner = false;
110 return *this;
111 }
112 };
113
114 class SalColormap
115 {
116 const SalDisplay* m_pDisplay;
117 Colormap m_hColormap;
118 std::vector<Color> m_aPalette; // Pseudocolor
119 SalVisual m_aVisual;
120 OwnershipFlag m_aVisualOwnership;
121 std::vector<sal_uInt16> m_aLookupTable; // Pseudocolor: 12bit reduction
122 Pixel m_nWhitePixel;
123 Pixel m_nBlackPixel;
124 Pixel m_nUsed; // Pseudocolor
125 SalX11Screen m_nXScreen;
126
127 void GetPalette();
128 void GetLookupTable();
129 public:
130 SalColormap( const SalDisplay* pSalDisplay,
131 Colormap hColormap,
132 SalX11Screen nXScreen );
133 SalColormap( sal_uInt16 nDepth );
134 SalColormap();
135
136 ~SalColormap();
137
138 SalColormap(SalColormap &&) = default;
139 SalColormap & operator =(SalColormap &&) = default;
140
GetXColormap() const141 Colormap GetXColormap() const { return m_hColormap; }
GetDisplay() const142 const SalDisplay* GetDisplay() const { return m_pDisplay; }
143 inline Display* GetXDisplay() const;
GetVisual() const144 const SalVisual& GetVisual() const { return m_aVisual; }
GetXVisual() const145 Visual* GetXVisual() const { return m_aVisual.GetVisual(); }
GetWhitePixel() const146 Pixel GetWhitePixel() const { return m_nWhitePixel; }
GetBlackPixel() const147 Pixel GetBlackPixel() const { return m_nBlackPixel; }
GetUsed() const148 Pixel GetUsed() const { return m_nUsed; }
149
150 bool GetXPixels( XColor &rColor,
151 int r,
152 int g,
153 int b ) const;
154 inline bool GetXPixel( XColor &rColor,
155 int r,
156 int g,
157 int b ) const;
158 Pixel GetPixel( Color nColor ) const;
159 Color GetColor( Pixel nPixel ) const;
160 };
161
162 class SalI18N_InputMethod;
163
164 typedef int(*YieldFunc)(int fd, void* data);
165
166 class SalXLib
167 {
168 protected:
169 timeval m_aTimeout;
170 sal_uLong m_nTimeoutMS;
171 int m_pTimeoutFDS[2];
172
173 int nFDs_;
174 fd_set aReadFDS_;
175 fd_set aExceptionFDS_;
176
177 Display *m_pDisplay;
178 std::unique_ptr<SalI18N_InputMethod> m_pInputMethod;
179
180 public:
181 SalXLib();
182 virtual ~SalXLib();
183 virtual void Init();
184
185 virtual bool Yield( bool bWait, bool bHandleAllCurrentEvents );
186 virtual void Wakeup();
187 void TriggerUserEventProcessing();
188
189 virtual void Insert( int fd, void* data,
190 YieldFunc pending,
191 YieldFunc queued,
192 YieldFunc handle );
193 virtual void Remove( int fd );
194
195 virtual void StartTimer( sal_uInt64 nMS );
196 virtual void StopTimer();
197
198 virtual bool CheckTimeout( bool bExecuteTimers = true );
199
GetInputMethod() const200 SalI18N_InputMethod* GetInputMethod() const { return m_pInputMethod.get(); }
GetDisplay() const201 Display* GetDisplay() const { return m_pDisplay; }
202 };
203
204 class SalI18N_KeyboardExtension;
205 class AttributeProvider;
206
207 extern "C" {
208 typedef Bool(*X_if_predicate)(Display*,XEvent*,XPointer);
209 }
210
211 class GLX11Window : public GLWindow
212 {
213 public:
214 Display* dpy;
215 int screen;
216 Window win;
217 XVisualInfo* vi;
218 GLXContext ctx;
219 OString GLXExtensions;
220
221 bool HasGLXExtension(const char* name) const;
222
223 GLX11Window();
224 virtual bool Synchronize(bool bOnoff) const override;
225 virtual ~GLX11Window() override;
226 };
227
228 class VCLPLUG_GEN_PUBLIC SalDisplay : public SalGenericDisplay
229 {
230 public:
231 struct RenderEntry
232 {
233 Pixmap m_aPixmap;
234 Picture m_aPicture;
235
RenderEntrySalDisplay::RenderEntry236 RenderEntry() : m_aPixmap( 0 ), m_aPicture( 0 ) {}
237 };
238
239 typedef std::unordered_map<int,RenderEntry> RenderEntryMap;
240
241 struct ScreenData
242 {
243 bool m_bInit;
244
245 ::Window m_aRoot;
246 ::Window m_aRefWindow;
247 Size m_aSize;
248 SalVisual m_aVisual;
249 SalColormap m_aColormap;
250 GC m_aMonoGC;
251 GC m_aCopyGC;
252 GC m_aAndInvertedGC;
253 GC m_aAndGC;
254 GC m_aOrGC;
255 GC m_aStippleGC;
256 Pixmap m_hInvert50;
257 mutable RenderEntryMap m_aRenderData;
258
ScreenDataSalDisplay::ScreenData259 ScreenData() :
260 m_bInit( false ),
261 m_aRoot( None ),
262 m_aRefWindow( None ),
263 m_aMonoGC( None ),
264 m_aCopyGC( None ),
265 m_aAndInvertedGC( None ),
266 m_aAndGC( None ),
267 m_aOrGC( None ),
268 m_aStippleGC( None ),
269 m_hInvert50( None ),
270 m_aRenderData( 1 )
271 {}
272 };
273
274 protected:
275 SalXLib *pXLib_;
276 SalI18N_KeyboardExtension *mpKbdExtension;
277
278 Display *pDisp_; // X Display
279
280 SalX11Screen m_nXDefaultScreen;
281 std::vector< ScreenData > m_aScreens;
282 ScreenData const m_aInvalidScreenData;
283 Pair aResolution_; // [dpi]
284 sal_uLong nMaxRequestSize_; // [byte]
285
286 srv_vendor_t meServerVendor;
287
288 // until x bytes
289
290 o3tl::enumarray<PointerStyle, Cursor> aPointerCache_;
291
292 // Keyboard
293 bool bNumLockFromXS_; // Num Lock handled by X Server
294 int nNumLockIndex_; // modifier index in modmap
295 KeySym nShiftKeySym_; // first shift modifier
296 KeySym nCtrlKeySym_; // first control modifier
297 KeySym nMod1KeySym_; // first mod1 modifier
298
299 std::unique_ptr<vcl_sal::WMAdaptor> m_pWMAdaptor;
300
301 bool m_bXinerama;
302 std::vector< tools::Rectangle > m_aXineramaScreens;
303 std::vector< int > m_aXineramaScreenIndexMap;
304 std::list<SalObject*> m_aSalObjects;
305
306 mutable Time m_nLastUserEventTime; // mutable because changed on first access
307
308 virtual bool Dispatch( XEvent *pEvent ) = 0;
309 void InitXinerama();
310 void InitRandR( ::Window aRoot ) const;
311 static void DeInitRandR();
312 void processRandREvent( XEvent* );
313
314 void doDestruct();
315 void addXineramaScreenUnique( int i, long i_nX, long i_nY, long i_nWidth, long i_nHeight );
316 Time GetEventTimeImpl( bool bAlwaysReget = false ) const;
317 public:
318 static bool BestOpenGLVisual(Display* pDisplay, int nScreen, XVisualInfo& rVI);
319 static bool BestVisual(Display *pDisp, int nScreen, XVisualInfo &rVI);
320
321 SalDisplay( Display* pDisp );
322
323 virtual ~SalDisplay() override;
324
325 void Init();
326
327 #ifdef DBG_UTIL
328 void PrintInfo() const;
329 void DbgPrintDisplayEvent(const char *pComment, XEvent *pEvent) const;
330 #endif
331
332 void Beep() const;
333
334 void ModifierMapping();
335 void SimulateKeyPress( sal_uInt16 nKeyCode );
336 KeyIndicatorState GetIndicatorState() const;
337 OUString GetKeyNameFromKeySym( KeySym keysym ) const;
338 OUString GetKeyName( sal_uInt16 nKeyCode ) const;
339 sal_uInt16 GetKeyCode( KeySym keysym, char*pcPrintable ) const;
340 KeySym GetKeySym( XKeyEvent *pEvent,
341 char *pPrintable,
342 int *pLen,
343 KeySym *pUnmodifiedKeySym,
344 Status *pStatus,
345 XIC = nullptr ) const;
346
347 Cursor GetPointer( PointerStyle ePointerStyle );
348 int CaptureMouse( SalFrame *pCapture );
349
350 ScreenData* initScreen( SalX11Screen nXScreen ) const;
getDataForScreen(SalX11Screen nXScreen) const351 const ScreenData& getDataForScreen( SalX11Screen nXScreen ) const
352 {
353 if( nXScreen.getXScreen() >= m_aScreens.size() )
354 return m_aInvalidScreenData;
355 if( ! m_aScreens[nXScreen.getXScreen()].m_bInit )
356 initScreen( nXScreen );
357 return m_aScreens[nXScreen.getXScreen()];
358 }
359
GetDrawable(SalX11Screen nXScreen) const360 ::Window GetDrawable( SalX11Screen nXScreen ) const { return getDataForScreen( nXScreen ).m_aRefWindow; }
GetDisplay() const361 Display *GetDisplay() const { return pDisp_; }
GetDefaultXScreen() const362 const SalX11Screen& GetDefaultXScreen() const { return m_nXDefaultScreen; }
GetScreenSize(SalX11Screen nXScreen) const363 const Size& GetScreenSize( SalX11Screen nXScreen ) const { return getDataForScreen( nXScreen ).m_aSize; }
GetServerVendor() const364 srv_vendor_t GetServerVendor() const { return meServerVendor; }
IsDisplay() const365 bool IsDisplay() const { return !!pXLib_; }
GetCopyGC(SalX11Screen nXScreen) const366 GC GetCopyGC( SalX11Screen nXScreen ) const { return getDataForScreen(nXScreen).m_aCopyGC; }
GetInvert50(SalX11Screen nXScreen) const367 Pixmap GetInvert50( SalX11Screen nXScreen ) const { return getDataForScreen(nXScreen).m_hInvert50; }
GetColormap(SalX11Screen nXScreen) const368 const SalColormap& GetColormap( SalX11Screen nXScreen ) const { return getDataForScreen(nXScreen).m_aColormap; }
GetVisual(SalX11Screen nXScreen) const369 const SalVisual& GetVisual( SalX11Screen nXScreen ) const { return getDataForScreen(nXScreen).m_aVisual; }
GetRenderEntries(SalX11Screen nXScreen) const370 RenderEntryMap& GetRenderEntries( SalX11Screen nXScreen ) const { return getDataForScreen(nXScreen).m_aRenderData; }
GetResolution() const371 const Pair &GetResolution() const { return aResolution_; }
GetMaxRequestSize() const372 sal_uLong GetMaxRequestSize() const { return nMaxRequestSize_; }
GetLastUserEventTime() const373 Time GetLastUserEventTime() const { return GetEventTimeImpl(); }
374 // this is an equivalent of gdk_x11_get_server_time()
GetX11ServerTime() const375 Time GetX11ServerTime() const { return GetEventTimeImpl( true ); }
376
377 bool XIfEventWithTimeout( XEvent*, XPointer, X_if_predicate ) const;
GetXLib() const378 SalXLib* GetXLib() const { return pXLib_; }
379
GetInputMethod() const380 SalI18N_InputMethod* GetInputMethod() const { return pXLib_->GetInputMethod(); }
GetKbdExtension() const381 SalI18N_KeyboardExtension* GetKbdExtension() const { return mpKbdExtension; }
SetKbdExtension(SalI18N_KeyboardExtension * pKbdExtension)382 void SetKbdExtension(SalI18N_KeyboardExtension *pKbdExtension)
383 { mpKbdExtension = pKbdExtension; }
getWMAdaptor() const384 ::vcl_sal::WMAdaptor* getWMAdaptor() const { return m_pWMAdaptor.get(); }
IsXinerama() const385 bool IsXinerama() const { return m_bXinerama; }
GetXineramaScreens() const386 const std::vector< tools::Rectangle >& GetXineramaScreens() const { return m_aXineramaScreens; }
GetRootWindow(SalX11Screen nXScreen) const387 ::Window GetRootWindow( SalX11Screen nXScreen ) const
388 { return getDataForScreen( nXScreen ).m_aRoot; }
GetXScreenCount() const389 unsigned int GetXScreenCount() const { return m_aScreens.size(); }
390
getFrames() const391 const SalFrameSet& getFrames() const { return m_aFrames; }
392
getSalObjects()393 std::list< SalObject* >& getSalObjects() { return m_aSalObjects; }
394 };
395
GetXDisplay() const396 inline Display *SalColormap::GetXDisplay() const
397 { return m_pDisplay->GetDisplay(); }
398
399 class SalX11Display : public SalDisplay
400 {
401 public:
402 SalX11Display( Display* pDisp );
403 virtual ~SalX11Display() override;
404
405 virtual bool Dispatch( XEvent *pEvent ) override;
406 virtual void Yield();
407 virtual void TriggerUserEventProcessing() override;
408
409 bool IsEvent();
410 void SetupInput();
411 };
412
413 namespace vcl_sal {
414 // get foreign key names
415 OUString getKeysymReplacementName(
416 const OUString& pLang,
417 KeySym nSymbol );
418
getSalDisplay(GenericUnixSalData const * data)419 inline SalDisplay *getSalDisplay(GenericUnixSalData const * data)
420 {
421 assert(data != nullptr);
422 assert(data->GetType() != SAL_DATA_GTK3);
423 return static_cast<SalDisplay *>(data->GetDisplay());
424 }
425 }
426
427 #endif // INCLUDED_VCL_INC_UNX_SALDISP_HXX
428
429 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
430