示例#1
0
void
FontManager::_AddSystemPaths()
{
	BPath path;
	if (find_directory(B_BEOS_FONTS_DIRECTORY, &path, true) == B_OK)
		_AddPath(path.Path());

	// We don't scan these in test mode to help shave off some startup time
#if !TEST_MODE
	if (find_directory(B_COMMON_FONTS_DIRECTORY, &path, true) == B_OK)
		_AddPath(path.Path());
#endif
}
示例#2
0
status_t
FontManager::_AddPath(const char* path)
{
	BEntry entry;
	status_t status = entry.SetTo(path);
	if (status != B_OK)
		return status;

	return _AddPath(entry);
}
示例#3
0
void
FontManager::AttachUser(uid_t userID)
{
	BAutolock locker(this);

#if !TEST_MODE
	// TODO: actually, find_directory() cannot know which user ID we want here
	// TODO: avoids user fonts in safe mode
	BPath path;
	if (find_directory(B_USER_FONTS_DIRECTORY, &path, true) != B_OK)
		return;

	_AddPath(path.Path());
#endif
}
示例#4
0
/*!	\brief Scan a folder for all valid fonts
	\param directoryPath Path of the folder to scan.
*/
status_t
FontManager::_ScanFontDirectory(font_directory& fontDirectory)
{
	// This bad boy does all the real work. It loads each entry in the
	// directory. If a valid font file, it adds both the family and the style.

	BDirectory directory;
	status_t status = directory.SetTo(&fontDirectory.directory);
	if (status != B_OK)
		return status;

	BEntry entry;
	while (directory.GetNextEntry(&entry) == B_OK) {
		if (entry.IsDirectory()) {
			// scan this directory recursively
			font_directory* newDirectory;
			if (_AddPath(entry, &newDirectory) == B_OK && newDirectory != NULL)
				_ScanFontDirectory(*newDirectory);

			continue;
		}

// TODO: Commenting this out makes my "Unicode glyph lookup"
// work with our default fonts. The real fix is to select the
// Unicode char map (if supported), and/or adjust the
// utf8 -> glyph-index mapping everywhere to handle other
// char maps. We could also ignore fonts that don't support
// the Unicode lookup as a temporary "solution".
#if 0
		FT_CharMap charmap = _GetSupportedCharmap(face);
		if (!charmap) {
		    FT_Done_Face(face);
		    continue;
    	}

		face->charmap = charmap;
#endif

		_AddFont(fontDirectory, entry);
			// takes over ownership of the FT_Face object
	}

	fontDirectory.revision = 1;
	return B_OK;
}
示例#5
0
/*!	\brief Creates all unknown font_directories of the specified path - but
		only if one of its parent directories is already known.

	This method is used to create the font_directories for font_mappings.
	It recursively walks upwards in the directory hierarchy until it finds
	a known font_directory (or hits the root directory, in which case it
	bails out).
*/
status_t
FontManager::_CreateDirectories(const char* path)
{
	FTRACE(("_CreateDirectories(path = %s)\n", path));

	if (!strcmp(path, "/")) {
		// we walked our way up to the root
		return B_ENTRY_NOT_FOUND;
	}

	BEntry entry;
	status_t status = entry.SetTo(path);
	if (status != B_OK)
		return status;

	node_ref nodeRef;
	status = entry.GetNodeRef(&nodeRef);
	if (status != B_OK)
		return status;

	// check if we are already know this directory

	font_directory* directory = _FindDirectory(nodeRef);
	if (directory != NULL)
		return B_OK;

	// We don't know this one yet - keep walking the path upwards
	// and try to find a match.

	BPath parent(path);
	status = parent.GetParent(&parent);
	if (status != B_OK)
		return status;

	status = _CreateDirectories(parent.Path());
	if (status != B_OK)
		return status;

	// We have our match, create sub directory

	return _AddPath(path);
}
示例#6
0
status_t
device_node::_GetNextDriverPath(void*& cookie, KPath& _path)
{
	Stack<KPath*>* stack = NULL;

	if (cookie == NULL) {
		// find all paths and add them
		stack = new(std::nothrow) Stack<KPath*>();
		if (stack == NULL)
			return B_NO_MEMORY;

		StackDeleter<KPath*> stackDeleter(stack);

		bool generic = false;
		uint16 type = 0;
		uint16 subType = 0;
		uint16 interface = 0;
		if (get_attr_uint16(this, B_DEVICE_TYPE, &type, false) != B_OK
			|| get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false)
					!= B_OK)
			generic = true;

		get_attr_uint16(this, B_DEVICE_INTERFACE, &interface, false);

		// TODO: maybe make this extendible via settings file?
		switch (type) {
			case PCI_mass_storage:
				switch (subType) {
					case PCI_scsi:
						_AddPath(*stack, "busses", "scsi");
						_AddPath(*stack, "busses", "virtio");
						break;
					case PCI_ide:
						_AddPath(*stack, "busses", "ata");
						_AddPath(*stack, "busses", "ide");
						break;
					case PCI_sata:
						// TODO: check for ahci interface
						_AddPath(*stack, "busses", "scsi");
						_AddPath(*stack, "busses", "ata");
						_AddPath(*stack, "busses", "ide");
						break;
					default:
						_AddPath(*stack, "busses");
						break;
				}
				break;
			case PCI_serial_bus:
				switch (subType) {
					case PCI_firewire:
						_AddPath(*stack, "busses", "firewire");
						break;
					case PCI_usb:
						_AddPath(*stack, "busses", "usb");
						break;
					default:
						_AddPath(*stack, "busses");
						break;
				}
				break;
			case PCI_network:
				_AddPath(*stack, "drivers", "net");
				_AddPath(*stack, "busses", "virtio");
				break;
			case PCI_display:
				_AddPath(*stack, "drivers", "graphics");
				break;
			case PCI_multimedia:
				switch (subType) {
					case PCI_audio:
					case PCI_hd_audio:
						_AddPath(*stack, "drivers", "audio");
						break;
					case PCI_video:
						_AddPath(*stack, "drivers", "video");
						break;
					default:
						_AddPath(*stack, "drivers");
						break;
				}
				break;
			default:
				if (sRootNode == this) {
					_AddPath(*stack, "busses/pci");
					_AddPath(*stack, "bus_managers");
				} else if (!generic) {
					_AddPath(*stack, "busses", "virtio");
					_AddPath(*stack, "drivers");
				} else {
					// For generic drivers, we only allow busses when the
					// request is more specified
					if (sGenericContextPath != NULL
						&& (!strcmp(sGenericContextPath, "disk")
							|| !strcmp(sGenericContextPath, "ports")
							|| !strcmp(sGenericContextPath, "bus"))) {
						_AddPath(*stack, "busses");
					}
					_AddPath(*stack, "drivers", sGenericContextPath);
					_AddPath(*stack, "busses/scsi");
					_AddPath(*stack, "busses/random");
				}
				break;
		}

		stackDeleter.Detach();

		cookie = (void*)stack;
	} else
		stack = static_cast<Stack<KPath*>*>(cookie);

	KPath* path;
	if (stack->Pop(&path)) {
		_path.Adopt(*path);
		delete path;
		return B_OK;
	}

	delete stack;
	return B_ENTRY_NOT_FOUND;
}
示例#7
0
void
FontManager::MessageReceived(BMessage* message)
{
	switch (message->what) {
		case B_NODE_MONITOR:
		{
			// TODO: support removing fonts!

			int32 opcode;
			if (message->FindInt32("opcode", &opcode) != B_OK)
				return;

			switch (opcode) {
				case B_ENTRY_CREATED:
				{
					const char* name;
					node_ref nodeRef;
					if (message->FindInt32("device", &nodeRef.device) != B_OK
						|| message->FindInt64("directory", &nodeRef.node) != B_OK
						|| message->FindString("name", &name) != B_OK)
						break;

					// TODO: make this better (possible under Haiku)
					snooze(100000);
						// let the font be written completely before trying to open it

					BEntry entry;
					if (set_entry(nodeRef, name, entry) != B_OK)
						break;

					if (entry.IsDirectory()) {
						// a new directory to watch for us
						_AddPath(entry);
					} else {
						// a new font
						font_directory* directory = _FindDirectory(nodeRef);
						if (directory == NULL) {
							// unknown directory? how come?
							break;
						}

						_AddFont(*directory, entry);
					}
					break;
				}

				case B_ENTRY_MOVED:
				{
					// has the entry been moved into a monitored directory or has
					// it been removed from one?
					const char* name;
					node_ref nodeRef;
					uint64 fromNode;
					uint64 node;
					if (message->FindInt32("device", &nodeRef.device) != B_OK
						|| message->FindInt64("to directory", &nodeRef.node) != B_OK
						|| message->FindInt64("from directory", (int64 *)&fromNode) != B_OK
						|| message->FindInt64("node", (int64 *)&node) != B_OK
						|| message->FindString("name", &name) != B_OK)
						break;

					font_directory* directory = _FindDirectory(nodeRef);

					BEntry entry;
					if (set_entry(nodeRef, name, entry) != B_OK)
						break;

					if (directory != NULL) {
						// something has been added to our watched font directories

						// test, if the source directory is one of ours as well
						nodeRef.node = fromNode;
						font_directory* fromDirectory = _FindDirectory(nodeRef);

						if (entry.IsDirectory()) {
							if (fromDirectory == NULL) {
								// there is a new directory to watch for us
								_AddPath(entry);
								FTRACE("new directory moved in");
							} else {
								// A directory from our watched directories has
								// been renamed or moved within the watched
								// directories - we only need to update the
								// path names of the styles in that directory
								nodeRef.node = node;
								directory = _FindDirectory(nodeRef);
								if (directory != NULL) {
									for (int32 i = 0; i < directory->styles.CountItems(); i++) {
										FontStyle* style = directory->styles.ItemAt(i);
										style->UpdatePath(directory->directory);
									}
								}
								FTRACE("directory renamed");
							}
						} else {
							if (fromDirectory != NULL) {
								// find style in source and move it to the target
								nodeRef.node = node;
								FontStyle* style = fromDirectory->FindStyle(nodeRef);
								if (style != NULL) {
									fromDirectory->styles.RemoveItem(style, false);
									directory->styles.AddItem(style);
									style->UpdatePath(directory->directory);
								}
								FTRACE(("font moved"));
							} else {
								FTRACE(("font added: %s\n", name));
								_AddFont(*directory, entry);
							}
						}
					} else {
						// and entry has been removed from our font directories
						if (entry.IsDirectory()) {
							if (entry.GetNodeRef(&nodeRef) == B_OK
								&& (directory = _FindDirectory(nodeRef)) != NULL)
								_RemoveDirectory(directory);
						} else {
							// remove font style from directory
							_RemoveStyle(nodeRef.device, fromNode, node);
						}
					}
					break;
				}

				case B_ENTRY_REMOVED:
				{
					node_ref nodeRef;
					uint64 directoryNode;
					if (message->FindInt32("device", &nodeRef.device) != B_OK
						|| message->FindInt64("directory", (int64 *)&directoryNode) != B_OK
						|| message->FindInt64("node", &nodeRef.node) != B_OK)
						break;

					font_directory* directory = _FindDirectory(nodeRef);
					if (directory != NULL) {
						// the directory has been removed, so we remove it as well
						_RemoveDirectory(directory);
					} else {
						// remove font style from directory
						_RemoveStyle(nodeRef.device, directoryNode, nodeRef.node);
					}
					break;
				}
			}
			break;
		}
	}
}