📄 directfb.c
字号:
/* directfb.c * DirectFB graphics driver * (c) 2002 Sven Neumann <sven@directfb.org> * * This file is a part of the Links program, released under GPL. *//* TODO: * - Store window size as driver params (?) * - Fix wrong colors on big-endian systems (fixed?) * - Make everything work correctly ;-) * * KNOWN PROBLEMS: * - If mouse drags don't work for you, update DirectFB * (the upcoming 0.9.14 release fixes this). */#include "cfg.h"#ifdef GRDRV_DIRECTFB#ifdef TEXT#undef TEXT#endif#include <netinet/in.h> /* for htons */#include <directfb.h>#include "links.h"#include "directfb_cursors.h"#define FOCUSED_OPACITY 0xFF#define UNFOCUSED_OPACITY 0xC0#define DIRECTFB_HASH_TABLE_SIZE 23struct graphics_device **directfb_hash_table[DIRECTFB_HASH_TABLE_SIZE];typedef struct _DFBDeviceData DFBDeviceData;struct _DFBDeviceData{ DFBWindowID id; IDirectFBWindow *window; IDirectFBSurface *surface; int mapped; DFBRegion flip_region; int flip_pending;};extern struct graphics_driver directfb_driver;static IDirectFB *dfb = NULL;static IDirectFBDisplayLayer *layer = NULL;static IDirectFBSurface *arrow = NULL;static IDirectFBEventBuffer *events = NULL;static DFBSurfacePixelFormat pixelformat = DSPF_UNKNOWN;static int event_timer = -1;static inline void directfb_set_color (IDirectFBSurface *surface, long color);static void directfb_register_flip (DFBDeviceData *data, int x, int y, int w, int h);static void directfb_flip_surface (void *pointer);static void directfb_check_events (void *pointer);static void directfb_translate_key (DFBWindowEvent *event, int *key, int *flag);static void directfb_add_to_table (struct graphics_device *gd);static void directfb_remove_from_table (struct graphics_device *gd);static struct graphics_device * directfb_lookup_in_table (DFBWindowID id);static unsigned char *directfb_fb_init_driver (unsigned char *param, unsigned char *display){ DFBDisplayLayerConfig config; DFBResult ret; if (dfb) return NULL; DirectFBInit (&g_argc, (char ***)(void *)&g_argv); ret = DirectFBCreate (&dfb); if (ret) { char message[128]; snprintf (message, sizeof (message), "%s\n", DirectFBErrorString (ret)); return stracpy (message); } dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer); layer->GetConfiguration (layer, &config); pixelformat = config.pixelformat; directfb_driver.depth = (((DFB_BYTES_PER_PIXEL (pixelformat) & 0x7)) | ((DFB_BITS_PER_PIXEL (pixelformat) & 0x1F) << 3)); /* endian test */ if (htons (0x1234) == 0x1234) directfb_driver.depth |= 0x100; switch (directfb_driver.depth) { case 33: case 65: case 122: case 130: case 378: case 386: case 451: case 195: case 452: case 196: case 708: break; default: layer->Release(layer); dfb->Release(dfb); return stracpy("Unsupported color depth.\n"); } directfb_driver.x = config.width; directfb_driver.y = config.height; memset (directfb_hash_table, 0, sizeof (directfb_hash_table)); if (dfb->CreateSurface (dfb, &arrow_desc, &arrow) != DFB_OK) arrow = NULL; return NULL;}static struct graphics_device *directfb_init_device (void){ struct graphics_device *gd; DFBDeviceData *data; IDirectFBWindow *window; DFBWindowDescription desc; if (!dfb || !layer) return NULL; desc.flags = DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY; desc.width = directfb_driver.x; desc.height = directfb_driver.y; desc.posx = 0; desc.posy = 0; if (layer->CreateWindow (layer, &desc, &window) != DFB_OK) return NULL; gd = mem_alloc (sizeof (struct graphics_device)); gd->size.x1 = 0; gd->size.y1 = 0; window->GetSize (window, &gd->size.x2, &gd->size.y2); gd->clip = gd->size; data = mem_alloc (sizeof (DFBDeviceData)); data->window = window; data->mapped = 0; data->flip_pending = 0; if (arrow) window->SetCursorShape (window, arrow, arrow_hot_x, arrow_hot_y); window->GetSurface (window, &data->surface); window->GetID (window, &data->id); gd->drv = &directfb_driver; gd->driver_data = data; gd->user_data = NULL; directfb_add_to_table (gd); if (!events) { window->CreateEventBuffer (window, &events); event_timer = install_timer (20, directfb_check_events, events); } else { window->AttachEventBuffer (window, events); } return gd;}static voiddirectfb_shutdown_device (struct graphics_device *gd){ DFBDeviceData *data; if (!gd) return; data = gd->driver_data; unregister_bottom_half (directfb_flip_surface, data); directfb_remove_from_table (gd); data->surface->Release (data->surface); data->window->Release (data->window); mem_free (data); mem_free (gd);}static voiddirectfb_shutdown_driver (void){ int i; if (!dfb) return; if (events) { kill_timer (event_timer); events->Release (events); events = NULL; } if (arrow) arrow->Release (arrow); layer->Release (layer); dfb->Release (dfb); for (i = 0; i < DIRECTFB_HASH_TABLE_SIZE; i++) if (directfb_hash_table[i]) mem_free (directfb_hash_table[i]); dfb = NULL;}static unsigned char *directfb_get_driver_param (void){ return NULL;}static intdirectfb_get_empty_bitmap (struct bitmap *bmp){ IDirectFBSurface *surface; DFBSurfaceDescription desc; bmp->data = bmp->flags = NULL; desc.flags = DSDESC_WIDTH | DSDESC_HEIGHT; desc.width = bmp->x; desc.height = bmp->y; if (dfb->CreateSurface (dfb, &desc, &surface) != DFB_OK) return 0; surface->Lock (surface, DSLF_READ | DSLF_WRITE, &bmp->data, &bmp->skip); bmp->flags = surface; return 0;}/*static intdirectfb_get_filled_bitmap (struct bitmap *bmp, long color){ IDirectFBSurface *surface; DFBSurfaceDescription desc; bmp->data = bmp->flags = NULL; desc.flags = DSDESC_WIDTH | DSDESC_HEIGHT; desc.width = bmp->x; desc.height = bmp->y; if (dfb->CreateSurface (dfb, &desc, &surface) != DFB_OK) return 0; directfb_set_color (surface, color); surface->FillRectangle (surface, 0, 0, bmp->x, bmp->y); surface->Lock (surface, DSLF_READ | DSLF_WRITE, &bmp->data, &bmp->skip); bmp->flags = surface; return 0;}*/static voiddirectfb_register_bitmap (struct bitmap *bmp){ IDirectFBSurface *surface = bmp->flags; surface->Unlock (surface); bmp->data = NULL;}static void *directfb_prepare_strip (struct bitmap *bmp, int top, int lines){ IDirectFBSurface *surface = bmp->flags; surface->Lock (surface, DSLF_READ | DSLF_WRITE, &bmp->data, &bmp->skip); return ((unsigned char *) bmp->data + top * bmp->skip);}static voiddirectfb_commit_strip (struct bitmap *bmp, int top, int lines){ IDirectFBSurface *surface = bmp->flags; surface->Unlock (surface); bmp->data = NULL;}static voiddirectfb_unregister_bitmap (struct bitmap *bmp){ IDirectFBSurface *surface = bmp->flags; surface->Release (surface);}static voiddirectfb_draw_bitmap (struct graphics_device *gd, struct bitmap *bmp, int x, int y){ DFBDeviceData *data = gd->driver_data; IDirectFBSurface *src = bmp->flags; data->surface->Blit (data->surface, src, NULL, x, y); directfb_register_flip (data, x, y, bmp->x, bmp->y);}static voiddirectfb_draw_bitmaps (struct graphics_device *gd, struct bitmap **bmps, int n, int x, int y){ DFBDeviceData *data = gd->driver_data; struct bitmap *bmp = *bmps; int x1 = x; int h = 0; if (n < 1) return; do { IDirectFBSurface *src = bmp->flags; data->surface->Blit (data->surface, src, NULL, x, y); if (h < bmp->y) h = bmp->y; x += bmp->x; bmp++; } while (--n); directfb_register_flip (data, x1, y, x - x1, h);}static longdirectfb_get_color (int rgb){ return rgb;}static voiddirectfb_fill_area (struct graphics_device *gd, int x1, int y1, int x2, int y2, long color){ DFBDeviceData *data = gd->driver_data; int w = x2 - x1; int h = y2 - y1; directfb_set_color (data->surface, color); data->surface->FillRectangle (data->surface, x1, y1, w, h); directfb_register_flip (data, x1, y1, w, h);}static voiddirectfb_draw_hline (struct graphics_device *gd, int left, int y, int right, long color){ DFBDeviceData *data = gd->driver_data; right--; directfb_set_color (data->surface, color); data->surface->DrawLine (data->surface, left, y, right, y); directfb_register_flip (data, left, y, right - left, 1);}static voiddirectfb_draw_vline (struct graphics_device *gd, int x, int top, int bottom, long color){ DFBDeviceData *data = gd->driver_data; bottom--; directfb_set_color (data->surface, color); data->surface->DrawLine (data->surface, x, top, x, bottom); directfb_register_flip (data, x, top, 1, bottom - top);}static voiddirectfb_set_clip_area (struct graphics_device *gd, struct rect *r){ DFBDeviceData *data = gd->driver_data; DFBRegion region = { r->x1, r->y1, r->x2 - 1, r->y2 - 1}; gd->clip = *r; data->surface->SetClip (data->surface, ®ion);}static intdirectfb_hscroll (struct graphics_device *gd, struct rect_set **set, int sc)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -