📄 grbeos.cpp
字号:
/*******************************************************************
*
* grbeos.c graphics driver for BeOS platform. 0.1
*
* This is the driver for displaying inside a window under BeOS,
* used by the graphics utility of the FreeType test suite.
*
* Written by Michael Pfeiffer.
* Copyright 2001 by Michael Pfeiffer
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
******************************************************************/
#include <be/app/Application.h>
#include <be/app/MessageQueue.h>
#include <be/interface/InterfaceDefs.h>
#include <be/interface/Window.h>
#include <be/interface/View.h>
#include <be/interface/Bitmap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <grobjs.h>
#include <grdevice.h>
#include "grbeos.h"
/* logging facility */
#include <stdarg.h>
#define DEBUG
#ifdef DEBUG
#define LOG(x) LogMessage##x
#else
#define LOG(x) /* empty */
#endif
#ifdef DEBUG
static void LogMessage( const char* fmt, ... )
{
va_list ap;
va_start( ap, fmt );
vfprintf( stderr, fmt, ap );
va_end( ap );
}
#endif
typedef struct _Translator
{
int32 beoskey;
grKey grkey;
} Translator;
static
Translator key_translators[] =
{
{ B_BACKSPACE, grKeyBackSpace },
{ B_TAB, grKeyTab },
{ B_ENTER, grKeyReturn },
{ B_ESCAPE, grKeyEsc },
{ B_HOME, grKeyHome },
{ B_LEFT_ARROW, grKeyLeft },
{ B_UP_ARROW, grKeyUp },
{ B_RIGHT_ARROW, grKeyRight },
{ B_DOWN_ARROW, grKeyDown },
{ B_PAGE_UP, grKeyPageUp },
{ B_PAGE_DOWN, grKeyPageDown },
{ B_END, grKeyEnd }
};
static
Translator fkey_translators[] =
{
{ B_F1_KEY, grKeyF1 },
{ B_F2_KEY, grKeyF2 },
{ B_F3_KEY, grKeyF3 },
{ B_F4_KEY, grKeyF4 },
{ B_F5_KEY, grKeyF5 },
{ B_F6_KEY, grKeyF6 },
{ B_F7_KEY, grKeyF7 },
{ B_F8_KEY, grKeyF8 },
{ B_F9_KEY, grKeyF9 },
{ B_F10_KEY, grKeyF10 },
{ B_F11_KEY, grKeyF11 },
{ B_F12_KEY, grKeyF12 }
};
static Translator* find_key(int32 key, Translator t[], int size) {
for (int i = 0; i < size; i++) {
if (t[i].beoskey == key) {
return &t[i];
}
}
return NULL;
}
static const grPixelMode pixel_modes[] =
{
gr_pixel_mode_mono,
gr_pixel_mode_gray
// gr_pixel_mode_rgb565,
// gr_pixel_mode_rgb32,
};
class Window;
typedef struct grBeOSSurface_
{
grSurface root;
Window* window;
} grBeOSSurface;
class Window : public BWindow {
private:
grBeOSSurface* _surface;
BBitmap* _offscreen;
BBitmap* _bitmap;
BMessageQueue _event_queue;
sem_id _locker;
class View : public BView {
BBitmap* _offscreen;
BMessageQueue* _event_queue;
sem_id _locker;
public:
View(BBitmap* offscreen, BMessageQueue* event_queue, sem_id locker, BRect r);
void Draw(BRect r);
void KeyDown(const char *bytes, int32 numBytes);
};
View* _view;
public:
Window(grBeOSSurface* surface, grBitmap* bitmap);
~Window();
void Refresh(int x, int y, int w, int h);
int listen_event(int event_mask, grEvent* grevent);
static grSurface* init_surface(grSurface* surface, grBitmap* bitmap);
static void done_surface(grSurface* surface);
static void refresh_rectangle(grSurface* surface, int x, int y, int w, int h);
static void set_title(grSurface* surface, const char* title);
static int listen_event(grSurface* surface, int event_mask, grEvent* grevent);
};
static int init_device();
static void done_device(void);
grDevice gr_beos_device =
{
sizeof( grBeOSSurface ),
"beos",
init_device,
done_device,
(grDeviceInitSurfaceFunc) Window::init_surface,
0,
0
};
static int init_device() {
gr_beos_device.num_pixel_modes = 2;
gr_beos_device.pixel_modes = (grPixelMode*) pixel_modes;
new BApplication("application/x.mp.freetype.test");
return 0;
}
static void done_device(void) {
if (be_app) {
delete be_app;
be_app = NULL;
}
}
Window::View::View(BBitmap* offscreen, BMessageQueue* event_queue, sem_id locker, BRect r) :
BView(r, "", B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW),
_offscreen(offscreen),
_event_queue(event_queue),
_locker(locker) {
SetViewColor(B_TRANSPARENT_COLOR);
}
void Window::View::Draw(BRect r) {
DrawBitmap(_offscreen);
}
void Window::View::KeyDown(const char *bytes, int32 numBytes) {
BMessage* m = Window()->CurrentMessage();
int32 key;
if (B_OK == m->FindInt32("key", &key)) {
Translator* t = NULL;
if (numBytes == 1) {
if (*bytes == B_FUNCTION_KEY) {
t = find_key(key, fkey_translators, sizeof(fkey_translators)/sizeof(Translator));
} else {
t = find_key(*bytes, key_translators, sizeof(key_translators)/sizeof(Translator));
}
}
if (t || numBytes == 1) {
_event_queue->Lock();
if (_event_queue->IsEmpty()) release_sem(_locker);
_event_queue->AddMessage(new BMessage(t ? t->grkey : *bytes));
_event_queue->Unlock();
return;
}
}
BView::KeyDown(bytes, numBytes);
}
int Window::listen_event(int event_mask, grEvent* grevent) {
acquire_sem(_locker);
_event_queue.Lock();
BMessage* m = _event_queue.NextMessage();
if (!_event_queue.IsEmpty()) release_sem(_locker);
_event_queue.Unlock();
grevent->type = gr_key_down;
grevent->key = (grKey)m->what;
delete m;
return 0;
}
Window::Window(grBeOSSurface* surface, grBitmap* bitmap) :
BWindow(BRect(20, 20, 100, 100), "", B_TITLED_WINDOW, B_NOT_CLOSABLE | B_NOT_RESIZABLE | B_NOT_ZOOMABLE) {
_locker = create_sem(0, "event_locker");
_surface = surface;
surface->root.done = done_surface;
surface->root.refresh_rect = refresh_rectangle;
surface->root.set_title = set_title;
surface->root.listen_event = listen_event;
surface->window = this;
int w = bitmap->width;
int h = bitmap->rows;
BRect r(0, 0, w, h);
switch (bitmap->mode) {
case gr_pixel_mode_mono:
_bitmap = new BBitmap(r, B_GRAY1);
break;
case gr_pixel_mode_gray:
_bitmap = new BBitmap(r, B_CMAP8);
break;
case gr_pixel_mode_rgb565:
_bitmap = new BBitmap(r, B_RGB16);
break;
case gr_pixel_mode_rgb32:
_bitmap = new BBitmap(r, B_RGB32);
break;
default:
LOG(("unsupported mode"));
exit(-1);
}
bitmap->buffer = (unsigned char*)_bitmap->Bits();
bitmap->pitch = _bitmap->BytesPerRow();
_surface->root.bitmap = *bitmap;
_offscreen = new BBitmap(r, B_RGB32);
_view = new View(_offscreen, &_event_queue, _locker, r);
AddChild(_view);
_view->MakeFocus(true);
ResizeTo(w, h);
Show();
}
Window::~Window() {
delete_sem(_locker);
delete _offscreen; delete _bitmap;
}
void Window::Refresh(int x, int y, int w, int h) {
int32* d = (int32*)_offscreen->Bits();
int32* dl = d;
uint8* s = (uint8*)_bitmap->Bits();
uint8* sl = s;
if (Lock()) {
switch(_surface->root.bitmap.mode) {
case gr_pixel_mode_mono:
for (y = 0; y < _surface->root.bitmap.rows; y++) {
sl = s;
dl = d;
for (x = 0; x < _surface->root.bitmap.width; x++) {
*dl = *sl ? -1 : 0;
sl++; dl++;
}
s += _bitmap->BytesPerRow();
d = (int32*)(((char*)d) + _offscreen->BytesPerRow());
}
break;
case gr_pixel_mode_gray:
for (y = 0; y < _surface->root.bitmap.rows; y++) {
sl = s;
int8* dx = (int8*)d;
for (x = 0; x < _surface->root.bitmap.width; x++) {
*dx = *sl; dx++;
*dx = *sl; dx++;
*dx = *sl; dx++;
*dx = *sl; dx++;
sl++;
}
s += _bitmap->BytesPerRow();
d = (int32*)(((char*)d) + _offscreen->BytesPerRow());
}
break;
default:
fprintf(stderr, "unsupported mode: %d\n", _surface->root.bitmap.mode);
break;
}
_view->Invalidate();
Unlock();
}
}
grSurface* Window::init_surface( grSurface* surface, grBitmap* bitmap) {
new Window((grBeOSSurface*) surface, bitmap);
return surface;
}
void Window::done_surface(grSurface* surface) {
Window* w = ((grBeOSSurface*)surface)->window;
if (w->Lock()) {
w->PostMessage(B_QUIT_REQUESTED);
w->Unlock();
}
}
void Window::refresh_rectangle(grSurface* surface, int x, int y, int w, int h) {
Window* win = ((grBeOSSurface*)surface)->window;
win->Refresh(x, y, w, h);
}
void Window::set_title(grSurface* surface, const char* title) {
Window* win = ((grBeOSSurface*)surface)->window;
if (win->Lock()) {
win->SetTitle(title);
win->Unlock();
}
}
int Window::listen_event(grSurface* surface, int event_mask, grEvent* grevent) {
Window* win = ((grBeOSSurface*)surface)->window;
return win->listen_event(event_mask, grevent);
}
/* End */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -