status_t get_scroll_bar_info(scroll_bar_info *info) { if (info == NULL) return B_BAD_VALUE; BPrivate::AppServerLink link; link.StartMessage(AS_GET_SCROLLBAR_INFO); int32 code; if (link.FlushWithReply(code) == B_OK && code == B_OK) { link.Read<scroll_bar_info>(info); return B_OK; } return B_ERROR; }
unicode_block BFont::Blocks() const { BPrivate::AppServerLink link; link.StartMessage(AS_GET_UNICODE_BLOCKS); link.Attach<uint16>(fFamilyID); link.Attach<uint16>(fStyleID); int32 status; if (link.FlushWithReply(status) != B_OK || status != B_OK) { return unicode_block(~0LL, ~0LL); } unicode_block blocksForFont; link.Read<unicode_block>(&blocksForFont); return blocksForFont; }
/*! \brief queries the server for the name of the decorator with a certain index \param index The index of the decorator to get the name for \param name BString to receive the name of the decorator \return B_OK if successful, B_ERROR if not */ status_t get_decorator_name(const int32 &index, BString &name) { BPrivate::AppServerLink link; link.StartMessage(AS_GET_DECORATOR_NAME); link.Attach<int32>(index); int32 code; if (link.FlushWithReply(code) == B_OK && code == B_OK) { char *string; if (link.ReadString(&string) == B_OK) { name = string; free(string); return B_OK; } } return B_ERROR; }
status_t _get_system_default_font_(const char* which, font_family family, font_style style, float* _size) { BPrivate::AppServerLink link; link.StartMessage(AS_GET_SYSTEM_DEFAULT_FONT); link.AttachString(which, B_OS_NAME_LENGTH); int32 status = B_ERROR; if (link.FlushWithReply(status) != B_OK || status < B_OK) return status; link.ReadString(family, sizeof(font_family)); link.ReadString(style, sizeof(font_style)); link.Read<float>(_size); return B_OK; }
void BFont::GetBoundingBoxesForStrings(const char* stringArray[], int32 numStrings, font_metric_mode mode, escapement_delta deltas[], BRect boundingBoxArray[]) const { if (!stringArray || numStrings < 1 || !boundingBoxArray) return; int32 code; BPrivate::AppServerLink link; link.StartMessage(AS_GET_BOUNDINGBOXES_STRINGS); link.Attach<uint16>(fFamilyID); link.Attach<uint16>(fStyleID); link.Attach<float>(fSize); link.Attach<float>(fRotation); link.Attach<float>(fShear); link.Attach<float>(fFalseBoldWidth); link.Attach<uint8>(fSpacing); link.Attach<uint32>(fFlags); link.Attach<font_metric_mode>(mode); link.Attach<int32>(numStrings); if (deltas) { for (int32 i = 0; i < numStrings; i++) { link.AttachString(stringArray[i]); link.Attach<escapement_delta>(deltas[i]); } } else { escapement_delta emptyDelta = {0, 0}; for (int32 i = 0; i < numStrings; i++) { link.AttachString(stringArray[i]); link.Attach<escapement_delta>(emptyDelta); } } if (link.FlushWithReply(code) != B_OK || code != B_OK) return; link.Read(boundingBoxArray, sizeof(BRect) * numStrings); }
void BFont::_GetBoundingBoxes(const char charArray[], int32 numChars, font_metric_mode mode, bool string_escapement, escapement_delta* delta, BRect boundingBoxArray[], bool asString) const { if (charArray == NULL || numChars < 1 || boundingBoxArray == NULL) return; int32 code; BPrivate::AppServerLink link; link.StartMessage(asString ? AS_GET_BOUNDINGBOXES_STRING : AS_GET_BOUNDINGBOXES_CHARS); link.Attach<uint16>(fFamilyID); link.Attach<uint16>(fStyleID); link.Attach<float>(fSize); link.Attach<float>(fRotation); link.Attach<float>(fShear); link.Attach<float>(fFalseBoldWidth); link.Attach<uint8>(fSpacing); link.Attach<uint32>(fFlags); link.Attach<font_metric_mode>(mode); link.Attach<bool>(string_escapement); if (delta != NULL) { link.Attach<escapement_delta>(*delta); } else { escapement_delta emptyDelta = {0, 0}; link.Attach<escapement_delta>(emptyDelta); } link.Attach<int32>(numChars); uint32 bytesInBuffer = UTF8CountBytes(charArray, numChars); link.Attach<int32>(bytesInBuffer); link.Attach(charArray, bytesInBuffer); if (link.FlushWithReply(code) != B_OK || code != B_OK) return; link.Read(boundingBoxArray, sizeof(BRect) * numChars); }
font_file_format BFont::FileFormat() const { BPrivate::AppServerLink link; link.StartMessage(AS_GET_FONT_FILE_FORMAT); link.Attach<uint16>(fFamilyID); link.Attach<uint16>(fStyleID); int32 status; if (link.FlushWithReply(status) != B_OK || status != B_OK) { // just take a safe bet... return B_TRUETYPE_WINDOWS; } uint16 format; link.Read<uint16>(&format); return (font_file_format)format; }
bool BDragger::AreDraggersDrawn() { DraggerManager* manager = DraggerManager::Default(); AutoLocker<DraggerManager> locker(manager); if (!manager->visibleInitialized) { BPrivate::AppServerLink link; link.StartMessage(AS_GET_SHOW_ALL_DRAGGERS); status_t status; if (link.FlushWithReply(status) == B_OK && status == B_OK) { link.Read<bool>(&manager->visible); manager->visibleInitialized = true; } else return false; } return manager->visible; }
void get_workspaces_layout(uint32* _columns, uint32* _rows) { int32 columns = 1; int32 rows = 1; BPrivate::AppServerLink link; link.StartMessage(AS_GET_WORKSPACE_LAYOUT); status_t status; if (link.FlushWithReply(status) == B_OK && status == B_OK) { link.Read<int32>(&columns); link.Read<int32>(&rows); } if (_columns != NULL) *_columns = columns; if (_rows != NULL) *_rows = rows; }
bool BFont::IncludesBlock(uint32 start, uint32 end) const { BPrivate::AppServerLink link; link.StartMessage(AS_GET_HAS_UNICODE_BLOCK); link.Attach<uint16>(fFamilyID); link.Attach<uint16>(fStyleID); link.Attach<uint32>(start); link.Attach<uint32>(end); int32 status; if (link.FlushWithReply(status) != B_OK || status != B_OK) { return false; } bool hasBlock; link.Read<bool>(&hasBlock); return hasBlock; }
client_window_info* get_window_info(int32 serverToken) { BPrivate::AppServerLink link; link.StartMessage(AS_GET_WINDOW_INFO); link.Attach<int32>(serverToken); int32 code; if (link.FlushWithReply(code) != B_OK || code != B_OK) return NULL; int32 size; link.Read<int32>(&size); client_window_info* info = (client_window_info*)malloc(size); if (info == NULL) return NULL; link.Read(info, size); return info; }
void BBitmap::_ReconnectToAppServer() { BPrivate::AppServerLink link; link.StartMessage(AS_RECONNECT_BITMAP); link.Attach<BRect>(fBounds); link.Attach<color_space>(fColorSpace); link.Attach<uint32>(fFlags); link.Attach<int32>(fBytesPerRow); link.Attach<int32>(0); link.Attach<int32>(fArea); link.Attach<int32>(fAreaOffset); status_t error; if (link.FlushWithReply(error) == B_OK && error == B_OK) { // server side success // Get token link.Read<int32>(&fServerToken); link.Read<area_id>(&fServerArea); } }
int32* get_token_list(team_id team, int32* _count) { BPrivate::AppServerLink link; link.StartMessage(AS_GET_WINDOW_LIST); link.Attach<team_id>(team); int32 code; if (link.FlushWithReply(code) != B_OK || code != B_OK) return NULL; int32 count; link.Read<int32>(&count); int32* tokens = (int32*)malloc(count * sizeof(int32)); if (tokens == NULL) return NULL; link.Read(tokens, count * sizeof(int32)); *_count = count; return tokens; }
void BFont::_GetExtraFlags() const { // TODO: this has to be const in order to allow other font getters to // stay const as well if (fExtraFlags != kUninitializedExtraFlags) return; BPrivate::AppServerLink link; link.StartMessage(AS_GET_EXTRA_FONT_FLAGS); link.Attach<uint16>(fFamilyID); link.Attach<uint16>(fStyleID); status_t status = B_ERROR; if (link.FlushWithReply(status) != B_OK || status != B_OK) { // use defaut values for the flags fExtraFlags = (uint32)B_FONT_LEFT_TO_RIGHT << B_PRIVATE_FONT_DIRECTION_SHIFT; return; } link.Read<uint32>(&fExtraFlags); }
void _init_global_fonts_() { BPrivate::AppServerLink link; link.StartMessage(AS_GET_SYSTEM_FONTS); int32 code; if (link.FlushWithReply(code) != B_OK || code != B_OK) { printf("DEBUG: Couldn't initialize global fonts!\n"); return; } char type[B_OS_NAME_LENGTH]; while (link.ReadString(type, sizeof(type)) >= B_OK && type[0]) { BFont dummy; BFont* font = &dummy; if (!strcmp(type, "plain")) font = &sPlainFont; else if (!strcmp(type, "bold")) font = &sBoldFont; else if (!strcmp(type, "fixed")) font = &sFixedFont; link.Read<uint16>(&font->fFamilyID); link.Read<uint16>(&font->fStyleID); link.Read<float>(&font->fSize); link.Read<uint16>(&font->fFace); link.Read<uint32>(&font->fFlags); font->fHeight.ascent = kUninitializedAscent; font->fExtraFlags = kUninitializedExtraFlags; } }
void BFont::GetHasGlyphs(const char charArray[], int32 numChars, bool hasArray[]) const { if (!charArray || numChars < 1 || !hasArray) return; int32 code; BPrivate::AppServerLink link; link.StartMessage(AS_GET_HAS_GLYPHS); link.Attach<uint16>(fFamilyID); link.Attach<uint16>(fStyleID); link.Attach<int32>(numChars); uint32 bytesInBuffer = UTF8CountBytes(charArray, numChars); link.Attach<int32>(bytesInBuffer); link.Attach(charArray, bytesInBuffer); if (link.FlushWithReply(code) != B_OK || code != B_OK) return; link.Read(hasArray, sizeof(bool) * numChars); }
void BFont::GetEdges(const char charArray[], int32 numChars, edge_info edgeArray[]) const { if (!charArray || numChars < 1 || !edgeArray) return; int32 code; BPrivate::AppServerLink link; link.StartMessage(AS_GET_EDGES); link.Attach<uint16>(fFamilyID); link.Attach<uint16>(fStyleID); link.Attach<int32>(numChars); uint32 bytesInBuffer = UTF8CountBytes(charArray, numChars); link.Attach<int32>(bytesInBuffer); link.Attach(charArray, bytesInBuffer); if (link.FlushWithReply(code) != B_OK || code != B_OK) return; link.Read(edgeArray, sizeof(edge_info) * numChars); }
/*! \brief Initializes the bitmap. \param bounds The bitmap dimensions. \param colorSpace The bitmap's color space. \param flags Creation flags. \param bytesPerRow The number of bytes per row the bitmap should use. \c B_ANY_BYTES_PER_ROW to let the constructor choose an appropriate value. \param screenID ??? */ void BBitmap::_InitObject(BRect bounds, color_space colorSpace, uint32 flags, int32 bytesPerRow, screen_id screenID) { //printf("BBitmap::InitObject(bounds: BRect(%.1f, %.1f, %.1f, %.1f), format: %ld, flags: %ld, bpr: %ld\n", // bounds.left, bounds.top, bounds.right, bounds.bottom, colorSpace, flags, bytesPerRow); // TODO: Should we handle rounding of the "bounds" here? How does R5 behave? status_t error = B_OK; #ifdef RUN_WITHOUT_APP_SERVER flags |= B_BITMAP_NO_SERVER_LINK; #endif // RUN_WITHOUT_APP_SERVER _CleanUp(); // check params if (!bounds.IsValid() || !bitmaps_support_space(colorSpace, NULL)) { error = B_BAD_VALUE; } else { // bounds is in floats and might be valid but much larger than what we // can handle the size could not be expressed in int32 double realSize = bounds.Width() * bounds.Height(); if (realSize > (double)(INT_MAX / 4)) { fprintf(stderr, "bitmap bounds is much too large: " "BRect(%.1f, %.1f, %.1f, %.1f)\n", bounds.left, bounds.top, bounds.right, bounds.bottom); error = B_BAD_VALUE; } } if (error == B_OK) { int32 bpr = get_bytes_per_row(colorSpace, bounds.IntegerWidth() + 1); if (bytesPerRow < 0) bytesPerRow = bpr; else if (bytesPerRow < bpr) // NOTE: How does R5 behave? error = B_BAD_VALUE; } // allocate the bitmap buffer if (error == B_OK) { // TODO: Let the app_server return the size when it allocated the bitmap int32 size = bytesPerRow * (bounds.IntegerHeight() + 1); if ((flags & B_BITMAP_NO_SERVER_LINK) != 0) { fBasePointer = (uint8*)malloc(size); if (fBasePointer) { fSize = size; fColorSpace = colorSpace; fBounds = bounds; fBytesPerRow = bytesPerRow; fFlags = flags; } else error = B_NO_MEMORY; } else { // Ask the server (via our owning application) to create a bitmap. BPrivate::AppServerLink link; // Attach Data: // 1) BRect bounds // 2) color_space space // 3) int32 bitmap_flags // 4) int32 bytes_per_row // 5) int32 screen_id::id link.StartMessage(AS_CREATE_BITMAP); link.Attach<BRect>(bounds); link.Attach<color_space>(colorSpace); link.Attach<uint32>(flags); link.Attach<int32>(bytesPerRow); link.Attach<int32>(screenID.id); if (link.FlushWithReply(error) == B_OK && error == B_OK) { // server side success // Get token link.Read<int32>(&fServerToken); uint8 allocationFlags; link.Read<uint8>(&allocationFlags); link.Read<area_id>(&fServerArea); link.Read<int32>(&fAreaOffset); BPrivate::ServerMemoryAllocator* allocator = BApplication::Private::ServerAllocator(); if ((allocationFlags & kNewAllocatorArea) != 0) { error = allocator->AddArea(fServerArea, fArea, fBasePointer, size); } else { error = allocator->AreaAndBaseFor(fServerArea, fArea, fBasePointer); if (error == B_OK) fBasePointer += fAreaOffset; } if ((allocationFlags & kFramebuffer) != 0) { // The base pointer will now point to an overlay_client_data // structure bytes per row might be modified to match // hardware constraints link.Read<int32>(&bytesPerRow); size = bytesPerRow * (bounds.IntegerHeight() + 1); } if (fServerArea >= B_OK) { fSize = size; fColorSpace = colorSpace; fBounds = bounds; fBytesPerRow = bytesPerRow; fFlags = flags; } else error = fServerArea; } if (error < B_OK) { fBasePointer = NULL; fServerToken = -1; fArea = -1; fServerArea = -1; fAreaOffset = -1; // NOTE: why not "0" in case of error? fFlags = flags; } else { BAutolock _(sBitmapListLock); sBitmapList.AddItem(this); } } fWindow = NULL; } fInitError = error; if (fInitError == B_OK) { // clear to white if the flags say so. if (flags & (B_BITMAP_CLEAR_TO_WHITE | B_BITMAP_ACCEPTS_VIEWS)) { if (fColorSpace == B_CMAP8) { // "255" is the "transparent magic" index for B_CMAP8 bitmaps // use the correct index for "white" memset(fBasePointer, 65, fSize); } else { // should work for most colorspaces memset(fBasePointer, 0xff, fSize); } } // TODO: Creating an offscreen window with a non32 bit bitmap // copies the current content of the bitmap to a back buffer. // So at this point the bitmap has to be already cleared to white. // Better move the above code to the server so the problem looks more // clear. if (flags & B_BITMAP_ACCEPTS_VIEWS) { fWindow = new(std::nothrow) BWindow(Bounds(), fServerToken); if (fWindow) { // A BWindow starts life locked and is unlocked // in Show(), but this window is never shown and // it's message loop is never started. fWindow->Unlock(); } else fInitError = B_NO_MEMORY; } } }
status_t get_mouse_bitmap(BBitmap** bitmap, BPoint* hotspot) { if (bitmap == NULL && hotspot == NULL) return B_BAD_VALUE; BPrivate::AppServerLink link; link.StartMessage(AS_GET_CURSOR_BITMAP); int32 code; status_t status = link.FlushWithReply(code); if (status != B_OK) return status; if (code != B_OK) return code; uint32 size = 0; uint32 cursorWidth = 0; uint32 cursorHeight = 0; // if link.Read() returns an error, the same error will be returned on // subsequent calls, so we'll check only the return value of the last call link.Read<uint32>(&size); link.Read<uint32>(&cursorWidth); link.Read<uint32>(&cursorHeight); if (hotspot == NULL) { BPoint dummy; link.Read<BPoint>(&dummy); } else link.Read<BPoint>(hotspot); void* data = NULL; if (size > 0) data = malloc(size); if (data == NULL) return B_NO_MEMORY; status = link.Read(data, size); if (status != B_OK) { free(data); return status; } BBitmap* cursorBitmap = new (std::nothrow) BBitmap(BRect(0, 0, cursorWidth - 1, cursorHeight - 1), B_RGBA32); if (cursorBitmap == NULL) { free(data); return B_NO_MEMORY; } status = cursorBitmap->InitCheck(); if (status == B_OK) cursorBitmap->SetBits(data, size, 0, B_RGBA32); free(data); if (status == B_OK && bitmap != NULL) *bitmap = cursorBitmap; else delete cursorBitmap; return status; }