~ubuntu-branches/ubuntu/saucy/clementine/saucy

« back to all changes in this revision

Viewing changes to src/core/mac_startup.mm

  • Committer: Package Import Robot
  • Author(s): Thomas PIERSON
  • Date: 2012-01-01 20:43:39 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120101204339-lsb6nndwhfy05sde
Tags: 1.0.1+dfsg-1
New upstream release. (Closes: #653926, #651611, #657391)

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
   along with Clementine.  If not, see <http://www.gnu.org/licenses/>.
16
16
*/
17
17
 
18
 
#import <IOKit/hidsystem/ev_keymap.h>
 
18
#import <AppKit/NSApplication.h>
19
19
#import <AppKit/NSEvent.h>
20
 
 
21
 
#import <AppKit/NSApplication.h>
 
20
#import <AppKit/NSGraphics.h>
 
21
#import <AppKit/NSNibDeclarations.h>
 
22
#import <AppKit/NSViewController.h>
22
23
 
23
24
#import <Foundation/NSAutoreleasePool.h>
24
25
#import <Foundation/NSBundle.h>
28
29
#import <Foundation/NSThread.h>
29
30
#import <Foundation/NSTimer.h>
30
31
#import <Foundation/NSURL.h>
31
 
#import <AppKit/NSNibDeclarations.h>
 
32
 
 
33
#import <IOKit/hidsystem/ev_keymap.h>
32
34
 
33
35
#import <Kernel/AvailabilityMacros.h>
34
36
 
 
37
#import <QuartzCore/CALayer.h>
 
38
 
 
39
#import "3rdparty/SPMediaKeyTap/SPMediaKeyTap.h"
 
40
 
35
41
#include "config.h"
36
42
#include "globalshortcuts.h"
37
43
#include "mac_delegate.h"
38
44
#include "mac_startup.h"
 
45
#include "mac_utilities.h"
39
46
#include "macglobalshortcutbackend.h"
40
47
#include "utilities.h"
 
48
#include "core/logging.h"
41
49
 
42
50
#ifdef HAVE_SPARKLE
43
51
#import <Sparkle/SUUpdater.h>
55
63
// See: http://www.rogueamoeba.com/utm/2007/09/29/apple-keyboard-media-key-event-handling/
56
64
 
57
65
@interface MacApplication :NSApplication {
 
66
  PlatformInterface* application_handler_;
 
67
  AppDelegate* delegate_;
 
68
  // shortcut_handler_ only used to temporarily save it
 
69
  // AppDelegate does all the heavy-shortcut-lifting
58
70
  MacGlobalShortcutBackend* shortcut_handler_;
59
 
  PlatformInterface* application_handler_;
60
71
}
61
72
 
62
73
- (MacGlobalShortcutBackend*) shortcut_handler;
65
76
- (PlatformInterface*) application_handler;
66
77
- (void) SetApplicationHandler: (PlatformInterface*)handler;
67
78
 
68
 
- (void) mediaKeyEvent: (int)key state: (BOOL)state repeat: (BOOL)repeat;
69
79
@end
70
80
 
 
81
#ifdef HAVE_BREAKPAD
 
82
static bool BreakpadCallback(int, int, mach_port_t, void*) {
 
83
  return true;
 
84
}
 
85
 
 
86
static BreakpadRef InitBreakpad() {
 
87
  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
88
  BreakpadRef breakpad = nil;
 
89
  NSDictionary* plist = [[NSBundle mainBundle] infoDictionary];
 
90
  if (plist) {
 
91
    breakpad = BreakpadCreate(plist);
 
92
    BreakpadSetFilterCallback(breakpad, &BreakpadCallback, NULL);
 
93
  }
 
94
  [pool release];
 
95
  return breakpad;
 
96
}
 
97
#endif // HAVE_BREAKPAD
 
98
 
71
99
@implementation AppDelegate
72
100
 
73
101
- (id) init {
74
102
  if ((self = [super init])) {
75
103
    application_handler_ = nil;
 
104
    shortcut_handler_ = nil;
76
105
    dock_menu_ = nil;
77
106
  }
78
107
  return self;
80
109
 
81
110
- (id) initWithHandler: (PlatformInterface*)handler {
82
111
  application_handler_ = handler;
 
112
 
 
113
#ifdef HAVE_BREAKPAD
 
114
  breakpad_ = InitBreakpad();
 
115
#endif
 
116
 
 
117
  // Register defaults for the whitelist of apps that want to use media keys
 
118
  [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:
 
119
     [SPMediaKeyTap defaultMediaKeyUserBundleIdentifiers], kMediaKeyUsingBundleIdentifiersDefaultsKey,
 
120
      nil]];
83
121
  return self;
84
122
}
85
123
 
98
136
  return dock_menu_;
99
137
}
100
138
 
 
139
- (void) setShortcutHandler: (MacGlobalShortcutBackend*)backend {
 
140
  shortcut_handler_ = backend;
 
141
}
 
142
 
 
143
- (MacGlobalShortcutBackend*) shortcut_handler { 
 
144
  return shortcut_handler_;
 
145
}
 
146
 
 
147
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
 
148
  key_tap_ = [[SPMediaKeyTap alloc] initWithDelegate:self];
 
149
  if([SPMediaKeyTap usesGlobalMediaKeyTap])
 
150
    [key_tap_ startWatchingMediaKeys];
 
151
  else
 
152
    qLog(Warning)<<"Media key monitoring disabled";
 
153
 
 
154
}
101
155
- (BOOL) application: (NSApplication*)app openFile:(NSString*)filename {
102
156
  qDebug() << "Wants to open:" << [filename UTF8String];
103
157
 
107
161
 
108
162
  return NO;
109
163
}
 
164
 
 
165
- (void) mediaKeyTap: (SPMediaKeyTap*)keyTap receivedMediaKeyEvent:(NSEvent*)event {
 
166
  NSAssert([event type] == NSSystemDefined && [event subtype] == SPSystemDefinedEventMediaKeys, @"Unexpected NSEvent in mediaKeyTap:receivedMediaKeyEvent:");
 
167
 
 
168
  int key_code = (([event data1] & 0xFFFF0000) >> 16);
 
169
  int key_flags = ([event data1] & 0x0000FFFF);
 
170
  BOOL key_is_released = (((key_flags & 0xFF00) >> 8)) == 0xB;
 
171
  // not used. keep just in case
 
172
  //  int key_repeat = (key_flags & 0x1);
 
173
 
 
174
  if (!shortcut_handler_) {
 
175
    return;
 
176
  }
 
177
  if (key_is_released) {
 
178
    shortcut_handler_->MacMediaKeyPressed(key_code);
 
179
  }
 
180
}
 
181
 
 
182
- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication*) sender {
 
183
#ifdef HAVE_BREAKPAD
 
184
  BreakpadRelease(breakpad_);
 
185
#endif
 
186
  return NSTerminateNow;
 
187
}
110
188
@end
111
189
 
112
190
@implementation MacApplication
114
192
- (id) init {
115
193
  if ((self = [super init])) {
116
194
    [self SetShortcutHandler:nil];
117
 
    [self SetApplicationHandler:nil];
118
195
  }
119
196
  return self;
120
197
}
121
198
 
122
199
- (MacGlobalShortcutBackend*) shortcut_handler {
 
200
  // should be the same as delegate_'s shortcut handler
123
201
  return shortcut_handler_;
124
202
}
125
203
 
126
204
- (void) SetShortcutHandler: (MacGlobalShortcutBackend*)handler {
127
205
  shortcut_handler_ = handler;
 
206
  if(delegate_)
 
207
    [delegate_ setShortcutHandler:handler];
128
208
}
129
209
 
130
210
- (PlatformInterface*) application_handler {
132
212
}
133
213
 
134
214
- (void) SetApplicationHandler: (PlatformInterface*)handler {
135
 
  AppDelegate* delegate = [[AppDelegate alloc] initWithHandler:handler];
136
 
  [self setDelegate:delegate];
 
215
  delegate_ = [[AppDelegate alloc] initWithHandler:handler];
 
216
  // App-shortcut-handler set before delegate is set.
 
217
  // this makes sure the delegate's shortcut_handler is set
 
218
  [delegate_ setShortcutHandler:shortcut_handler_];
 
219
  [self setDelegate:delegate_];
137
220
}
138
221
 
139
222
-(void) sendEvent: (NSEvent*)event {
140
 
  if ([event type] == NSSystemDefined && [event subtype] == 8) {
141
 
    int keycode = (([event data1] & 0xFFFF0000) >> 16);
142
 
    int keyflags = ([event data1] & 0x0000FFFF);
143
 
    int keystate = (((keyflags & 0xFF00) >> 8)) == 0xA;
144
 
    int keyrepeat = (keyflags & 0x1);
145
 
 
146
 
    [self mediaKeyEvent: keycode state: keystate repeat: keyrepeat];
 
223
  // If event tap is not installed, handle events that reach the app instead
 
224
  BOOL shouldHandleMediaKeyEventLocally = ![SPMediaKeyTap usesGlobalMediaKeyTap];
 
225
  
 
226
  if(shouldHandleMediaKeyEventLocally && [event type] == NSSystemDefined && [event subtype] == SPSystemDefinedEventMediaKeys) {
 
227
    [(id)[self delegate] mediaKeyTap: nil receivedMediaKeyEvent: event];
147
228
  }
148
229
 
149
230
  [super sendEvent: event];
150
231
}
151
232
 
152
 
-(void) mediaKeyEvent: (int)key state: (BOOL)state repeat: (BOOL)repeat {
153
 
  if (!shortcut_handler_) {
154
 
    return;
155
 
  }
156
 
  if (state == 0) {
157
 
    shortcut_handler_->MacMediaKeyPressed(key);
158
 
  }
159
 
}
160
 
 
161
233
@end
162
234
 
163
235
namespace mac {
256
328
        toPath:[NSString stringWithUTF8String: new_config_dir.toUtf8().constData()]
257
329
        error: &error];
258
330
    if (!ret) {
259
 
      qWarning() << [[error localizedDescription] UTF8String];
 
331
      qLog(Warning) << [[error localizedDescription] UTF8String];
260
332
    }
261
333
    moved_dir = true;
262
334
  }
266
338
    QSettings settings;
267
339
    bool ret = QFile::rename(old_config_path, settings.fileName());
268
340
    if (ret) {
269
 
      qWarning() << "Migrated old config file: " << old_config_path << "to: " << settings.fileName();
 
341
      qLog(Warning) << "Migrated old config file: " << old_config_path << "to: " << settings.fileName();
270
342
    }
271
343
  }
272
344
 
273
345
  return moved_dir;
274
346
}
275
347
 
 
348
static int MapFunctionKey(int keycode) {
 
349
  switch (keycode) {
 
350
    // Function keys
 
351
    case NSInsertFunctionKey: return Qt::Key_Insert;
 
352
    case NSDeleteFunctionKey: return Qt::Key_Delete;
 
353
    case NSPauseFunctionKey: return Qt::Key_Pause;
 
354
    case NSPrintFunctionKey: return Qt::Key_Print;
 
355
    case NSSysReqFunctionKey: return Qt::Key_SysReq;
 
356
    case NSHomeFunctionKey: return Qt::Key_Home;
 
357
    case NSEndFunctionKey: return Qt::Key_End;
 
358
    case NSLeftArrowFunctionKey: return Qt::Key_Left;
 
359
    case NSUpArrowFunctionKey: return Qt::Key_Up;
 
360
    case NSRightArrowFunctionKey: return Qt::Key_Right;
 
361
    case NSDownArrowFunctionKey: return Qt::Key_Down;
 
362
    case NSPageUpFunctionKey: return Qt::Key_PageUp;
 
363
    case NSPageDownFunctionKey: return Qt::Key_PageDown;
 
364
    case NSScrollLockFunctionKey: return Qt::Key_ScrollLock;
 
365
    case NSF1FunctionKey: return Qt::Key_F1;
 
366
    case NSF2FunctionKey: return Qt::Key_F2;
 
367
    case NSF3FunctionKey: return Qt::Key_F3;
 
368
    case NSF4FunctionKey: return Qt::Key_F4;
 
369
    case NSF5FunctionKey: return Qt::Key_F5;
 
370
    case NSF6FunctionKey: return Qt::Key_F6;
 
371
    case NSF7FunctionKey: return Qt::Key_F7;
 
372
    case NSF8FunctionKey: return Qt::Key_F8;
 
373
    case NSF9FunctionKey: return Qt::Key_F9;
 
374
    case NSF10FunctionKey: return Qt::Key_F10;
 
375
    case NSF11FunctionKey: return Qt::Key_F11;
 
376
    case NSF12FunctionKey: return Qt::Key_F12;
 
377
    case NSF13FunctionKey: return Qt::Key_F13;
 
378
    case NSF14FunctionKey: return Qt::Key_F14;
 
379
    case NSF15FunctionKey: return Qt::Key_F15;
 
380
    case NSF16FunctionKey: return Qt::Key_F16;
 
381
    case NSF17FunctionKey: return Qt::Key_F17;
 
382
    case NSF18FunctionKey: return Qt::Key_F18;
 
383
    case NSF19FunctionKey: return Qt::Key_F19;
 
384
    case NSF20FunctionKey: return Qt::Key_F20;
 
385
    case NSF21FunctionKey: return Qt::Key_F21;
 
386
    case NSF22FunctionKey: return Qt::Key_F22;
 
387
    case NSF23FunctionKey: return Qt::Key_F23;
 
388
    case NSF24FunctionKey: return Qt::Key_F24;
 
389
    case NSF25FunctionKey: return Qt::Key_F25;
 
390
    case NSF26FunctionKey: return Qt::Key_F26;
 
391
    case NSF27FunctionKey: return Qt::Key_F27;
 
392
    case NSF28FunctionKey: return Qt::Key_F28;
 
393
    case NSF29FunctionKey: return Qt::Key_F29;
 
394
    case NSF30FunctionKey: return Qt::Key_F30;
 
395
    case NSF31FunctionKey: return Qt::Key_F31;
 
396
    case NSF32FunctionKey: return Qt::Key_F32;
 
397
    case NSF33FunctionKey: return Qt::Key_F33;
 
398
    case NSF34FunctionKey: return Qt::Key_F34;
 
399
    case NSF35FunctionKey: return Qt::Key_F35;
 
400
    case NSMenuFunctionKey: return Qt::Key_Menu;
 
401
    case NSHelpFunctionKey: return Qt::Key_Help;
 
402
  }
 
403
 
 
404
  return 0;
 
405
}
 
406
 
 
407
QKeySequence KeySequenceFromNSEvent(NSEvent* event) {
 
408
  NSString* str = [event charactersIgnoringModifiers];
 
409
  NSString* upper = [str uppercaseString];
 
410
  const char* chars = [upper UTF8String];
 
411
  NSUInteger modifiers = [event modifierFlags];
 
412
  int key = 0;
 
413
  unsigned char c = chars[0];
 
414
  switch (c) {
 
415
    case 0x1b: key = Qt::Key_Escape; break;
 
416
    case 0x09: key = Qt::Key_Tab; break;
 
417
    case 0x0d: key = Qt::Key_Return; break;
 
418
    case 0x08: key = Qt::Key_Backspace; break;
 
419
    case 0x03: key = Qt::Key_Enter; break;
 
420
  }
 
421
 
 
422
  if (key == 0) {
 
423
    if (c >= 0x20 && c <= 0x7e) {  // ASCII from space to ~
 
424
      key = c;
 
425
    } else {
 
426
      key = MapFunctionKey([event keyCode]);
 
427
      if (key == 0) {
 
428
        return QKeySequence();
 
429
      }
 
430
    }
 
431
  }
 
432
 
 
433
  if (modifiers & NSShiftKeyMask) {
 
434
    key += Qt::SHIFT;
 
435
  }
 
436
  if (modifiers & NSControlKeyMask) {
 
437
    key += Qt::META;
 
438
  }
 
439
  if (modifiers & NSAlternateKeyMask) {
 
440
    key += Qt::ALT;
 
441
  }
 
442
  if (modifiers & NSCommandKeyMask) {
 
443
    key += Qt::CTRL;
 
444
  }
 
445
 
 
446
  return QKeySequence(key);
 
447
}
 
448
 
276
449
}  // namespace mac