char *svga_rcall(uint64_t source, struct vfs_obj *file, const char *args) { char *rets = NULL; int x, y, d, w, h; int mode; if (!strcmp(args, "getmode")) { rets = malloc(16); sprintf(rets, "%d %d %d", svga.w, svga.h, svga.d); return rets; } if (!strcmp(args, "listmodes")) { return strdup(modesstr); } if (!strcmp(args, "unshare")) { mutex_spin(&file->mutex); page_free(buffer, msize(buffer)); free(buffer); buffer = valloc(svga.w * svga.h * 4); mutex_free(&file->mutex); return strdup("T"); } if (!strncmp(args, "setmode ", 8)) { if (sscanf(args + 8, "%i %i %i", &x, &y, &d) != 3) { return strdup(""); } mutex_spin(&file->mutex); mode = svga_find_mode(x, y, d); if (svga_set_mode(mode)) { return strdup(""); } page_free(buffer, msize(buffer)); free(buffer); buffer = valloc(svga.w * svga.h * 4); mutex_free(&file->mutex); return strdup("T"); } if (!strncmp(args, "syncrect ", 9)) { if (sscanf(args + 9, "%i %i %i %i", &x, &y, &w, &h) != 4) { return strdup(""); } mutex_spin(&file->mutex); svga_fliprect(buffer, x, y, w, h); mutex_free(&file->mutex); return strdup("T"); } return NULL; }
int main(int argc, char **argv) { struct vfs_obj *root; char *modesstr0; char *modestr; int i; root = calloc(sizeof(struct vfs_obj), 1); root->type = RP_TYPE_FILE; root->size = 0; root->acl = acl_set_default(root->acl, PERM_READ | PERM_WRITE); vfs_set_index(0, root); svga_init(); // generate list of modes modesstr = strdup(""); for (i = 0; i < modelist_count; i++) { modesstr0 = modesstr; modestr = malloc(16); sprintf(modestr, "%d:%d:%d ", modelist[i].w, modelist[i].h, modelist[i].d); modesstr = strvcat(modesstr, modestr, NULL); free(modesstr0); } svga_set_mode(svga_find_mode(640, 480, 24)); buffer = malloc(svga.w * svga.h * 4); /* set up driver interface */ di_wrap_sync (svga_sync); di_wrap_share(svga_share); di_wrap_rcall(svga_rcall); di_wrap_read (svga_read); di_wrap_write(svga_write); vfs_wrap_init(); /* register the driver as /dev/svga0 */ io_link("/dev/svga0", RP_CONS(getpid(), 0)); msendb(RP_CONS(getppid(), 0), PORT_CHILD); _done(); return 0; }
int main(int argc, char **argv) { struct robject *canvas; char *modesstr0; char *modestr; int i; rdi_init(); canvas = rdi_file_cons(robject_new_index(), ACCS_READ | ACCS_WRITE | ACCS_EVENT); robject_set_data(canvas, "type", (void*) "canvas share"); svga_init(); // generate list of modes modesstr = strdup(""); for (i = 0; i < modelist_count; i++) { modesstr0 = modesstr; modestr = malloc(16); sprintf(modestr, "%d:%d:%d ", modelist[i].w, modelist[i].h, modelist[i].d); modesstr = strvcat(modesstr, modestr, NULL); free(modesstr0); } svga_set_mode(svga_find_mode(640, 480, 24)); buffer = malloc(svga.w * svga.h * 4); /* set up driver interface */ robject_set_call(canvas, "getmode", svga_rcall_getmode, STAT_READER); robject_set_call(canvas, "listmodes", svga_rcall_listmodes, STAT_READER); robject_set_call(canvas, "unshare", svga_rcall_unshare, STAT_WRITER); robject_set_call(canvas, "setmode", svga_rcall_setmode, STAT_WRITER); robject_set_call(canvas, "syncrect", svga_rcall_syncrect, STAT_WRITER); robject_set_call(canvas, "sync", svga_rcall_sync, STAT_WRITER); rdi_global_share_hook = svga_share; /* register the driver as /dev/svga0 */ fs_plink("/dev/svga0", RP_CONS(getpid(), canvas->index), NULL); msendb(RP_CONS(getppid(), 0), PORT_CHILD); _done(); return 0; }
char *svga_rcall_setmode(struct robject *self, rp_t source, int argc, char **argv) { int x, y, d; int mode; if (argc != 4) return NULL; x = atoi(argv[1]); y = atoi(argv[2]); d = atoi(argv[3]); mutex_spin(&self->driver_mutex); mode = svga_find_mode(x, y, d); if (svga_set_mode(mode)) return NULL; page_free(buffer, msize(buffer)); free(buffer); buffer = valloc(svga.w * svga.h * 4); mutex_free(&self->driver_mutex); return strdup("T"); }