1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
)
42 [static_cast<NSAutoreleasePool
*>(pPool
) release
];
47 mpTimerProc( nullptr ),
48 mpInstance( nullptr ),
49 mpFirstObject( nullptr ),
51 mpFirstPrinter( nullptr ),
52 mpFontList( nullptr ),
54 mxRGBSpace( CGColorSpaceCreateWithName(kCGColorSpaceSRGB
) ),
55 mxGraySpace( CGColorSpaceCreateWithName(kCGColorSpaceGenericGrayGamma2_2
) ),
57 mbIsScrollbarDoubleMax( false ),
58 #if !HAVE_FEATURE_MACOSX_SANDBOX
59 mpAppleRemoteMainController( nullptr ),
61 mpDockIconClickHandler( nil
),
66 maCursors
.fill( INVALID_CURSOR_PTR
);
67 if( s_aAutoReleaseKey
== nullptr )
68 s_aAutoReleaseKey
= osl_createThreadKey( releasePool
);
73 CGColorSpaceRelease( mxRGBSpace
);
74 CGColorSpaceRelease( mxGraySpace
);
75 for( NSCursor
* pCurs
: maCursors
)
77 if( pCurs
&& pCurs
!= INVALID_CURSOR_PTR
)
80 if( s_aAutoReleaseKey
)
82 // release the last pool
83 NSAutoreleasePool
* pPool
= reinterpret_cast<NSAutoreleasePool
*>( osl_getThreadKeyData( s_aAutoReleaseKey
) );
86 osl_setThreadKeyData( s_aAutoReleaseKey
, nullptr );
90 osl_destroyThreadKey( s_aAutoReleaseKey
);
91 s_aAutoReleaseKey
= nullptr;
93 #if !HAVE_FEATURE_MACOSX_SANDBOX
94 if ( mpAppleRemoteMainController
)
95 [mpAppleRemoteMainController release
];
100 [mpStatusItem release
];
103 SetSalData( nullptr );
106 void SalData::ensureThreadAutoreleasePool()
108 NSAutoreleasePool
* pPool
= nil
;
109 if( s_aAutoReleaseKey
)
111 pPool
= reinterpret_cast<NSAutoreleasePool
*>( osl_getThreadKeyData( s_aAutoReleaseKey
) );
114 pPool
= [[NSAutoreleasePool alloc
] init
];
115 osl_setThreadKeyData( s_aAutoReleaseKey
, pPool
);
120 OSL_FAIL( "no autorelease key" );
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
);
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
];
147 #define MAKE_CURSOR( vcl_name, name, name2 ) \
149 aHotSpot = NSPoint{name##curs_x_hot, name##curs_y_hot}; \
153 NSCursor
* SalData::getCursor( PointerStyle i_eStyle
)
155 NSCursor
* pCurs
= maCursors
[ i_eStyle
];
156 if( pCurs
!= INVALID_CURSOR_PTR
)
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
);
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
);
245 SAL_WARN( "vcl", "pointer style " << static_cast<sal_Int32
>(i_eStyle
) << "not implemented" );
246 assert( false && "pointer style not implemented" );
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
];
270 pCurs
= [[NSCursor alloc
] initWithImage
: theImage hotSpot
: aHotSpot
];
272 maCursors
[ i_eStyle
] = pCurs
;
276 NSStatusItem
* SalData::getStatusItem()
278 SalData
* pData
= GetSalData();
279 if( ! pData
->mpStatusItem
)
281 NSStatusBar
* pStatBar
=[NSStatusBar systemStatusBar
];
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
295 return pData
->mpStatusItem
;
298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */