36
36
// One Compile to copy them all and in the bundle bind them,
37
37
// in the Land of MacOS X where the Drop-Shadows lie.
39
// warning: the Apple Quartz version still uses some Quickdraw calls,
40
// mostly to get around the single active context in QD and
41
// to implement clipping. This should be changed into pure
42
// Quartz calls in the near future.
40
44
// we don't need the following definition because we deliver only
41
45
// true mouse moves. On very slow systems however, this flag may
131
137
FL_KP+'6', FL_KP+'7', 0, FL_KP+'8', FL_KP+'9', 0, 0, 0,
133
139
FL_F+5, FL_F+6, FL_F+7, FL_F+3, FL_F+8, FL_F+9, 0, FL_F+11,
134
0, 0, FL_Print, FL_Scroll_Lock, 0, FL_F+10, 0, FL_F+12,
140
0, 0, FL_Print, FL_Scroll_Lock, 0, FL_F+10, FL_Menu, FL_F+12,
136
142
0, FL_Pause, FL_Help, FL_Home, FL_Page_Up, FL_Delete, FL_F+4, FL_End,
137
143
FL_F+2, FL_Page_Down, FL_F+1, FL_Left, FL_Right, FL_Down, FL_Up, 0,
971
979
fl_lock_function();
973
GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &mods );
981
int kind = GetEventKind(event);
983
// get the modifiers for any of the events
984
GetEventParameter( event, kEventParamKeyModifiers, typeUInt32,
985
NULL, sizeof(UInt32), NULL, &mods );
974
986
if ( prevMods == 0xffffffff ) prevMods = mods;
976
GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
978
GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &key );
981
switch ( GetEventKind( event ) )
988
// get the key code only for key events
990
unsigned char key = 0;
991
unsigned short sym = 0;
992
if (kind!=kEventRawKeyModifiersChanged) {
993
GetEventParameter( event, kEventParamKeyCode, typeUInt32,
994
NULL, sizeof(UInt32), NULL, &keyCode );
995
GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar,
996
NULL, sizeof(char), NULL, &key );
998
/* output a human readbale event identifier for debugging
1001
case kEventRawKeyDown: ev = "kEventRawKeyDown"; break;
1002
case kEventRawKeyRepeat: ev = "kEventRawKeyRepeat"; break;
1003
case kEventRawKeyUp: ev = "kEventRawKeyUp"; break;
1004
case kEventRawKeyModifiersChanged: ev = "kEventRawKeyModifiersChanged"; break;
1005
default: ev = "unknown";
1007
printf("%08x %08x %08x '%c' %s \n", mods, keyCode, key, key, ev);
983
1011
case kEventRawKeyDown:
984
1012
case kEventRawKeyRepeat:
987
1015
case kEventRawKeyUp:
988
1016
if ( !sendEvent ) sendEvent = FL_KEYUP;
989
// if the user pressed alt/option, event_key should have the keycap, but event_text should generate the international symbol
1017
// if the user pressed alt/option, event_key should have the keycap,
1018
// but event_text should generate the international symbol
990
1019
if ( isalpha(key) )
991
1020
sym = tolower(key);
992
1021
else if ( Fl::e_state&FL_CTRL && key<32 )
994
else if ( Fl::e_state&FL_ALT )
995
sym = keycode_to_sym( keyCode & 0x7f, 0, macKeyLookUp[ keyCode & 0x7f ] ); // find the keycap of this key
1023
else if ( Fl::e_state&FL_ALT ) // find the keycap of this key
1024
sym = keycode_to_sym( keyCode & 0x7f, 0, macKeyLookUp[ keyCode & 0x7f ] );
997
1026
sym = macKeyLookUp[ keyCode & 0x7f ];
998
1027
Fl::e_keysym = sym;
999
1028
if ( keyCode==0x4c ) key=0x0d;
1000
if ( ( (sym>=FL_KP) && (sym<=FL_KP_Last) ) || ((sym&0xff00)==0) || (sym==FL_Tab) || (sym==FL_Enter) ) {
1029
// Matt: the Mac has no concept of a NumLock key, or at least not visible
1030
// Matt: to Carbon. The kEventKeyModifierNumLockMask is only set when
1031
// Matt: a numeric keypad key is pressed and does not correspond with
1032
// Matt: the NumLock light in PowerBook keyboards.
1033
if ( (sym >= FL_KP && sym <= FL_KP_Last) || !(sym & 0xff00) ||
1034
sym == FL_Tab || sym == FL_Enter) {
1001
1035
buffer[0] = key;
1002
1036
Fl::e_length = 1;
1024
1058
while (window->parent()) window = window->window();
1025
1059
if (sendEvent && Fl::handle(sendEvent,window)) {
1026
fl_unlock_function();
1060
fl_unlock_function();
1028
1061
return noErr; // return noErr if FLTK handled the event
1030
1063
fl_unlock_function();
1032
return CallNextEventHandler( nextHandler, event );;
1064
//return CallNextEventHandler( nextHandler, event );;
1065
// Matt: I had better results (no duplicate events) always returning
1066
// Matt: 'noErr'. System keyboard events still seem to work just fine.
1294
1337
//Proceed to positioning the window fully inside the screen, if possible
1295
//Make border's lower right corner visible
1296
if (Fl::w() < X+W) X = Fl::w() - W;
1297
if (Fl::h() < Y+H) Y = Fl::h() - H;
1298
//Make border's upper left corner visible
1301
//Make client area's lower right corner visible
1302
if (Fl::w() < X+dx+ w->w()) X = Fl::w() - w->w() - dx;
1303
if (Fl::h() < Y+dy+ w->h()) Y = Fl::h() - w->h() - dy;
1304
//Make client area's upper left corner visible
1305
if (X+xoff < 0) X = -xoff;
1306
if (Y+yoff < 0) Y = -yoff;
1339
// let's get a little elaborate here. Mac OS X puts a lot of stuff on the desk
1340
// that we want to avoid when positioning our window, namely the Dock and the
1341
// top menu bar (and even more stuff in 10.4 Tiger). So we will go through the
1342
// list of all available screens and find the one that this window is most
1343
// likely to go to, and then reposition it to fit withing the 'good' area.
1345
// find the screen, that the center of this window will fall into
1346
int R = X+W, B = Y+H; // right and bottom
1347
int cx = (X+R)/2, cy = (Y+B)/2; // center of window;
1349
for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
1351
if ( cx >= gp->gdRect.left && cx <= gp->gdRect.right
1352
&& cy >= gp->gdRect.top && cy <= gp->gdRect.bottom)
1355
// if the center doesn't fall on a screen, try the top left
1357
for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
1359
if ( X >= gp->gdRect.left && X <= gp->gdRect.right
1360
&& Y >= gp->gdRect.top && Y <= gp->gdRect.bottom)
1364
// if that doesn't fall on a screen, try the top right
1366
for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
1368
if ( R >= gp->gdRect.left && R <= gp->gdRect.right
1369
&& Y >= gp->gdRect.top && Y <= gp->gdRect.bottom)
1373
// if that doesn't fall on a screen, try the bottom left
1375
for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
1377
if ( X >= gp->gdRect.left && X <= gp->gdRect.right
1378
&& B >= gp->gdRect.top && B <= gp->gdRect.bottom)
1382
// last resort, try the bottom right
1384
for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
1386
if ( R >= gp->gdRect.left && R <= gp->gdRect.right
1387
&& B >= gp->gdRect.top && B <= gp->gdRect.bottom)
1391
// if we still have not found a screen, we will use the main
1392
// screen, the one that has the application menu bar.
1393
if (!gd) gd = GetMainDevice();
1395
GetAvailableWindowPositioningBounds(gd, &r);
1396
if ( R > r.right ) X -= R - r.right;
1397
if ( B > r.bottom ) Y -= B - r.bottom;
1398
if ( X < r.left ) X = r.left;
1399
if ( Y < r.top ) Y = r.top;
1307
1402
//Return the client area's top left corner in (X,Y)
1320
1415
FSpMakeFSRef( fs, &fsRef );
1321
1416
FSRefMakePath( &fsRef, (UInt8*)dst, 1024 );
1322
1417
return strlen(dst);
1323
/* keep the code below. The above function is only implemented in OS X, so we might need the other code for OS 9 and friends
1325
if ( fs->parID != fsRtParID )
1328
OSErr ret = FSMakeFSSpec( fs->vRefNum, fs->parID, 0, &parent );
1329
if ( ret != noErr ) return 0;
1330
offset = FSSpec2UnixPath( &parent, dst );
1333
if ( fs->parID == fsRtParID && fs->vRefNum == -100 ) //+ bad hack: we assume that volume -100 is mounted as root
1335
memcpy( dst, "/", 2 );
1336
return 1; // don't add anything to the filename - we are fine already
1339
short len = fs->name[0];
1340
if ( fs->parID == fsRtParID ) { // assume tat all other volumes are in this directory (international name WILL vary!)
1341
memcpy( dst, "/Volumes", 8 );
1345
if ( offset!=1 ) dst[ offset++ ] = '/'; // avoid double '/'
1346
memcpy( dst+offset, fs->name+1, len );
1347
dst[ len+offset ] = 0;
1352
1420
Fl_Window *fl_dnd_target_window = 0;
1846
1919
fl_clip_region( 0 );
1847
1920
SetPortClipRegion( GetWindowPort(i->xid), fl_window_region );
1921
#ifdef __APPLE_QUARTZ__
1922
QDBeginCGContext(GetWindowPort(i->xid), &i->gc);
1924
CGContextSaveGState(fl_gc);
1925
Fl_X::q_fill_context();
1930
// helper function to manage the current CGContext fl_gc
1931
#ifdef __APPLE_QUARTZ__
1932
extern Fl_Color fl_color_;
1933
extern class Fl_FontSize *fl_fontsize;
1934
extern void fl_font(class Fl_FontSize*);
1935
extern void fl_quartz_restore_line_style_();
1937
// FLTK has only on global graphics state. This function copies the FLTK state into the
1938
// current Quartz context
1939
void Fl_X::q_fill_context() {
1944
GetPortBounds(GetWindowPort( fl_window ), &portRect);
1945
hgt = portRect.bottom-portRect.top;
1947
hgt = CGBitmapContextGetHeight(fl_gc);
1949
CGContextTranslateCTM(fl_gc, 0.5, hgt-0.5f);
1950
CGContextScaleCTM(fl_gc, 1.0f, -1.0f);
1951
static CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 };
1952
CGContextSetTextMatrix(fl_gc, font_mx);
1953
fl_font(fl_fontsize);
1954
fl_color(fl_color_);
1955
fl_quartz_restore_line_style_();
1958
// The only way to reste clipping to its original state is to pop the current graphics
1959
// state and restore the global state.
1960
void Fl_X::q_clear_clipping() {
1962
CGContextRestoreGState(fl_gc);
1963
CGContextSaveGState(fl_gc);
1966
// Give the Quartz context back to the system
1967
void Fl_X::q_release_context(Fl_X *x) {
1968
if (x && x->gc!=fl_gc) return;
1970
CGContextRestoreGState(fl_gc);
1971
if (fl_window) QDEndCGContext(GetWindowPort(fl_window), &fl_gc);
1975
void Fl_X::q_begin_image(CGRect &rect, int cx, int cy, int w, int h) {
1976
CGContextSaveGState(fl_gc);
1977
CGAffineTransform mx = CGContextGetCTM(fl_gc);
1979
r2.origin.x -= 0.5f;
1980
r2.origin.y -= 0.5f;
1981
CGContextClipToRect(fl_gc, r2);
1982
mx.d = -1.0; mx.tx = -mx.tx;
1983
CGContextConcatCTM(fl_gc, mx);
1984
rect.origin.x = rect.origin.x - cx;
1985
rect.origin.y = (mx.ty+0.5f) - rect.origin.y - h + cy;
1986
rect.size.width = w;
1987
rect.size.height = h;
1990
void Fl_X::q_end_image() {
1991
CGContextRestoreGState(fl_gc);
1851
1996
////////////////////////////////////////////////////////////////
1852
1997
// Cut & paste.