Application.cpp revision dc3ebdec
152a38012Sejakowatz//------------------------------------------------------------------------------
252a38012Sejakowatz//	Copyright (c) 2001-2002, OpenBeOS
352a38012Sejakowatz//
452a38012Sejakowatz//	Permission is hereby granted, free of charge, to any person obtaining a
552a38012Sejakowatz//	copy of this software and associated documentation files (the "Software"),
652a38012Sejakowatz//	to deal in the Software without restriction, including without limitation
752a38012Sejakowatz//	the rights to use, copy, modify, merge, publish, distribute, sublicense,
852a38012Sejakowatz//	and/or sell copies of the Software, and to permit persons to whom the
952a38012Sejakowatz//	Software is furnished to do so, subject to the following conditions:
1052a38012Sejakowatz//
1152a38012Sejakowatz//	The above copyright notice and this permission notice shall be included in
1252a38012Sejakowatz//	all copies or substantial portions of the Software.
1352a38012Sejakowatz//
1452a38012Sejakowatz//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1552a38012Sejakowatz//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1652a38012Sejakowatz//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1752a38012Sejakowatz//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1852a38012Sejakowatz//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1952a38012Sejakowatz//	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2052a38012Sejakowatz//	DEALINGS IN THE SOFTWARE.
2152a38012Sejakowatz//
2252a38012Sejakowatz//	File Name:		Application.cpp
2352a38012Sejakowatz//	Author:			Erik Jaesler (erik@cgsoftware.com)
2452a38012Sejakowatz//	Description:	BApplication class is the center of the application
2552a38012Sejakowatz//					universe.  The global be_app and be_app_messenger
2652a38012Sejakowatz//					variables are defined here as well.
2752a38012Sejakowatz//------------------------------------------------------------------------------
2852a38012Sejakowatz
2952a38012Sejakowatz// Standard Includes -----------------------------------------------------------
3073a2b29fSIngo Weinhold#include <new>
31c7f20c70SIngo Weinhold#include <stdio.h>
3273a2b29fSIngo Weinhold#include <string.h>
3373a2b29fSIngo Weinhold#include <unistd.h>
3452a38012Sejakowatz
3552a38012Sejakowatz// System Includes -------------------------------------------------------------
3653b9eef8SStefano Ceccherini#include <Alert.h>
3773a2b29fSIngo Weinhold#include <AppFileInfo.h>
3852a38012Sejakowatz#include <Application.h>
398a526591SIngo Weinhold#include <AppMisc.h>
40c7f20c70SIngo Weinhold#include <Cursor.h>
4173a2b29fSIngo Weinhold#include <Entry.h>
4273a2b29fSIngo Weinhold#include <File.h>
4353b9eef8SStefano Ceccherini#include <InterfaceDefs.h>
44c7f20c70SIngo Weinhold#include <Locker.h>
4573a2b29fSIngo Weinhold#include <Path.h>
46b1698c8eSejakowatz#include <PropertyInfo.h>
47c7f20c70SIngo Weinhold#include <RegistrarDefs.h>
48c7f20c70SIngo Weinhold#include <Roster.h>
492ed834e3SIngo Weinhold#include <RosterPrivate.h>
50ebbcbbcaSejakowatz#include <Window.h>
5152a38012Sejakowatz
5252a38012Sejakowatz// Project Includes ------------------------------------------------------------
53ebbcbbcaSejakowatz#include <LooperList.h>
54ebbcbbcaSejakowatz#include <ObjectLocker.h>
55582e2dddSDarkWyrm#include <AppServerLink.h>
567c7ee64aSDarkWyrm#include <ServerProtocol.h>
57591d280eSDarkWyrm#include <PortLink.h>
58591d280eSDarkWyrm#include <PortMessage.h>
5952a38012Sejakowatz
6052a38012Sejakowatz// Local Includes --------------------------------------------------------------
6152a38012Sejakowatz
6252a38012Sejakowatz// Local Defines ---------------------------------------------------------------
63dc3ebdecSAdi Oanca#define RUN_WITHOUT_REGISTRAR
6452a38012Sejakowatz
6552a38012Sejakowatz// Globals ---------------------------------------------------------------------
6652a38012SejakowatzBApplication*	be_app = NULL;
6752a38012SejakowatzBMessenger		be_app_messenger;
6852a38012Sejakowatz
6952a38012SejakowatzBResources*	BApplication::_app_resources = NULL;
7052a38012SejakowatzBLocker		BApplication::_app_resources_lock("_app_resources_lock");
7152a38012Sejakowatz
722284462cSejakowatzproperty_info gApplicationPropInfo[] =
732284462cSejakowatz{
74ebbcbbcaSejakowatz	{
75ebbcbbcaSejakowatz		"Window",
76ebbcbbcaSejakowatz			{},
77ebbcbbcaSejakowatz			{B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER},
78ebbcbbcaSejakowatz			NULL, 0,
79ebbcbbcaSejakowatz			{},
80ebbcbbcaSejakowatz			{},
81ebbcbbcaSejakowatz			{}
82ebbcbbcaSejakowatz	},
83ebbcbbcaSejakowatz	{
84ebbcbbcaSejakowatz		"Window",
85ebbcbbcaSejakowatz			{},
86ebbcbbcaSejakowatz			{B_NAME_SPECIFIER},
87ebbcbbcaSejakowatz			NULL, 1,
88ebbcbbcaSejakowatz			{},
89ebbcbbcaSejakowatz			{},
90ebbcbbcaSejakowatz			{}
91ebbcbbcaSejakowatz	},
92ebbcbbcaSejakowatz	{
93ebbcbbcaSejakowatz		"Looper",
94ebbcbbcaSejakowatz			{},
95ebbcbbcaSejakowatz			{B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER},
96ebbcbbcaSejakowatz			NULL, 2,
97ebbcbbcaSejakowatz			{},
98ebbcbbcaSejakowatz			{},
99ebbcbbcaSejakowatz			{}
100ebbcbbcaSejakowatz	},
101ebbcbbcaSejakowatz	{
102ebbcbbcaSejakowatz		"Looper",
103ebbcbbcaSejakowatz			{},
104ebbcbbcaSejakowatz			{B_ID_SPECIFIER},
105ebbcbbcaSejakowatz			NULL, 3,
106ebbcbbcaSejakowatz			{},
107ebbcbbcaSejakowatz			{},
108ebbcbbcaSejakowatz			{}
109ebbcbbcaSejakowatz	},
110ebbcbbcaSejakowatz	{
111ebbcbbcaSejakowatz		"Looper",
112ebbcbbcaSejakowatz			{},
113ebbcbbcaSejakowatz			{B_NAME_SPECIFIER},
114ebbcbbcaSejakowatz			NULL, 4,
115ebbcbbcaSejakowatz			{},
116ebbcbbcaSejakowatz			{},
117ebbcbbcaSejakowatz			{}
118ebbcbbcaSejakowatz	},
119ebbcbbcaSejakowatz	{
120ebbcbbcaSejakowatz		"Name",
121ebbcbbcaSejakowatz			{B_GET_PROPERTY},
122ebbcbbcaSejakowatz			{B_DIRECT_SPECIFIER},
123ebbcbbcaSejakowatz			NULL, 5,
124ebbcbbcaSejakowatz			{B_STRING_TYPE},
125ebbcbbcaSejakowatz			{},
126ebbcbbcaSejakowatz			{}
127ebbcbbcaSejakowatz	},
128ebbcbbcaSejakowatz	{
129ebbcbbcaSejakowatz		"Window",
130ebbcbbcaSejakowatz			{B_COUNT_PROPERTIES},
131ebbcbbcaSejakowatz			{B_DIRECT_SPECIFIER},
132ebbcbbcaSejakowatz			NULL, 5,
133ebbcbbcaSejakowatz			{B_INT32_TYPE},
134ebbcbbcaSejakowatz			{},
135ebbcbbcaSejakowatz			{}
136ebbcbbcaSejakowatz	},
137ebbcbbcaSejakowatz	{
138ebbcbbcaSejakowatz		"Loopers",
139ebbcbbcaSejakowatz			{B_GET_PROPERTY},
140ebbcbbcaSejakowatz			{B_DIRECT_SPECIFIER},
141ebbcbbcaSejakowatz			NULL, 5,
142ebbcbbcaSejakowatz			{B_MESSENGER_TYPE},
143ebbcbbcaSejakowatz			{},
144ebbcbbcaSejakowatz			{}
145ebbcbbcaSejakowatz	},
146ebbcbbcaSejakowatz	{
147ebbcbbcaSejakowatz		"Windows",
148ebbcbbcaSejakowatz			{B_GET_PROPERTY},
149ebbcbbcaSejakowatz			{B_DIRECT_SPECIFIER},
150ebbcbbcaSejakowatz			NULL, 5,
151ebbcbbcaSejakowatz			{B_MESSENGER_TYPE},
152ebbcbbcaSejakowatz			{},
153ebbcbbcaSejakowatz			{}
154ebbcbbcaSejakowatz	},
155ebbcbbcaSejakowatz	{
156ebbcbbcaSejakowatz		"Looper",
157ebbcbbcaSejakowatz			{B_COUNT_PROPERTIES},
158ebbcbbcaSejakowatz			{B_DIRECT_SPECIFIER},
159ebbcbbcaSejakowatz			NULL, 5,
160ebbcbbcaSejakowatz			{B_INT32_TYPE},
161ebbcbbcaSejakowatz			{},
162ebbcbbcaSejakowatz			{}
163ebbcbbcaSejakowatz	},
164ebbcbbcaSejakowatz	{}
1652284462cSejakowatz};
1662284462cSejakowatz
16773a2b29fSIngo Weinhold// argc/argv
16873a2b29fSIngo Weinholdextern const int __libc_argc;
16973a2b29fSIngo Weinholdextern const char * const *__libc_argv;
17052a38012Sejakowatz
171752c4971Sejakowatzclass BMenuWindow : public BWindow
172752c4971Sejakowatz{
173752c4971Sejakowatz};
174c7f20c70SIngo Weinhold//------------------------------------------------------------------------------
175c7f20c70SIngo Weinhold
176c7f20c70SIngo Weinhold// debugging
177c7f20c70SIngo Weinhold//#define DBG(x) x
178c7f20c70SIngo Weinhold#define DBG(x)
179c7f20c70SIngo Weinhold#define OUT	printf
180c7f20c70SIngo Weinhold
181c7f20c70SIngo Weinholdenum {
182c7f20c70SIngo Weinhold	NOT_IMPLEMENTED	= B_ERROR,
183c7f20c70SIngo Weinhold};
184c7f20c70SIngo Weinhold
18573a2b29fSIngo Weinhold// prototypes of helper functions
18673a2b29fSIngo Weinholdstatic const char* looper_name_for(const char *signature);
1879986313cSIngo Weinholdstatic status_t check_app_signature(const char *signature);
188c7f20c70SIngo Weinhold
18952a38012Sejakowatz//------------------------------------------------------------------------------
19052a38012SejakowatzBApplication::BApplication(const char* signature)
191c7f20c70SIngo Weinhold			: BLooper(looper_name_for(signature)),
192c7f20c70SIngo Weinhold			  fAppName(NULL),
193c7f20c70SIngo Weinhold			  fServerFrom(-1),
194c7f20c70SIngo Weinhold			  fServerTo(-1),
195c7f20c70SIngo Weinhold			  fServerHeap(NULL),
196c7f20c70SIngo Weinhold			  fPulseRate(500000),
197c7f20c70SIngo Weinhold			  fInitialWorkspace(0),
198c7f20c70SIngo Weinhold			  fDraggedMessage(NULL),
199c7f20c70SIngo Weinhold			  fPulseRunner(NULL),
200c7f20c70SIngo Weinhold			  fInitError(B_NO_INIT),
201c7f20c70SIngo Weinhold			  fReadyToRunCalled(false)
20252a38012Sejakowatz{
203c7f20c70SIngo Weinhold	InitData(signature, NULL);
20452a38012Sejakowatz}
20552a38012Sejakowatz//------------------------------------------------------------------------------
20652a38012SejakowatzBApplication::BApplication(const char* signature, status_t* error)
207c7f20c70SIngo Weinhold			: BLooper(looper_name_for(signature)),
208c7f20c70SIngo Weinhold			  fAppName(NULL),
209c7f20c70SIngo Weinhold			  fServerFrom(-1),
210c7f20c70SIngo Weinhold			  fServerTo(-1),
211c7f20c70SIngo Weinhold			  fServerHeap(NULL),
212c7f20c70SIngo Weinhold			  fPulseRate(500000),
213c7f20c70SIngo Weinhold			  fInitialWorkspace(0),
214c7f20c70SIngo Weinhold			  fDraggedMessage(NULL),
215c7f20c70SIngo Weinhold			  fPulseRunner(NULL),
216c7f20c70SIngo Weinhold			  fInitError(B_NO_INIT),
217c7f20c70SIngo Weinhold			  fReadyToRunCalled(false)
21852a38012Sejakowatz{
219c7f20c70SIngo Weinhold	InitData(signature, error);
22052a38012Sejakowatz}
22152a38012Sejakowatz//------------------------------------------------------------------------------
22252a38012SejakowatzBApplication::~BApplication()
22352a38012Sejakowatz{
224f28a6f70SAdi Oanca	// tell all loopers(usualy windows) to quit. Also, wait for them.
225dc3ebdecSAdi Oanca	BWindow*	window = NULL;
226f28a6f70SAdi Oanca	BList		looperList;
227f28a6f70SAdi Oanca	{
228f28a6f70SAdi Oanca		using namespace BPrivate;
229f28a6f70SAdi Oanca		BObjectLocker<BLooperList> ListLock(gLooperList);
230f28a6f70SAdi Oanca		if (ListLock.IsLocked())
231f28a6f70SAdi Oanca			gLooperList.GetLooperList(&looperList);
232f28a6f70SAdi Oanca	}
233f28a6f70SAdi Oanca
234f28a6f70SAdi Oanca	for (int32 i = 0; i < looperList.CountItems(); i++)
235f28a6f70SAdi Oanca	{
236dc3ebdecSAdi Oanca		window	= dynamic_cast<BWindow*>((BLooper*)looperList.ItemAt(i));
237dc3ebdecSAdi Oanca		if (window)
238f28a6f70SAdi Oanca		{
239dc3ebdecSAdi Oanca			window->Lock();
240dc3ebdecSAdi Oanca			window->Quit();
241f28a6f70SAdi Oanca		}
242f28a6f70SAdi Oanca	}
243f28a6f70SAdi Oanca
244dc3ebdecSAdi Oanca	// unregister from the roster
245dc3ebdecSAdi Oanca	BRoster::Private().RemoveApp(Team());
246dc3ebdecSAdi Oanca
247f28a6f70SAdi Oanca	// tell app_server we're quiting...
248f28a6f70SAdi Oanca	PortLink		link(fServerFrom);
249f28a6f70SAdi Oanca	link.SetOpCode(B_QUIT_REQUESTED);
250f28a6f70SAdi Oanca	link.Flush();
251f28a6f70SAdi Oanca
2528a526591SIngo Weinhold	// uninitialize be_app and be_app_messenger
2538a526591SIngo Weinhold	be_app = NULL;
254ad4fdf8dSIngo Weinhold// R5 doesn't uninitialize be_app_messenger.
255ad4fdf8dSIngo Weinhold//	be_app_messenger = BMessenger();
25652a38012Sejakowatz}
25752a38012Sejakowatz//------------------------------------------------------------------------------
25852a38012SejakowatzBApplication::BApplication(BMessage* data)
259c7f20c70SIngo Weinhold			: BLooper(looper_name_for(NULL)),
260c7f20c70SIngo Weinhold			  fAppName(NULL),
261c7f20c70SIngo Weinhold			  fServerFrom(-1),
262c7f20c70SIngo Weinhold			  fServerTo(-1),
263c7f20c70SIngo Weinhold			  fServerHeap(NULL),
264c7f20c70SIngo Weinhold			  fPulseRate(500000),
265c7f20c70SIngo Weinhold			  fInitialWorkspace(0),
266c7f20c70SIngo Weinhold			  fDraggedMessage(NULL),
267c7f20c70SIngo Weinhold			  fPulseRunner(NULL),
268c7f20c70SIngo Weinhold			  fInitError(B_NO_INIT),
269c7f20c70SIngo Weinhold			  fReadyToRunCalled(false)
27052a38012Sejakowatz{
27152a38012Sejakowatz}
27252a38012Sejakowatz//------------------------------------------------------------------------------
27352a38012SejakowatzBArchivable* BApplication::Instantiate(BMessage* data)
27452a38012Sejakowatz{
27552a38012Sejakowatz	if (!validate_instantiation(data, "BApplication"))
27652a38012Sejakowatz	{
27752a38012Sejakowatz		return NULL;
27852a38012Sejakowatz	}
27952a38012Sejakowatz
28052a38012Sejakowatz	return new BApplication(data);
28152a38012Sejakowatz}
28252a38012Sejakowatz//------------------------------------------------------------------------------
28352a38012Sejakowatzstatus_t BApplication::Archive(BMessage* data, bool deep) const
28452a38012Sejakowatz{
285c7f20c70SIngo Weinhold	return NOT_IMPLEMENTED;
28652a38012Sejakowatz}
28752a38012Sejakowatz//------------------------------------------------------------------------------
28852a38012Sejakowatzstatus_t BApplication::InitCheck() const
28952a38012Sejakowatz{
29052a38012Sejakowatz	return fInitError;
29152a38012Sejakowatz}
29252a38012Sejakowatz//------------------------------------------------------------------------------
29352a38012Sejakowatzthread_id BApplication::Run()
29452a38012Sejakowatz{
295c7f20c70SIngo Weinhold	AssertLocked();
296c7f20c70SIngo Weinhold
297c7f20c70SIngo Weinhold	if (fRunCalled)
298c7f20c70SIngo Weinhold	{
299c7f20c70SIngo Weinhold		// Not allowed to call Run() more than once
300c7f20c70SIngo Weinhold		// TODO: test
301c7f20c70SIngo Weinhold		// find out what message is actually here
302c7f20c70SIngo Weinhold		debugger("");
303c7f20c70SIngo Weinhold	}
304c7f20c70SIngo Weinhold
3059986313cSIngo Weinhold	// Note: We need a local variable too (for the return value), since
3069986313cSIngo Weinhold	// fTaskID is cleared by Quit().
3079986313cSIngo Weinhold	thread_id thread = fTaskID = find_thread(NULL);
308c7f20c70SIngo Weinhold
309c7f20c70SIngo Weinhold	if (fMsgPort == B_NO_MORE_PORTS || fMsgPort == B_BAD_VALUE)
310c7f20c70SIngo Weinhold	{
311c7f20c70SIngo Weinhold		return fMsgPort;
312c7f20c70SIngo Weinhold	}
313c7f20c70SIngo Weinhold
314c7f20c70SIngo Weinhold	fRunCalled = true;
315c7f20c70SIngo Weinhold
316c7f20c70SIngo Weinhold	run_task();
317c7f20c70SIngo Weinhold
3189986313cSIngo Weinhold	return thread;
31952a38012Sejakowatz}
32052a38012Sejakowatz//------------------------------------------------------------------------------
32152a38012Sejakowatzvoid BApplication::Quit()
32252a38012Sejakowatz{
32398207f6fSIngo Weinhold	bool unlock = false;
324c7f20c70SIngo Weinhold	if (!IsLocked()) {
325c7f20c70SIngo Weinhold		const char* name = Name();
326c7f20c70SIngo Weinhold		if (!name)
327c7f20c70SIngo Weinhold			name = "no-name";
32898207f6fSIngo Weinhold		printf("ERROR - you must Lock the application object before calling "
32998207f6fSIngo Weinhold			   "Quit(), team=%ld, looper=%s\n", Team(), name);
33098207f6fSIngo Weinhold		unlock = true;
33198207f6fSIngo Weinhold		if (!Lock())
33298207f6fSIngo Weinhold			return;
333c7f20c70SIngo Weinhold	}
334c7f20c70SIngo Weinhold	// Delete the object, if not running only.
33598207f6fSIngo Weinhold	if (!fRunCalled) {
336c7f20c70SIngo Weinhold		delete this;
33798207f6fSIngo Weinhold	} else if (find_thread(NULL) != fTaskID) {
33898207f6fSIngo Weinhold		// We are not the looper thread.
33998207f6fSIngo Weinhold		// We push a _QUIT_ into the queue.
34098207f6fSIngo Weinhold		// TODO: When BLooper::AddMessage() is done, use that instead of
34198207f6fSIngo Weinhold		// PostMessage()??? This would overtake messages that are still at
34298207f6fSIngo Weinhold		// the port.
34398207f6fSIngo Weinhold		// NOTE: We must not unlock here -- otherwise we had to re-lock, which
34498207f6fSIngo Weinhold		// may not work. This is bad, since, if the port is full, it
34598207f6fSIngo Weinhold		// won't get emptier, as the looper thread needs to lock the object
34698207f6fSIngo Weinhold		// before dispatching messages.
34798207f6fSIngo Weinhold		while (PostMessage(_QUIT_, this) == B_WOULD_BLOCK)
34898207f6fSIngo Weinhold			snooze(10000);
34998207f6fSIngo Weinhold	} else {
35098207f6fSIngo Weinhold		// We are the looper thread.
35198207f6fSIngo Weinhold		// Just set fTerminating to true which makes us fall through the
35298207f6fSIngo Weinhold		// message dispatching loop and return from Run().
35398207f6fSIngo Weinhold		fTerminating = true;
35498207f6fSIngo Weinhold	}
35598207f6fSIngo Weinhold	// If we had to lock the object, unlock now.
35698207f6fSIngo Weinhold	if (unlock)
35798207f6fSIngo Weinhold		Unlock();
35852a38012Sejakowatz}
35952a38012Sejakowatz//------------------------------------------------------------------------------
36052a38012Sejakowatzbool BApplication::QuitRequested()
36152a38012Sejakowatz{
362c7f20c70SIngo Weinhold	// No windows -- nothing to do.
363c7f20c70SIngo Weinhold	return BLooper::QuitRequested();
36452a38012Sejakowatz}
36552a38012Sejakowatz//------------------------------------------------------------------------------
36652a38012Sejakowatzvoid BApplication::Pulse()
36752a38012Sejakowatz{
36852a38012Sejakowatz}
36952a38012Sejakowatz//------------------------------------------------------------------------------
37052a38012Sejakowatzvoid BApplication::ReadyToRun()
37152a38012Sejakowatz{
37252a38012Sejakowatz}
37352a38012Sejakowatz//------------------------------------------------------------------------------
37452a38012Sejakowatzvoid BApplication::MessageReceived(BMessage* msg)
37552a38012Sejakowatz{
376c7f20c70SIngo Weinhold	BLooper::MessageReceived(msg);
37752a38012Sejakowatz}
37852a38012Sejakowatz//------------------------------------------------------------------------------
37952a38012Sejakowatzvoid BApplication::ArgvReceived(int32 argc, char** argv)
38052a38012Sejakowatz{
38152a38012Sejakowatz}
38252a38012Sejakowatz//------------------------------------------------------------------------------
38352a38012Sejakowatzvoid BApplication::AppActivated(bool active)
38452a38012Sejakowatz{
38552a38012Sejakowatz}
38652a38012Sejakowatz//------------------------------------------------------------------------------
38752a38012Sejakowatzvoid BApplication::RefsReceived(BMessage* a_message)
38852a38012Sejakowatz{
38952a38012Sejakowatz}
39052a38012Sejakowatz//------------------------------------------------------------------------------
39152a38012Sejakowatzvoid BApplication::AboutRequested()
39252a38012Sejakowatz{
39353b9eef8SStefano Ceccherini	thread_info info;
39453b9eef8SStefano Ceccherini	if (get_thread_info(Thread(), &info) == B_OK) {
39553b9eef8SStefano Ceccherini		BAlert *alert = new BAlert("_about_", info.name, "OK");
39653b9eef8SStefano Ceccherini		alert->Go(NULL);
39753b9eef8SStefano Ceccherini	}
39852a38012Sejakowatz}
39952a38012Sejakowatz//------------------------------------------------------------------------------
40052a38012SejakowatzBHandler* BApplication::ResolveSpecifier(BMessage* msg, int32 index,
40152a38012Sejakowatz										 BMessage* specifier, int32 form,
40252a38012Sejakowatz										 const char* property)
40352a38012Sejakowatz{
404c7f20c70SIngo Weinhold	return NULL;	// not implemented
40552a38012Sejakowatz}
40652a38012Sejakowatz//------------------------------------------------------------------------------
40752a38012Sejakowatzvoid BApplication::ShowCursor()
40852a38012Sejakowatz{
409582e2dddSDarkWyrm	// Because we're just sending an opcode, we can skip the BSession and fake the protocol
410582e2dddSDarkWyrm	int32 foo=AS_SHOW_CURSOR;
41145799af7SDarkWyrm	write_port(fServerTo,AS_SHOW_CURSOR,&foo,sizeof(int32));
41252a38012Sejakowatz}
41352a38012Sejakowatz//------------------------------------------------------------------------------
41452a38012Sejakowatzvoid BApplication::HideCursor()
41552a38012Sejakowatz{
416582e2dddSDarkWyrm	// Because we're just sending an opcode, we can skip the BSession and fake the protocol
417582e2dddSDarkWyrm	int32 foo=AS_HIDE_CURSOR;
41845799af7SDarkWyrm	write_port(fServerTo,AS_HIDE_CURSOR,&foo,sizeof(int32));
41952a38012Sejakowatz}
42052a38012Sejakowatz//------------------------------------------------------------------------------
42152a38012Sejakowatzvoid BApplication::ObscureCursor()
42252a38012Sejakowatz{
423582e2dddSDarkWyrm	// Because we're just sending an opcode, we can skip the BSession and fake the protocol
424582e2dddSDarkWyrm	int32 foo=AS_OBSCURE_CURSOR;
42545799af7SDarkWyrm	write_port(fServerTo,AS_OBSCURE_CURSOR,&foo,sizeof(int32));
42652a38012Sejakowatz}
42752a38012Sejakowatz//------------------------------------------------------------------------------
42852a38012Sejakowatzbool BApplication::IsCursorHidden() const
42952a38012Sejakowatz{
43045799af7SDarkWyrm	PortMessage msg;
4317c7ee64aSDarkWyrm
432582e2dddSDarkWyrm	BPrivate::BAppServerLink link;
43345799af7SDarkWyrm	link.SetOpCode(AS_QUERY_CURSOR_HIDDEN);
43445799af7SDarkWyrm	link.FlushWithReply(&msg);
43545799af7SDarkWyrm	return (msg.Code()==SERVER_TRUE)?true:false;
43652a38012Sejakowatz}
43752a38012Sejakowatz//------------------------------------------------------------------------------
43852a38012Sejakowatzvoid BApplication::SetCursor(const void* cursor)
43952a38012Sejakowatz{
44052a38012Sejakowatz	// BeBook sez: If you want to call SetCursor() without forcing an immediate
44152a38012Sejakowatz	//				sync of the Application Server, you have to use a BCursor.
44252a38012Sejakowatz	// By deductive reasoning, this function forces a sync. =)
44352a38012Sejakowatz	BCursor Cursor(cursor);
44452a38012Sejakowatz	SetCursor(&Cursor, true);
44552a38012Sejakowatz}
44652a38012Sejakowatz//------------------------------------------------------------------------------
44752a38012Sejakowatzvoid BApplication::SetCursor(const BCursor* cursor, bool sync)
44852a38012Sejakowatz{
449582e2dddSDarkWyrm	BPrivate::BAppServerLink link;
45045799af7SDarkWyrm	PortMessage msg;
45145799af7SDarkWyrm
45245799af7SDarkWyrm	link.SetOpCode(AS_SET_CURSOR_BCURSOR);
45345799af7SDarkWyrm	link.Attach<bool>(sync);
45445799af7SDarkWyrm	link.Attach<int32>(cursor->m_serverToken);
455582e2dddSDarkWyrm	if(sync)
45645799af7SDarkWyrm		link.FlushWithReply(&msg);
45745799af7SDarkWyrm	else
45845799af7SDarkWyrm		link.Flush();
45952a38012Sejakowatz}
46052a38012Sejakowatz//------------------------------------------------------------------------------
46152a38012Sejakowatzint32 BApplication::CountWindows() const
46252a38012Sejakowatz{
46352a38012Sejakowatz	// BeBook sez: The windows list includes all windows explicitely created by
46452a38012Sejakowatz	//				the app ... but excludes private windows create by Be
46552a38012Sejakowatz	//				classes.
46652a38012Sejakowatz	// I'm taking this to include private menu windows, thus the incl_menus
46752a38012Sejakowatz	// param is false.
46852a38012Sejakowatz	return count_windows(false);
46952a38012Sejakowatz}
47052a38012Sejakowatz//------------------------------------------------------------------------------
47152a38012SejakowatzBWindow* BApplication::WindowAt(int32 index) const
47252a38012Sejakowatz{
47352a38012Sejakowatz	// BeBook sez: The windows list includes all windows explicitely created by
47452a38012Sejakowatz	//				the app ... but excludes private windows create by Be
47552a38012Sejakowatz	//				classes.
47652a38012Sejakowatz	// I'm taking this to include private menu windows, thus the incl_menus
47752a38012Sejakowatz	// param is false.
47852a38012Sejakowatz	return window_at(index, false);
47952a38012Sejakowatz}
48052a38012Sejakowatz//------------------------------------------------------------------------------
48152a38012Sejakowatzint32 BApplication::CountLoopers() const
48252a38012Sejakowatz{
483ebbcbbcaSejakowatz	using namespace BPrivate;
484ebbcbbcaSejakowatz	BObjectLocker<BLooperList> ListLock(gLooperList);
485ebbcbbcaSejakowatz	if (ListLock.IsLocked())
486ebbcbbcaSejakowatz	{
487ebbcbbcaSejakowatz		return gLooperList.CountLoopers();
488ebbcbbcaSejakowatz	}
489ebbcbbcaSejakowatz
490ebbcbbcaSejakowatz	return B_ERROR;	// Some bad, non-specific thing has happened
49152a38012Sejakowatz}
49252a38012Sejakowatz//------------------------------------------------------------------------------
49352a38012SejakowatzBLooper* BApplication::LooperAt(int32 index) const
49452a38012Sejakowatz{
495ebbcbbcaSejakowatz	using namespace BPrivate;
496ebbcbbcaSejakowatz	BLooper* Looper = NULL;
497ebbcbbcaSejakowatz	BObjectLocker<BLooperList> ListLock(gLooperList);
498ebbcbbcaSejakowatz	if (ListLock.IsLocked())
499ebbcbbcaSejakowatz	{
500ebbcbbcaSejakowatz		Looper = gLooperList.LooperAt(index);
501ebbcbbcaSejakowatz	}
502ebbcbbcaSejakowatz
503ebbcbbcaSejakowatz	return Looper;
50452a38012Sejakowatz}
50552a38012Sejakowatz//------------------------------------------------------------------------------
50652a38012Sejakowatzbool BApplication::IsLaunching() const
50752a38012Sejakowatz{
50852a38012Sejakowatz	return !fReadyToRunCalled;
50952a38012Sejakowatz}
51052a38012Sejakowatz//------------------------------------------------------------------------------
51152a38012Sejakowatzstatus_t BApplication::GetAppInfo(app_info* info) const
51252a38012Sejakowatz{
51352a38012Sejakowatz	return be_roster->GetRunningAppInfo(be_app->Team(), info);
51452a38012Sejakowatz}
51552a38012Sejakowatz//------------------------------------------------------------------------------
51652a38012SejakowatzBResources* BApplication::AppResources()
51752a38012Sejakowatz{
518c7f20c70SIngo Weinhold	return NULL;	// not implemented
51952a38012Sejakowatz}
52052a38012Sejakowatz//------------------------------------------------------------------------------
52173a2b29fSIngo Weinholdvoid BApplication::DispatchMessage(BMessage* message, BHandler* handler)
52273a2b29fSIngo Weinhold{
52373a2b29fSIngo Weinhold	switch (message->what) {
52473a2b29fSIngo Weinhold		case B_ARGV_RECEIVED:
52573a2b29fSIngo Weinhold		{
52673a2b29fSIngo Weinhold			// build the argv vector
52773a2b29fSIngo Weinhold			status_t error = B_OK;
52873a2b29fSIngo Weinhold			int32 argc;
52973a2b29fSIngo Weinhold			char **argv = NULL;
53073a2b29fSIngo Weinhold			if (message->FindInt32("argc", &argc) == B_OK && argc > 0) {
53173a2b29fSIngo Weinhold				argv = new char*[argc];
53273a2b29fSIngo Weinhold				for (int32 i = 0; error == B_OK && i < argc; i++)
53373a2b29fSIngo Weinhold					argv[i] = NULL;
53473a2b29fSIngo Weinhold				// copy the arguments
53573a2b29fSIngo Weinhold				for (int32 i = 0; error == B_OK && i < argc; i++) {
53673a2b29fSIngo Weinhold					const char *arg = NULL;
53773a2b29fSIngo Weinhold					error = message->FindString("argv", i, &arg);
53873a2b29fSIngo Weinhold					if (error == B_OK && arg) {
53917e6de7aSshadow						argv[i] = new(std::nothrow) char[strlen(arg) + 1];
54073a2b29fSIngo Weinhold						if (argv[i])
54173a2b29fSIngo Weinhold							strcpy(argv[i], arg);
54273a2b29fSIngo Weinhold						else
54373a2b29fSIngo Weinhold							error = B_NO_MEMORY;
54473a2b29fSIngo Weinhold					}
54573a2b29fSIngo Weinhold				}
54673a2b29fSIngo Weinhold			}
54773a2b29fSIngo Weinhold			// call the hook
54873a2b29fSIngo Weinhold			if (error == B_OK)
54973a2b29fSIngo Weinhold				ArgvReceived(argc, argv);
55073a2b29fSIngo Weinhold			// cleanup
55173a2b29fSIngo Weinhold			if (argv) {
55273a2b29fSIngo Weinhold				for (int32 i = 0; i < argc; i++)
55373a2b29fSIngo Weinhold					delete[] argv[i];
55473a2b29fSIngo Weinhold				delete[] argv;
55573a2b29fSIngo Weinhold			}
55673a2b29fSIngo Weinhold			break;
55773a2b29fSIngo Weinhold		}
55873a2b29fSIngo Weinhold		case B_REFS_RECEIVED:
55973a2b29fSIngo Weinhold			RefsReceived(message);
56073a2b29fSIngo Weinhold			break;
56173a2b29fSIngo Weinhold		case B_READY_TO_RUN:
56273a2b29fSIngo Weinhold			// TODO: Find out, whether to set fReadyToRunCalled before or
56373a2b29fSIngo Weinhold			// after calling the hook.
56473a2b29fSIngo Weinhold			ReadyToRun();
56573a2b29fSIngo Weinhold			fReadyToRunCalled = true;
56673a2b29fSIngo Weinhold			break;
56773a2b29fSIngo Weinhold		default:
56873a2b29fSIngo Weinhold			BLooper::DispatchMessage(message, handler);
56973a2b29fSIngo Weinhold			break;
57073a2b29fSIngo Weinhold	}
57152a38012Sejakowatz}
57252a38012Sejakowatz//------------------------------------------------------------------------------
57352a38012Sejakowatzvoid BApplication::SetPulseRate(bigtime_t rate)
57452a38012Sejakowatz{
57552a38012Sejakowatz	fPulseRate = rate;
57652a38012Sejakowatz}
57752a38012Sejakowatz//------------------------------------------------------------------------------
57852a38012Sejakowatzstatus_t BApplication::GetSupportedSuites(BMessage* data)
57952a38012Sejakowatz{
580ad4fdf8dSIngo Weinhold	status_t err = B_OK;
5812284462cSejakowatz	if (!data)
5822284462cSejakowatz	{
5832284462cSejakowatz		err = B_BAD_VALUE;
5842284462cSejakowatz	}
5852284462cSejakowatz
5862284462cSejakowatz	if (!err)
5872284462cSejakowatz	{
5882284462cSejakowatz		err = data->AddString("Suites", "suite/vnd.Be-application");
5892284462cSejakowatz		if (!err)
5902284462cSejakowatz		{
5912284462cSejakowatz			BPropertyInfo PropertyInfo(gApplicationPropInfo);
5922284462cSejakowatz			err = data->AddFlat("message", &PropertyInfo);
5932284462cSejakowatz			if (!err)
5942284462cSejakowatz			{
5952284462cSejakowatz				err = BHandler::GetSupportedSuites(data);
5962284462cSejakowatz			}
5972284462cSejakowatz		}
5982284462cSejakowatz	}
5992284462cSejakowatz
6002284462cSejakowatz	return err;
60152a38012Sejakowatz}
60252a38012Sejakowatz//------------------------------------------------------------------------------
60352a38012Sejakowatzstatus_t BApplication::Perform(perform_code d, void* arg)
60452a38012Sejakowatz{
605c7f20c70SIngo Weinhold	return NOT_IMPLEMENTED;
60652a38012Sejakowatz}
60752a38012Sejakowatz//------------------------------------------------------------------------------
60852a38012SejakowatzBApplication::BApplication(uint32 signature)
60952a38012Sejakowatz{
61052a38012Sejakowatz}
61152a38012Sejakowatz//------------------------------------------------------------------------------
61252a38012SejakowatzBApplication::BApplication(const BApplication& rhs)
61352a38012Sejakowatz{
61452a38012Sejakowatz}
61552a38012Sejakowatz//------------------------------------------------------------------------------
61652a38012SejakowatzBApplication& BApplication::operator=(const BApplication& rhs)
61752a38012Sejakowatz{
618c7f20c70SIngo Weinhold	return *this;
61952a38012Sejakowatz}
62052a38012Sejakowatz//------------------------------------------------------------------------------
62152a38012Sejakowatzvoid BApplication::_ReservedApplication1()
62252a38012Sejakowatz{
62352a38012Sejakowatz}
62452a38012Sejakowatz//------------------------------------------------------------------------------
62552a38012Sejakowatzvoid BApplication::_ReservedApplication2()
62652a38012Sejakowatz{
62752a38012Sejakowatz}
62852a38012Sejakowatz//------------------------------------------------------------------------------
62952a38012Sejakowatzvoid BApplication::_ReservedApplication3()
63052a38012Sejakowatz{
63152a38012Sejakowatz}
63252a38012Sejakowatz//------------------------------------------------------------------------------
63352a38012Sejakowatzvoid BApplication::_ReservedApplication4()
63452a38012Sejakowatz{
63552a38012Sejakowatz}
63652a38012Sejakowatz//------------------------------------------------------------------------------
63752a38012Sejakowatzvoid BApplication::_ReservedApplication5()
63852a38012Sejakowatz{
63952a38012Sejakowatz}
64052a38012Sejakowatz//------------------------------------------------------------------------------
64152a38012Sejakowatzvoid BApplication::_ReservedApplication6()
64252a38012Sejakowatz{
64352a38012Sejakowatz}
64452a38012Sejakowatz//------------------------------------------------------------------------------
64552a38012Sejakowatzvoid BApplication::_ReservedApplication7()
64652a38012Sejakowatz{
64752a38012Sejakowatz}
64852a38012Sejakowatz//------------------------------------------------------------------------------
64952a38012Sejakowatzvoid BApplication::_ReservedApplication8()
65052a38012Sejakowatz{
65152a38012Sejakowatz}
65252a38012Sejakowatz//------------------------------------------------------------------------------
65352a38012Sejakowatzbool BApplication::ScriptReceived(BMessage* msg, int32 index, BMessage* specifier, int32 form, const char* property)
65452a38012Sejakowatz{
655c7f20c70SIngo Weinhold	return false;	// not implemented
65652a38012Sejakowatz}
65752a38012Sejakowatz//------------------------------------------------------------------------------
65852a38012Sejakowatzvoid BApplication::run_task()
65952a38012Sejakowatz{
660c7f20c70SIngo Weinhold	task_looper();
66152a38012Sejakowatz}
66252a38012Sejakowatz//------------------------------------------------------------------------------
66352a38012Sejakowatzvoid BApplication::InitData(const char* signature, status_t* error)
66452a38012Sejakowatz{
6658a526591SIngo Weinhold	// check whether there exists already an application
6668a526591SIngo Weinhold	if (be_app)
6678a526591SIngo Weinhold		debugger("2 BApplication objects were created. Only one is allowed.");
668c7f20c70SIngo Weinhold	// check signature
6699986313cSIngo Weinhold	fInitError = check_app_signature(signature);
670c7f20c70SIngo Weinhold	fAppName = signature;
67136aeb57dSIngo Weinhold	bool isRegistrar
67236aeb57dSIngo Weinhold		= (signature && !strcasecmp(signature, kRegistrarSignature));
67373a2b29fSIngo Weinhold	// get team and thread
67473a2b29fSIngo Weinhold	team_id team = Team();
675121f83ddSIngo Weinhold	thread_id thread = BPrivate::main_thread_for(team);
67673a2b29fSIngo Weinhold	// get app executable ref
67773a2b29fSIngo Weinhold	entry_ref ref;
6789986313cSIngo Weinhold	if (fInitError == B_OK)
679121f83ddSIngo Weinhold		fInitError = BPrivate::get_app_ref(&ref);
68073a2b29fSIngo Weinhold	// get the BAppFileInfo and extract the information we need
68173a2b29fSIngo Weinhold	uint32 appFlags = B_REG_DEFAULT_APP_FLAGS;
68273a2b29fSIngo Weinhold	if (fInitError == B_OK) {
68373a2b29fSIngo Weinhold		BAppFileInfo fileInfo;
68473a2b29fSIngo Weinhold		BFile file(&ref, B_READ_ONLY);
68573a2b29fSIngo Weinhold		fInitError = fileInfo.SetTo(&file);
68673a2b29fSIngo Weinhold		if (fInitError == B_OK) {
68773a2b29fSIngo Weinhold			fileInfo.GetAppFlags(&appFlags);
68873a2b29fSIngo Weinhold			char appFileSignature[B_MIME_TYPE_LENGTH + 1];
68973a2b29fSIngo Weinhold			// compare the file signature and the supplied signature
69073a2b29fSIngo Weinhold			if (fileInfo.GetSignature(appFileSignature) == B_OK) {
69136aeb57dSIngo Weinhold				if (strcasecmp(appFileSignature, signature) != 0) {
69273a2b29fSIngo Weinhold					printf("Signature in rsrc doesn't match constructor arg. "
69373a2b29fSIngo Weinhold						   "(%s,%s)\n", signature, appFileSignature);
69473a2b29fSIngo Weinhold				}
69573a2b29fSIngo Weinhold			}
69673a2b29fSIngo Weinhold		}
69773a2b29fSIngo Weinhold	}
698ca34e8a0SDarkWyrm#ifndef RUN_WITHOUT_REGISTRAR
6999231d6b0SIngo Weinhold	// check whether be_roster is valid
7002ed834e3SIngo Weinhold	if (fInitError == B_OK && !isRegistrar
7012ed834e3SIngo Weinhold		&& !BRoster::Private().IsMessengerValid(false)) {
70269b461cdSIngo Weinhold		printf("FATAL: be_roster is not valid. Is the registrar running?\n");
7039231d6b0SIngo Weinhold		fInitError = B_NO_INIT;
7049231d6b0SIngo Weinhold	}
705ca34e8a0SDarkWyrm
70673a2b29fSIngo Weinhold	// check whether or not we are pre-registered
70773a2b29fSIngo Weinhold	bool preRegistered = false;
70873a2b29fSIngo Weinhold	app_info appInfo;
7092ed834e3SIngo Weinhold	if (fInitError == B_OK && !isRegistrar) {
7102ed834e3SIngo Weinhold		preRegistered = BRoster::Private().IsAppPreRegistered(&ref, team,
7112ed834e3SIngo Weinhold															  &appInfo);
7122ed834e3SIngo Weinhold	}
71373a2b29fSIngo Weinhold	if (preRegistered) {
71473a2b29fSIngo Weinhold		// we are pre-registered => the app info has been filled in
71573a2b29fSIngo Weinhold		// Check whether we need to replace the looper port with a port
71673a2b29fSIngo Weinhold		// created by the roster.
71773a2b29fSIngo Weinhold		if (appInfo.port >= 0 && appInfo.port != fMsgPort) {
71873a2b29fSIngo Weinhold			delete_port(fMsgPort);
71973a2b29fSIngo Weinhold			fMsgPort = appInfo.port;
72073a2b29fSIngo Weinhold		} else
72173a2b29fSIngo Weinhold			appInfo.port = fMsgPort;
722d8c0f6e4SIngo Weinhold		// check the signature and correct it, if necessary
72336aeb57dSIngo Weinhold		if (strcasecmp(appInfo.signature, fAppName))
7242ed834e3SIngo Weinhold			BRoster::Private().SetSignature(team, fAppName);
72573a2b29fSIngo Weinhold		// complete the registration
7262ed834e3SIngo Weinhold		fInitError = BRoster::Private().CompleteRegistration(team, thread,
7272ed834e3SIngo Weinhold															 appInfo.port);
72873a2b29fSIngo Weinhold	} else if (fInitError == B_OK) {
72973a2b29fSIngo Weinhold		// not pre-registered -- try to register the application
73073a2b29fSIngo Weinhold		team_id otherTeam = -1;
73173a2b29fSIngo Weinhold		// the registrar must not register
73273a2b29fSIngo Weinhold		if (!isRegistrar) {
7332ed834e3SIngo Weinhold			fInitError = BRoster::Private().AddApplication(signature, &ref,
7342ed834e3SIngo Weinhold				appFlags, team, thread, fMsgPort, true, NULL, &otherTeam);
73573a2b29fSIngo Weinhold		}
7369986313cSIngo Weinhold		if (fInitError == B_ALREADY_RUNNING) {
73773a2b29fSIngo Weinhold			// An instance is already running and we asked for
7389986313cSIngo Weinhold			// single/exclusive launch. Send our argv to the running app.
7399986313cSIngo Weinhold			// Do that only, if the app is NOT B_ARGV_ONLY.
7409986313cSIngo Weinhold			if (otherTeam >= 0 && __libc_argc > 1) {
74173a2b29fSIngo Weinhold				app_info otherAppInfo;
74273a2b29fSIngo Weinhold				if (be_roster->GetRunningAppInfo(otherTeam, &otherAppInfo)
7439986313cSIngo Weinhold					== B_OK && !(otherAppInfo.flags & B_ARGV_ONLY)) {
7449986313cSIngo Weinhold					// create an B_ARGV_RECEIVED message
7459986313cSIngo Weinhold					BMessage argvMessage(B_ARGV_RECEIVED);
7469986313cSIngo Weinhold					do_argv(&argvMessage);
7479986313cSIngo Weinhold					// replace the first argv string with the path of the
7489986313cSIngo Weinhold					// other application
74973a2b29fSIngo Weinhold					BPath path;
75073a2b29fSIngo Weinhold					if (path.SetTo(&otherAppInfo.ref) == B_OK)
75173a2b29fSIngo Weinhold						argvMessage.ReplaceString("argv", 0, path.Path());
7529986313cSIngo Weinhold					// send the message
7539986313cSIngo Weinhold					BMessenger(NULL, otherTeam).SendMessage(&argvMessage);
75473a2b29fSIngo Weinhold				}
75573a2b29fSIngo Weinhold			}
7569986313cSIngo Weinhold		} else if (fInitError == B_OK) {
75773a2b29fSIngo Weinhold			// the registrations was successful
75873a2b29fSIngo Weinhold			// Create a B_ARGV_RECEIVED message and send it to ourselves.
7599986313cSIngo Weinhold			// Do that even, if we are B_ARGV_ONLY.
76073a2b29fSIngo Weinhold			// TODO: When BLooper::AddMessage() is done, use that instead of
76173a2b29fSIngo Weinhold			// PostMessage().
7629986313cSIngo Weinhold			if (__libc_argc > 1) {
76373a2b29fSIngo Weinhold				BMessage argvMessage(B_ARGV_RECEIVED);
76473a2b29fSIngo Weinhold				do_argv(&argvMessage);
76573a2b29fSIngo Weinhold				PostMessage(&argvMessage, this);
76673a2b29fSIngo Weinhold			}
76773a2b29fSIngo Weinhold			// send a B_READY_TO_RUN message as well
76873a2b29fSIngo Weinhold			PostMessage(B_READY_TO_RUN, this);
7699986313cSIngo Weinhold		} else if (fInitError > B_ERRORS_END) {
7709986313cSIngo Weinhold			// Registrar internal errors shouldn't fall into the user's hands.
7719986313cSIngo Weinhold			fInitError = B_ERROR;
7729986313cSIngo Weinhold		}
77373a2b29fSIngo Weinhold	}
774ca34e8a0SDarkWyrm#endif	// ifdef RUN_WITHOUT_REGISTRAR
775ca34e8a0SDarkWyrm
77653b9eef8SStefano Ceccherini	// TODO: Not sure about the order
77753b9eef8SStefano Ceccherini	if (fInitError == B_OK)
77853b9eef8SStefano Ceccherini		connect_to_app_server();
77953b9eef8SStefano Ceccherini	if (fInitError == B_OK)
78053b9eef8SStefano Ceccherini		setup_server_heaps();
78153b9eef8SStefano Ceccherini	if (fInitError == B_OK)
78253b9eef8SStefano Ceccherini		get_scs();
78353b9eef8SStefano Ceccherini	if (fInitError == B_OK)
78453b9eef8SStefano Ceccherini		fInitError = _init_interface_kit_();
78553b9eef8SStefano Ceccherini
7868a526591SIngo Weinhold	// init be_app and be_app_messenger
7878a526591SIngo Weinhold	if (fInitError == B_OK) {
7888a526591SIngo Weinhold		be_app = this;
7893057c103SIngo Weinhold		be_app_messenger = BMessenger(NULL, this);
7908a526591SIngo Weinhold	}
7914a87ab98SIngo Weinhold	// set the BHandler's name
7924a87ab98SIngo Weinhold	if (fInitError == B_OK)
7934a87ab98SIngo Weinhold		SetName(ref.name);
794ad4fdf8dSIngo Weinhold	// create meta MIME
795ad4fdf8dSIngo Weinhold	if (fInitError == B_OK) {
796ad4fdf8dSIngo Weinhold		BPath path;
797ad4fdf8dSIngo Weinhold		if (path.SetTo(&ref) == B_OK)
798ad4fdf8dSIngo Weinhold			create_app_meta_mime(path.Path(), false, true, false);
799ad4fdf8dSIngo Weinhold	}
8009986313cSIngo Weinhold	// Return the error or exit, if there was an error and no error variable
8019986313cSIngo Weinhold	// has been supplied.
802c7f20c70SIngo Weinhold	if (error)
803c7f20c70SIngo Weinhold		*error = fInitError;
8049986313cSIngo Weinhold	else if (fInitError != B_OK)
8059986313cSIngo Weinhold		exit(0);
80652a38012Sejakowatz}
80752a38012Sejakowatz//------------------------------------------------------------------------------
80852a38012Sejakowatzvoid BApplication::BeginRectTracking(BRect r, bool trackWhole)
80952a38012Sejakowatz{
810582e2dddSDarkWyrm	BPrivate::BAppServerLink link;
81145799af7SDarkWyrm	link.Attach<int32>(AS_BEGIN_RECT_TRACKING);
81245799af7SDarkWyrm	link.Attach<BRect>(r);
81345799af7SDarkWyrm	link.Attach<int32>(trackWhole);
81445799af7SDarkWyrm	link.Flush();
81552a38012Sejakowatz}
81652a38012Sejakowatz//------------------------------------------------------------------------------
81752a38012Sejakowatzvoid BApplication::EndRectTracking()
81852a38012Sejakowatz{
819582e2dddSDarkWyrm	int32 foo=AS_END_RECT_TRACKING;
82045799af7SDarkWyrm	write_port(fServerTo,AS_END_RECT_TRACKING,&foo,sizeof(int32));
82152a38012Sejakowatz}
82252a38012Sejakowatz//------------------------------------------------------------------------------
82352a38012Sejakowatzvoid BApplication::get_scs()
82452a38012Sejakowatz{
82553b9eef8SStefano Ceccherini	//gPrivateScreen = new BPrivateScreen();
82652a38012Sejakowatz}
82752a38012Sejakowatz//------------------------------------------------------------------------------
82852a38012Sejakowatzvoid BApplication::setup_server_heaps()
82952a38012Sejakowatz{
83052a38012Sejakowatz}
83152a38012Sejakowatz//------------------------------------------------------------------------------
83252a38012Sejakowatzvoid* BApplication::rw_offs_to_ptr(uint32 offset)
83352a38012Sejakowatz{
834c7f20c70SIngo Weinhold	return NULL;	// not implemented
83552a38012Sejakowatz}
83652a38012Sejakowatz//------------------------------------------------------------------------------
83752a38012Sejakowatzvoid* BApplication::ro_offs_to_ptr(uint32 offset)
83852a38012Sejakowatz{
839c7f20c70SIngo Weinhold	return NULL;	// not implemented
84052a38012Sejakowatz}
84152a38012Sejakowatz//------------------------------------------------------------------------------
84252a38012Sejakowatzvoid* BApplication::global_ro_offs_to_ptr(uint32 offset)
84352a38012Sejakowatz{
844c7f20c70SIngo Weinhold	return NULL;	// not implemented
84552a38012Sejakowatz}
84652a38012Sejakowatz//------------------------------------------------------------------------------
84752a38012Sejakowatzvoid BApplication::connect_to_app_server()
84852a38012Sejakowatz{
84953b9eef8SStefano Ceccherini	fServerFrom = find_port(SERVER_PORT_NAME);
85053b9eef8SStefano Ceccherini	if (fServerFrom > 0) {
85153b9eef8SStefano Ceccherini		// Create the port so that the app_server knows where to send messages
85253b9eef8SStefano Ceccherini		fServerTo = create_port(100, "a<fServerTo");
85353b9eef8SStefano Ceccherini		if (fServerTo > 0) {
85453b9eef8SStefano Ceccherini			// AS_CREATE_APP:
85553b9eef8SStefano Ceccherini
85653b9eef8SStefano Ceccherini			// Attach data:
85753b9eef8SStefano Ceccherini			// 1) port_id - receiver port of a regular app
858f28a6f70SAdi Oanca			// 2) port_id - looper port for this BApplication
859f28a6f70SAdi Oanca			// 3) team_id - team identification field
860f28a6f70SAdi Oanca			// 4) int32 - handler ID token of the app
861f28a6f70SAdi Oanca			// 5) char * - signature of the regular app
86253b9eef8SStefano Ceccherini			PortLink link(fServerFrom);
86353b9eef8SStefano Ceccherini			PortMessage pmsg;
86453b9eef8SStefano Ceccherini
86553b9eef8SStefano Ceccherini			link.SetOpCode(AS_CREATE_APP);
86653b9eef8SStefano Ceccherini			link.Attach<port_id>(fServerTo);
867f28a6f70SAdi Oanca			link.Attach<port_id>(_get_looper_port_(this));
868f28a6f70SAdi Oanca			link.Attach<team_id>(Team());
869f28a6f70SAdi Oanca			link.Attach<int32>(_get_object_token_(this));
87053b9eef8SStefano Ceccherini			link.AttachString(fAppName);
87153b9eef8SStefano Ceccherini			link.FlushWithReply(&pmsg);
87253b9eef8SStefano Ceccherini
87353b9eef8SStefano Ceccherini			// Reply code: AS_CREATE_APP
87453b9eef8SStefano Ceccherini			// Reply data:
87553b9eef8SStefano Ceccherini			//	1) port_id server-side application port (fServerFrom value)
87653b9eef8SStefano Ceccherini			pmsg.Read<port_id>(&fServerFrom);
87753b9eef8SStefano Ceccherini		}
87853b9eef8SStefano Ceccherini		else
87953b9eef8SStefano Ceccherini			fInitError = fServerTo;
88053b9eef8SStefano Ceccherini	} else
88153b9eef8SStefano Ceccherini		fInitError = fServerFrom;
88252a38012Sejakowatz}
88352a38012Sejakowatz//------------------------------------------------------------------------------
88452a38012Sejakowatzvoid BApplication::send_drag(BMessage* msg, int32 vs_token, BPoint offset, BRect drag_rect, BHandler* reply_to)
88552a38012Sejakowatz{
88652a38012Sejakowatz}
88752a38012Sejakowatz//------------------------------------------------------------------------------
88852a38012Sejakowatzvoid BApplication::send_drag(BMessage* msg, int32 vs_token, BPoint offset, int32 bitmap_token, drawing_mode dragMode, BHandler* reply_to)
88952a38012Sejakowatz{
89052a38012Sejakowatz}
89152a38012Sejakowatz//------------------------------------------------------------------------------
89252a38012Sejakowatzvoid BApplication::write_drag(_BSession_* session, BMessage* a_message)
89352a38012Sejakowatz{
89452a38012Sejakowatz}
89552a38012Sejakowatz//------------------------------------------------------------------------------
89652a38012Sejakowatzbool BApplication::quit_all_windows(bool force)
89752a38012Sejakowatz{
898c7f20c70SIngo Weinhold	return false;	// not implemented
89952a38012Sejakowatz}
90052a38012Sejakowatz//------------------------------------------------------------------------------
90152a38012Sejakowatzbool BApplication::window_quit_loop(bool, bool)
90252a38012Sejakowatz{
903c7f20c70SIngo Weinhold	return false;	// not implemented
90452a38012Sejakowatz}
90552a38012Sejakowatz//------------------------------------------------------------------------------
90673a2b29fSIngo Weinholdvoid BApplication::do_argv(BMessage* message)
90773a2b29fSIngo Weinhold{
90873a2b29fSIngo Weinhold	if (message) {
90973a2b29fSIngo Weinhold		int32 argc = __libc_argc;
91073a2b29fSIngo Weinhold		const char * const *argv = __libc_argv;
91173a2b29fSIngo Weinhold		// add argc
91273a2b29fSIngo Weinhold		message->AddInt32("argc", argc);
91373a2b29fSIngo Weinhold		// add argv
91473a2b29fSIngo Weinhold		for (int32 i = 0; i < argc; i++)
91573a2b29fSIngo Weinhold			message->AddString("argv", argv[i]);
91673a2b29fSIngo Weinhold		// add current working directory
91773a2b29fSIngo Weinhold		char cwd[B_PATH_NAME_LENGTH + 1];
91873a2b29fSIngo Weinhold		if (getcwd(cwd, B_PATH_NAME_LENGTH + 1))
91973a2b29fSIngo Weinhold			message->AddString("cwd", cwd);
92073a2b29fSIngo Weinhold	}
92152a38012Sejakowatz}
92252a38012Sejakowatz//------------------------------------------------------------------------------
92352a38012Sejakowatzuint32 BApplication::InitialWorkspace()
92452a38012Sejakowatz{
925c7f20c70SIngo Weinhold	return 0;	// not implemented
92652a38012Sejakowatz}
92752a38012Sejakowatz//------------------------------------------------------------------------------
92852a38012Sejakowatzint32 BApplication::count_windows(bool incl_menus) const
92952a38012Sejakowatz{
930ebbcbbcaSejakowatz	using namespace BPrivate;
931ebbcbbcaSejakowatz
932ebbcbbcaSejakowatz	// Windows are BLoopers, so we can just check each BLooper to see if it's
933ebbcbbcaSejakowatz	// a BWindow (or BMenuWindow)
934ebbcbbcaSejakowatz	int32 count = 0;
935ebbcbbcaSejakowatz	BObjectLocker<BLooperList> ListLock(gLooperList);
936ebbcbbcaSejakowatz	if (ListLock.IsLocked())
937ebbcbbcaSejakowatz	{
938ebbcbbcaSejakowatz		BLooper* Looper = NULL;
939ebbcbbcaSejakowatz		for (int32 i = 0; i < gLooperList.CountLoopers(); ++i)
940ebbcbbcaSejakowatz		{
941ebbcbbcaSejakowatz			Looper = gLooperList.LooperAt(i);
942ebbcbbcaSejakowatz			if (dynamic_cast<BWindow*>(Looper))
943ebbcbbcaSejakowatz			{
944<