📄 harness.c
字号:
/* Copyright 1999, Be Incorporated. All Rights Reserved. This file may be used under the terms of the Be Sample Code License.*/#include <FindDirectory.h>#include <OS.h>#include <image.h>#include <graphic_driver.h>#include <Accelerant.h>#include <stdio.h>#include <dirent.h>#include <string.h>#include <sys/stat.h>#include <malloc.h>#include <errno.h>#include "video_overlay.h"static uint8 my_hand_cursor_xor[] = {#if 0 0xf0, 0x0f, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x08, 0x10, 0x08, 0x10, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f#else0x0,0x0,0x0,0x0,0x38,0x0,0x24,0x0,0x24,0x0,0x13,0xe0,0x12,0x5c,0x9,0x2a,0x8,0x1,0x3c,0x1,0x4c,0x1,0x42,0x1,0x30,0x1,0xc,0x1,0x2,0x0,0x1,0x0#endif};static uint8 my_hand_cursor_and[] = {#if 0 0xf0, 0x0f, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x08, 0x10, 0x08, 0x10, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f#else0x0,0x0,0x0,0x0,0x38,0x0,0x3c,0x0,0x3c,0x0,0x1f,0xe0,0x1f,0xfc,0xf,0xfe,0xf,0xff,0x3f,0xff,0x7f,0xff,0x7f,0xff,0x3f,0xff,0xf,0xff,0x3,0xfe,0x1,0xf8#endif};static const char *spaceToString(uint32 cs) { const char *s; switch (cs) {#define s2s(a) case a: s = #a ; break s2s(B_RGB32); s2s(B_RGBA32); s2s(B_RGB32_BIG); s2s(B_RGBA32_BIG); s2s(B_RGB16); s2s(B_RGB16_BIG); s2s(B_RGB15); s2s(B_RGBA15); s2s(B_RGB15_BIG); s2s(B_RGBA15_BIG); s2s(B_CMAP8); s2s(B_GRAY8); s2s(B_GRAY1); s2s(B_YUV422); s2s(B_YUV411); s2s(B_YUV9); s2s(B_YUV12); s2s(B_YCbCr422); s2s(B_YCbCr411); default: s = "unknown"; break;#undef s2s } return s;}int pick_from_list(const char *msg, char **list) { int count = 1; int choice; puts(msg); while (*list) { printf(" %2.0d) %s\n", count, *list); list++; count++; } while (1) { printf("Enter [1-%d]: ", count-1); fflush(stdout); scanf("%d", &choice); if ((choice >= 0) && (choice < count)) break; } return choice - 1;}/* return a file descriptor of the desired device, or -1 on failure */int pick_device(const char *apath) { int count = 0; int choice; DIR *d; struct dirent *e; char name_buf[1024], message[256], *names[16], *name = name_buf; /* open directory apath */ d = opendir(apath); if (!d) return B_ERROR; /* get a list of devices, filtering out . and .. */ while ((e = readdir(d)) != NULL) { if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, "..")) continue; strcpy(name, e->d_name); names[count++] = name; name += strlen(name)+1; } closedir(d); names[count] = NULL; /* if there are no devices, return error */ if (count == 0) return B_ERROR; /* prompt user for which device */ sprintf(message, "Choose from these devices found in %s:", apath); choice = pick_from_list(message, names); if (choice >= 0) { sprintf(message, "%s/%s", apath, names[choice]); return open(message, B_READ_WRITE); } return B_ERROR;}image_id load_accelerant(int fd, GetAccelerantHook *hook) { status_t result; image_id image = -1; int i; char signature[1024], path[PATH_MAX]; struct stat st; const static directory_which vols[] = { B_USER_ADDONS_DIRECTORY, B_COMMON_ADDONS_DIRECTORY, B_BEOS_ADDONS_DIRECTORY }; /* get signature from driver */ result = ioctl(fd, B_GET_ACCELERANT_SIGNATURE, &signature, sizeof(signature)); if (result != B_OK) goto done; printf("B_GET_ACCELERANT_SIGNATURE returned ->%s<-\n", signature); // note failure by default image = -1; for(i=0; i < sizeof (vols) / sizeof (vols[0]); i++) { /* --- compute directory path to common or beos addon directory on floppy or boot volume --- */ if (find_directory (vols[i], -1, false, path, PATH_MAX) != B_OK) continue; strcat (path, "/accelerants/"); strcat (path, signature); // don't try to load non-existant files if (stat(path, &st) != 0) continue; printf("Trying to load accelerant: %s\n", path); // load the image image = load_add_on(path); if (image >= 0) { printf("Accelerant loaded!\n"); // get entrypoint from accelerant result = get_image_symbol(image, B_ACCELERANT_ENTRY_POINT,#if defined(__INTEL__) B_SYMBOL_TYPE_ANY,#else B_SYMBOL_TYPE_TEXT,#endif (void **)hook); if (result == B_OK) { init_accelerant ia; printf("Entry point %s() found\n", B_ACCELERANT_ENTRY_POINT); ia = (init_accelerant)(*hook)(B_INIT_ACCELERANT, NULL); printf("init_accelerant is 0x%08lx\n", (uint32)ia); if (ia && ((result = ia(fd)) == B_OK)) { // we have a winner! printf("Accelerant %s accepts the job!\n", path); break; } else { printf("init_accelerant refuses the the driver: %ld\n", result); } } else { printf("Couldn't find the entry point :-(\n"); } // unload the accelerant, as we must be able to init! unload_add_on(image); } if (image < 0) printf("image failed to load :-(\n"); // mark failure to load image image = -1; } printf("Add-on image id: %ld\n", image);done: return image;}typedef struct { uint32 opcode; char *command_name;} command;#define MK_CMD(x) { x, #x }enum { T_PICK_A_MODE = B_ACCELERANT_PRIVATE_START+10000};static command commands[] = { /* mode configuration */ MK_CMD(B_ACCELERANT_MODE_COUNT), /* required */ MK_CMD(B_GET_MODE_LIST), /* required */ MK_CMD(T_PICK_A_MODE), MK_CMD(B_PROPOSE_DISPLAY_MODE), /* optional */ MK_CMD(B_SET_DISPLAY_MODE), /* required */ MK_CMD(B_GET_DISPLAY_MODE), /* required */ MK_CMD(B_GET_FRAME_BUFFER_CONFIG), /* required */ MK_CMD(B_GET_PIXEL_CLOCK_LIMITS), /* required */ MK_CMD(B_MOVE_DISPLAY), /* optional */ MK_CMD(B_SET_INDEXED_COLORS), /* required if driver supports 8bit indexed modes */ MK_CMD(B_ACCELERANT_RETRACE_SEMAPHORE), MK_CMD(B_SET_DPMS_MODE), /* optional */ /* cursor managment */ MK_CMD(B_MOVE_CURSOR), /* optional */ MK_CMD(B_SET_CURSOR_SHAPE), /* optional */ MK_CMD(B_SHOW_CURSOR), /* optional */ /* synchronization */ MK_CMD(B_ACQUIRE_ENGINE), MK_CMD(B_RELEASE_ENGINE), MK_CMD(B_WAIT_ENGINE_IDLE), /* 2D acceleration */ MK_CMD(B_SCREEN_TO_SCREEN_BLIT), MK_CMD(B_FILL_RECTANGLE), MK_CMD(B_INVERT_RECTANGLE), MK_CMD(B_FILL_SPAN), // overlays MK_CMD(B_OVERLAY_COUNT), MK_CMD(B_OVERLAY_SUPPORTED_SPACES), MK_CMD(B_OVERLAY_SUPPORTED_FEATURES), MK_CMD(B_ALLOCATE_OVERLAY_BUFFER), MK_CMD(B_RELEASE_OVERLAY_BUFFER), MK_CMD(B_GET_OVERLAY_CONSTRAINTS), MK_CMD(B_ALLOCATE_OVERLAY), MK_CMD(B_RELEASE_OVERLAY), MK_CMD(B_CONFIGURE_OVERLAY)};#define CMD_SIZE (sizeof(commands) / sizeof(command))void missing_feature(char *s) { printf("Accelerant doesn't implement required feature %s\n", s);}void missing_option(char *s) { printf("Accelerant doesn't implement optional feature %s\n", s);}void failed_with_reason(char *s, status_t r) { printf("%s failed with reason %ld (0x%08lx)\n", s, r, r);}void dump_mode(display_mode *dm) { display_timing *t = &(dm->timing); printf(" pixel_clock: %ldKHz\n", t->pixel_clock); printf(" H: %4d %4d %4d %4d\n", t->h_display, t->h_sync_start, t->h_sync_end, t->h_total); printf(" V: %4d %4d %4d %4d\n", t->v_display, t->v_sync_start, t->v_sync_end, t->v_total); printf(" timing flags:"); if (t->flags & B_BLANK_PEDESTAL) printf(" B_BLANK_PEDESTAL"); if (t->flags & B_TIMING_INTERLACED) printf(" B_TIMING_INTERLACED"); if (t->flags & B_POSITIVE_HSYNC) printf(" B_POSITIVE_HSYNC"); if (t->flags & B_POSITIVE_VSYNC) printf(" B_POSITIVE_VSYNC"); if (t->flags & B_SYNC_ON_GREEN) printf(" B_SYNC_ON_GREEN"); if (!t->flags) printf(" (none)\n"); else printf("\n"); printf(" refresh rate: %4.2f\n", ((double)t->pixel_clock * 1000) / ((double)t->h_total * (double)t->v_total)); printf(" color space: %s\n", spaceToString(dm->space)); printf(" virtual size: %dx%d\n", dm->virtual_width, dm->virtual_height); printf("dispaly start: %d,%d\n", dm->h_display_start, dm->v_display_start); printf(" mode flags:"); if (dm->flags & B_SCROLL) printf(" B_SCROLL"); if (dm->flags & B_8_BIT_DAC) printf(" B_8_BIT_DAC"); if (dm->flags & B_HARDWARE_CURSOR) printf(" B_HARDWARE_CURSOR"); if (dm->flags & B_PARALLEL_ACCESS) printf(" B_PARALLEL_ACCESS"); if (!dm->flags) printf(" (none)\n"); else printf("\n");}display_mode * pick_a_mode(display_mode *mode_list, uint32 mode_count) { char **modes = (char **)calloc(sizeof(char *),mode_count+1); char buffer[128]; int mode; display_mode *dm = NULL; if (!modes) { printf("Couldn't allocate enough RAM for pick-a-mode list.\n"); goto done; } for (mode = 0; mode < mode_count; mode++) { display_mode *dm = mode_list + mode; sprintf(buffer, "%dx%d@%ldKHz (%dx%d virtual) %s", dm->timing.h_display, dm->timing.v_display, dm->timing.pixel_clock, dm->virtual_width, dm->virtual_height, spaceToString(dm->space)); modes[mode] = strdup(buffer); } modes[mode] = NULL; mode = pick_from_list("Select a display mode:", modes); if (mode >= 0) { dm = mode_list + mode; dump_mode(dm); } for (mode = 0; mode < mode_count; mode++) free(modes[mode]); free(modes);done: return dm;}void dump_overlay_limits( const char *name, const overlay_limits *limits ){ printf( "%s limits:\n", name ); printf( " h_alignment: %d\n", limits->h_alignment ); printf( " v_alignment: %d\n", limits->v_alignment ); printf( " width_alignment: %d\n", limits->width_alignment ); printf( "height_alignment: %d\n", limits->height_alignment ); printf( " width: %d-%d\n", limits->width.min, limits->width.max ); printf( " height: %d-%d\n", limits->height.min, limits->height.max ); printf( "\n" );}void dump_overlay_scale_limits( const char *name, const overlay_float_minmax *limits ){ printf( "%s limits: %4.2f-%4.2f\n", name, limits->min, limits->max );}void exercise_driver(GetAccelerantHook gah) { /* make list of commands for picker */ char **cmds = (char **)calloc(sizeof(char *), 1 + CMD_SIZE); int i; status_t result; uint32 mode_count = 0; display_mode dm, *mode_list = NULL; engine_token *et; bool valid_mode = FALSE, engine_acquired = FALSE; const uint32 *overlay_cs = NULL; const char **overlay_cs_names = NULL; const overlay_buffer *ob = NULL; overlay_token ot = NULL; if (!cmds) { printf("Couldn't allocate memory for command name list!\n"); return; } for (i = 0; i < CMD_SIZE; i++) cmds[i] = commands[i].command_name; cmds[i] = NULL; while ((i = pick_from_list("Pick a command:", cmds)) >= 0) { switch (commands[i].opcode) { case B_ACCELERANT_MODE_COUNT: { accelerant_mode_count gmc = gah(B_ACCELERANT_MODE_COUNT, NULL); if (!gmc) { missing_feature(cmds[i]); break; } mode_count = gmc(); printf("Device supports %ld modes\n", mode_count); } break; case B_GET_MODE_LIST: { get_mode_list gml = gah(B_GET_MODE_LIST, NULL); if (!gml) { missing_feature(cmds[i]); break; } if (mode_count == 0) { printf("Do B_ACCELERANT_MODE_COUNT first!\n"); break; } if (mode_list) free(mode_list); mode_list = (display_mode *)calloc(sizeof(display_mode), mode_count); if (!mode_list) { printf("Couldn't allocate enough RAM for display_mode list.\n"); break; } result = gml(mode_list); printf("Mode list retrieved with result %ld\n", result); } break; case T_PICK_A_MODE: { if (mode_list) { display_mode *adm = pick_a_mode(mode_list, mode_count); if (adm) { dm = *adm; valid_mode = TRUE; } } else printf("Do B_GET_MODE_LIST first!\n"); } break; case B_SET_DISPLAY_MODE: { set_display_mode sdc = gah(B_SET_DISPLAY_MODE, NULL); if (!sdc) { missing_feature(cmds[i]); break; } if (!valid_mode) { printf("Do T_PICK_A_MODE or B_PROPOSE_DISPLAY_MODE first!\n"); break; } result = sdc(&dm); printf("set_display_mode() completed with result %ld\n", result); } break; case B_GET_DISPLAY_MODE: { get_display_mode gdc = gah(B_GET_DISPLAY_MODE, NULL); if (!gdc) { missing_feature(cmds[i]); break; } result = gdc(&dm); if (result != B_OK) { printf("get_display_mode() failed: %ld (0x%08lx)\n", result, result); break; } printf("get_display_mode() suceeded!\n"); valid_mode = TRUE; dump_mode(&dm); } break; case B_GET_FRAME_BUFFER_CONFIG: { frame_buffer_config fbc; get_frame_buffer_config gfbc = gah(B_GET_FRAME_BUFFER_CONFIG, NULL); if (!gfbc) { missing_feature(cmds[i]); break; } if (!valid_mode) { printf("Do T_PICK_A_MODE or B_PROPOSE_DISPLAY_MODE first!\n"); break; } result = gfbc(&fbc); if (result != B_OK) { printf("get_frame_buffer_config() failed: %ld (0x%08lx)\n", result, result); break; } printf("get_frame_buffer_config() suceeded!\n"); printf(" frame buffer: 0x%08lx\n", (uint32)fbc.frame_buffer); printf(" dma buffer: 0x%08lx\n", (uint32)fbc.frame_buffer_dma); printf("bytes per row: %ld\n\n", fbc.bytes_per_row); switch (dm.space & ~0x3000) { case B_CMAP8: { int16 x, y; uint8 *fb = (uint8 *)fbc.frame_buffer; printf(" frame buffer is 8bpp\n"); /* make a checkerboard pattern */ for (y = 0; y < (dm.virtual_height >> 1); y++) { for (x = 0; x < (dm.virtual_width >> 1); x++) { fb[x] = 0; } for (; x < dm.virtual_width; x++) { fb[x] = 0xff; } fb += fbc.bytes_per_row; } for (; y < dm.virtual_height; y++) { for (x = 0; x < (dm.virtual_width >> 1); x++) { fb[x] = 0xff; } for (; x < dm.virtual_width; x++) { fb[x] = 0; } fb += fbc.bytes_per_row; } } break; case B_RGB16_BIG: case B_RGB16_LITTLE: case B_RGB15_BIG: case B_RGBA15_BIG: case B_RGB15_LITTLE: case B_RGBA15_LITTLE: { int x, y; uint16 *fb = (uint16 *)fbc.frame_buffer; printf(" frame buffer is 16bpp\n"); /* make a checkerboard pattern */ for (y = 0; y < (dm.virtual_height >> 1); y++) { for (x = 0; x < (dm.virtual_width >> 1); x++) { fb[x] = 0; } for (; x < dm.virtual_width; x++) { fb[x] = 0xffff; } fb = (uint16 *)(((uint8 *)fb) + fbc.bytes_per_row); } for (; y < dm.virtual_height; y++) { for (x = 0; x < (dm.virtual_width >> 1); x++) { fb[x] = 0xffff; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -