~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/widget/src/cocoa/nsCocoaWindow.mm

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Netscape Public License
 
6
 * Version 1.1 (the "License"); you may not use this file except in
 
7
 * compliance with the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/NPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is mozilla.org code.
 
16
 *
 
17
 * The Initial Developer of the Original Code is 
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 1998
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 * Alternatively, the contents of this file may be used under the terms of
 
25
 * either the GNU General Public License Version 2 or later (the "GPL"), or 
 
26
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
27
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
28
 * of those above. If you wish to allow use of your version of this file only
 
29
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
30
 * use your version of this file under the terms of the NPL, indicate your
 
31
 * decision by deleting the provisions above and replace them with the notice
 
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
33
 * the provisions above, a recipient may use your version of this file under
 
34
 * the terms of any one of the NPL, the GPL or the LGPL.
 
35
 *
 
36
 * ***** END LICENSE BLOCK ***** */
 
37
 
 
38
#include "nsCocoaWindow.h"
 
39
 
 
40
#include "nsIServiceManager.h"    // for drag and drop
 
41
#include "nsWidgetsCID.h"
 
42
#include "nsIDragService.h"
 
43
#include "nsIDragSession.h"
 
44
#include "nsIDragSessionMac.h"
 
45
#include "nsIScreen.h"
 
46
#include "nsIScreenManager.h"
 
47
#include "nsGUIEvent.h"
 
48
#include "nsCarbonHelpers.h"
 
49
#include "nsGFXUtils.h"
 
50
#include "nsMacResources.h"
 
51
#include "nsIRollupListener.h"
 
52
#import "nsChildView.h"
 
53
 
 
54
#include "nsIEventQueueService.h"
 
55
 
 
56
#if TARGET_CARBON
 
57
#include <CFString.h>
 
58
#endif
 
59
 
 
60
#include <Gestalt.h>
 
61
#include <Quickdraw.h>
 
62
 
 
63
#if UNIVERSAL_INTERFACES_VERSION < 0x0340
 
64
enum {
 
65
  kEventWindowConstrain = 83
 
66
};
 
67
const UInt32 kWindowLiveResizeAttribute = (1L << 28);
 
68
#endif
 
69
 
 
70
// Define Class IDs -- i hate having to do this
 
71
static NS_DEFINE_CID(kCDragServiceCID,  NS_DRAGSERVICE_CID);
 
72
//static const char *sScreenManagerContractID = "@mozilla.org/gfx/screenmanager;1";
 
73
 
 
74
// from MacHeaders.c
 
75
#ifndef topLeft
 
76
  #define topLeft(r)  (((Point *) &(r))[0])
 
77
#endif
 
78
#ifndef botRight
 
79
  #define botRight(r) (((Point *) &(r))[1])
 
80
#endif
 
81
 
 
82
// externs defined in nsWindow.cpp
 
83
extern nsIRollupListener * gRollupListener;
 
84
extern nsIWidget         * gRollupWidget;
 
85
 
 
86
static PRBool OnMacOSX();
 
87
 
 
88
#define kWindowPositionSlop 20
 
89
 
 
90
 
 
91
#if 0
 
92
void SetDragActionBasedOnModifiers ( nsIDragService* inDragService, short inModifiers ) ; 
 
93
 
 
94
 
 
95
//
 
96
// SetDragActionsBasedOnModifiers [static]
 
97
//
 
98
// Examines the MacOS modifier keys and sets the appropriate drag action on the
 
99
// drag session to copy/move/etc
 
100
//
 
101
void
 
102
SetDragActionBasedOnModifiers ( nsIDragService* inDragService, short inModifiers ) 
 
103
{
 
104
  nsCOMPtr<nsIDragSession> dragSession;
 
105
  inDragService->GetCurrentSession ( getter_AddRefs(dragSession) );
 
106
  if ( dragSession ) {
 
107
    PRUint32 action = nsIDragService::DRAGDROP_ACTION_MOVE;
 
108
    
 
109
    // force copy = option, alias = cmd-option, default is move
 
110
    if ( inModifiers & optionKey ) {
 
111
      if ( inModifiers & cmdKey )
 
112
        action = nsIDragService::DRAGDROP_ACTION_LINK;
 
113
      else
 
114
        action = nsIDragService::DRAGDROP_ACTION_COPY;
 
115
    }
 
116
 
 
117
    dragSession->SetDragAction ( action );    
 
118
  }
 
119
 
 
120
} // SetDragActionBasedOnModifiers
 
121
 
 
122
#pragma mark -
 
123
 
 
124
 
 
125
//ļæ½ļæ½ļæ½ this should probably go into the drag session as a static
 
126
pascal OSErr
 
127
nsCocoaWindow :: DragTrackingHandler ( DragTrackingMessage theMessage, WindowPtr theWindow, 
 
128
                    void *handlerRefCon, DragReference theDrag)
 
129
{
 
130
  // holds our drag service across multiple calls to this callback. The reference to
 
131
  // the service is obtained when the mouse enters the window and is released when
 
132
  // the mouse leaves the window (or there is a drop). This prevents us from having
 
133
  // to re-establish the connection to the service manager 15 times a second when
 
134
  // handling the |kDragTrackingInWindow| message.
 
135
  static nsIDragService* sDragService = nsnull;
 
136
 
 
137
  nsCocoaWindow* geckoWindow = reinterpret_cast<nsCocoaWindow*>(handlerRefCon);
 
138
  if ( !theWindow || !geckoWindow )
 
139
    return dragNotAcceptedErr;
 
140
    
 
141
  nsresult rv = NS_OK;
 
142
  switch ( theMessage ) {
 
143
  
 
144
    case kDragTrackingEnterHandler:
 
145
      break;
 
146
      
 
147
    case kDragTrackingEnterWindow:
 
148
    {
 
149
      // get our drag service for the duration of the drag.
 
150
      nsresult rv = nsServiceManager::GetService(kCDragServiceCID,
 
151
                                                NS_GET_IID(nsIDragService),
 
152
                                              (nsISupports **)&sDragService);
 
153
            NS_ASSERTION ( sDragService, "Couldn't get a drag service, we're in biiig trouble" );
 
154
 
 
155
      // tell the session about this drag
 
156
      if ( sDragService ) {
 
157
        sDragService->StartDragSession();
 
158
        nsCOMPtr<nsIDragSessionMac> macSession ( do_QueryInterface(sDragService) );
 
159
        if ( macSession )
 
160
          macSession->SetDragReference ( theDrag );
 
161
      }
 
162
      
 
163
      // let gecko know that the mouse has entered the window so it
 
164
      // can start tracking and sending enter/exit events to frames.
 
165
      Point mouseLocGlobal;
 
166
      ::GetDragMouse ( theDrag, &mouseLocGlobal, nsnull );
 
167
      geckoWindow->DragEvent ( NS_DRAGDROP_ENTER, mouseLocGlobal, 0L );     
 
168
      break;
 
169
    }
 
170
    
 
171
    case kDragTrackingInWindow:
 
172
    {
 
173
      Point mouseLocGlobal;
 
174
      ::GetDragMouse ( theDrag, &mouseLocGlobal, nsnull );
 
175
      short modifiers;
 
176
      ::GetDragModifiers ( theDrag, &modifiers, nsnull, nsnull );
 
177
      
 
178
      NS_ASSERTION ( sDragService, "If we don't have a drag service, we're fucked" );
 
179
      
 
180
      // set the drag action on the service so the frames know what is going on
 
181
      SetDragActionBasedOnModifiers ( sDragService, modifiers );
 
182
      
 
183
      // clear out the |canDrop| property of the drag session. If it's meant to
 
184
      // be, it will be set again.
 
185
      nsCOMPtr<nsIDragSession> session;
 
186
      sDragService->GetCurrentSession(getter_AddRefs(session));
 
187
      NS_ASSERTION ( session, "If we don't have a drag session, we're fucked" );
 
188
      if ( session )
 
189
        session->SetCanDrop(PR_FALSE);
 
190
 
 
191
      // pass into gecko for handling...
 
192
      geckoWindow->DragEvent ( NS_DRAGDROP_OVER, mouseLocGlobal, modifiers );
 
193
      break;
 
194
    }
 
195
    
 
196
    case kDragTrackingLeaveWindow:
 
197
    {
 
198
      // tell the drag service that we're done with it.
 
199
      if ( sDragService ) {
 
200
        sDragService->EndDragSession();
 
201
        
 
202
        // clear out the dragRef in the drag session. We are guaranteed that
 
203
        // this will be called _after_ the drop has been processed (if there
 
204
        // is one), so we're not destroying valuable information if the drop
 
205
        // was in our window.
 
206
        nsCOMPtr<nsIDragSessionMac> macSession ( do_QueryInterface(sDragService) );
 
207
        if ( macSession )
 
208
          macSession->SetDragReference ( 0 );         
 
209
      }     
 
210
    
 
211
      // let gecko know that the mouse has left the window so it
 
212
      // can stop tracking and sending enter/exit events to frames.
 
213
      Point mouseLocGlobal;
 
214
      ::GetDragMouse ( theDrag, &mouseLocGlobal, nsnull );
 
215
      geckoWindow->DragEvent ( NS_DRAGDROP_EXIT, mouseLocGlobal, 0L );
 
216
      
 
217
      ::HideDragHilite ( theDrag );
 
218
  
 
219
      // we're _really_ done with it, so let go of the service.
 
220
      if ( sDragService ) {
 
221
        nsServiceManager::ReleaseService(kCDragServiceCID, sDragService);
 
222
        sDragService = nsnull;      
 
223
      }
 
224
      
 
225
      break;
 
226
    }
 
227
    
 
228
  } // case of each drag message
 
229
 
 
230
  return noErr;
 
231
  
 
232
} // DragTrackingHandler
 
233
 
 
234
 
 
235
//ļæ½ļæ½ļæ½ this should probably go into the drag session as a static
 
236
pascal OSErr
 
237
nsCocoaWindow :: DragReceiveHandler (WindowPtr theWindow, void *handlerRefCon,
 
238
                  DragReference theDragRef)
 
239
{
 
240
  // get our window back from the refCon
 
241
  nsCocoaWindow* geckoWindow = reinterpret_cast<nsCocoaWindow*>(handlerRefCon);
 
242
  if ( !theWindow || !geckoWindow )
 
243
    return dragNotAcceptedErr;
 
244
    
 
245
    // We make the assuption that the dragOver handlers have correctly set
 
246
    // the |canDrop| property of the Drag Session. Before we dispatch the event
 
247
    // into Gecko, check that value and either dispatch it or set the result
 
248
    // code to "spring-back" and show the user the drag failed. 
 
249
    OSErr result = noErr;
 
250
  nsCOMPtr<nsIDragService> dragService ( do_GetService(kCDragServiceCID) );
 
251
  if ( dragService ) {
 
252
    nsCOMPtr<nsIDragSession> dragSession;
 
253
    dragService->GetCurrentSession ( getter_AddRefs(dragSession) );
 
254
    if ( dragSession ) {
 
255
      // if the target has set that it can accept the drag, pass along
 
256
      // to gecko, otherwise set phasers for failure.
 
257
      PRBool canDrop = PR_FALSE;
 
258
      if ( NS_SUCCEEDED(dragSession->GetCanDrop(&canDrop)) )
 
259
        if ( canDrop ) {
 
260
                  // pass the drop event along to Gecko
 
261
                  Point mouseLocGlobal;
 
262
                  ::GetDragMouse ( theDragRef, &mouseLocGlobal, nsnull );
 
263
                  short modifiers;
 
264
                  ::GetDragModifiers ( theDragRef, &modifiers, nsnull, nsnull );
 
265
                  geckoWindow->DragEvent ( NS_DRAGDROP_DROP, mouseLocGlobal, modifiers );
 
266
                }
 
267
                else
 
268
          result = dragNotAcceptedErr;  
 
269
    } // if a valid drag session
 
270
        
 
271
    // we don't need the drag session anymore, the user has released the
 
272
    // mouse and the event has already gone to gecko.
 
273
    dragService->EndDragSession();
 
274
  }
 
275
  
 
276
  return result;
 
277
  
 
278
} // DragReceiveHandler
 
279
 
 
280
#endif
 
281
 
 
282
 
 
283
NS_IMPL_ISUPPORTS_INHERITED0(nsCocoaWindow, Inherited)
 
284
 
 
285
 
 
286
//-------------------------------------------------------------------------
 
287
//
 
288
// nsCocoaWindow constructor
 
289
//
 
290
//-------------------------------------------------------------------------
 
291
nsCocoaWindow::nsCocoaWindow()
 
292
#if 0
 
293
  , mWindowMadeHere(PR_FALSE)
 
294
  , mIsDialog(PR_FALSE)
 
295
  , mMacEventHandler(nsnull)
 
296
  , mAcceptsActivation(PR_TRUE)
 
297
  , mIsActive(PR_FALSE)
 
298
  , mZoomOnShow(PR_FALSE)
 
299
#endif
 
300
 
301
  mOffsetParent(nsnull)
 
302
, mIsDialog(PR_FALSE)
 
303
, mIsResizing(PR_FALSE)
 
304
, mWindowMadeHere(PR_FALSE)
 
305
, mWindow(nil)
 
306
{
 
307
#if 0
 
308
  mMacEventHandler.reset(new nsMacEventHandler(this));
 
309
  WIDGET_SET_CLASSNAME("nsCocoaWindow");  
 
310
 
 
311
  // create handlers for drag&drop
 
312
  mDragTrackingHandlerUPP = NewDragTrackingHandlerUPP(DragTrackingHandler);
 
313
  mDragReceiveHandlerUPP = NewDragReceiveHandlerUPP(DragReceiveHandler);
 
314
#endif
 
315
}
 
316
 
 
317
 
 
318
//-------------------------------------------------------------------------
 
319
//
 
320
// nsCocoaWindow destructor
 
321
//
 
322
//-------------------------------------------------------------------------
 
323
nsCocoaWindow::~nsCocoaWindow()
 
324
{
 
325
  if ( mWindow && mWindowMadeHere ) {
 
326
    [mWindow autorelease];
 
327
    [mDelegate autorelease];
 
328
  }
 
329
  
 
330
#if 0
 
331
  if (mWindowPtr)
 
332
  {
 
333
    if (mWindowMadeHere)
 
334
      ::DisposeWindow(mWindowPtr);
 
335
      
 
336
    // clean up DragManager stuff
 
337
    if ( mDragTrackingHandlerUPP ) {
 
338
      ::RemoveTrackingHandler ( mDragTrackingHandlerUPP, mWindowPtr );
 
339
      ::DisposeDragTrackingHandlerUPP ( mDragTrackingHandlerUPP );
 
340
     }
 
341
    if ( mDragReceiveHandlerUPP ) {
 
342
      ::RemoveReceiveHandler ( mDragReceiveHandlerUPP, mWindowPtr );
 
343
      ::DisposeDragReceiveHandlerUPP ( mDragReceiveHandlerUPP );
 
344
    }
 
345
 
 
346
    nsMacMessageSink::RemoveRaptorWindowFromList(mWindowPtr);
 
347
    mWindowPtr = nsnull;
 
348
  }
 
349
#endif
 
350
  
 
351
}
 
352
 
 
353
 
 
354
//-------------------------------------------------------------------------
 
355
//
 
356
// Utility method for implementing both Create(nsIWidget ...) and
 
357
// Create(nsNativeWidget...)
 
358
//-------------------------------------------------------------------------
 
359
 
 
360
nsresult nsCocoaWindow::StandardCreate(nsIWidget *aParent,
 
361
                        const nsRect &aRect,
 
362
                        EVENT_CALLBACK aHandleEventFunction,
 
363
                        nsIDeviceContext *aContext,
 
364
                        nsIAppShell *aAppShell,
 
365
                        nsIToolkit *aToolkit,
 
366
                        nsWidgetInitData *aInitData,
 
367
                        nsNativeWidget aNativeParent)
 
368
{
 
369
  Inherited::BaseCreate ( aParent, aRect, aHandleEventFunction, aContext, aAppShell,
 
370
                            aToolkit, aInitData );
 
371
                            
 
372
  if ( !aNativeParent ) {
 
373
    mOffsetParent = aParent;
 
374
 
 
375
    nsWindowType windowType = eWindowType_toplevel;
 
376
    if (aInitData) {
 
377
      mWindowType = aInitData->mWindowType;
 
378
      // if a toplevel window was requested without a titlebar, use a dialog windowproc
 
379
      if (aInitData->mWindowType == eWindowType_toplevel &&
 
380
        (aInitData->mBorderStyle == eBorderStyle_none ||
 
381
         aInitData->mBorderStyle != eBorderStyle_all && !(aInitData->mBorderStyle & eBorderStyle_title)))
 
382
        windowType = eWindowType_dialog;
 
383
    } 
 
384
    else
 
385
      mWindowType = (mIsDialog ? eWindowType_dialog : eWindowType_toplevel);
 
386
    
 
387
    // create the cocoa window
 
388
    NSRect rect;
 
389
    rect.origin.x = rect.origin.y = 1.0;
 
390
    rect.size.width = rect.size.height = 1.0;
 
391
    unsigned int features = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask 
 
392
                              | NSResizableWindowMask;
 
393
    if ( mWindowType == eWindowType_popup || mWindowType == eWindowType_invisible )
 
394
      features = 0;
 
395
 
 
396
    // XXXdwh Just don't make popup windows yet.  They mess up the world.
 
397
    if (mWindowType == eWindowType_popup)
 
398
      return NS_OK;
 
399
 
 
400
    mWindow = [[NSWindow alloc] initWithContentRect:rect styleMask:features 
 
401
                        backing:NSBackingStoreBuffered defer:NO];
 
402
    
 
403
    // Popups will receive a "close" message when an app terminates
 
404
    // that causes an extra release to occur.  Make sure popups
 
405
    // are set not to release when closed.
 
406
    if (features == 0)
 
407
      [mWindow setReleasedWhenClosed: NO];
 
408
 
 
409
    // create a quickdraw view as the toplevel content view of the window
 
410
    NSQuickDrawView* content = [[[NSQuickDrawView alloc] init] autorelease];
 
411
    [content setFrame:[[mWindow contentView] frame]];
 
412
    [mWindow setContentView:content];
 
413
    
 
414
    // register for mouse-moved events. The default is to ignore them for perf reasons.
 
415
    [mWindow setAcceptsMouseMovedEvents:YES];
 
416
    
 
417
    // setup our notification delegate. Note that setDelegate: does NOT retain.
 
418
    mDelegate = [[WindowDelegate alloc] initWithGeckoWindow:this];
 
419
    [mWindow setDelegate:mDelegate];
 
420
    
 
421
    mWindowMadeHere = PR_TRUE;    
 
422
  }
 
423
 
 
424
#if 0
 
425
  short bottomPinDelta = 0;     // # of pixels to subtract to pin window bottom
 
426
  nsCOMPtr<nsIToolkit> theToolkit = aToolkit;
 
427
  
 
428
  // build the main native window
 
429
  if (aNativeParent == nsnull)
 
430
  {
 
431
    nsWindowType windowType;
 
432
    if (aInitData)
 
433
    {
 
434
      mWindowType = aInitData->mWindowType;
 
435
      // if a toplevel window was requested without a titlebar, use a dialog windowproc
 
436
      if (aInitData->mWindowType == eWindowType_toplevel &&
 
437
        (aInitData->mBorderStyle == eBorderStyle_none ||
 
438
         aInitData->mBorderStyle != eBorderStyle_all && !(aInitData->mBorderStyle & eBorderStyle_title)))
 
439
        windowType = eWindowType_dialog;
 
440
    } else
 
441
      mWindowType = (mIsDialog ? eWindowType_dialog : eWindowType_toplevel);
 
442
 
 
443
    short     wDefProcID = kWindowDocumentProc;
 
444
    Boolean   goAwayFlag;
 
445
    short     hOffset;
 
446
    short     vOffset;
 
447
 
 
448
    switch (mWindowType)
 
449
    {
 
450
      case eWindowType_popup:
 
451
        // We're a popup, context menu, etc. Sets
 
452
        // mAcceptsActivation to false so we don't activate the window
 
453
        // when we show it.
 
454
        mOffsetParent = aParent;
 
455
        if( !aParent )
 
456
          theToolkit = getter_AddRefs(aParent->GetToolkit());
 
457
 
 
458
        mAcceptsActivation = PR_FALSE;
 
459
        goAwayFlag = false;
 
460
        hOffset = 0;
 
461
        vOffset = 0;
 
462
#if TARGET_CARBON
 
463
        wDefProcID = kWindowSimpleProc;
 
464
#else
 
465
        wDefProcID = plainDBox;
 
466
#endif
 
467
        break;
 
468
 
 
469
      case eWindowType_child:
 
470
        wDefProcID = plainDBox;
 
471
        goAwayFlag = false;
 
472
        hOffset = 0;
 
473
        vOffset = 0;
 
474
        break;
 
475
 
 
476
      case eWindowType_dialog:
 
477
        if (aInitData)
 
478
        {
 
479
          // Prior to Carbon, defProcs were solely about appearance. If told to create a dialog,
 
480
          // we could use, for example, |kWindowMovableModalDialogProc| even if the dialog wasn't
 
481
          // supposed to be modal. Carbon breaks this assumption, enforcing modality when using these
 
482
          // particular proc ids. As a result, when compiling under Carbon we have to use the
 
483
          // standard window proc id's and below, after we have a windowPtr, we'll hide the closebox
 
484
          // that comes with the standard window proc.
 
485
          //
 
486
          // I'm making the assumption here that any dialog created w/out a titlebar is modal and am
 
487
          // therefore keeping the old modal dialog proc. I'm only special-casing dialogs with a 
 
488
          // titlebar since those are the only ones that might end up not being modal.
 
489
          
 
490
          switch (aInitData->mBorderStyle)
 
491
          {
 
492
            case eBorderStyle_none:
 
493
              wDefProcID = kWindowModalDialogProc;
 
494
              break;
 
495
              
 
496
            case eBorderStyle_all:
 
497
              #if TARGET_CARBON
 
498
                wDefProcID = kWindowGrowDocumentProc;
 
499
              #else
 
500
                wDefProcID = kWindowMovableModalGrowProc;   // should we add a close box (kWindowGrowDocumentProc) ?
 
501
              #endif
 
502
              break;
 
503
              
 
504
            case eBorderStyle_default:
 
505
              wDefProcID = kWindowModalDialogProc;
 
506
              break;
 
507
            
 
508
            default:
 
509
              // we ignore the close flag here, since mac dialogs should never have a close box.
 
510
              switch(aInitData->mBorderStyle & (eBorderStyle_resizeh | eBorderStyle_title))
 
511
              {
 
512
                // combinations of individual options.
 
513
                case eBorderStyle_title:
 
514
                  #if TARGET_CARBON
 
515
                    wDefProcID = kWindowDocumentProc;
 
516
                  #else
 
517
                    wDefProcID = kWindowMovableModalDialogProc;
 
518
                  #endif
 
519
                  break;
 
520
                                    
 
521
                case eBorderStyle_resizeh:
 
522
                case (eBorderStyle_title | eBorderStyle_resizeh):
 
523
                  #if TARGET_CARBON
 
524
                    wDefProcID = kWindowGrowDocumentProc;
 
525
                  #else
 
526
                    wDefProcID = kWindowMovableModalGrowProc;   // this is the only kind of resizable dialog.
 
527
                  #endif
 
528
                  break;
 
529
                                  
 
530
                default:
 
531
                  NS_WARNING("Unhandled combination of window flags");
 
532
                  break;
 
533
              }
 
534
          }
 
535
        }
 
536
        else
 
537
        {
 
538
          wDefProcID = kWindowModalDialogProc;
 
539
          goAwayFlag = true; // revisit this below
 
540
        }
 
541
                
 
542
        hOffset = kDialogMarginWidth;
 
543
        vOffset = kDialogTitleBarHeight;
 
544
        break;
 
545
 
 
546
      case eWindowType_toplevel:
 
547
        if (aInitData &&
 
548
          aInitData->mBorderStyle != eBorderStyle_all &&
 
549
          aInitData->mBorderStyle != eBorderStyle_default &&
 
550
          (aInitData->mBorderStyle == eBorderStyle_none ||
 
551
           !(aInitData->mBorderStyle & eBorderStyle_resizeh)))
 
552
          wDefProcID = kWindowDocumentProc;
 
553
        else
 
554
          wDefProcID = kWindowFullZoomGrowDocumentProc;
 
555
        goAwayFlag = true;
 
556
        hOffset = kWindowMarginWidth;
 
557
        vOffset = kWindowTitleBarHeight;
 
558
        break;
 
559
 
 
560
      case eWindowType_invisible:
 
561
        // don't do anything
 
562
        break;
 
563
    }
 
564
 
 
565
    // now turn off some default features if requested by aInitData
 
566
    if (aInitData && aInitData->mBorderStyle != eBorderStyle_all)
 
567
    {
 
568
      if (aInitData->mBorderStyle == eBorderStyle_none ||
 
569
          aInitData->mBorderStyle == eBorderStyle_default &&
 
570
          windowType == eWindowType_dialog ||
 
571
          !(aInitData->mBorderStyle & eBorderStyle_close))
 
572
        goAwayFlag = false;
 
573
    }
 
574
 
 
575
    Rect wRect;
 
576
    nsRectToMacRect(aRect, wRect);
 
577
 
 
578
    if (eWindowType_popup != mWindowType)
 
579
      ::OffsetRect(&wRect, hOffset, vOffset + ::GetMBarHeight());
 
580
    else
 
581
      ::OffsetRect(&wRect, hOffset, vOffset);
 
582
 
 
583
    nsCOMPtr<nsIScreenManager> screenmgr = do_GetService(sScreenManagerContractID);
 
584
    if (screenmgr) {
 
585
      nsCOMPtr<nsIScreen> screen;
 
586
      //screenmgr->GetPrimaryScreen(getter_AddRefs(screen));
 
587
      screenmgr->ScreenForRect(wRect.left, wRect.top,
 
588
                                 wRect.right - wRect.left, wRect.bottom - wRect.top,
 
589
                                 getter_AddRefs(screen));
 
590
      if (screen) {
 
591
          PRInt32 left, top, width, height;
 
592
        screen->GetAvailRect(&left, &top, &width, &height);
 
593
        if (wRect.bottom > top+height) {
 
594
          bottomPinDelta = wRect.bottom - (top+height);
 
595
          wRect.bottom -= bottomPinDelta;
 
596
        }
 
597
      }
 
598
    }
 
599
    mWindowPtr = ::NewCWindow(nil, &wRect, "\p", false, wDefProcID, (WindowRef)-1, goAwayFlag, (long)nsnull);
 
600
    mWindowMadeHere = PR_TRUE;
 
601
  }
 
602
  else
 
603
  {
 
604
    mWindowPtr = (WindowPtr)aNativeParent;
 
605
    mWindowMadeHere = PR_FALSE;
 
606
  }
 
607
 
 
608
  if (mWindowPtr == nsnull)
 
609
    return NS_ERROR_OUT_OF_MEMORY;
 
610
  
 
611
  nsMacMessageSink::AddRaptorWindowToList(mWindowPtr, this);
 
612
 
 
613
  // create the root control
 
614
  ControlHandle   rootControl = nil;
 
615
  if (GetRootControl(mWindowPtr, &rootControl) != noErr)
 
616
  {
 
617
    OSErr err = CreateRootControl(mWindowPtr, &rootControl);
 
618
    NS_ASSERTION(err == noErr, "Error creating window root control");
 
619
  }
 
620
 
 
621
  // reset the coordinates to (0,0) because it's the top level widget
 
622
  // and adjust for any adjustment required to requested window bottom
 
623
  nsRect bounds(0, 0, aRect.width, aRect.height - bottomPinDelta);
 
624
 
 
625
  // init base class
 
626
  // (note: aParent is ignored. Mac (real) windows don't want parents)
 
627
  Inherited::StandardCreate(nil, bounds, aHandleEventFunction, aContext, aAppShell, theToolkit, aInitData);
 
628
 
 
629
#if TARGET_CARBON
 
630
  if ( mWindowType == eWindowType_popup ) {
 
631
    // OSX enforces window layering so we have to make sure that popups can
 
632
    // appear over modal dialogs (at the top of the layering chain). Create
 
633
    // the popup like normal and change its window class to the modal layer.
 
634
    //
 
635
    // XXX This needs to use ::SetWindowGroup() when we move to headers that
 
636
    // XXX support it.
 
637
    ::SetWindowClass(mWindowPtr, kModalWindowClass);
 
638
  }
 
639
  else if ( mWindowType == eWindowType_dialog ) {
 
640
    // Dialogs on mac don't have a close box, but we probably used a defproc above that
 
641
    // contains one. Thankfully, carbon lets us turn it off after the window has been 
 
642
    // created. Do so. We currently leave the collapse widget for all dialogs.
 
643
    ::ChangeWindowAttributes(mWindowPtr, 0L, kWindowCloseBoxAttribute );
 
644
  }
 
645
  
 
646
  // Setup the live window resizing
 
647
  if ( mWindowType == eWindowType_toplevel || mWindowType == eWindowType_invisible ) {
 
648
    WindowAttributes removeAttributes = kWindowNoAttributes;
 
649
    if ( mWindowType == eWindowType_invisible )
 
650
      removeAttributes |= kWindowInWindowMenuAttribute;     
 
651
    ::ChangeWindowAttributes ( mWindowPtr, kWindowLiveResizeAttribute, removeAttributes );
 
652
    
 
653
    EventTypeSpec windEventList[] = { {kEventClassWindow, kEventWindowBoundsChanged},
 
654
                                      {kEventClassWindow, kEventWindowConstrain} };
 
655
    EventTypeSpec scrollEventList[] = { {kEventClassMouse, kEventMouseWheelMoved} };
 
656
    OSStatus err1 = ::InstallWindowEventHandler ( mWindowPtr, NewEventHandlerUPP(WindowEventHandler), 2, windEventList, this, NULL );
 
657
    OSStatus err2 = ::InstallWindowEventHandler ( mWindowPtr, NewEventHandlerUPP(ScrollEventHandler), 1, scrollEventList, this, NULL );
 
658
      // note, passing NULL as the final param to IWEH() causes the UPP to be disposed automatically
 
659
      // when the event target (the window) goes away. See CarbonEvents.h for info.
 
660
    
 
661
    NS_ASSERTION(err1 == noErr && err2 == noErr, "Couldn't install Carbon Event handlers");
 
662
  }  
 
663
#endif
 
664
  
 
665
    
 
666
  // register tracking and receive handlers with the native Drag Manager
 
667
  if ( mDragTrackingHandlerUPP ) {
 
668
    OSErr result = ::InstallTrackingHandler ( mDragTrackingHandlerUPP, mWindowPtr, this );
 
669
    NS_ASSERTION ( result == noErr, "can't install drag tracking handler");
 
670
  }
 
671
  if ( mDragReceiveHandlerUPP ) {
 
672
    OSErr result = ::InstallReceiveHandler ( mDragReceiveHandlerUPP, mWindowPtr, this );
 
673
    NS_ASSERTION ( result == noErr, "can't install drag receive handler");
 
674
  }
 
675
 
 
676
  // If we're a popup, we don't want a border (we want CSS to draw it for us). So
 
677
  // install our own window defProc.
 
678
  if ( mWindowType == eWindowType_popup )
 
679
    InstallBorderlessDefProc(mWindowPtr);
 
680
 
 
681
#endif
 
682
 
 
683
  return NS_OK;
 
684
}
 
685
 
 
686
 
 
687
#if 0
 
688
 
 
689
pascal OSStatus
 
690
nsCocoaWindow :: ScrollEventHandler ( EventHandlerCallRef inHandlerChain, EventRef inEvent, void* userData )
 
691
{
 
692
  EventMouseWheelAxis axis = kEventMouseWheelAxisY;
 
693
  SInt32 delta = 0;
 
694
  Point mouseLoc;
 
695
  OSErr err1 = ::GetEventParameter ( inEvent, kEventParamMouseWheelAxis, typeMouseWheelAxis,
 
696
                        NULL, sizeof(EventMouseWheelAxis), NULL, &axis ); 
 
697
  OSErr err2 = ::GetEventParameter ( inEvent, kEventParamMouseWheelDelta, typeLongInteger,
 
698
                        NULL, sizeof(SInt32), NULL, &delta ); 
 
699
  OSErr err3 = ::GetEventParameter ( inEvent, kEventParamMouseLocation, typeQDPoint,
 
700
                        NULL, sizeof(Point), NULL, &mouseLoc ); 
 
701
 
 
702
  if ( err1 == noErr && err2 == noErr && err3 == noErr ) {
 
703
    nsCocoaWindow* self = NS_REINTERPRET_CAST(nsCocoaWindow*, userData);
 
704
    if ( self )
 
705
      self->mMacEventHandler->Scroll ( axis, delta, mouseLoc );
 
706
  }
 
707
  return noErr;
 
708
  
 
709
} // ScrollEventHandler
 
710
 
 
711
 
 
712
pascal OSStatus
 
713
nsCocoaWindow :: WindowEventHandler ( EventHandlerCallRef inHandlerChain, EventRef inEvent, void* userData )
 
714
{
 
715
  OSStatus retVal = noErr;
 
716
  
 
717
  WindowRef myWind = NULL;
 
718
  ::GetEventParameter ( inEvent, kEventParamDirectObject, typeWindowRef, NULL, sizeof(myWind), NULL, &myWind );
 
719
  if ( myWind ) {
 
720
    UInt32 what = ::GetEventKind ( inEvent );
 
721
    switch ( what ) {
 
722
    
 
723
      case kEventWindowBoundsChanged:
 
724
      {
 
725
        // are we moving or resizing the window? we only care about resize.
 
726
        UInt32 attributes = 0;
 
727
        ::GetEventParameter ( inEvent, kEventParamAttributes, typeUInt32, NULL, sizeof(attributes), NULL, &attributes );
 
728
        if ( attributes & kWindowBoundsChangeSizeChanged ) {
 
729
          Rect bounds;
 
730
          ::InvalWindowRect(myWind, ::GetWindowPortBounds(myWind, &bounds));
 
731
          
 
732
          // resize the window and repaint
 
733
          nsCocoaWindow* self = NS_REINTERPRET_CAST(nsCocoaWindow*, userData);
 
734
          if ( self && !self->mResizeIsFromUs ) {
 
735
            self->mMacEventHandler->ResizeEvent(myWind);
 
736
            self->mMacEventHandler->UpdateEvent();
 
737
          }
 
738
        }
 
739
        break;
 
740
      }
 
741
      
 
742
      case kEventWindowConstrain:
 
743
      {
 
744
        // Ignore this event if we're an invisible window, otherwise pass along the
 
745
        // chain to ensure it's onscreen.
 
746
        nsCocoaWindow* self = NS_REINTERPRET_CAST(nsCocoaWindow*, userData);
 
747
        if ( self ) {
 
748
          if ( self->mWindowType != eWindowType_invisible )
 
749
            retVal = ::CallNextEventHandler( inHandlerChain, inEvent );
 
750
        }
 
751
        break;
 
752
      }      
 
753
        
 
754
      default:
 
755
        // do nothing...
 
756
        break;
 
757
    
 
758
    } // case of which event?
 
759
  }
 
760
  
 
761
  return retVal;
 
762
  
 
763
} // WindowEventHandler
 
764
 
 
765
#endif
 
766
 
 
767
 
 
768
//-------------------------------------------------------------------------
 
769
//
 
770
// Create a nsCocoaWindow using a native window provided by the application
 
771
//
 
772
//-------------------------------------------------------------------------
 
773
NS_IMETHODIMP nsCocoaWindow::Create(nsNativeWidget aNativeParent,
 
774
                      const nsRect &aRect,
 
775
                      EVENT_CALLBACK aHandleEventFunction,
 
776
                      nsIDeviceContext *aContext,
 
777
                      nsIAppShell *aAppShell,
 
778
                      nsIToolkit *aToolkit,
 
779
                      nsWidgetInitData *aInitData)
 
780
{
 
781
  return(StandardCreate(nsnull, aRect, aHandleEventFunction,
 
782
                          aContext, aAppShell, aToolkit, aInitData,
 
783
                            aNativeParent));
 
784
}
 
785
 
 
786
 
 
787
NS_IMETHODIMP nsCocoaWindow::Create(nsIWidget* aParent,
 
788
                      const nsRect &aRect,
 
789
                      EVENT_CALLBACK aHandleEventFunction,
 
790
                      nsIDeviceContext *aContext,
 
791
                      nsIAppShell *aAppShell,
 
792
                      nsIToolkit *aToolkit,
 
793
                      nsWidgetInitData *aInitData)
 
794
{
 
795
  return(StandardCreate(aParent, aRect, aHandleEventFunction,
 
796
                          aContext, aAppShell, aToolkit, aInitData,
 
797
                            nsnull));
 
798
}
 
799
 
 
800
 
 
801
void*
 
802
nsCocoaWindow::GetNativeData(PRUint32 aDataType)
 
803
{
 
804
  void* retVal = nsnull;
 
805
  
 
806
  switch ( aDataType ) {
 
807
    
 
808
    // to emulate how windows works, we always have to return a NSView
 
809
    // for NS_NATIVE_WIDGET
 
810
    case NS_NATIVE_WIDGET:
 
811
    case NS_NATIVE_DISPLAY:
 
812
      retVal = [mWindow contentView];
 
813
      break;
 
814
      
 
815
    case NS_NATIVE_WINDOW:  
 
816
      retVal = mWindow;
 
817
      break;
 
818
      
 
819
    case NS_NATIVE_GRAPHIC:          // quickdraw port of top view (for now)
 
820
      retVal = [[mWindow contentView] qdPort];
 
821
      break;
 
822
      
 
823
#if 0
 
824
    case NS_NATIVE_REGION:
 
825
    retVal = (void*)mVisRegion;
 
826
      break;
 
827
 
 
828
    case NS_NATIVE_COLORMAP:
 
829
      //ļæ½TODO
 
830
      break;
 
831
 
 
832
    case NS_NATIVE_OFFSETX:
 
833
      point.MoveTo(mBounds.x, mBounds.y);
 
834
      LocalToWindowCoordinate(point);
 
835
      retVal = (void*)point.x;
 
836
      break;
 
837
 
 
838
    case NS_NATIVE_OFFSETY:
 
839
      point.MoveTo(mBounds.x, mBounds.y);
 
840
      LocalToWindowCoordinate(point);
 
841
      retVal = (void*)point.y;
 
842
      break;
 
843
    
 
844
    case NS_NATIVE_PLUGIN_PORT:
 
845
      // this needs to be a combination of the port and the offsets.
 
846
      if (mPluginPort == nsnull)
 
847
        mPluginPort = new nsPluginPort;
 
848
      
 
849
      point.MoveTo(mBounds.x, mBounds.y);
 
850
      LocalToWindowCoordinate(point);
 
851
      
 
852
      // for compatibility with 4.X, this origin is what you'd pass
 
853
      // to SetOrigin.
 
854
      mPluginPort->port = ::GetWindowPort(mWindowPtr);
 
855
      mPluginPort->portx = -point.x;
 
856
      mPluginPort->porty = -point.y;
 
857
    
 
858
      retVal = (void*)mPluginPort;
 
859
      break;
 
860
#endif
 
861
  }
 
862
 
 
863
  return retVal;
 
864
}
 
865
 
 
866
NS_IMETHODIMP
 
867
nsCocoaWindow::IsVisible(PRBool & aState)
 
868
{
 
869
  aState = mVisible;
 
870
  return NS_OK;
 
871
}
 
872
   
 
873
//-------------------------------------------------------------------------
 
874
//
 
875
// Hide or show this window
 
876
//
 
877
//-------------------------------------------------------------------------
 
878
NS_IMETHODIMP nsCocoaWindow::Show(PRBool bState)
 
879
{
 
880
  if ( bState )
 
881
    [mWindow orderFront:NULL];
 
882
  else
 
883
    [mWindow orderOut:NULL];
 
884
 
 
885
  mVisible = bState;
 
886
 
 
887
#if 0
 
888
  // we need to make sure we call ::Show/HideWindow() to generate the 
 
889
  // necessary activate/deactivate events. Calling ::ShowHide() is
 
890
  // not adequate, unless we don't want activation (popups). (pinkerton).
 
891
  if ( bState && !mBounds.IsEmpty() ) {
 
892
    if ( mAcceptsActivation )
 
893
      ::ShowWindow(mWindowPtr);
 
894
    else {
 
895
      ::ShowHide(mWindowPtr, true);
 
896
      ::BringToFront(mWindowPtr); // competes with ComeToFront, but makes popups work
 
897
    }
 
898
    if (mZoomOnShow) {
 
899
      SetSizeMode(nsSizeMode_Maximized);
 
900
      mZoomOnShow = PR_FALSE;
 
901
    }
 
902
    ComeToFront();
 
903
  }
 
904
  else {
 
905
    // when a toplevel window goes away, make sure we rollup any popups that may 
 
906
    // be lurking. We want to catch this here because we're guaranteed that
 
907
    // we hide a window before we destroy it, and doing it here more closely
 
908
    // approximates where we do the same thing on windows.
 
909
    if ( mWindowType == eWindowType_toplevel ) {
 
910
      if ( gRollupListener )
 
911
        gRollupListener->Rollup();
 
912
      NS_IF_RELEASE(gRollupListener);
 
913
      NS_IF_RELEASE(gRollupWidget);
 
914
    }
 
915
    ::HideWindow(mWindowPtr);
 
916
  }
 
917
  
 
918
#endif
 
919
 
 
920
  return NS_OK;
 
921
}
 
922
 
 
923
 
 
924
NS_IMETHODIMP nsCocoaWindow::Enable(PRBool aState)
 
925
{
 
926
  return NS_OK;
 
927
}
 
928
 
 
929
 
 
930
NS_IMETHODIMP nsCocoaWindow::IsEnabled(PRBool *aState)
 
931
{
 
932
  if (aState)
 
933
    *aState = PR_TRUE;
 
934
  return NS_OK;
 
935
}
 
936
 
 
937
 
 
938
/*
 
939
NS_METHOD nsWindow::Minimize(void)
 
940
{
 
941
  return NS_OK;
 
942
}
 
943
 
 
944
NS_METHOD nsWindow::Maximize(void)
 
945
{
 
946
  return NS_OK;
 
947
}
 
948
 
 
949
NS_METHOD nsWindow::Restore(void)
 
950
{
 
951
  return NS_OK;
 
952
}
 
953
*/
 
954
 
 
955
NS_IMETHODIMP nsCocoaWindow::ConstrainPosition(PRBool aAllowSlop,
 
956
                                               PRInt32 *aX, PRInt32 *aY)
 
957
{
 
958
#if 0
 
959
  if (eWindowType_popup == mWindowType || !mWindowMadeHere)
 
960
    return NS_OK;
 
961
 
 
962
  // Sanity check against screen size
 
963
  // make sure the window stays visible
 
964
 
 
965
  // get the window bounds
 
966
  Rect portBounds;
 
967
  ::GetWindowPortBounds(mWindowPtr, &portBounds);
 
968
  short pos;
 
969
  short windowWidth = portBounds.right - portBounds.left;
 
970
  short windowHeight = portBounds.bottom - portBounds.top;
 
971
 
 
972
  // now get our playing field. use the current screen, or failing that for any reason,
 
973
  // the GrayRgn (which of course is arguably more correct but has drawbacks as well)
 
974
  Rect screenRect;
 
975
  nsCOMPtr<nsIScreenManager> screenmgr = do_GetService(sScreenManagerContractID);
 
976
  if (screenmgr) {
 
977
    nsCOMPtr<nsIScreen> screen;
 
978
    PRInt32 left, top, width, height, fullHeight;
 
979
 
 
980
    // zero size rects can happen during window creation, and confuse
 
981
    // the screen manager
 
982
    width = windowWidth > 0 ? windowWidth : 1;
 
983
    height = windowHeight > 0 ? windowHeight : 1;
 
984
    screenmgr->ScreenForRect(*aX, *aY, width, height,
 
985
                            getter_AddRefs(screen));
 
986
    if (screen) {
 
987
      screen->GetAvailRect(&left, &top, &width, &height);
 
988
      screen->GetRect(&left, &top, &width, &fullHeight);
 
989
      screenRect.left = left;
 
990
      screenRect.right = left+width;
 
991
      screenRect.top = top;
 
992
      screenRect.bottom = top+height;
 
993
    }
 
994
  } else
 
995
    ::GetRegionBounds(::GetGrayRgn(), &screenRect);
 
996
 
 
997
  pos = screenRect.left;
 
998
  if (windowWidth > kWindowPositionSlop)
 
999
    pos -= windowWidth - kWindowPositionSlop;
 
1000
  if (*aX < pos)
 
1001
    *aX = pos;
 
1002
  else if (*aX >= screenRect.right - kWindowPositionSlop)
 
1003
    *aX = screenRect.right - kWindowPositionSlop;
 
1004
 
 
1005
  pos = screenRect.top;
 
1006
  if (windowHeight > kWindowPositionSlop)
 
1007
    pos -= windowHeight - kWindowPositionSlop;
 
1008
  if (*aY < pos)
 
1009
    *aY = pos;
 
1010
  else if (*aY >= screenRect.bottom - kWindowPositionSlop)
 
1011
    *aY = screenRect.bottom - kWindowPositionSlop;
 
1012
 
 
1013
#endif
 
1014
  return NS_OK;
 
1015
}
 
1016
 
 
1017
//-------------------------------------------------------------------------
 
1018
//
 
1019
// Move this window
 
1020
//
 
1021
//-------------------------------------------------------------------------
 
1022
//-------------------------------------------------------------------------
 
1023
// Move
 
1024
//-------------------------------------------------------------------------
 
1025
NS_IMETHODIMP nsCocoaWindow::Move(PRInt32 aX, PRInt32 aY)
 
1026
{  
 
1027
  if ( mWindow ) {  
 
1028
    // if we're a popup, we have to convert from our parent widget's coord
 
1029
    // system to the global coord system first because the (x,y) we're given
 
1030
    // is in its coordinate system.
 
1031
    if ( mWindowType == eWindowType_popup ) {
 
1032
      nsRect localRect, globalRect; 
 
1033
      localRect.x = aX;
 
1034
      localRect.y = aY;  
 
1035
      if ( mOffsetParent ) {
 
1036
        mOffsetParent->WidgetToScreen(localRect,globalRect);
 
1037
        aX=globalRect.x;
 
1038
        aY=globalRect.y;
 
1039
     }
 
1040
    }
 
1041
    
 
1042
    NSPoint coord = {aX, aY};
 
1043
    //coord = [mWindow convertBaseToScreen:coord];
 
1044
//printf("moving to %d %d. screen coords %f %f\n", aX, aY, coord.x, coord.y);
 
1045
 
 
1046
 //FIXME -- ensure it's on the screen. Cocoa automatically corrects for windows
 
1047
 //   with title bars, but for other windows, we have to do this...
 
1048
 
 
1049
    // the point we have assumes that the screen origin is the top-left. Well,
 
1050
    // it's not. Use the screen object to convert.
 
1051
    //FIXME -- doesn't work on monitors other than primary
 
1052
    NSRect screenRect = [[NSScreen mainScreen] frame];
 
1053
    coord.y = (screenRect.origin.y + screenRect.size.height) - coord.y;
 
1054
//printf("final coords %f %f\n", coord.x, coord.y);
 
1055
//printf("- window coords before %f %f\n", [mWindow frame].origin.x, [mWindow frame].origin.y);
 
1056
    [mWindow setFrameTopLeftPoint:coord];
 
1057
//printf("- window coords after %f %f\n", [mWindow frame].origin.x, [mWindow frame].origin.y);
 
1058
  }
 
1059
  
 
1060
#if 0
 
1061
  StPortSetter setOurPortForLocalToGlobal ( mWindowPtr );
 
1062
  
 
1063
  if (eWindowType_popup == mWindowType) {
 
1064
    PRInt32 xOffset=0,yOffset=0;
 
1065
    nsRect  localRect,globalRect;
 
1066
 
 
1067
    // convert to screen coordinates
 
1068
    localRect.x = aX;
 
1069
    localRect.y = aY;
 
1070
    localRect.width = 100;
 
1071
    localRect.height = 100; 
 
1072
 
 
1073
    if ( mOffsetParent ) {
 
1074
      mOffsetParent->WidgetToScreen(localRect,globalRect);
 
1075
      aX=globalRect.x;
 
1076
      aY=globalRect.y;
 
1077
      
 
1078
      // there is a bug on OSX where if we call ::MoveWindow() with the same
 
1079
      // coordinates (within a pixel or two) as a window's current location, it will 
 
1080
      // move to (0,0,-1,-1). The fix is to not move the window if we're already
 
1081
      // there. (radar# 2669004)
 
1082
#if TARGET_CARBON
 
1083
      const PRInt32 kMoveThreshold = 2;
 
1084
#else
 
1085
      const PRInt32 kMoveThreshold = 0;
 
1086
#endif
 
1087
      Rect currBounds;
 
1088
      ::GetWindowBounds ( mWindowPtr, kWindowGlobalPortRgn, &currBounds );
 
1089
      if ( abs(currBounds.left-aX) > kMoveThreshold || abs(currBounds.top-aY) > kMoveThreshold ) {
 
1090
        ::MoveWindow(mWindowPtr, aX, aY, false);
 
1091
        
 
1092
        Rect newBounds;
 
1093
        ::GetWindowBounds ( mWindowPtr, kWindowGlobalPortRgn, &newBounds );
 
1094
      }  
 
1095
    }
 
1096
 
 
1097
    return NS_OK;
 
1098
  } else if (mWindowMadeHere) {
 
1099
    Rect portBounds;
 
1100
    ::GetWindowPortBounds(mWindowPtr, &portBounds);
 
1101
 
 
1102
    if (mIsDialog) {
 
1103
      aX += kDialogMarginWidth;
 
1104
      aY += kDialogTitleBarHeight;
 
1105
    } else {
 
1106
      aX += kWindowMarginWidth;
 
1107
      aY += kWindowTitleBarHeight;
 
1108
    }
 
1109
 
 
1110
    nsCOMPtr<nsIScreenManager> screenmgr = do_GetService(sScreenManagerContractID);
 
1111
    if (screenmgr) {
 
1112
      nsCOMPtr<nsIScreen> screen;
 
1113
      PRInt32 left, top, width, height, fullTop;
 
1114
      // adjust for unset bounds, which confuses the screen manager
 
1115
      width = portBounds.right - portBounds.left;
 
1116
      height = portBounds.bottom - portBounds.top;
 
1117
      if (height <= 0) height = 1;
 
1118
      if (width <= 0) width = 1;
 
1119
 
 
1120
      screenmgr->ScreenForRect(aX, aY, width, height,
 
1121
                               getter_AddRefs(screen));
 
1122
      if (screen) {
 
1123
        screen->GetAvailRect(&left, &top, &width, &height);
 
1124
        screen->GetRect(&left, &fullTop, &width, &height);
 
1125
        aY += top-fullTop;
 
1126
      }
 
1127
    }
 
1128
 
 
1129
    // move the window if it has not been moved yet
 
1130
    // (ie. if this function isn't called in response to a DragWindow event)
 
1131
    Point macPoint = topLeft(portBounds);
 
1132
    ::LocalToGlobal(&macPoint);
 
1133
    if (macPoint.h != aX || macPoint.v != aY)
 
1134
      ::MoveWindow(mWindowPtr, aX, aY, false);
 
1135
 
 
1136
    // propagate the event in global coordinates
 
1137
    Inherited::Move(aX, aY);
 
1138
 
 
1139
    // reset the coordinates to (0,0) because it's the top level widget
 
1140
    mBounds.x = 0;
 
1141
    mBounds.y = 0;
 
1142
  }
 
1143
#endif
 
1144
  return NS_OK;
 
1145
}
 
1146
 
 
1147
//-------------------------------------------------------------------------
 
1148
//
 
1149
// Position the window behind the given window
 
1150
//
 
1151
//-------------------------------------------------------------------------
 
1152
NS_METHOD nsCocoaWindow::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
 
1153
                                     nsIWidget *aWidget, PRBool aActivate)
 
1154
{
 
1155
#if 0
 
1156
  if (aWidget) {
 
1157
    WindowPtr behind = (WindowPtr)aWidget->GetNativeData(NS_NATIVE_DISPLAY);
 
1158
    ::SendBehind(mWindowPtr, behind);
 
1159
    ::HiliteWindow(mWindowPtr, FALSE);
 
1160
  } else {
 
1161
    if (::FrontWindow() != mWindowPtr)
 
1162
      ::SelectWindow(mWindowPtr);
 
1163
  }
 
1164
#endif
 
1165
  return NS_OK;
 
1166
}
 
1167
 
 
1168
//-------------------------------------------------------------------------
 
1169
//
 
1170
// zoom/restore
 
1171
//
 
1172
//-------------------------------------------------------------------------
 
1173
NS_METHOD nsCocoaWindow::SetSizeMode(PRInt32 aMode)
 
1174
{
 
1175
#if 0
 
1176
  nsresult rv;
 
1177
  PRInt32  currentMode;
 
1178
 
 
1179
  if (aMode == nsSizeMode_Minimized) // unlikely on the Mac
 
1180
    return NS_ERROR_UNEXPECTED;
 
1181
 
 
1182
  // already done? it's bad to rezoom a window, so do nothing
 
1183
  rv = nsBaseWidget::GetSizeMode(&currentMode);
 
1184
  if (NS_SUCCEEDED(rv) && currentMode == aMode)
 
1185
    return NS_OK;
 
1186
 
 
1187
  if (!mVisible) {
 
1188
    /* zooming on the Mac doesn't seem to work until the window is visible.
 
1189
       the rest of the app is structured to zoom before the window is visible
 
1190
       to avoid flashing. here's where we defeat that. */
 
1191
    if (aMode == nsSizeMode_Maximized)
 
1192
      mZoomOnShow = PR_TRUE;
 
1193
  } else {
 
1194
    Rect macRect;
 
1195
    rv = nsBaseWidget::SetSizeMode(aMode);
 
1196
    if (NS_SUCCEEDED(rv)) {
 
1197
      if (aMode == nsSizeMode_Maximized) {
 
1198
        CalculateAndSetZoomedSize();
 
1199
        ::ZoomWindow(mWindowPtr, inZoomOut, ::FrontWindow() == mWindowPtr);
 
1200
      } else
 
1201
        ::ZoomWindow(mWindowPtr, inZoomIn, ::FrontWindow() == mWindowPtr);
 
1202
      ::GetWindowPortBounds(mWindowPtr, &macRect);
 
1203
      Resize(macRect.right - macRect.left, macRect.bottom - macRect.top, PR_FALSE);
 
1204
    }
 
1205
  }
 
1206
#endif
 
1207
 
 
1208
  return NS_OK;
 
1209
}
 
1210
 
 
1211
void nsCocoaWindow::CalculateAndSetZoomedSize()
 
1212
{
 
1213
#if 0
 
1214
  StPortSetter setOurPort(mWindowPtr);
 
1215
 
 
1216
  // calculate current window portbounds
 
1217
  Rect windRect;
 
1218
  ::GetWindowPortBounds(mWindowPtr, &windRect);
 
1219
  ::LocalToGlobal((Point *)&windRect.top);
 
1220
  ::LocalToGlobal((Point *)&windRect.bottom);
 
1221
 
 
1222
  // calculate window's borders on each side, these differ in Aqua / Platinum
 
1223
  short wTitleHeight;
 
1224
  short wLeftBorder;
 
1225
  short wRightBorder;
 
1226
  short wBottomBorder;
 
1227
       
 
1228
  RgnHandle structRgn = ::NewRgn();
 
1229
  ::GetWindowRegion(mWindowPtr, kWindowStructureRgn, structRgn);
 
1230
  Rect structRgnBounds;
 
1231
  ::GetRegionBounds(structRgn, &structRgnBounds);
 
1232
  wTitleHeight = windRect.top - structRgnBounds.top;
 
1233
  wLeftBorder = windRect.left - structRgnBounds.left;
 
1234
  wRightBorder =  structRgnBounds.right - windRect.right;
 
1235
  wBottomBorder = structRgnBounds.bottom - windRect.bottom;
 
1236
 
 
1237
  ::DisposeRgn(structRgn);
 
1238
 
 
1239
  windRect.top -= wTitleHeight;
 
1240
  windRect.bottom += wBottomBorder;
 
1241
  windRect.right += wRightBorder;
 
1242
  windRect.left -= wLeftBorder;
 
1243
 
 
1244
  // find which screen the window is (mostly) on and get its rect. GetAvailRect()
 
1245
  // handles subtracting out the menubar and the dock for us. Set the zoom rect
 
1246
  // to the screen rect, less some fudging and room for icons on the primary screen.
 
1247
  nsCOMPtr<nsIScreenManager> screenMgr = do_GetService(sScreenManagerContractID);
 
1248
  if ( screenMgr ) {
 
1249
    nsCOMPtr<nsIScreen> screen;
 
1250
    screenMgr->ScreenForRect ( windRect.left, windRect.top, windRect.right - windRect.left, windRect.bottom - windRect.top,
 
1251
                                getter_AddRefs(screen) );
 
1252
    if ( screen ) {
 
1253
      nsRect newWindowRect;
 
1254
      screen->GetAvailRect ( &newWindowRect.x, &newWindowRect.y, &newWindowRect.width, &newWindowRect.height );
 
1255
      
 
1256
      // leave room for icons on primary screen
 
1257
      nsCOMPtr<nsIScreen> primaryScreen;
 
1258
      screenMgr->GetPrimaryScreen ( getter_AddRefs(primaryScreen) );
 
1259
      if (screen == primaryScreen) {
 
1260
        int iconSpace = 96;
 
1261
#if TARGET_CARBON
 
1262
        if(::OnMacOSX()) {
 
1263
          iconSpace = 128;  //icons/grid is wider on Mac OS X
 
1264
        }
 
1265
#endif
 
1266
        newWindowRect.width -= iconSpace;
 
1267
      }
 
1268
 
 
1269
      Rect zoomRect;
 
1270
      ::SetRect(&zoomRect,
 
1271
                  newWindowRect.x + wLeftBorder,
 
1272
                  newWindowRect.y + wTitleHeight,
 
1273
                  newWindowRect.x + newWindowRect.width - wRightBorder,
 
1274
                  newWindowRect.y + newWindowRect.height - wBottomBorder); 
 
1275
      ::SetWindowStandardState ( mWindowPtr, &zoomRect );
 
1276
    }
 
1277
  }
 
1278
#endif
 
1279
  
 
1280
} // CalculateAndSetZoomedSize
 
1281
 
 
1282
 
 
1283
//-------------------------------------------------------------------------
 
1284
//
 
1285
// Resize this window to a point given in global (screen) coordinates. This
 
1286
// differs from simple Move(): that method makes JavaScript place windows
 
1287
// like other browsers: it puts the top-left corner of the outer edge of the
 
1288
// window border at the given coordinates, offset from the menubar.
 
1289
// MoveToGlobalPoint expects the top-left corner of the portrect, which
 
1290
// is inside the border, and is not offset by the menubar height.
 
1291
//
 
1292
//-------------------------------------------------------------------------
 
1293
void nsCocoaWindow::MoveToGlobalPoint(PRInt32 aX, PRInt32 aY)
 
1294
{
 
1295
#if 0
 
1296
  PRInt32 left, top, width, height, fullTop;
 
1297
  Rect portBounds;
 
1298
 
 
1299
  StPortSetter doThatThingYouDo(mWindowPtr);
 
1300
  ::GetWindowPortBounds(mWindowPtr, &portBounds);
 
1301
 
 
1302
  width = portBounds.right - portBounds.left;
 
1303
  height = portBounds.bottom - portBounds.top;
 
1304
  ::LocalToGlobal(&topLeft(portBounds));
 
1305
 
 
1306
  nsCOMPtr<nsIScreenManager> screenmgr = do_GetService(sScreenManagerContractID);
 
1307
  if (screenmgr) {
 
1308
    nsCOMPtr<nsIScreen> screen;
 
1309
    //screenmgr->GetPrimaryScreen(getter_AddRefs(screen));
 
1310
    screenmgr->ScreenForRect(portBounds.left, portBounds.top, width, height,
 
1311
                             getter_AddRefs(screen));
 
1312
    if (screen) {
 
1313
      screen->GetAvailRect(&left, &top, &width, &height);
 
1314
      screen->GetRect(&left, &fullTop, &width, &height);
 
1315
      aY -= top-fullTop;
 
1316
    }
 
1317
  }
 
1318
 
 
1319
  if (mIsDialog) {
 
1320
    aX -= kDialogMarginWidth;
 
1321
    aY -= kDialogTitleBarHeight;
 
1322
  } else {
 
1323
    aX -= kWindowMarginWidth;
 
1324
    aY -= kWindowTitleBarHeight;
 
1325
  }
 
1326
  Move(aX, aY);
 
1327
#endif
 
1328
}
 
1329
 
 
1330
 
 
1331
NS_IMETHODIMP nsCocoaWindow::Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
 
1332
{
 
1333
  Move(aX, aY);
 
1334
  Resize(aWidth, aHeight, aRepaint);
 
1335
  return NS_OK;
 
1336
}
 
1337
 
 
1338
 
 
1339
//-------------------------------------------------------------------------
 
1340
//
 
1341
// Resize this window
 
1342
//
 
1343
//-------------------------------------------------------------------------
 
1344
NS_IMETHODIMP nsCocoaWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
 
1345
{
 
1346
  if ( mWindow ) {
 
1347
    NSRect newBounds = [mWindow frame];
 
1348
    newBounds.size.width = aWidth;
 
1349
    if ( mWindowType == eWindowType_popup )
 
1350
      newBounds.size.height = aHeight;
 
1351
    else
 
1352
      newBounds.size.height = aHeight + kTitleBarHeight;     // add height of title bar
 
1353
    StartResizing();
 
1354
    [mWindow setFrame:newBounds display:NO];
 
1355
    StopResizing();
 
1356
  }
 
1357
 
 
1358
  mBounds.width  = aWidth;
 
1359
  mBounds.height = aHeight;
 
1360
  
 
1361
  // tell gecko to update all the child widgets
 
1362
  ReportSizeEvent();
 
1363
  
 
1364
#if 0
 
1365
  if (mWindowMadeHere) {
 
1366
      // Sanity check against screen size
 
1367
      Rect screenRect;
 
1368
    ::GetRegionBounds(::GetGrayRgn(), &screenRect);
 
1369
 
 
1370
      // Need to use non-negative coordinates
 
1371
      PRInt32 screenWidth;
 
1372
      if(screenRect.left < 0)
 
1373
        screenWidth = screenRect.right - screenRect.left;
 
1374
      else
 
1375
        screenWidth = screenRect.right;
 
1376
        
 
1377
      PRInt32 screenHeight;
 
1378
      if(screenRect.top < 0)
 
1379
        screenHeight = screenRect.bottom - screenRect.top;
 
1380
      else
 
1381
        screenHeight = screenRect.bottom;
 
1382
          
 
1383
      if(aHeight > screenHeight)
 
1384
        aHeight = screenHeight;
 
1385
        
 
1386
      if(aWidth > screenWidth)
 
1387
        aWidth = screenWidth;      
 
1388
    
 
1389
    Rect macRect;
 
1390
    ::GetWindowPortBounds ( mWindowPtr, &macRect );
 
1391
 
 
1392
    short w = macRect.right - macRect.left;
 
1393
    short h = macRect.bottom - macRect.top;
 
1394
    Boolean needReposition = (w == 1 && h == 1);
 
1395
 
 
1396
    if ((w != aWidth) || (h != aHeight))
 
1397
    {
 
1398
      // make sure that we don't infinitely recurse if live-resize is on
 
1399
      mResizeIsFromUs = PR_TRUE;
 
1400
      ::SizeWindow(mWindowPtr, aWidth, aHeight, aRepaint);
 
1401
      mResizeIsFromUs = PR_FALSE;
 
1402
 
 
1403
#if defined(XP_MACOSX)
 
1404
      // workaround for bug in MacOSX if windows start life as 1x1.
 
1405
      if (needReposition)
 
1406
        RepositionWindow(mWindowPtr, NULL, kWindowCascadeOnMainScreen);
 
1407
#endif
 
1408
    }
 
1409
  }
 
1410
#endif
 
1411
  //Inherited::Resize(aWidth, aHeight, aRepaint);
 
1412
  return NS_OK;
 
1413
}
 
1414
 
 
1415
NS_IMETHODIMP nsCocoaWindow::GetScreenBounds(nsRect &aRect) {
 
1416
#if 0 
 
1417
  nsRect localBounds;
 
1418
  PRInt32 yAdjust = 0;
 
1419
 
 
1420
  GetBounds(localBounds);
 
1421
  // nsCocoaWindow local bounds are always supposed to be local (0,0) but in the middle of a move
 
1422
  // can be global. This next adjustment assures they are in local coordinates, even then.
 
1423
  localBounds.MoveBy(-localBounds.x, -localBounds.y);
 
1424
  WidgetToScreen(localBounds, aRect);
 
1425
 
 
1426
  nsCOMPtr<nsIScreenManager> screenmgr = do_GetService(sScreenManagerContractID);
 
1427
  if (screenmgr) {
 
1428
    nsCOMPtr<nsIScreen> screen;
 
1429
    //screenmgr->GetPrimaryScreen(getter_AddRefs(screen));
 
1430
    screenmgr->ScreenForRect(aRect.x, aRect.y, aRect.width, aRect.height,
 
1431
                             getter_AddRefs(screen));
 
1432
    if (screen) {
 
1433
      PRInt32 left, top, width, height, fullTop;
 
1434
      screen->GetAvailRect(&left, &top, &width, &height);
 
1435
      screen->GetRect(&left, &fullTop, &width, &height);
 
1436
      yAdjust = top-fullTop;
 
1437
    }
 
1438
  }
 
1439
 
 
1440
  if (mIsDialog)
 
1441
    aRect.MoveBy(-kDialogMarginWidth, -kDialogTitleBarHeight-yAdjust);
 
1442
  else
 
1443
    aRect.MoveBy(-kWindowMarginWidth, -kWindowTitleBarHeight-yAdjust);
 
1444
 
 
1445
#endif
 
1446
  return NS_OK;
 
1447
}
 
1448
 
 
1449
//-------------------------------------------------------------------------
 
1450
//
 
1451
//
 
1452
//-------------------------------------------------------------------------
 
1453
PRBool nsCocoaWindow::OnPaint(nsPaintEvent &event)
 
1454
{
 
1455
  return PR_TRUE; // don't dispatch the update event
 
1456
}
 
1457
 
 
1458
//-------------------------------------------------------------------------
 
1459
//
 
1460
// Set this window's title
 
1461
//
 
1462
//-------------------------------------------------------------------------
 
1463
NS_IMETHODIMP nsCocoaWindow::SetTitle(const nsString& aTitle)
 
1464
{
 
1465
  NSString* title = [NSString stringWithCharacters:aTitle.get() length:aTitle.Length()];
 
1466
  [mWindow setTitle:title];
 
1467
 
 
1468
  return NS_OK;
 
1469
}
 
1470
 
 
1471
 
 
1472
//-------------------------------------------------------------------------
 
1473
// Pass notification of some drag event to Gecko
 
1474
//
 
1475
// The drag manager has let us know that something related to a drag has
 
1476
// occurred in this window. It could be any number of things, ranging from 
 
1477
// a drop, to a drag enter/leave, or a drag over event. The actual event
 
1478
// is passed in |aMessage| and is passed along to our event hanlder so Gecko
 
1479
// knows about it.
 
1480
//-------------------------------------------------------------------------
 
1481
PRBool nsCocoaWindow::DragEvent ( unsigned int aMessage, Point aMouseGlobal, UInt16 aKeyModifiers )
 
1482
{
 
1483
#if 0
 
1484
  PRBool retVal;
 
1485
  if (mMacEventHandler.get())
 
1486
    retVal = mMacEventHandler->DragEvent(aMessage, aMouseGlobal, aKeyModifiers);
 
1487
  else
 
1488
    retVal = PR_FALSE;
 
1489
  return retVal;
 
1490
#endif
 
1491
  return PR_FALSE;
 
1492
}
 
1493
 
 
1494
//-------------------------------------------------------------------------
 
1495
//
 
1496
// Like ::BringToFront, but constrains the window to its z-level
 
1497
//
 
1498
//-------------------------------------------------------------------------
 
1499
void nsCocoaWindow::ComeToFront() {
 
1500
#if 0
 
1501
  nsZLevelEvent  event(NS_SETZLEVEL, this);
 
1502
 
 
1503
  event.point.x = mBounds.x;
 
1504
  event.point.y = mBounds.y;
 
1505
  event.time = PR_IntervalNow();
 
1506
 
 
1507
  event.mImmediate = PR_TRUE;
 
1508
 
 
1509
  DispatchWindowEvent(event);
 
1510
#endif
 
1511
}
 
1512
 
 
1513
 
 
1514
NS_IMETHODIMP nsCocoaWindow::ResetInputState()
 
1515
{
 
1516
//  return mMacEventHandler->ResetInputState();
 
1517
  return NS_OK;
 
1518
}
 
1519
 
 
1520
void nsCocoaWindow::SetIsActive(PRBool aActive)
 
1521
{
 
1522
//  mIsActive = aActive;
 
1523
}
 
1524
 
 
1525
void nsCocoaWindow::IsActive(PRBool* aActive)
 
1526
{
 
1527
//  *aActive = mIsActive;
 
1528
}
 
1529
 
 
1530
 
 
1531
//
 
1532
// Return true if we are on Mac OS X, caching the result after the first call
 
1533
//
 
1534
static PRBool
 
1535
OnMacOSX()
 
1536
{
 
1537
 
 
1538
  static PRBool gInitVer = PR_FALSE;
 
1539
  static PRBool gOnMacOSX = PR_FALSE;
 
1540
  if(! gInitVer) {
 
1541
    long version;
 
1542
    OSErr err = ::Gestalt(gestaltSystemVersion, &version);
 
1543
    gOnMacOSX = (err == noErr && version >= 0x00001000);
 
1544
    gInitVer = PR_TRUE;
 
1545
  }
 
1546
  return gOnMacOSX;
 
1547
}
 
1548
 
 
1549
 
 
1550
#if 0
 
1551
 
 
1552
//
 
1553
// DispatchEvent
 
1554
//
 
1555
// 
 
1556
NS_IMETHODIMP
 
1557
nsCocoaWindow::DispatchEvent ( void* anEvent, void* aView, PRBool *_retval )
 
1558
{
 
1559
  *_retval = PR_FALSE;
 
1560
 
 
1561
#if 0  
 
1562
  NSEvent* event = NS_REINTERPRET_CAST(NSEvent*, anEvent);
 
1563
  NS_ASSERTION(event, "null event");
 
1564
  
 
1565
  ChildView* view = NS_REINTERPRET_CAST(ChildView*, aView);
 
1566
  
 
1567
  nsMouseEvent geckoEvent(0, view ? [view widget] : this)
 
1568
  
 
1569
  geckoEvent.nativeMsg = anEvent;
 
1570
  geckoEvent.time = PR_IntervalNow();
 
1571
  NSPoint mouseLoc = [event locationInWindow];
 
1572
  geckoEvent.refPoint.x = NS_STATIC_CAST(nscoord, mouseLoc.x);
 
1573
  geckoEvent.refPoint.y = NS_STATIC_CAST(nscoord, mouseLoc.y);
 
1574
//printf("-- global mouse click at (%ld,%ld)\n", geckoEvent.refPoint.x, geckoEvent.refPoint.y );
 
1575
  if ( view ) {
 
1576
    // convert point to view coordinate system
 
1577
    NSPoint localPoint = [view convertPoint:mouseLoc fromView:nil];
 
1578
    geckoEvent.point.x = NS_STATIC_CAST(nscoord, localPoint.x);
 
1579
    geckoEvent.point.y = NS_STATIC_CAST(nscoord, localPoint.y);
 
1580
//printf("-- local mouse click at (%ld,%ld) widget = %ld\n", geckoEvent.point.x, geckoEvent.point.y,
 
1581
//          geckoEvent.widget );
 
1582
  }
 
1583
  else
 
1584
    geckoEvent.point = geckoEvent.refPoint;
 
1585
 
 
1586
  NSEventType type = [event type];
 
1587
  switch ( type ) {
 
1588
    case NSLeftMouseDown:
 
1589
      //printf("left mouse down\n");
 
1590
      geckoEvent.message = NS_MOUSE_LEFT_BUTTON_DOWN;
 
1591
      geckoEvent.clickCount = [event clickCount];
 
1592
      break;
 
1593
    case NSLeftMouseUp:
 
1594
      //printf("left mouse up\n");
 
1595
      break;
 
1596
    case NSMouseMoved:
 
1597
      printf("mouse move\n");
 
1598
      break;
 
1599
    case NSKeyDown:
 
1600
      printf("key down\n");
 
1601
      break;
 
1602
    case NSKeyUp:
 
1603
      printf("key up\n");
 
1604
      break;
 
1605
    case NSScrollWheel:
 
1606
      printf("scroll wheel\n");
 
1607
      break;
 
1608
    case NSLeftMouseDragged:
 
1609
      printf("drag\n");
 
1610
      break;
 
1611
 
 
1612
    default:
 
1613
      printf("other\n");
 
1614
      break;    
 
1615
  }
 
1616
 
 
1617
  nsEventStatus status = nsEventStatus_eIgnore;
 
1618
  DispatchEvent ( &geckoEvent, status );
 
1619
  
 
1620
  *_retval = PR_TRUE;
 
1621
#endif
 
1622
 
 
1623
  return NS_OK;
 
1624
}
 
1625
 
 
1626
#endif
 
1627
 
 
1628
 
 
1629
//-------------------------------------------------------------------------
 
1630
//
 
1631
// Invokes callback and  ProcessEvent method on Event Listener object
 
1632
//
 
1633
//-------------------------------------------------------------------------
 
1634
NS_IMETHODIMP 
 
1635
nsCocoaWindow::DispatchEvent(nsGUIEvent* event, nsEventStatus& aStatus)
 
1636
{
 
1637
  aStatus = nsEventStatus_eIgnore;
 
1638
 
 
1639
  nsIWidget* aWidget = event->widget;
 
1640
  NS_IF_ADDREF(aWidget);
 
1641
  
 
1642
  if (nsnull != mMenuListener){
 
1643
    if(NS_MENU_EVENT == event->eventStructType)
 
1644
      aStatus = mMenuListener->MenuSelected( static_cast<nsMenuEvent&>(*event) );
 
1645
  }
 
1646
  if (mEventCallback)
 
1647
    aStatus = (*mEventCallback)(event);
 
1648
 
 
1649
  // Dispatch to event listener if event was not consumed
 
1650
  if ((aStatus != nsEventStatus_eConsumeNoDefault) && (mEventListener != nsnull))
 
1651
    aStatus = mEventListener->ProcessEvent(*event);
 
1652
 
 
1653
  NS_IF_RELEASE(aWidget);
 
1654
 
 
1655
  return NS_OK;
 
1656
}
 
1657
 
 
1658
 
 
1659
void
 
1660
nsCocoaWindow::ReportSizeEvent()
 
1661
{
 
1662
  // nsEvent
 
1663
  nsSizeEvent sizeEvent(NS_SIZE, this);
 
1664
  sizeEvent.time        = PR_IntervalNow();
 
1665
 
 
1666
  // nsSizeEvent
 
1667
  sizeEvent.windowSize  = &mBounds;
 
1668
  sizeEvent.mWinWidth   = mBounds.width;
 
1669
  sizeEvent.mWinHeight  = mBounds.height;
 
1670
  
 
1671
  // dispatch event
 
1672
  nsEventStatus status = nsEventStatus_eIgnore;
 
1673
  DispatchEvent(&sizeEvent, status);
 
1674
}
 
1675
 
 
1676
 
 
1677
#if 0
 
1678
 
 
1679
PRBool
 
1680
nsCocoaWindow::IsResizing ( ) const 
 
1681
 
1682
  return mIsResizing;
 
1683
}
 
1684
 
 
1685
void StartResizing ( ) 
 
1686
 
1687
  mIsResizing = PR_TRUE;
 
1688
}
 
1689
 
 
1690
void StopResizing ( ) 
 
1691
 
1692
  mIsResizing = PR_FALSE;
 
1693
}
 
1694
 
 
1695
#endif
 
1696
 
 
1697
 
 
1698
#pragma mark -
 
1699
 
 
1700
 
 
1701
@implementation WindowDelegate
 
1702
 
 
1703
 
 
1704
- (id)initWithGeckoWindow:(nsCocoaWindow*)geckoWind
 
1705
{
 
1706
  [super init];
 
1707
  mGeckoWindow = geckoWind;
 
1708
  return self;
 
1709
}
 
1710
 
 
1711
- (void)windowDidResize:(NSNotification *)aNotification
 
1712
{
 
1713
  if ( !mGeckoWindow->IsResizing() ) {
 
1714
    // must remember to give Gecko top-left, not straight cocoa origin
 
1715
    // and that Gecko already compensates for the title bar, so we have to
 
1716
    // strip it out here.
 
1717
    NSRect frameRect = [[aNotification object] frame];
 
1718
    mGeckoWindow->Resize ( NS_STATIC_CAST(PRInt32,frameRect.size.width),
 
1719
                            NS_STATIC_CAST(PRInt32,frameRect.size.height - nsCocoaWindow::kTitleBarHeight), PR_TRUE );
 
1720
  }
 
1721
}
 
1722
 
 
1723
 
 
1724
- (void)windowDidBecomeMain:(NSNotification *)aNotification
 
1725
{
 
1726
  //printf("got activation\n");
 
1727
}
 
1728
 
 
1729
 
 
1730
- (void)windowDidResignMain:(NSNotification *)aNotification
 
1731
{
 
1732
  //printf("got deactivate\n");
 
1733
}
 
1734
 
 
1735
 
 
1736
- (void)windowDidBecomeKey:(NSNotification *)aNotification
 
1737
{
 
1738
  //printf("we're key window\n");
 
1739
}
 
1740
 
 
1741
 
 
1742
- (void)windowDidResignKey:(NSNotification *)aNotification
 
1743
{
 
1744
  //printf("we're not the key window\n");
 
1745
}
 
1746
 
 
1747
 
 
1748
- (void)windowDidMove:(NSNotification *)aNotification
 
1749
{
 
1750
}
 
1751
 
 
1752
@end