//
// Copyright 2005 The Android Open Source Project
//
// Simulated device definition.
//
// The "root" of the data structures here is PhoneCollection, which may
// discard the entire set if the user asks to re-scan the phone definitions.
// These structures should be considered read-only.
//
// PhoneCollection (single global instance)
// -->PhoneData
// -->PhoneDisplay
// -->PhoneMode
// -->PhoneView
//
#ifndef _SIM_PHONE_DATA_H
#define _SIM_PHONE_DATA_H
#include <stdio.h>
#include "tinyxml.h"
#include "PhoneButton.h"
#include "LoadableImage.h"
#include <ui/PixelFormat.h>
#include "utils.h"
/*
* This represents the keyboard type of the simulated device
*/
class PhoneKeyboard {
public:
PhoneKeyboard(void)
: mQwerty(false), mKeyMap(NULL)
{}
~PhoneKeyboard(void) {
free((void*)mKeyMap);
}
PhoneKeyboard(const PhoneKeyboard& src)
: mQwerty(false), mKeyMap(NULL)
{
CopyMembers(src);
}
PhoneKeyboard& operator=(const PhoneKeyboard& src) {
if (this != &src) // self-assignment
CopyMembers(src);
return *this;
}
void CopyMembers(const PhoneKeyboard& src) {
mQwerty = src.mQwerty;
mKeyMap = src.mKeyMap ? strdup(src.mKeyMap) : NULL;
}
bool ProcessAndValidate(TiXmlNode* pNode);
bool getQwerty() { return mQwerty; }
const char *getKeyMap() { return mKeyMap; }
private:
bool mQwerty;
const char * mKeyMap;
};
/*
* This represents a single display device, usually an LCD screen.
* It also includes an optional surrounding graphic, usually a picture of
* the device itself.
*/
class PhoneDisplay {
public:
PhoneDisplay(void)
: mName(NULL)
{}
~PhoneDisplay(void) {
delete[] mName;
}
PhoneDisplay(const PhoneDisplay& src)
: mName(NULL)
{
CopyMembers(src);
}
PhoneDisplay& operator=(const PhoneDisplay& src) {
if (this != &src) // self-assignment
CopyMembers(src);
return *this;
}
void CopyMembers(const PhoneDisplay& src) {
// Can't memcpy and member-copy the container classes, because the
// containers have already been constructed, and for operator= they
// might even have stuff in them.
delete[] mName;
mName = android::strdupNew(src.mName);
mWidth = src.mWidth;
mHeight = src.mHeight;
mFormat = src.mFormat;
mRefresh = src.mRefresh;
}
bool ProcessAndValidate(TiXmlNode* pNode);
const char* GetName(void) const { return mName; }
int GetWidth(void) const { return mWidth; }
int GetHeight(void) const { return mHeight; }
android::PixelFormat GetFormat(void) const { return mFormat; }
int GetRefresh(void) const { return mRefresh; }
static bool IsCompatible(PhoneDisplay* pDisplay1, PhoneDisplay* pDisplay2);
private:
char* mName;
// display dimensions, in pixels
int mWidth;
int mHeight;
// frame buffer format
android::PixelFormat mFormat;
// display refresh rate, in fps
int mRefresh;
};
/*
* This is a "view" of a device, which includes the display, a background
* image, and perhaps some clickable keys for input.
*
* Because the key graphics are associated with a particular display, we
* hold a list of keys here. (It also allows the possibility of handling
* a situation where the same key shows up in multiple background images,
* e.g. a flip phone with a "volume" key on the side. If we include the
* key in both places, we can highlight it on both displays.)
*/
class PhoneView {
public:
PhoneView(void)
: mDisplayName(NULL)
{}
~PhoneView(void) {
delete[] mDisplayName;
}
PhoneView(const PhoneView& src) {
CopyMembers(src);
}
PhoneView& operator=(const PhoneView& src) {
if (this != &src) // self-assignment
CopyMembers(src);
return *this;
}
void CopyMembers(const PhoneView& src) {
// Can't memcpy and member-copy the container classes, because the
// containers have already been constructed, and for operator= they
// might even have stuff in them.
mImageList = src.mImageList;
mButtonList = src.mButtonList;
mDisplayName = android::strdupNew(src.mDisplayName);
mXOffset = src.mXOffset;
mYOffset = src.mYOffset;
mRotation = src.mRotation;
}
// load or unload resources, e.g. wxBitmaps from image files
bool LoadResources(void);
bool UnloadResources(void);
// simple accessors
int GetXOffset(void) const { return mXOffset; }
int GetYOffset(void) const { return mYOffset; }
const char* GetDisplayName(void) const { return mDisplayName; }
// image list access
int GetBkgImageCount(void) const;
const LoadableImage* GetBkgImage(int idx) const;
// find the first button that covers the specified coords
PhoneButton* FindButtonHit(int x, int y);
// find the first button with a matching key code
PhoneButton* FindButtonByKey(int32_t keyCode);
bool ProcessAndValidate(TiXmlNode* pNode, const char* directory);
bool ProcessImage(TiXmlNode* pNode, const char* directory);
bool ProcessButton(TiXmlNode* pNode, const char* directory);
private:
// background images for the phone picture that surrounds the display
android::List<LoadableImage> mImageList;
// list of accessible buttons, some of which have highlight graphics
android::List<PhoneButton> mButtonList;
char* mDisplayName;
// these determine where in the image the display output goes
int mXOffset;
int mYOffset;
// clockwise rotation of the output; sim must rotate in opposite direction
typedef enum Rotation {
kRotUnknown = 0,
kRot0,
kRot90,
kRot180,
kRot270,
} Rotation;
Rotation mRotation;
};
/*
* One mode of a phone. Simple devices only have one mode. Flip phones
* have two (opened and closed). Other devices might have more. The
* mode is communicated to the runtime because it may need to process
* input events differently.
*/
class PhoneMode {
public:
PhoneMode(void)
: mName(NULL)
{}
~PhoneMode(void) {
delete[] mName;
}
PhoneMode(const PhoneMode& src)
: mName(NULL)
{
CopyMembers(src);
}
PhoneMode& operator=(const PhoneMode& src) {
if (this != &src) // self-assignment
CopyMembers(src);
return *this;
}
void CopyMembers(const PhoneMode& src) {
delete[] mName;
mName = android::strdupNew(src.mName);
mViewList = src.mViewList;
}
// load or unload resources for this object and all members of mViewList
bool LoadResources(void);
bool UnloadResources(void);
// get the #of views
int GetNumViews(void) const { return mViewList.size(); }
// get the Nth display
PhoneView* GetPhoneView(int viewNum);
const char* GetName(void) const { return mName; }
void SetName(const char* name) {
delete[] mName;
mName = android::strdupNew(name);
}
// load the <mode> section from the config file
bool ProcessAndValidate(TiXmlNode* pNode, const char* directory);
private:
char* mName;
android::List<PhoneView> mViewList;
};
/*
* This holds the data for one device.
*
* Each device may have multiple "modes", e.g. a flip-phone that can be
* open or shut. Each mode has different configurations for the visible
* displays and active keys.
*/
class PhoneData {
public:
PhoneData(void) :
mName(NULL), mTitle(NULL), mDirectory(NULL)
{}
virtual ~PhoneData(void) {
delete[] mName;
delete[] mTitle;
delete[] mDirectory;
}
PhoneData(const PhoneData& src)
: mName(NULL), mTitle(NULL), mDirectory(NULL)
{
CopyMembers(src);
}
PhoneData& operator=(const PhoneData& src) {
if (this != &src) // self-assignment
CopyMembers(src);
return *this;
}
void CopyMembers(const PhoneData& src) {
delete[] mName;
delete[] mTitle;
delete[] mDirectory;
mName = android::strdupNew(src.mName);
mTitle = android::strdupNew(src.mTitle);
mDirectory = android::strdupNew(src.mDirectory);
mModeList = src.mModeList;
mDisplayList = src.mDisplayList;
mKeyboardList = src.mKeyboardList;
}
// initialize the object with the phone data in the specified dir
bool Create(const char* directory);
// load or unload resources, e.g. wxBitmaps from image files
bool LoadResources(void);
bool UnloadResources(void);
// simple accessors
const char* GetName(void) const { return mName; }
void SetName(const char* name) {
delete[] mName;
mName = android::strdupNew(name);
}
const char* GetTitle(void) const { return mTitle; }
void SetTitle(const char* title) {
delete[] mTitle;
mTitle = android::strdupNew(title);
}
const char* GetDirectory(void) const { return mDirectory; }
void SetDirectory(const char* dir) {
delete[] mDirectory;
mDirectory = android::strdupNew(dir);
}
// get number of modes
int GetNumModes(void) const { return mModeList.size(); }
// get the specified mode object
PhoneMode* GetPhoneMode(int idx);
PhoneMode* GetPhoneMode(const char* modeName);
// get number of displays
int GetNumDisplays(void) const { return mDisplayList.size(); }
// get the specified display object
PhoneDisplay* GetPhoneDisplay(int idx);
PhoneDisplay* GetPhoneDisplay(const char* displayName);
// get the index of the matching display
int GetPhoneDisplayIndex(const char* displayName);
// get number of keyboards
int GetNumKeyboards(void) const { return mKeyboardList.size(); }
// get the specified display object
PhoneKeyboard* GetPhoneKeyboard(int idx);
private:
bool ProcessAndValidate(TiXmlDocument* pDoc);
bool ProcessDevice(TiXmlNode* pNode);
bool ProcessTitle(TiXmlNode* pNode);
char* mName;
char* mTitle;
char* mDirectory;
android::List<PhoneMode> mModeList;
android::List<PhoneDisplay> mDisplayList;
android::List<PhoneKeyboard> mKeyboardList;
};
#endif // _SIM_PHONE_DATA_H