A stripped down to the bare minimum app_server, so that we no longer need
to compile our libbe.so with RUN_WIHTOUT_APP_SERVER for the image. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12190 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
79757df990
commit
a350a0f58e
@ -1,3 +1,4 @@
|
|||||||
SubDir OBOS_TOP src tests apps ;
|
SubDir OBOS_TOP src tests apps ;
|
||||||
|
|
||||||
SubInclude OBOS_TOP src tests apps miniterminal ;
|
SubInclude OBOS_TOP src tests apps miniterminal ;
|
||||||
|
SubInclude OBOS_TOP src tests apps fake_app_server ;
|
||||||
|
358
src/tests/apps/fake_app_server/AppServer.cpp
Normal file
358
src/tests/apps/fake_app_server/AppServer.cpp
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2001-2005, Haiku, Inc.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// File Name: AppServer.cpp
|
||||||
|
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||||
|
// Description: main manager object for the app_server
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
#include <AppDefs.h>
|
||||||
|
#include <Accelerant.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <Directory.h>
|
||||||
|
#include <PortLink.h>
|
||||||
|
|
||||||
|
#include <File.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include "AppServer.h"
|
||||||
|
#include "ServerProtocol.h"
|
||||||
|
#include "ServerApp.h"
|
||||||
|
#include <TokenSpace.h>
|
||||||
|
#if 0
|
||||||
|
#include "ColorSet.h"
|
||||||
|
#include "DisplayDriver.h"
|
||||||
|
#include "ServerCursor.h"
|
||||||
|
#include "ServerWindow.h"
|
||||||
|
#include "DefaultDecorator.h"
|
||||||
|
#include "RGBColor.h"
|
||||||
|
#include "BitmapManager.h"
|
||||||
|
#include "CursorManager.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "FontServer.h"
|
||||||
|
#include "Desktop.h"
|
||||||
|
#include "RootLayer.h"
|
||||||
|
#endif
|
||||||
|
#include <StopWatch.h>
|
||||||
|
|
||||||
|
#ifdef DEBUG_KEYHANDLING
|
||||||
|
# include <stdio.h>
|
||||||
|
# define KBTRACE(x) printf x
|
||||||
|
#else
|
||||||
|
# define KBTRACE(x) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#define DEBUG_SERVER
|
||||||
|
#ifdef DEBUG_SERVER
|
||||||
|
# define DEBUG 1
|
||||||
|
# include <Debug.h>
|
||||||
|
# define STRACE(x) _sPrintf x
|
||||||
|
#else
|
||||||
|
# define STRACE(x) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Globals
|
||||||
|
|
||||||
|
AppServer::AppServer(void)
|
||||||
|
{
|
||||||
|
fMessagePort = create_port(200, SERVER_PORT_NAME);
|
||||||
|
|
||||||
|
fAppList = new BList(0);
|
||||||
|
fQuittingServer= false;
|
||||||
|
|
||||||
|
// This is necessary to mediate access between the Poller and app_server threads
|
||||||
|
fActiveAppLock= create_sem(1,"app_server_active_sem");
|
||||||
|
|
||||||
|
// This locker is for app_server and Picasso to vy for control of the ServerApp list
|
||||||
|
fAppListLock= create_sem(1,"app_server_applist_sem");
|
||||||
|
|
||||||
|
// Spawn our thread-monitoring thread
|
||||||
|
fPicassoThreadID= spawn_thread(PicassoThread,"picasso", B_NORMAL_PRIORITY, this);
|
||||||
|
if (fPicassoThreadID >= 0)
|
||||||
|
resume_thread(fPicassoThreadID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AppServer::~AppServer(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
AppServer::PicassoThread(void *data)
|
||||||
|
{
|
||||||
|
int32 i;
|
||||||
|
AppServer *appserver=(AppServer*)data;
|
||||||
|
ServerApp *app;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
#if 1
|
||||||
|
acquire_sem(appserver->fAppListLock);
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
app=(ServerApp*)appserver->fAppList->ItemAt(i++);
|
||||||
|
if(!app)
|
||||||
|
break;
|
||||||
|
|
||||||
|
app->PingTarget();
|
||||||
|
}
|
||||||
|
release_sem(appserver->fAppListLock);
|
||||||
|
#endif
|
||||||
|
// we do this every other second so as not to suck *too* many CPU cycles
|
||||||
|
snooze(1000000);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
thread_id
|
||||||
|
AppServer::Run(void)
|
||||||
|
{
|
||||||
|
MainLoop();
|
||||||
|
kill_thread(fPicassoThreadID);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Main message-monitoring loop for the regular message port - no input messages!
|
||||||
|
void
|
||||||
|
AppServer::MainLoop(void)
|
||||||
|
{
|
||||||
|
BPortLink pmsg(-1,fMessagePort);
|
||||||
|
int32 code=0;
|
||||||
|
status_t err=B_OK;
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
STRACE(("info: AppServer::MainLoop listening on port %ld.\n", fMessagePort));
|
||||||
|
err=pmsg.GetNextReply(&code);
|
||||||
|
|
||||||
|
if(err<B_OK)
|
||||||
|
{
|
||||||
|
STRACE(("MainLoop:pmsg.GetNextReply failed\n"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(code)
|
||||||
|
{
|
||||||
|
case B_QUIT_REQUESTED:
|
||||||
|
case AS_CREATE_APP:
|
||||||
|
case AS_DELETE_APP:
|
||||||
|
case AS_GET_SCREEN_MODE:
|
||||||
|
case AS_UPDATED_CLIENT_FONTLIST:
|
||||||
|
case AS_QUERY_FONTS_CHANGED:
|
||||||
|
case AS_SET_UI_COLORS:
|
||||||
|
case AS_GET_UI_COLOR:
|
||||||
|
case AS_SET_DECORATOR:
|
||||||
|
case AS_GET_DECORATOR:
|
||||||
|
case AS_R5_SET_DECORATOR:
|
||||||
|
DispatchMessage(code,pmsg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
STRACE(("Server::MainLoop received unexpected code %ld(offset %ld)\n",
|
||||||
|
code,code-SERVER_TRUE));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AppServer::DispatchMessage(int32 code, BPortLink &msg)
|
||||||
|
{
|
||||||
|
switch(code)
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
case AS_CREATE_APP:
|
||||||
|
{
|
||||||
|
// Create the ServerApp to node monitor a new BApplication
|
||||||
|
|
||||||
|
// Attached data:
|
||||||
|
// 1) port_id - receiver port of a regular app
|
||||||
|
// 2) port_id - client looper port - for send messages to the client
|
||||||
|
// 2) team_id - app's team ID
|
||||||
|
// 3) int32 - handler token of the regular app
|
||||||
|
// 4) char * - signature of the regular app
|
||||||
|
|
||||||
|
// Find the necessary data
|
||||||
|
team_id clientTeamID=-1;
|
||||||
|
port_id clientLooperPort=-1;
|
||||||
|
port_id app_port=-1;
|
||||||
|
int32 htoken=B_NULL_TOKEN;
|
||||||
|
char *app_signature=NULL;
|
||||||
|
|
||||||
|
msg.Read<port_id>(&app_port);
|
||||||
|
msg.Read<port_id>(&clientLooperPort);
|
||||||
|
msg.Read<team_id>(&clientTeamID);
|
||||||
|
msg.Read<int32>(&htoken);
|
||||||
|
msg.ReadString(&app_signature);
|
||||||
|
|
||||||
|
// Create the ServerApp subthread for this app
|
||||||
|
acquire_sem(fAppListLock);
|
||||||
|
|
||||||
|
port_id server_listen=create_port(DEFAULT_MONITOR_PORT_SIZE, app_signature);
|
||||||
|
if(server_listen<B_OK)
|
||||||
|
{
|
||||||
|
release_sem(fAppListLock);
|
||||||
|
printf("No more ports left. Time to crash. Have a nice day! :)\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ServerApp *newapp=NULL;
|
||||||
|
newapp= new ServerApp(app_port,server_listen, clientLooperPort, clientTeamID,
|
||||||
|
htoken, app_signature);
|
||||||
|
|
||||||
|
// add the new ServerApp to the known list of ServerApps
|
||||||
|
fAppList->AddItem(newapp);
|
||||||
|
|
||||||
|
release_sem(fAppListLock);
|
||||||
|
|
||||||
|
BPortLink replylink(app_port);
|
||||||
|
replylink.StartMessage(SERVER_TRUE);
|
||||||
|
replylink.Attach<int32>(newapp->fMessagePort);
|
||||||
|
replylink.Flush();
|
||||||
|
|
||||||
|
// This is necessary because BPortLink::ReadString allocates memory
|
||||||
|
if(app_signature)
|
||||||
|
free(app_signature);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AS_DELETE_APP:
|
||||||
|
{
|
||||||
|
// Delete a ServerApp. Received only from the respective ServerApp when a
|
||||||
|
// BApplication asks it to quit.
|
||||||
|
|
||||||
|
// Attached Data:
|
||||||
|
// 1) thread_id - thread ID of the ServerApp to be deleted
|
||||||
|
|
||||||
|
int32 i=0,
|
||||||
|
appnum=fAppList->CountItems();
|
||||||
|
|
||||||
|
ServerApp *srvapp=NULL;
|
||||||
|
thread_id srvapp_id=-1;
|
||||||
|
|
||||||
|
if(msg.Read<thread_id>(&srvapp_id)<B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
acquire_sem(fAppListLock);
|
||||||
|
|
||||||
|
// Run through the list of apps and nuke the proper one
|
||||||
|
for(i= 0; i < appnum; i++)
|
||||||
|
{
|
||||||
|
srvapp=(ServerApp *)fAppList->ItemAt(i);
|
||||||
|
|
||||||
|
if(srvapp != NULL && srvapp->fMonitorThreadID== srvapp_id)
|
||||||
|
{
|
||||||
|
srvapp=(ServerApp *)fAppList->RemoveItem(i);
|
||||||
|
if(srvapp)
|
||||||
|
{
|
||||||
|
status_t temp;
|
||||||
|
wait_for_thread(srvapp_id, &temp);
|
||||||
|
delete srvapp;
|
||||||
|
srvapp= NULL;
|
||||||
|
}
|
||||||
|
break; // jump out of our for() loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
release_sem(fAppListLock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
case AS_QUERY_FONTS_CHANGED:
|
||||||
|
{
|
||||||
|
// Seeing how the client merely wants an answer, we'll skip the BPortLink
|
||||||
|
// and all its overhead and just write the code to port.
|
||||||
|
port_id replyport;
|
||||||
|
if (msg.Read<port_id>(&replyport) < B_OK)
|
||||||
|
break;
|
||||||
|
BPortLink replylink(replyport);
|
||||||
|
replylink.StartMessage(SERVER_FALSE);
|
||||||
|
replylink.Flush();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AS_GET_DECORATOR:
|
||||||
|
{
|
||||||
|
// Attached Data:
|
||||||
|
// 1) port_id reply port
|
||||||
|
|
||||||
|
port_id replyport=-1;
|
||||||
|
if(msg.Read<port_id>(&replyport)<B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BPortLink replylink(replyport);
|
||||||
|
replylink.StartMessage(AS_GET_DECORATOR);
|
||||||
|
replylink.AttachString("none");
|
||||||
|
replylink.Flush();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AS_GET_SCREEN_MODE:
|
||||||
|
{
|
||||||
|
// Synchronous message call to get the stats on the current screen mode
|
||||||
|
// in the app_server. Simply a hack in place for the Input Server until
|
||||||
|
// BScreens are done.
|
||||||
|
|
||||||
|
// Attached Data:
|
||||||
|
// 1) port_id - port to reply to
|
||||||
|
|
||||||
|
// Returned Data:
|
||||||
|
// 1) int32 width
|
||||||
|
// 2) int32 height
|
||||||
|
// 3) int depth
|
||||||
|
|
||||||
|
display_mode dmode;
|
||||||
|
|
||||||
|
port_id replyport=-1;
|
||||||
|
if(msg.Read<port_id>(&replyport)<B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
BPortLink replylink(replyport);
|
||||||
|
replylink.StartMessage(AS_GET_SCREEN_MODE);
|
||||||
|
replylink.Attach<display_mode>(dmode);
|
||||||
|
replylink.Flush();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case AS_UPDATED_CLIENT_FONTLIST:
|
||||||
|
case AS_SET_UI_COLORS:
|
||||||
|
case AS_SET_DECORATOR:
|
||||||
|
case AS_R5_SET_DECORATOR:
|
||||||
|
case AS_SET_SYSCURSOR_DEFAULTS:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
// There can be only one....
|
||||||
|
if (find_port(SERVER_PORT_NAME) != B_NAME_NOT_FOUND)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
AppServer app_server;
|
||||||
|
app_server.Run();
|
||||||
|
return 0;
|
||||||
|
}
|
46
src/tests/apps/fake_app_server/AppServer.h
Normal file
46
src/tests/apps/fake_app_server/AppServer.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef _OPENBEOS_APP_SERVER_H_
|
||||||
|
#define _OPENBEOS_APP_SERVER_H_
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
#include <Locker.h>
|
||||||
|
#include <List.h>
|
||||||
|
#include <Application.h>
|
||||||
|
#include <Window.h>
|
||||||
|
#include <String.h>
|
||||||
|
#include "Decorator.h"
|
||||||
|
#include "ServerConfig.h"
|
||||||
|
|
||||||
|
class Layer;
|
||||||
|
class BMessage;
|
||||||
|
class ServerApp;
|
||||||
|
class DisplayDriver;
|
||||||
|
class BPortLink;
|
||||||
|
class CursorManager;
|
||||||
|
class BitmapManager;
|
||||||
|
|
||||||
|
class AppServer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AppServer(void);
|
||||||
|
~AppServer(void);
|
||||||
|
|
||||||
|
static int32 PollerThread(void *data);
|
||||||
|
static int32 PicassoThread(void *data);
|
||||||
|
thread_id Run(void);
|
||||||
|
void MainLoop(void);
|
||||||
|
|
||||||
|
void DispatchMessage(int32 code, BPortLink &link);
|
||||||
|
|
||||||
|
private:
|
||||||
|
port_id fMessagePort;
|
||||||
|
bool fQuittingServer;
|
||||||
|
|
||||||
|
BList *fAppList;
|
||||||
|
thread_id fPicassoThreadID;
|
||||||
|
|
||||||
|
sem_id fActiveAppLock, fAppListLock;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern AppServer *app_server;
|
||||||
|
|
||||||
|
#endif
|
854
src/tests/apps/fake_app_server/BGet++.cpp
Normal file
854
src/tests/apps/fake_app_server/BGet++.cpp
Normal file
@ -0,0 +1,854 @@
|
|||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2001-2002, Haiku, Inc.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// File Name: bget++.cpp
|
||||||
|
// Author: John Walker <kelvin@fourmilab.ch>
|
||||||
|
// DarkWyrm <bpmagic@columbus.rr.com>
|
||||||
|
// Description: public domain BGET pool allocator converted to C++
|
||||||
|
// Distributed with Haiku under MIT license
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This class is based on the BGET pool allocator. Original code was in standard
|
||||||
|
ANSI C with a bunch of static variables. The original code was placed into the
|
||||||
|
MemPool class and the original allocation, release, and compacting functions
|
||||||
|
were made into virtual members. MemPool also, unlike the original code, makes
|
||||||
|
use of malloc() and free() to handle dynamic memory needs. AreaPool is a MemPool
|
||||||
|
subclass which uses areas to handle memory management needs in large chunks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Buffer allocation size quantum: all buffers allocated are a multiple of this size. '
|
||||||
|
// This MUST be a power of two.
|
||||||
|
#define SizeQuant 4
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <OS.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
// Declare the interface, including the requested buffer size type, ssize_t.
|
||||||
|
#include "BGet++.h"
|
||||||
|
|
||||||
|
// Queue links
|
||||||
|
struct qlinks
|
||||||
|
{
|
||||||
|
struct bfhead *flink; // Forward link
|
||||||
|
struct bfhead *blink; // Backward link
|
||||||
|
};
|
||||||
|
|
||||||
|
// Header in allocated and free buffers
|
||||||
|
struct bhead
|
||||||
|
{
|
||||||
|
// Relative link back to previous free buffer in memory or 0 if previous
|
||||||
|
// buffer is allocated.
|
||||||
|
ssize_t prevfree;
|
||||||
|
|
||||||
|
// Buffer size: positive if free, negative if allocated.
|
||||||
|
ssize_t bsize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BH(p) ((struct bhead *) (p))
|
||||||
|
|
||||||
|
// Header in directly allocated buffers (by acqfcn)
|
||||||
|
struct bdhead
|
||||||
|
{
|
||||||
|
ssize_t tsize; // Total size, including overhead
|
||||||
|
struct bhead bh; // Common header
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BDH(p) ((struct bdhead *) (p))
|
||||||
|
|
||||||
|
// Header in free buffers
|
||||||
|
struct bfhead
|
||||||
|
{
|
||||||
|
// Common allocated/free header
|
||||||
|
struct bhead bh;
|
||||||
|
|
||||||
|
// Links on free list
|
||||||
|
struct qlinks ql;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BFH(p) ((struct bfhead *) (p))
|
||||||
|
|
||||||
|
static struct bfhead freelist =
|
||||||
|
{
|
||||||
|
// List of free buffers
|
||||||
|
{0, 0},
|
||||||
|
{&freelist, &freelist}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Minimum allocation quantum:
|
||||||
|
#define QLSize (sizeof(struct qlinks))
|
||||||
|
#define SizeQ ((SizeQuant > QLSize) ? SizeQuant : QLSize)
|
||||||
|
|
||||||
|
// End sentinel: value placed in bsize field of dummy block delimiting end of
|
||||||
|
// pool block. The most negative number which will fit in a ssize_t,
|
||||||
|
// defined in a way that the compiler will accept.
|
||||||
|
#define ESent ((ssize_t) (-(((1L << (sizeof(ssize_t) * 8 - 2)) - 1) * 2) - 2))
|
||||||
|
|
||||||
|
|
||||||
|
MemPool::MemPool(void)
|
||||||
|
: totalloc(0),
|
||||||
|
numget(0),
|
||||||
|
numrel(0),
|
||||||
|
numpblk(0),
|
||||||
|
numpget(0),
|
||||||
|
numprel(0),
|
||||||
|
numdget(0),
|
||||||
|
numdrel(0),
|
||||||
|
exp_incr(0),
|
||||||
|
pool_len(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MemPool::~MemPool(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate a buffer from the available space in the memory pool
|
||||||
|
void *MemPool::GetBuffer(ssize_t requested_size, bool zero)
|
||||||
|
{
|
||||||
|
ssize_t size = requested_size;
|
||||||
|
struct bfhead *b;
|
||||||
|
|
||||||
|
struct bfhead *best;
|
||||||
|
void *buf;
|
||||||
|
|
||||||
|
int compactseq = 0;
|
||||||
|
|
||||||
|
assert(size > 0);
|
||||||
|
|
||||||
|
if (size < (ssize_t)SizeQ)
|
||||||
|
{
|
||||||
|
// Need at least room for the queue links.
|
||||||
|
size = SizeQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SizeQuant > 1
|
||||||
|
size = (size + (SizeQuant - 1)) & (~(SizeQuant - 1));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Add overhead in allocated buffer to size required.
|
||||||
|
size += sizeof(struct bhead);
|
||||||
|
|
||||||
|
// If a compact function was provided in the call to bectl(), wrap
|
||||||
|
// a loop around the allocation process to allow compaction to
|
||||||
|
// intervene in case we don't find a suitable buffer in the chain.
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
b = freelist.ql.flink;
|
||||||
|
best = &freelist;
|
||||||
|
|
||||||
|
|
||||||
|
// Scan the free list searching for the first buffer big enough
|
||||||
|
// to hold the requested size buffer.
|
||||||
|
|
||||||
|
while (b != &freelist)
|
||||||
|
{
|
||||||
|
if (b->bh.bsize >= size)
|
||||||
|
{
|
||||||
|
if ((best == &freelist) || (b->bh.bsize < best->bh.bsize))
|
||||||
|
{
|
||||||
|
best = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b = b->ql.flink; // Link to next buffer
|
||||||
|
}
|
||||||
|
b = best;
|
||||||
|
|
||||||
|
while (b != &freelist)
|
||||||
|
{
|
||||||
|
if ((ssize_t) b->bh.bsize >= size)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Buffer is big enough to satisfy the request. Allocate it to the caller.
|
||||||
|
// We must decide whether the buffer is large enough to split into the part
|
||||||
|
// given to the caller and a free buffer that remains on the free list, or
|
||||||
|
// whether the entire buffer should be removed from the free list and given
|
||||||
|
// to the caller in its entirety. We only split the buffer if enough room
|
||||||
|
// remains for a header plus the minimum quantum of allocation.
|
||||||
|
|
||||||
|
if ((b->bh.bsize - size) > (ssize_t)(SizeQ + (sizeof(struct bhead))))
|
||||||
|
{
|
||||||
|
struct bhead *ba, *bn;
|
||||||
|
|
||||||
|
ba = BH(((char *) b) + (b->bh.bsize - size));
|
||||||
|
bn = BH(((char *) ba) + size);
|
||||||
|
assert(bn->prevfree == b->bh.bsize);
|
||||||
|
|
||||||
|
// Subtract size from length of free block.
|
||||||
|
b->bh.bsize -= size;
|
||||||
|
|
||||||
|
// Link allocated buffer to the previous free buffer.
|
||||||
|
ba->prevfree = b->bh.bsize;
|
||||||
|
|
||||||
|
// Plug negative size into user buffer.
|
||||||
|
ba->bsize = -(ssize_t) size;
|
||||||
|
|
||||||
|
// Mark buffer after this one not preceded by free block.
|
||||||
|
bn->prevfree = 0;
|
||||||
|
|
||||||
|
totalloc += size;
|
||||||
|
numget++; // Increment number of GetBuffer() calls
|
||||||
|
|
||||||
|
buf = (void *) ((((char *) ba) + sizeof(struct bhead)));
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct bhead *ba;
|
||||||
|
|
||||||
|
ba = BH(((char *) b) + b->bh.bsize);
|
||||||
|
assert(ba->prevfree == b->bh.bsize);
|
||||||
|
|
||||||
|
// The buffer isn't big enough to split. Give the whole
|
||||||
|
// shebang to the caller and remove it from the free list.
|
||||||
|
|
||||||
|
assert(b->ql.blink->ql.flink == b);
|
||||||
|
assert(b->ql.flink->ql.blink == b);
|
||||||
|
b->ql.blink->ql.flink = b->ql.flink;
|
||||||
|
b->ql.flink->ql.blink = b->ql.blink;
|
||||||
|
|
||||||
|
totalloc += b->bh.bsize;
|
||||||
|
numget++; // Increment number of GetBuffer() calls
|
||||||
|
|
||||||
|
// Negate size to mark buffer allocated.
|
||||||
|
b->bh.bsize = -(b->bh.bsize);
|
||||||
|
|
||||||
|
// Zero the back pointer in the next buffer in memory
|
||||||
|
// to indicate that this buffer is allocated.
|
||||||
|
ba->prevfree = 0;
|
||||||
|
|
||||||
|
// Give user buffer starting at queue links.
|
||||||
|
buf = (void *) &(b->ql);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b = b->ql.flink; // Link to next buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// We failed to find a buffer. If there's a compact function
|
||||||
|
// defined, notify it of the size requested. If it returns
|
||||||
|
// TRUE, try the allocation again.
|
||||||
|
|
||||||
|
if(!CompactMem(size, ++compactseq))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No buffer available with requested size free.
|
||||||
|
|
||||||
|
// Don't give up yet -- look in the reserve supply.
|
||||||
|
if (size > (ssize_t)(exp_incr - sizeof(struct bhead)))
|
||||||
|
{
|
||||||
|
// Request is too large to fit in a single expansion
|
||||||
|
// block. Try to satisy it by a direct buffer acquisition.
|
||||||
|
struct bdhead *bdh;
|
||||||
|
|
||||||
|
size += sizeof(struct bdhead) - sizeof(struct bhead);
|
||||||
|
if ((bdh = BDH(AcquireMem((ssize_t) size))) != NULL)
|
||||||
|
{
|
||||||
|
// Mark the buffer special by setting the size field
|
||||||
|
// of its header to zero.
|
||||||
|
bdh->bh.bsize = 0;
|
||||||
|
bdh->bh.prevfree = 0;
|
||||||
|
bdh->tsize = size;
|
||||||
|
|
||||||
|
totalloc += size;
|
||||||
|
|
||||||
|
// Increment number of GetBuffer() calls
|
||||||
|
numget++;
|
||||||
|
|
||||||
|
// Direct GetBuffer() call count
|
||||||
|
numdget++;
|
||||||
|
|
||||||
|
buf = (void *) (bdh + 1);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
// Try to obtain a new expansion block
|
||||||
|
void *newpool;
|
||||||
|
|
||||||
|
if ((newpool = AcquireMem((ssize_t) exp_incr)) != NULL)
|
||||||
|
{
|
||||||
|
AddToPool(newpool, exp_incr);
|
||||||
|
|
||||||
|
// This can't, I say, can't get into a loop
|
||||||
|
buf = GetBuffer(requested_size);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Still no buffer available
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Code from bgetz -- zeroing code
|
||||||
|
/*
|
||||||
|
char *buf = (char *) GetBuffer(size);
|
||||||
|
|
||||||
|
if (buf != NULL)
|
||||||
|
{
|
||||||
|
struct bhead *b;
|
||||||
|
ssize_t rsize;
|
||||||
|
|
||||||
|
b = BH(buf - sizeof(struct bhead));
|
||||||
|
rsize = -(b->bsize);
|
||||||
|
|
||||||
|
if (rsize == 0)
|
||||||
|
{
|
||||||
|
struct bdhead *bd;
|
||||||
|
|
||||||
|
bd = BDH(buf - sizeof(struct bdhead));
|
||||||
|
rsize = bd->tsize - sizeof(struct bdhead);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rsize -= sizeof(struct bhead);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(rsize >= size);
|
||||||
|
memset(buf, 0, (MemSize) rsize);
|
||||||
|
}
|
||||||
|
return ((void *) buf);
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reallocate a buffer. This is a minimal implementation, simply in terms
|
||||||
|
// of ReleaseBuffer() and GetBuffer(). It could be enhanced to allow the
|
||||||
|
// buffer to grow into adjacent free blocks and to avoid moving data unnecessarily.
|
||||||
|
void *MemPool::ReallocateBuffer(void *buf, ssize_t size)
|
||||||
|
{
|
||||||
|
void *nbuf;
|
||||||
|
|
||||||
|
// Old size of buffer
|
||||||
|
ssize_t osize;
|
||||||
|
struct bhead *b;
|
||||||
|
|
||||||
|
if ((nbuf = GetBuffer(size)) == NULL)
|
||||||
|
{
|
||||||
|
// Acquire new buffer
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf == NULL)
|
||||||
|
{
|
||||||
|
return nbuf;
|
||||||
|
}
|
||||||
|
b = BH(((char *) buf) - sizeof(struct bhead));
|
||||||
|
osize = -b->bsize;
|
||||||
|
|
||||||
|
if (osize == 0)
|
||||||
|
{
|
||||||
|
// Buffer acquired directly through acqfcn.
|
||||||
|
struct bdhead *bd;
|
||||||
|
|
||||||
|
bd = BDH(((char *) buf) - sizeof(struct bdhead));
|
||||||
|
osize = bd->tsize - sizeof(struct bdhead);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
osize -= sizeof(struct bhead);
|
||||||
|
assert(osize > 0);
|
||||||
|
|
||||||
|
// Copy the data
|
||||||
|
memcpy((char *) nbuf, (char *) buf, (int) ((size < osize) ? size : osize));
|
||||||
|
ReleaseBuffer(buf);
|
||||||
|
return nbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BREL -- Release a buffer.
|
||||||
|
void MemPool::ReleaseBuffer(void *buf)
|
||||||
|
{
|
||||||
|
struct bfhead *b, *bn;
|
||||||
|
|
||||||
|
b = BFH(((char *) buf) - sizeof(struct bhead));
|
||||||
|
|
||||||
|
// Increment number of ReleaseBuffer() calls
|
||||||
|
numrel++;
|
||||||
|
|
||||||
|
assert(buf != NULL);
|
||||||
|
|
||||||
|
// Directly-acquired buffer?
|
||||||
|
if (b->bh.bsize == 0)
|
||||||
|
{
|
||||||
|
struct bdhead *bdh;
|
||||||
|
|
||||||
|
bdh = BDH(((char *) buf) - sizeof(struct bdhead));
|
||||||
|
assert(b->bh.prevfree == 0);
|
||||||
|
|
||||||
|
totalloc -= bdh->tsize;
|
||||||
|
assert(totalloc >= 0);
|
||||||
|
|
||||||
|
// Number of direct releases
|
||||||
|
numdrel++;
|
||||||
|
|
||||||
|
memset((char *) buf, 0x55, (int) (bdh->tsize - sizeof(struct bdhead)));
|
||||||
|
|
||||||
|
// Release it directly.
|
||||||
|
ReleaseMem((void *) bdh);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Buffer size must be negative, indicating that the buffer is allocated.
|
||||||
|
if (b->bh.bsize >= 0)
|
||||||
|
{
|
||||||
|
bn = NULL;
|
||||||
|
}
|
||||||
|
assert(b->bh.bsize < 0);
|
||||||
|
|
||||||
|
// Back pointer in next buffer must be zero, indicating the same thing:
|
||||||
|
assert(BH((char *) b - b->bh.bsize)->prevfree == 0);
|
||||||
|
|
||||||
|
totalloc += b->bh.bsize;
|
||||||
|
assert(totalloc >= 0);
|
||||||
|
|
||||||
|
|
||||||
|
// If the back link is nonzero, the previous buffer is free.
|
||||||
|
|
||||||
|
if (b->bh.prevfree != 0)
|
||||||
|
{
|
||||||
|
// The previous buffer is free. Consolidate this buffer with it
|
||||||
|
// by adding the length of this buffer to the previous free
|
||||||
|
// buffer. Note that we subtract the size in the buffer being
|
||||||
|
// released, since it's negative to indicate that the buffer is allocated.
|
||||||
|
|
||||||
|
register ssize_t size = b->bh.bsize;
|
||||||
|
|
||||||
|
// Make the previous buffer the one we're working on.
|
||||||
|
assert(BH((char *) b - b->bh.prevfree)->bsize == b->bh.prevfree);
|
||||||
|
b = BFH(((char *) b) - b->bh.prevfree);
|
||||||
|
b->bh.bsize -= size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The previous buffer isn't allocated. Insert this buffer on the
|
||||||
|
// free list as an isolated free block.
|
||||||
|
assert(freelist.ql.blink->ql.flink == &freelist);
|
||||||
|
assert(freelist.ql.flink->ql.blink == &freelist);
|
||||||
|
b->ql.flink = &freelist;
|
||||||
|
b->ql.blink = freelist.ql.blink;
|
||||||
|
freelist.ql.blink = b;
|
||||||
|
b->ql.blink->ql.flink = b;
|
||||||
|
b->bh.bsize = -b->bh.bsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we look at the next buffer in memory, located by advancing from
|
||||||
|
// the start of this buffer by its size, to see if that buffer is
|
||||||
|
// free. If it is, we combine this buffer with the next one in
|
||||||
|
// memory, dechaining the second buffer from the free list.
|
||||||
|
|
||||||
|
bn = BFH(((char *) b) + b->bh.bsize);
|
||||||
|
if (bn->bh.bsize > 0)
|
||||||
|
{
|
||||||
|
// The buffer is free. Remove it from the free list and add
|
||||||
|
// its size to that of our buffer.
|
||||||
|
assert(BH((char *) bn + bn->bh.bsize)->prevfree == bn->bh.bsize);
|
||||||
|
assert(bn->ql.blink->ql.flink == bn);
|
||||||
|
assert(bn->ql.flink->ql.blink == bn);
|
||||||
|
bn->ql.blink->ql.flink = bn->ql.flink;
|
||||||
|
bn->ql.flink->ql.blink = bn->ql.blink;
|
||||||
|
b->bh.bsize += bn->bh.bsize;
|
||||||
|
|
||||||
|
// Finally, advance to the buffer that follows the newly
|
||||||
|
// consolidated free block. We must set its backpointer to the
|
||||||
|
// head of the consolidated free block. We know the next block
|
||||||
|
// must be an allocated block because the process of recombination
|
||||||
|
// guarantees that two free blocks will never be contiguous in
|
||||||
|
// memory.
|
||||||
|
bn = BFH(((char *) b) + b->bh.bsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(((char *) b) + sizeof(struct bfhead), 0x55,(int) (b->bh.bsize - sizeof(struct bfhead)));
|
||||||
|
|
||||||
|
assert(bn->bh.bsize < 0);
|
||||||
|
|
||||||
|
// The next buffer is allocated. Set the backpointer in it to point
|
||||||
|
// to this buffer; the previous free buffer in memory.
|
||||||
|
bn->bh.prevfree = b->bh.bsize;
|
||||||
|
|
||||||
|
// If a block-release function is defined, and this free buffer
|
||||||
|
// constitutes the entire block, release it. Note that pool_len
|
||||||
|
// is defined in such a way that the test will fail unless all
|
||||||
|
// pool blocks are the same size.
|
||||||
|
|
||||||
|
if (((ssize_t) b->bh.bsize) == (ssize_t)(pool_len - sizeof(struct bhead)))
|
||||||
|
{
|
||||||
|
assert(b->bh.prevfree == 0);
|
||||||
|
assert(BH((char *) b + b->bh.bsize)->bsize == ESent);
|
||||||
|
assert(BH((char *) b + b->bh.bsize)->prevfree == b->bh.bsize);
|
||||||
|
|
||||||
|
// Unlink the buffer from the free list
|
||||||
|
b->ql.blink->ql.flink = b->ql.flink;
|
||||||
|
b->ql.flink->ql.blink = b->ql.blink;
|
||||||
|
|
||||||
|
ReleaseMem(b);
|
||||||
|
|
||||||
|
// Nr of expansion block releases
|
||||||
|
numprel++;
|
||||||
|
|
||||||
|
// Total number of blocks
|
||||||
|
numpblk--;
|
||||||
|
assert(numpblk == numpget - numprel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a region of memory to the buffer pool.
|
||||||
|
void MemPool::AddToPool(void *buf, ssize_t len)
|
||||||
|
{
|
||||||
|
struct bfhead *b = BFH(buf);
|
||||||
|
struct bhead *bn;
|
||||||
|
|
||||||
|
len &= ~(SizeQuant - 1);
|
||||||
|
|
||||||
|
if (pool_len == 0)
|
||||||
|
{
|
||||||
|
pool_len = len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (len != pool_len)
|
||||||
|
{
|
||||||
|
pool_len = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number of block acquisitions
|
||||||
|
numpget++;
|
||||||
|
|
||||||
|
// Number of blocks total
|
||||||
|
numpblk++;
|
||||||
|
assert(numpblk == numpget - numprel);
|
||||||
|
|
||||||
|
// Since the block is initially occupied by a single free buffer,
|
||||||
|
// it had better not be (much) larger than the largest buffer
|
||||||
|
// whose size we can store in bhead.bsize.
|
||||||
|
assert(len - sizeof(struct bhead) <= -((ssize_t) ESent + 1));
|
||||||
|
|
||||||
|
// Clear the backpointer at the start of the block to indicate that
|
||||||
|
// there is no free block prior to this one. That blocks
|
||||||
|
// recombination when the first block in memory is released.
|
||||||
|
b->bh.prevfree = 0;
|
||||||
|
|
||||||
|
// Chain the new block to the free list.
|
||||||
|
assert(freelist.ql.blink->ql.flink == &freelist);
|
||||||
|
assert(freelist.ql.flink->ql.blink == &freelist);
|
||||||
|
b->ql.flink = &freelist;
|
||||||
|
b->ql.blink = freelist.ql.blink;
|
||||||
|
freelist.ql.blink = b;
|
||||||
|
b->ql.blink->ql.flink = b;
|
||||||
|
|
||||||
|
// Create a dummy allocated buffer at the end of the pool. This dummy
|
||||||
|
// buffer is seen when a buffer at the end of the pool is released and
|
||||||
|
// blocks recombination of the last buffer with the dummy buffer at
|
||||||
|
// the end. The length in the dummy buffer is set to the largest
|
||||||
|
// negative number to denote the end of the pool for diagnostic
|
||||||
|
// routines (this specific value is not counted on by the actual
|
||||||
|
// allocation and release functions).
|
||||||
|
|
||||||
|
len -= sizeof(struct bhead);
|
||||||
|
b->bh.bsize = (ssize_t) len;
|
||||||
|
|
||||||
|
memset(((char *) b) + sizeof(struct bfhead), 0x55,(int) (len - sizeof(struct bfhead)));
|
||||||
|
|
||||||
|
bn = BH(((char *) b) + len);
|
||||||
|
bn->prevfree = (ssize_t) len;
|
||||||
|
|
||||||
|
// Definition of ESent assumes two's complement!
|
||||||
|
assert((~0) == -1);
|
||||||
|
bn->bsize = ESent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Return buffer allocation free space statistics.
|
||||||
|
void MemPool::Stats(ssize_t *curalloc, ssize_t *totfree, ssize_t *maxfree,
|
||||||
|
long *nget, long *nrel)
|
||||||
|
{
|
||||||
|
struct bfhead *b = freelist.ql.flink;
|
||||||
|
|
||||||
|
*nget = numget;
|
||||||
|
*nrel = numrel;
|
||||||
|
*curalloc = totalloc;
|
||||||
|
*totfree = 0;
|
||||||
|
*maxfree = -1;
|
||||||
|
while (b != &freelist)
|
||||||
|
{
|
||||||
|
assert(b->bh.bsize > 0);
|
||||||
|
*totfree += b->bh.bsize;
|
||||||
|
if (b->bh.bsize > *maxfree)
|
||||||
|
{
|
||||||
|
*maxfree = b->bh.bsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Link to next buffer
|
||||||
|
b = b->ql.flink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Return extended statistics
|
||||||
|
void MemPool::ExtendedStats(ssize_t *pool_incr, long *npool, long *npget, long *nprel,
|
||||||
|
long *ndget, long *ndrel)
|
||||||
|
{
|
||||||
|
*pool_incr = (pool_len < 0) ? -exp_incr : exp_incr;
|
||||||
|
*npool = numpblk;
|
||||||
|
*npget = numpget;
|
||||||
|
*nprel = numprel;
|
||||||
|
*ndget = numdget;
|
||||||
|
*ndrel = numdrel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Dump the data in a buffer. This is called with the user data pointer,
|
||||||
|
// and backs up to the buffer header. It will dump either a free block
|
||||||
|
// or an allocated one.
|
||||||
|
void MemPool::BufferDump(void *buf)
|
||||||
|
{
|
||||||
|
struct bfhead *b;
|
||||||
|
unsigned char *bdump;
|
||||||
|
ssize_t bdlen;
|
||||||
|
|
||||||
|
b = BFH(((char *) buf) - sizeof(struct bhead));
|
||||||
|
assert(b->bh.bsize != 0);
|
||||||
|
if (b->bh.bsize < 0)
|
||||||
|
{
|
||||||
|
bdump = (unsigned char *) buf;
|
||||||
|
bdlen = (-b->bh.bsize) - sizeof(struct bhead);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bdump = (unsigned char *) (((char *) b) + sizeof(struct bfhead));
|
||||||
|
bdlen = b->bh.bsize - sizeof(struct bfhead);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (bdlen > 0)
|
||||||
|
{
|
||||||
|
int i, dupes = 0;
|
||||||
|
ssize_t l = bdlen;
|
||||||
|
char bhex[50], bascii[20];
|
||||||
|
|
||||||
|
if (l > 16)
|
||||||
|
{
|
||||||
|
l = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < l; i++)
|
||||||
|
{
|
||||||
|
sprintf(bhex + i * 3, "%02X ", bdump[i]);
|
||||||
|
bascii[i] = isprint(bdump[i]) ? bdump[i] : ' ';
|
||||||
|
}
|
||||||
|
bascii[i] = 0;
|
||||||
|
printf("%-48s %s\n", bhex, bascii);
|
||||||
|
bdump += l;
|
||||||
|
bdlen -= l;
|
||||||
|
while ((bdlen > 16) && (memcmp((char *) (bdump - 16),(char *) bdump, 16) == 0))
|
||||||
|
{
|
||||||
|
dupes++;
|
||||||
|
bdump += 16;
|
||||||
|
bdlen -= 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dupes > 1)
|
||||||
|
{
|
||||||
|
printf(" (%d lines [%d bytes] identical to above line skipped)\n",
|
||||||
|
dupes, dupes * 16);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dupes == 1)
|
||||||
|
{
|
||||||
|
bdump -= 16;
|
||||||
|
bdlen += 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump a buffer pool. The buffer headers are always listed. If DUMPALLOC is
|
||||||
|
// nonzero, the contents of allocated buffers are dumped. If DUMPFREE is
|
||||||
|
// nonzero, free blocks are dumped as well. If FreeWipe checking is enabled,
|
||||||
|
// free blocks which have been clobbered will always be dumped.
|
||||||
|
void MemPool::PoolDump(void *buf, bool dumpalloc, bool dumpfree)
|
||||||
|
{
|
||||||
|
struct bfhead *b = BFH(buf);
|
||||||
|
|
||||||
|
while (b->bh.bsize != ESent)
|
||||||
|
{
|
||||||
|
ssize_t bs = b->bh.bsize;
|
||||||
|
|
||||||
|
if (bs < 0)
|
||||||
|
{
|
||||||
|
bs = -bs;
|
||||||
|
printf("Allocated buffer: size %6ld bytes.\n", (long) bs);
|
||||||
|
if (dumpalloc)
|
||||||
|
{
|
||||||
|
BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *lerr = "";
|
||||||
|
|
||||||
|
assert(bs > 0);
|
||||||
|
if ((b->ql.blink->ql.flink != b) || (b->ql.flink->ql.blink != b))
|
||||||
|
{
|
||||||
|
lerr = " (Bad free list links)";
|
||||||
|
}
|
||||||
|
printf("Free block: size %6ld bytes.%s\n",
|
||||||
|
(long) bs, lerr);
|
||||||
|
|
||||||
|
lerr = ((char *) b) + sizeof(struct bfhead);
|
||||||
|
if ((bs > (ssize_t)sizeof(struct bfhead)) && ((*lerr != 0x55) ||
|
||||||
|
(memcmp(lerr, lerr + 1, (int) (bs - (sizeof(struct bfhead) + 1))) != 0)))
|
||||||
|
{
|
||||||
|
printf("(Contents of above free block have been overstored.)\n");
|
||||||
|
BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dumpfree)
|
||||||
|
{
|
||||||
|
BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b = BFH(((char *) b) + bs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate a buffer pool.
|
||||||
|
int MemPool::Validate(void *buf)
|
||||||
|
{
|
||||||
|
struct bfhead *b = BFH(buf);
|
||||||
|
|
||||||
|
while (b->bh.bsize != ESent)
|
||||||
|
{
|
||||||
|
ssize_t bs = b->bh.bsize;
|
||||||
|
|
||||||
|
if (bs < 0)
|
||||||
|
{
|
||||||
|
bs = -bs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *lerr = "";
|
||||||
|
|
||||||
|
assert(bs > 0);
|
||||||
|
if (bs <= 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((b->ql.blink->ql.flink != b) || (b->ql.flink->ql.blink != b))
|
||||||
|
{
|
||||||
|
printf("Free block: size %6ld bytes. (Bad free list links)\n",
|
||||||
|
(long) bs);
|
||||||
|
assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lerr = ((char *) b) + sizeof(struct bfhead);
|
||||||
|
if ((bs > (ssize_t)sizeof(struct bfhead)) && ((*lerr != 0x55) ||
|
||||||
|
(memcmp(lerr, lerr + 1,(int) (bs - (sizeof(struct bfhead) + 1))) != 0)))
|
||||||
|
{
|
||||||
|
printf("(Contents of above free block have been overstored.)\n");
|
||||||
|
BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
|
||||||
|
assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
b = BFH(((char *) b) + bs);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int *MemPool::CompactMem(ssize_t sizereq, int sequence)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MemPool::AcquireMem(ssize_t size)
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemPool::ReleaseMem(void *buffer)
|
||||||
|
{
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
AreaPool::AreaPool(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AreaPool::~AreaPool(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void *AreaPool::AcquireMem(ssize_t size)
|
||||||
|
{
|
||||||
|
long areasize=0;
|
||||||
|
area_id a;
|
||||||
|
int *parea;
|
||||||
|
|
||||||
|
if(size<B_PAGE_SIZE)
|
||||||
|
areasize=B_PAGE_SIZE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if((size % B_PAGE_SIZE)!=0)
|
||||||
|
areasize=((long)(size/B_PAGE_SIZE)+1)*B_PAGE_SIZE;
|
||||||
|
else
|
||||||
|
areasize=size;
|
||||||
|
}
|
||||||
|
|
||||||
|
a=create_area("AreaPool_area",(void**)&parea,B_ANY_ADDRESS,areasize,
|
||||||
|
B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||||
|
|
||||||
|
if(a==B_BAD_VALUE || a==B_NO_MEMORY || a==B_ERROR)
|
||||||
|
{
|
||||||
|
printf("ERROR: AreaPool couldn't allocate area!!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parea;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AreaPool::ReleaseMem(void *buffer)
|
||||||
|
{
|
||||||
|
area_id trash=area_for(buffer);
|
||||||
|
|
||||||
|
if(trash==B_ERROR)
|
||||||
|
return;
|
||||||
|
|
||||||
|
delete_area(trash);
|
||||||
|
}
|
||||||
|
|
53
src/tests/apps/fake_app_server/BGet++.h
Normal file
53
src/tests/apps/fake_app_server/BGet++.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#ifndef HGET_H_
|
||||||
|
#define HGET_H_
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
class MemPool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MemPool(void);
|
||||||
|
virtual ~MemPool(void);
|
||||||
|
|
||||||
|
void AddToPool(void *buffer, ssize_t len);
|
||||||
|
void *GetBuffer(ssize_t size, bool zero=false);
|
||||||
|
void *ReallocateBuffer(void *buffer, ssize_t size);
|
||||||
|
void ReleaseBuffer(void *buffer);
|
||||||
|
|
||||||
|
virtual int *CompactMem(ssize_t sizereq, int sequence);
|
||||||
|
virtual void *AcquireMem(ssize_t size);
|
||||||
|
virtual void ReleaseMem(void *buffer);
|
||||||
|
void SetPoolIncrement(ssize_t increment);
|
||||||
|
ssize_t PoolIncrement(void);
|
||||||
|
|
||||||
|
void Stats(ssize_t *curalloc, ssize_t *totfree, ssize_t *maxfree,
|
||||||
|
long *nget, long *nrel);
|
||||||
|
|
||||||
|
void ExtendedStats(ssize_t *pool_incr, long *npool, long *npget,
|
||||||
|
long *nprel, long *ndget, long *ndrel);
|
||||||
|
|
||||||
|
void BufferDump(void *buf);
|
||||||
|
void PoolDump(void *pool, bool dumpalloc, bool dumpfree);
|
||||||
|
int Validate(void *buffer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ssize_t totalloc;
|
||||||
|
long numget, numrel;
|
||||||
|
long numpblk;
|
||||||
|
long numpget, numprel;
|
||||||
|
long numdget, numdrel;
|
||||||
|
ssize_t exp_incr;
|
||||||
|
ssize_t pool_len;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class AreaPool : public MemPool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AreaPool(void);
|
||||||
|
virtual ~AreaPool(void);
|
||||||
|
virtual void *AcquireMem(ssize_t size);
|
||||||
|
virtual void ReleaseMem(void *buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
17
src/tests/apps/fake_app_server/Jamfile
Normal file
17
src/tests/apps/fake_app_server/Jamfile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
SubDir OBOS_TOP src tests apps fake_app_server ;
|
||||||
|
|
||||||
|
UseLibraryHeaders agg png zlib ;
|
||||||
|
UsePrivateHeaders app interface [ FDirName servers app ] ;
|
||||||
|
UseHeaders [ FDirName $(OBOS_TOP) src servers app drawing ] ;
|
||||||
|
UseHeaders [ FDirName $(OBOS_TOP) src servers app drawing Painter ] ;
|
||||||
|
UseHeaders [ FDirName $(OBOS_TOP) src servers app drawing Painter drawing_modes ] ;
|
||||||
|
UseHeaders [ FDirName $(OBOS_TOP) src servers app drawing Painter font_support ] ;
|
||||||
|
UseFreeTypeHeaders ;
|
||||||
|
|
||||||
|
Server fake_app_server :
|
||||||
|
AppServer.cpp
|
||||||
|
ServerApp.cpp
|
||||||
|
BGet++.cpp
|
||||||
|
Utils.cpp
|
||||||
|
: libroot.so libbe.so
|
||||||
|
;
|
1150
src/tests/apps/fake_app_server/ServerApp.cpp
Normal file
1150
src/tests/apps/fake_app_server/ServerApp.cpp
Normal file
File diff suppressed because it is too large
Load Diff
110
src/tests/apps/fake_app_server/ServerApp.h
Normal file
110
src/tests/apps/fake_app_server/ServerApp.h
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2001-2005, Haiku, Inc.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// File Name: ServerApp.h
|
||||||
|
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||||
|
// Adi Oanca <adioanca@myrealbox.com>
|
||||||
|
// Description: Server-side BApplication counterpart
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
#ifndef _SERVERAPP_H_
|
||||||
|
#define _SERVERAPP_H_
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
#include <String.h>
|
||||||
|
#include <LinkMsgReader.h>
|
||||||
|
#include <LinkMsgSender.h>
|
||||||
|
//#include "FMWList.h"
|
||||||
|
|
||||||
|
class AppServer;
|
||||||
|
class BMessage;
|
||||||
|
class BPortLink;
|
||||||
|
class BList;
|
||||||
|
class DisplayDriver;
|
||||||
|
class ServerCursor;
|
||||||
|
class ServerBitmap;
|
||||||
|
class AreaPool;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class ServerApp ServerApp.h
|
||||||
|
\brief Counterpart to BApplication within the app_server
|
||||||
|
*/
|
||||||
|
class ServerApp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ServerApp(port_id sendport, port_id rcvport, port_id clientLooperPort,
|
||||||
|
team_id clientTeamID, int32 handlerID, char *signature);
|
||||||
|
virtual ~ServerApp(void);
|
||||||
|
|
||||||
|
bool Run(void);
|
||||||
|
static int32 MonitorApp(void *data);
|
||||||
|
void Lock(void);
|
||||||
|
void Unlock(void);
|
||||||
|
bool IsLocked(void);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Determines whether the application is the active one
|
||||||
|
\return true if active, false if not.
|
||||||
|
*/
|
||||||
|
bool IsActive(void) const { return fIsActive; }
|
||||||
|
|
||||||
|
void Activate(bool value);
|
||||||
|
bool PingTarget(void);
|
||||||
|
|
||||||
|
void PostMessage(int32 code);
|
||||||
|
|
||||||
|
void SendMessageToClient( const BMessage* msg ) const;
|
||||||
|
void SetAppCursor(void);
|
||||||
|
|
||||||
|
team_id ClientTeamID();
|
||||||
|
|
||||||
|
const char * Title() const { return fSignature.String(); }
|
||||||
|
protected:
|
||||||
|
friend class AppServer;
|
||||||
|
friend class ServerWindow;
|
||||||
|
|
||||||
|
void DispatchMessage(int32 code, LinkMsgReader &link);
|
||||||
|
|
||||||
|
port_id fClientAppPort,
|
||||||
|
fMessagePort,
|
||||||
|
// TODO: find out why there is both the app port and the looper port. Do
|
||||||
|
// we really need both?
|
||||||
|
fClientLooperPort;
|
||||||
|
|
||||||
|
BString fSignature;
|
||||||
|
thread_id fMonitorThreadID;
|
||||||
|
|
||||||
|
team_id fClientTeamID;
|
||||||
|
|
||||||
|
LinkMsgReader *fMsgReader;
|
||||||
|
LinkMsgSender *fMsgSender;
|
||||||
|
|
||||||
|
/* BList *fSWindowList,
|
||||||
|
*fBitmapList,
|
||||||
|
*fPictureList;
|
||||||
|
*/ sem_id fLockSem;
|
||||||
|
bool fCursorHidden;
|
||||||
|
bool fIsActive;
|
||||||
|
int32 fHandlerToken;
|
||||||
|
AreaPool *fSharedMem;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
327
src/tests/apps/fake_app_server/Utils.cpp
Normal file
327
src/tests/apps/fake_app_server/Utils.cpp
Normal file
@ -0,0 +1,327 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2001-2002, Haiku
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// File Name: Utils.cpp
|
||||||
|
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||||
|
// Description: Miscellaneous utility functions
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "Utils.h"
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Send a BMessage to a Looper target
|
||||||
|
\param port Receiver port of the targeted Looper
|
||||||
|
\param BMessage to send
|
||||||
|
|
||||||
|
This SendMessage takes ownership of the message sent, so deleting them after this
|
||||||
|
call is unnecessary. Passing an invalid port will have unpredictable results.
|
||||||
|
*/
|
||||||
|
void SendMessage(port_id port, BMessage *message, int32 target)
|
||||||
|
{
|
||||||
|
if(!message)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(target==-1)
|
||||||
|
_set_message_target_(message,target,true);
|
||||||
|
else
|
||||||
|
_set_message_target_(message,target,false);
|
||||||
|
|
||||||
|
ssize_t flatsize=message->FlattenedSize();
|
||||||
|
char *buffer=new char[flatsize];
|
||||||
|
|
||||||
|
if(message->Flatten(buffer,flatsize)==B_OK)
|
||||||
|
write_port(port, message->what, buffer,flatsize);
|
||||||
|
|
||||||
|
delete [] buffer;
|
||||||
|
delete message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Below are friend functions for BMessage which currently are not in the Message.cpp
|
||||||
|
that we need to send messages to BLoopers and such. Placed here to allow compilation.
|
||||||
|
*/
|
||||||
|
void _set_message_target_(BMessage *msg, int32 target, bool preferred)
|
||||||
|
{
|
||||||
|
if (preferred)
|
||||||
|
{
|
||||||
|
msg->fTarget = -1;
|
||||||
|
msg->fPreferred = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg->fTarget = target;
|
||||||
|
msg->fPreferred = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 _get_message_target_(BMessage *msg)
|
||||||
|
{
|
||||||
|
if (msg->fPreferred)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return msg->fTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _use_preferred_target_(BMessage *msg)
|
||||||
|
{
|
||||||
|
return msg->fPreferred;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *MsgCodeToString(int32 code)
|
||||||
|
{
|
||||||
|
// Used to translate BMessage message codes back to a character
|
||||||
|
// format
|
||||||
|
char string [10];
|
||||||
|
sprintf(string,"'%x%x%x%x'",(char)((code & 0xFF000000) >> 24),
|
||||||
|
(char)((code & 0x00FF0000) >> 16),
|
||||||
|
(char)((code & 0x0000FF00) >> 8),
|
||||||
|
(char)((code & 0x000000FF)) );
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
BString MsgCodeToBString(int32 code)
|
||||||
|
{
|
||||||
|
// Used to translate BMessage message codes back to a character
|
||||||
|
// format
|
||||||
|
char string [10];
|
||||||
|
sprintf(string,"'%x%x%x%x'",(char)((code & 0xFF000000) >> 24),
|
||||||
|
(char)((code & 0x00FF0000) >> 16),
|
||||||
|
(char)((code & 0x0000FF00) >> 8),
|
||||||
|
(char)((code & 0x000000FF)) );
|
||||||
|
|
||||||
|
BString bstring(string);
|
||||||
|
return bstring;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t ConvertModeToDisplayMode(uint32 mode, display_mode *dmode)
|
||||||
|
{
|
||||||
|
if(!mode)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
switch(mode)
|
||||||
|
{
|
||||||
|
case B_8_BIT_640x400:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=640;
|
||||||
|
dmode->virtual_height=400;
|
||||||
|
dmode->space=B_CMAP8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_8_BIT_640x480:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=640;
|
||||||
|
dmode->virtual_height=480;
|
||||||
|
dmode->space=B_CMAP8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_15_BIT_640x480:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=640;
|
||||||
|
dmode->virtual_height=480;
|
||||||
|
dmode->space=B_RGB15;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_16_BIT_640x480:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=640;
|
||||||
|
dmode->virtual_height=480;
|
||||||
|
dmode->space=B_RGB16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_32_BIT_640x480:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=640;
|
||||||
|
dmode->virtual_height=480;
|
||||||
|
dmode->space=B_RGB32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_8_BIT_800x600:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=800;
|
||||||
|
dmode->virtual_height=600;
|
||||||
|
dmode->space=B_CMAP8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_15_BIT_800x600:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=800;
|
||||||
|
dmode->virtual_height=600;
|
||||||
|
dmode->space=B_RGB15;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_16_BIT_800x600:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=800;
|
||||||
|
dmode->virtual_height=600;
|
||||||
|
dmode->space=B_RGB16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_32_BIT_800x600:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=800;
|
||||||
|
dmode->virtual_height=600;
|
||||||
|
dmode->space=B_RGB32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_8_BIT_1024x768:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1024;
|
||||||
|
dmode->virtual_height=768;
|
||||||
|
dmode->space=B_CMAP8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_15_BIT_1024x768:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1024;
|
||||||
|
dmode->virtual_height=768;
|
||||||
|
dmode->space=B_RGB15;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_16_BIT_1024x768:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1024;
|
||||||
|
dmode->virtual_height=768;
|
||||||
|
dmode->space=B_RGB16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_32_BIT_1024x768:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1024;
|
||||||
|
dmode->virtual_height=768;
|
||||||
|
dmode->space=B_RGB32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_8_BIT_1152x900:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1152;
|
||||||
|
dmode->virtual_height=900;
|
||||||
|
dmode->space=B_CMAP8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_15_BIT_1152x900:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1152;
|
||||||
|
dmode->virtual_height=900;
|
||||||
|
dmode->space=B_RGB15;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_16_BIT_1152x900:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1152;
|
||||||
|
dmode->virtual_height=900;
|
||||||
|
dmode->space=B_RGB16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_32_BIT_1152x900:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1152;
|
||||||
|
dmode->virtual_height=900;
|
||||||
|
dmode->space=B_RGB32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_8_BIT_1280x1024:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1280;
|
||||||
|
dmode->virtual_height=1024;
|
||||||
|
dmode->space=B_CMAP8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_15_BIT_1280x1024:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1280;
|
||||||
|
dmode->virtual_height=1024;
|
||||||
|
dmode->space=B_RGB15;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_16_BIT_1280x1024:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1280;
|
||||||
|
dmode->virtual_height=1024;
|
||||||
|
dmode->space=B_RGB16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_32_BIT_1280x1024:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1280;
|
||||||
|
dmode->virtual_height=1024;
|
||||||
|
dmode->space=B_RGB32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_8_BIT_1600x1200:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1600;
|
||||||
|
dmode->virtual_height=1200;
|
||||||
|
dmode->space=B_CMAP8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_15_BIT_1600x1200:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1600;
|
||||||
|
dmode->virtual_height=1200;
|
||||||
|
dmode->space=B_RGB15;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_16_BIT_1600x1200:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1600;
|
||||||
|
dmode->virtual_height=1200;
|
||||||
|
dmode->space=B_RGB16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_32_BIT_1600x1200:
|
||||||
|
{
|
||||||
|
dmode->virtual_width=1600;
|
||||||
|
dmode->virtual_height=1200;
|
||||||
|
dmode->space=B_RGB32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
BRect CalculatePolygonBounds(BPoint *pts, int32 pointcount)
|
||||||
|
{
|
||||||
|
if(!pts)
|
||||||
|
return BRect(0,0,0,0);
|
||||||
|
|
||||||
|
BRect r(0,0,0,0);
|
||||||
|
|
||||||
|
// shamelessly stolen from Marc's BPolygon code and tweaked to fit. :P
|
||||||
|
r = BRect(pts[0], pts[0]);
|
||||||
|
|
||||||
|
for (int32 i = 1; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (pts[i].x < r.left)
|
||||||
|
r.left = pts[i].x;
|
||||||
|
if (pts[i].y < r.top)
|
||||||
|
r.top = pts[i].y;
|
||||||
|
if (pts[i].x > r.right)
|
||||||
|
r.right = pts[i].x;
|
||||||
|
if (pts[i].y > r.bottom)
|
||||||
|
r.bottom = pts[i].y;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
39
src/tests/apps/fake_app_server/Utils.h
Normal file
39
src/tests/apps/fake_app_server/Utils.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2001-2002, Haiku
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// File Name: Utils.h
|
||||||
|
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||||
|
// Description: Miscellaneous utility functions
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
#ifndef UTILS_H_
|
||||||
|
#define UTILS_H_
|
||||||
|
|
||||||
|
#include <Message.h>
|
||||||
|
#include <OS.h>
|
||||||
|
#include <Accelerant.h>
|
||||||
|
|
||||||
|
void SendMessage(port_id port, BMessage *message, int32 target=-1);
|
||||||
|
const char *MsgCodeToString(int32 code);
|
||||||
|
BString MsgCodeToBString(int32 code);
|
||||||
|
status_t ConvertModeToDisplayMode(uint32 mode, display_mode *dmode);
|
||||||
|
BRect CalculatePolygonBounds(BPoint *pts, int32 pointcount);
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user