bump product version to 6.4.0.3
[LibreOffice.git] / vcl / osx / saldata.cxx
blob5235f657f8cad75c7e98a2373437b8f65267ece4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
22 #include <osl/diagnose.h>
23 #include <osx/saldata.hxx>
24 #include <osx/salnsmenu.h>
25 #include <osx/salinst.h>
26 #include <o3tl/enumarray.hxx>
27 #include <tools/stream.hxx>
28 #include <vcl/ImageTree.hxx>
29 #include <vcl/settings.hxx>
30 #include <i18nlangtag/languagetag.hxx>
31 #include <sal/log.hxx>
32 #include <bitmaps.hlst>
33 #include <cursor_hotspots.hxx>
35 #import "apple_remote/RemoteMainController.h"
37 oslThreadKey SalData::s_aAutoReleaseKey = nullptr;
39 static void releasePool( void* pPool )
41 if( pPool )
42 [static_cast<NSAutoreleasePool*>(pPool) release];
45 SalData::SalData()
47 mpTimerProc( nullptr ),
48 mpInstance( nullptr ),
49 mpFirstObject( nullptr ),
50 mpFirstVD( nullptr ),
51 mpFirstPrinter( nullptr ),
52 mpFontList( nullptr ),
53 mpStatusItem( nil ),
54 mxRGBSpace( CGColorSpaceCreateWithName(kCGColorSpaceSRGB) ),
55 mxGraySpace( CGColorSpaceCreateWithName(kCGColorSpaceGenericGrayGamma2_2) ),
56 maCursors(),
57 mbIsScrollbarDoubleMax( false ),
58 #if !HAVE_FEATURE_MACOSX_SANDBOX
59 mpAppleRemoteMainController( nullptr ),
60 #endif
61 mpDockIconClickHandler( nil ),
62 mnDPIX( 0 ),
63 mnDPIY( 0 )
65 SetSalData(this);
66 maCursors.fill( INVALID_CURSOR_PTR );
67 if( s_aAutoReleaseKey == nullptr )
68 s_aAutoReleaseKey = osl_createThreadKey( releasePool );
71 SalData::~SalData()
73 CGColorSpaceRelease( mxRGBSpace );
74 CGColorSpaceRelease( mxGraySpace );
75 for( NSCursor* pCurs : maCursors )
77 if( pCurs && pCurs != INVALID_CURSOR_PTR )
78 [pCurs release];
80 if( s_aAutoReleaseKey )
82 // release the last pool
83 NSAutoreleasePool* pPool = reinterpret_cast<NSAutoreleasePool*>( osl_getThreadKeyData( s_aAutoReleaseKey ) );
84 if( pPool )
86 osl_setThreadKeyData( s_aAutoReleaseKey, nullptr );
87 [pPool release];
90 osl_destroyThreadKey( s_aAutoReleaseKey );
91 s_aAutoReleaseKey = nullptr;
93 #if !HAVE_FEATURE_MACOSX_SANDBOX
94 if ( mpAppleRemoteMainController )
95 [mpAppleRemoteMainController release];
96 #endif
98 if( mpStatusItem )
100 [mpStatusItem release];
101 mpStatusItem = nil;
103 SetSalData( nullptr );
106 void SalData::ensureThreadAutoreleasePool()
108 NSAutoreleasePool* pPool = nil;
109 if( s_aAutoReleaseKey )
111 pPool = reinterpret_cast<NSAutoreleasePool*>( osl_getThreadKeyData( s_aAutoReleaseKey ) );
112 if( ! pPool )
114 pPool = [[NSAutoreleasePool alloc] init];
115 osl_setThreadKeyData( s_aAutoReleaseKey, pPool );
118 else
120 OSL_FAIL( "no autorelease key" );
124 namespace {
126 NSImage* load_icon_by_name(const OUString& rIconName)
128 OUString sIconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
129 OUString sUILang = Application::GetSettings().GetUILanguageTag().getBcp47();
130 auto xMemStm = ImageTree::get().getImageStream(rIconName, sIconTheme, sUILang);
131 if (!xMemStm)
132 return nullptr;
134 auto data = xMemStm->GetData();
135 auto length = xMemStm->TellEnd();
136 NSData * byteData = [NSData dataWithBytes:data length:length];
137 NSBitmapImageRep * imageRep = [NSBitmapImageRep imageRepWithData:byteData];
138 NSSize imageSize = NSMakeSize(CGImageGetWidth([imageRep CGImage]), CGImageGetHeight([imageRep CGImage]));
140 NSImage * image = [[NSImage alloc] initWithSize:imageSize];
141 [image addRepresentation:imageRep];
142 return image;
147 #define MAKE_CURSOR( vcl_name, name, name2 ) \
148 case vcl_name: \
149 aHotSpot = NSPoint{name##curs_x_hot, name##curs_y_hot}; \
150 aIconName = name2; \
151 break
153 NSCursor* SalData::getCursor( PointerStyle i_eStyle )
155 NSCursor* pCurs = maCursors[ i_eStyle ];
156 if( pCurs != INVALID_CURSOR_PTR )
157 return pCurs;
159 NSPoint aHotSpot;
160 OUString aIconName;
162 switch( i_eStyle )
164 // TODO
165 MAKE_CURSOR( PointerStyle::Wait, wait_, RID_CURSOR_WAIT );
166 MAKE_CURSOR( PointerStyle::NWSize, nwsize_, RID_CURSOR_NWSIZE );
167 MAKE_CURSOR( PointerStyle::NESize, nesize_, RID_CURSOR_NESIZE );
168 MAKE_CURSOR( PointerStyle::SWSize, swsize_, RID_CURSOR_SWSIZE );
169 MAKE_CURSOR( PointerStyle::SESize, sesize_, RID_CURSOR_SESIZE );
170 MAKE_CURSOR( PointerStyle::WindowNWSize, window_nwsize_, RID_CURSOR_WINDOW_NWSIZE );
171 MAKE_CURSOR( PointerStyle::WindowNESize, window_nesize_, RID_CURSOR_WINDOW_NESIZE );
172 MAKE_CURSOR( PointerStyle::WindowSWSize, window_swsize_, RID_CURSOR_WINDOW_SWSIZE );
173 MAKE_CURSOR( PointerStyle::WindowSESize, window_sesize_, RID_CURSOR_WINDOW_SESIZE );
175 MAKE_CURSOR( PointerStyle::Help, help_, RID_CURSOR_HELP );
176 MAKE_CURSOR( PointerStyle::Pen, pen_, RID_CURSOR_PEN );
177 MAKE_CURSOR( PointerStyle::Null, null, RID_CURSOR_NULL );
178 MAKE_CURSOR( PointerStyle::Magnify, magnify_, RID_CURSOR_MAGNIFY );
179 MAKE_CURSOR( PointerStyle::Fill, fill_, RID_CURSOR_FILL );
180 MAKE_CURSOR( PointerStyle::MoveData, movedata_, RID_CURSOR_MOVE_DATA );
181 MAKE_CURSOR( PointerStyle::CopyData, copydata_, RID_CURSOR_COPY_DATA );
182 MAKE_CURSOR( PointerStyle::MoveFile, movefile_, RID_CURSOR_MOVE_FILE );
183 MAKE_CURSOR( PointerStyle::CopyFile, copyfile_, RID_CURSOR_COPY_FILE );
184 MAKE_CURSOR( PointerStyle::MoveFiles, movefiles_, RID_CURSOR_MOVE_FILES );
185 MAKE_CURSOR( PointerStyle::CopyFiles, copyfiles_, RID_CURSOR_COPY_FILES );
186 MAKE_CURSOR( PointerStyle::NotAllowed, nodrop_, RID_CURSOR_NOT_ALLOWED );
187 MAKE_CURSOR( PointerStyle::Rotate, rotate_, RID_CURSOR_ROTATE );
188 MAKE_CURSOR( PointerStyle::HShear, hshear_, RID_CURSOR_H_SHEAR );
189 MAKE_CURSOR( PointerStyle::VShear, vshear_, RID_CURSOR_V_SHEAR );
190 MAKE_CURSOR( PointerStyle::DrawLine, drawline_, RID_CURSOR_DRAW_LINE );
191 MAKE_CURSOR( PointerStyle::DrawRect, drawrect_, RID_CURSOR_DRAW_RECT );
192 MAKE_CURSOR( PointerStyle::DrawPolygon, drawpolygon_, RID_CURSOR_DRAW_POLYGON );
193 MAKE_CURSOR( PointerStyle::DrawBezier, drawbezier_, RID_CURSOR_DRAW_BEZIER );
194 MAKE_CURSOR( PointerStyle::DrawArc, drawarc_, RID_CURSOR_DRAW_ARC );
195 MAKE_CURSOR( PointerStyle::DrawPie, drawpie_, RID_CURSOR_DRAW_PIE );
196 MAKE_CURSOR( PointerStyle::DrawCircleCut, drawcirclecut_, RID_CURSOR_DRAW_CIRCLE_CUT );
197 MAKE_CURSOR( PointerStyle::DrawEllipse, drawellipse_, RID_CURSOR_DRAW_ELLIPSE );
198 MAKE_CURSOR( PointerStyle::DrawConnect, drawconnect_, RID_CURSOR_DRAW_CONNECT );
199 MAKE_CURSOR( PointerStyle::DrawText, drawtext_, RID_CURSOR_DRAW_TEXT );
200 MAKE_CURSOR( PointerStyle::Mirror, mirror_, RID_CURSOR_MIRROR );
201 MAKE_CURSOR( PointerStyle::Crook, crook_, RID_CURSOR_CROOK );
202 MAKE_CURSOR( PointerStyle::Crop, crop_, RID_CURSOR_CROP );
203 MAKE_CURSOR( PointerStyle::MovePoint, movepoint_, RID_CURSOR_MOVE_POINT );
204 MAKE_CURSOR( PointerStyle::MoveBezierWeight, movebezierweight_, RID_CURSOR_MOVE_BEZIER_WEIGHT );
205 MAKE_CURSOR( PointerStyle::DrawFreehand, drawfreehand_, RID_CURSOR_DRAW_FREEHAND );
206 MAKE_CURSOR( PointerStyle::DrawCaption, drawcaption_, RID_CURSOR_DRAW_CAPTION );
207 MAKE_CURSOR( PointerStyle::LinkData, linkdata_, RID_CURSOR_LINK_DATA );
208 MAKE_CURSOR( PointerStyle::MoveDataLink, movedlnk_, RID_CURSOR_MOVE_DATA_LINK );
209 MAKE_CURSOR( PointerStyle::CopyDataLink, copydlnk_, RID_CURSOR_COPY_DATA_LINK );
210 MAKE_CURSOR( PointerStyle::LinkFile, linkfile_, RID_CURSOR_LINK_FILE );
211 MAKE_CURSOR( PointerStyle::MoveFileLink, moveflnk_, RID_CURSOR_MOVE_FILE_LINK );
212 MAKE_CURSOR( PointerStyle::CopyFileLink, copyflnk_, RID_CURSOR_COPY_FILE_LINK );
213 MAKE_CURSOR( PointerStyle::Chart, chart_, RID_CURSOR_CHART );
214 MAKE_CURSOR( PointerStyle::Detective, detective_, RID_CURSOR_DETECTIVE );
215 MAKE_CURSOR( PointerStyle::PivotCol, pivotcol_, RID_CURSOR_PIVOT_COLUMN );
216 MAKE_CURSOR( PointerStyle::PivotRow, pivotrow_, RID_CURSOR_PIVOT_ROW );
217 MAKE_CURSOR( PointerStyle::PivotField, pivotfld_, RID_CURSOR_PIVOT_FIELD );
218 MAKE_CURSOR( PointerStyle::PivotDelete, pivotdel_, RID_CURSOR_PIVOT_DELETE );
219 MAKE_CURSOR( PointerStyle::Chain, chain_, RID_CURSOR_CHAIN );
220 MAKE_CURSOR( PointerStyle::ChainNotAllowed, chainnot_, RID_CURSOR_CHAIN_NOT_ALLOWED );
221 MAKE_CURSOR( PointerStyle::AutoScrollN, asn_, RID_CURSOR_AUTOSCROLL_N );
222 MAKE_CURSOR( PointerStyle::AutoScrollS, ass_, RID_CURSOR_AUTOSCROLL_S );
223 MAKE_CURSOR( PointerStyle::AutoScrollW, asw_, RID_CURSOR_AUTOSCROLL_W );
224 MAKE_CURSOR( PointerStyle::AutoScrollE, ase_, RID_CURSOR_AUTOSCROLL_E );
225 MAKE_CURSOR( PointerStyle::AutoScrollNW, asnw_, RID_CURSOR_AUTOSCROLL_NW );
226 MAKE_CURSOR( PointerStyle::AutoScrollNE, asne_, RID_CURSOR_AUTOSCROLL_NE );
227 MAKE_CURSOR( PointerStyle::AutoScrollSW, assw_, RID_CURSOR_AUTOSCROLL_SW );
228 MAKE_CURSOR( PointerStyle::AutoScrollSE, asse_, RID_CURSOR_AUTOSCROLL_SE );
229 MAKE_CURSOR( PointerStyle::AutoScrollNS, asns_, RID_CURSOR_AUTOSCROLL_NS );
230 MAKE_CURSOR( PointerStyle::AutoScrollWE, aswe_, RID_CURSOR_AUTOSCROLL_WE );
231 MAKE_CURSOR( PointerStyle::AutoScrollNSWE, asnswe_, RID_CURSOR_AUTOSCROLL_NSWE );
232 MAKE_CURSOR( PointerStyle::TextVertical, vertcurs_, RID_CURSOR_TEXT_VERTICAL );
234 // #i32329#
235 MAKE_CURSOR( PointerStyle::TabSelectS, tblsels_, RID_CURSOR_TAB_SELECT_S );
236 MAKE_CURSOR( PointerStyle::TabSelectE, tblsele_, RID_CURSOR_TAB_SELECT_E );
237 MAKE_CURSOR( PointerStyle::TabSelectSE, tblselse_, RID_CURSOR_TAB_SELECT_SE );
238 MAKE_CURSOR( PointerStyle::TabSelectW, tblselw_, RID_CURSOR_TAB_SELECT_W );
239 MAKE_CURSOR( PointerStyle::TabSelectSW, tblselsw_, RID_CURSOR_TAB_SELECT_SW );
241 MAKE_CURSOR( PointerStyle::HideWhitespace, hidewhitespace_, RID_CURSOR_HIDE_WHITESPACE );
242 MAKE_CURSOR( PointerStyle::ShowWhitespace, showwhitespace_, RID_CURSOR_SHOW_WHITESPACE );
244 default:
245 SAL_WARN( "vcl", "pointer style " << static_cast<sal_Int32>(i_eStyle) << "not implemented" );
246 assert( false && "pointer style not implemented" );
247 break;
250 NSImage* theImage = load_icon_by_name(aIconName);
251 assert ([theImage size].width == 128 || [theImage size].width == 32);
252 if ([theImage size].width == 128)
254 // If we have a 128x128 image, generate scaled versions of it.
255 // This will result in macOS picking a reasonably sized image for different screen dpi.
256 NSSize cursorSize = NSMakeSize(32,32);
257 NSImage *multiResImage = [[NSImage alloc] initWithSize:cursorSize];
258 for (int scale = 1; scale <= 4; scale++) {
259 NSAffineTransform *xform = [[NSAffineTransform alloc] init];
260 [xform scaleBy:scale];
261 id hints = @{ NSImageHintCTM: xform };
262 CGImageRef rasterCGImage = [theImage CGImageForProposedRect:nullptr context:nil hints:hints];
263 NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithCGImage:rasterCGImage];
264 [rep setSize:cursorSize];
265 [multiResImage addRepresentation:rep];
267 pCurs = [[NSCursor alloc] initWithImage: multiResImage hotSpot: aHotSpot];
269 else
270 pCurs = [[NSCursor alloc] initWithImage: theImage hotSpot: aHotSpot];
272 maCursors[ i_eStyle ] = pCurs;
273 return pCurs;
276 NSStatusItem* SalData::getStatusItem()
278 SalData* pData = GetSalData();
279 if( ! pData->mpStatusItem )
281 NSStatusBar* pStatBar =[NSStatusBar systemStatusBar];
282 if( pStatBar )
284 pData->mpStatusItem = [pStatBar statusItemWithLength: NSVariableStatusItemLength];
285 [pData->mpStatusItem retain];
286 OOStatusItemView* pView = [[OOStatusItemView alloc] init];
287 SAL_WNODEPRECATED_DECLARATIONS_PUSH
288 // "'setView:' is deprecated: first deprecated in macOS 10.14 - Use the standard
289 // button property instead"
290 [pData->mpStatusItem setView: pView ];
291 SAL_WNODEPRECATED_DECLARATIONS_POP
292 [pView display];
295 return pData->mpStatusItem;
298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */