Add copy of .ttf font with .eot extension for testing
[wine-gecko.git] / widget / src / photon / nsAppShell.cpp
blobd5c0e0bedfe68ab46fec965f05fae252b6870ff3
1 /* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
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.
15 * The Original Code is mozilla.org code.
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.
22 * Contributor(s):
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 MPL, 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 MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "prmon.h"
39 #include "plhash.h"
40 #include "nsCOMPtr.h"
41 #include "nsAppShell.h"
42 #include "nsIAppShell.h"
43 #include "nsIServiceManager.h"
44 #include "nsIEventQueueService.h"
46 #include <stdlib.h>
48 #include "nsIWidget.h"
49 #include "nsCRT.h"
51 #include <Pt.h>
52 #include <errno.h>
54 /* Global Definitions */
55 PRBool nsAppShell::gExitMainLoop = PR_FALSE;
57 static PLHashTable *sQueueHashTable = nsnull;
58 static PLHashTable *sCountHashTable = nsnull;
60 // Set our static member
61 PRBool nsAppShell::mPtInited = PR_FALSE;
63 //-------------------------------------------------------------------------
65 // XPCOM CIDs
67 //-------------------------------------------------------------------------
68 static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
70 //-------------------------------------------------------------------------
72 // nsAppShell constructor
74 //-------------------------------------------------------------------------
75 nsAppShell::nsAppShell()
77 mEventQueue = nsnull;
78 mFD = -1;
81 //-------------------------------------------------------------------------
83 // nsAppShell destructor
85 //-------------------------------------------------------------------------
86 nsAppShell::~nsAppShell()
88 if (mFD != -1)
90 int err=PtAppRemoveFd(NULL,mFD);
92 if (err==-1)
94 NS_WARNING("nsAppShell::~EventQueueTokenQueue Run Error calling PtAppRemoveFd");
95 #ifdef DEBUG
96 printf("nsAppShell::~EventQueueTokenQueue Run Error calling PtAppRemoveFd mFD=<%d> errno=<%d>\n", mFD, errno);
97 #endif
99 mFD = -1;
104 //-------------------------------------------------------------------------
106 // nsISupports implementation macro
108 //-------------------------------------------------------------------------
109 NS_IMPL_ISUPPORTS1(nsAppShell, nsIAppShell)
111 //-------------------------------------------------------------------------
113 // Enter a message handler loop
115 //-------------------------------------------------------------------------
117 static int event_processor_callback(int fd, void *data, unsigned mode)
119 nsIEventQueue *eventQueue = (nsIEventQueue*)data;
120 PtHold();
121 if (eventQueue)
122 eventQueue->ProcessPendingEvents();
123 PtRelease();
124 return Pt_CONTINUE;
128 //-------------------------------------------------------------------------
130 // Create the application shell
132 //-------------------------------------------------------------------------
134 NS_IMETHODIMP nsAppShell::Create(int *bac, char **bav)
137 This used to be done in the init function of nsToolkit. It was moved here because the phoenix
138 browser may ( when -ProfileManager is used ) create/ListenToEventQueue of an nsAppShell before
139 the toolkit is initialized and ListenToEventQueue relies on the Pt being already initialized
141 if( !mPtInited )
143 PtInit( NULL );
144 PtChannelCreate(); // Force use of pulses
145 mPtInited = PR_TRUE;
148 return NS_OK;
151 //-------------------------------------------------------------------------
153 // Spinup - do any preparation necessary for running a message loop
155 //-------------------------------------------------------------------------
156 NS_METHOD nsAppShell::Spinup()
158 nsresult rv = NS_OK;
160 // Get the event queue service
161 nsCOMPtr<nsIEventQueueService> eventQService = do_GetService(kEventQueueServiceCID, &rv);
163 if (NS_FAILED(rv)) {
164 NS_ASSERTION("Could not obtain event queue service", PR_FALSE);
165 return rv;
168 //Get the event queue for the thread.
169 rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(mEventQueue));
171 // If we got an event queue, use it.
172 if (mEventQueue)
173 goto done;
175 // otherwise create a new event queue for the thread
176 rv = eventQService->CreateThreadEventQueue();
177 if (NS_FAILED(rv)) {
178 NS_ASSERTION("Could not create the thread event queue", PR_FALSE);
179 return rv;
182 // Ask again nicely for the event queue now that we have created one.
183 rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(mEventQueue));
185 // XXX shouldn't this be automatic?
186 done:
187 ListenToEventQueue(mEventQueue, PR_TRUE);
189 return rv;
192 //-------------------------------------------------------------------------
194 // Spindown - do any cleanup necessary for finishing a message loop
196 //-------------------------------------------------------------------------
197 NS_METHOD nsAppShell::Spindown()
199 if (mEventQueue) {
200 ListenToEventQueue(mEventQueue, PR_FALSE);
201 mEventQueue->ProcessPendingEvents();
202 mEventQueue = nsnull;
205 return NS_OK;
208 /* This routine replaces the standard PtMainLoop() for Photon */
209 /* We had to replace it to provide a mechanism (ExitMainLoop) to exit */
210 /* the loop. */
212 void MyMainLoop( void )
214 nsAppShell::gExitMainLoop = PR_FALSE;
215 while (! nsAppShell::gExitMainLoop)
217 PtProcessEvent();
220 #ifdef DEBUG
221 printf("nsAppShell: MyMainLoop exiting!\n");
222 #endif
225 //-------------------------------------------------------------------------
227 // Run
229 //-------------------------------------------------------------------------
230 NS_IMETHODIMP nsAppShell::Run()
232 if (!mEventQueue)
233 Spinup();
235 if (!mEventQueue)
236 return NS_ERROR_NOT_INITIALIZED;
238 // kick up gtk_main. this won't return until gtk_main_quit is called
239 MyMainLoop();
241 Spindown();
243 return NS_OK;
246 //-------------------------------------------------------------------------
248 // Exit a message handler loop
250 //-------------------------------------------------------------------------
252 NS_METHOD nsAppShell::Exit()
254 gExitMainLoop = PR_TRUE;
255 return NS_OK;
259 #define NUMBER_HASH_KEY(_num) ((PLHashNumber) _num)
261 static PLHashNumber
262 IntHashKey(PRInt32 key)
264 return NUMBER_HASH_KEY(key);
267 NS_IMETHODIMP nsAppShell::ListenToEventQueue(nsIEventQueue *aQueue,
268 PRBool aListen)
271 if (!sQueueHashTable) {
272 sQueueHashTable = PL_NewHashTable(3, (PLHashFunction)IntHashKey,
273 PL_CompareValues, PL_CompareValues, 0, 0);
275 if (!sCountHashTable) {
276 sCountHashTable = PL_NewHashTable(3, (PLHashFunction)IntHashKey,
277 PL_CompareValues, PL_CompareValues, 0, 0);
280 if (aListen) {
281 /* add listener */
282 PRInt32 key = aQueue->GetEventQueueSelectFD();
284 /* only add if we arn't already in the table */
285 if (!PL_HashTableLookup(sQueueHashTable, (void *)(key))) {
286 PRInt32 tag = PtAppAddFd( NULL, aQueue->GetEventQueueSelectFD(), (Pt_FD_READ | Pt_FD_NOPOLL | Pt_FD_DRAIN ),
287 event_processor_callback, aQueue );
289 if (tag >= 0) {
290 PL_HashTableAdd(sQueueHashTable, (void *)(key), (void *)(key));
293 /* bump up the count */
294 int count = (int)(PL_HashTableLookup(sCountHashTable, (void *)(key)));
295 PL_HashTableAdd(sCountHashTable, (void *)(key), (void *)(count+1));
296 } else {
297 /* remove listener */
298 PRInt32 key = aQueue->GetEventQueueSelectFD();
300 int count = (int)(PL_HashTableLookup(sCountHashTable, (void *)(key)));
301 if (count - 1 == 0) {
302 int tag = (int)(PL_HashTableLookup(sQueueHashTable, (void *)(key)));
303 if (tag > 0) {
304 PtAppRemoveFd(NULL, key);
305 PL_HashTableRemove(sQueueHashTable, (void *)(key));
308 PL_HashTableAdd(sCountHashTable, (void *)(key), (void *)(count-1));
312 return NS_OK;