⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 launcher.c

📁 一个嵌入式操作系统(microwindows)的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
								lineno);}void read_config(lstate *state){	int lineno = 1;	FILE *fp;	char *buf = my_malloc(256);	if(!(fp = fopen(state->config_file, "r"))) {		fprintf(stderr, "Couldn't open config file \"%s\"\n",							state->config_file);		exit(2);	}	state->litems = NULL;	state->numlitems = 0;	state->ssitems = NULL;	state->randomss = 0;	state->numssitems = 0;	state->stitems = NULL;	state->rotatess = 0;	while(fgets(buf, 256, fp)) {		parse_config_line(state, buf, lineno);		lineno++;	}	fclose(fp);	free(buf);	if(state->randomss) choose_random_screensaver(state);	else state->curssitem = state->ssitems;		if(!state->numlitems) {		fprintf(stderr, "No valid launcher items in config file\n");		exit(5);	}}void draw_item(lstate *state, litem *item){	GR_SIZE width, height, base, x, len;	GrDrawImageToFit(item->wid, state->gc, ICON_X_POSITION, ICON_Y_POSITION,				ICON_WIDTH, ICON_HEIGHT, item->iconid);	len = strlen(item->name);	GrGetGCTextSize(state->gc, item->name, len, 0, &width, &height, &base);	if(width >= ITEM_WIDTH) x = 0;	else x = (ITEM_WIDTH - width) / 2;	GrText(item->wid, state->gc, x, TEXT_Y_POSITION, item->name, len, 0);}void handle_exposure_event(lstate *state){	GR_EVENT_EXPOSURE *event = &state->event.exposure;	litem *i = state->litems;	if(event->wid == state->main_window) return;	while(i) {		if(event->wid == i->wid) {			draw_item(state, i);			return;		}		i = i->next;	}	fprintf(stderr, "Got exposure event for unknown window %d\n",							event->wid);}pid_t launch_program(prog_item *prog){	pid_t pid;	if((pid = fork()) == -1) perror("Couldn't fork");	else if(!pid) {		if(execvp(prog->command, prog->argv) == -1)			fprintf(stderr, "Couldn't start \"%s\": %s\n",					prog->command, strerror(errno));		exit(7);	}	return pid;}void handle_mouse_event(lstate *state){	GR_EVENT_MOUSE *event = &state->event.mouse;	litem *i = state->litems;	if(event->wid == state->main_window) return;	while(i) {		if(event->wid == i->wid) {			launch_program(i->prog);			return;		}		i = i->next;	}	fprintf(stderr, "Got mouse event for unknown window %d\n", event->wid);}void choose_random_screensaver(lstate *state){	int i;	ssitem *s;	if(!state->numssitems) return;	do {		i = rand() % state->numssitems;		s = state->ssitems;		while(i--) s = s->next;	} while(s == state->curssitem);	state->curssitem = s;}void activate_screensaver(lstate *state){	sspid = launch_program(state->curssitem->prog);	if(state->randomss) choose_random_screensaver(state);	else {		state->curssitem = state->curssitem->next;		if(!state->curssitem) state->curssitem = state->ssitems;	}}void deactivate_screensaver(lstate *state){	if(sspid >= 0) kill(sspid, SIGINT);}void handle_screensaver_event(lstate *state){	GR_EVENT_SCREENSAVER *event = &state->event.screensaver;	if(event->activate != GR_TRUE) {		if(state->ssrotatetimer > 0)			GrDestroyTimer(state->ssrotatetimer);		return;	}	if(!state->ssitems) {		fprintf(stderr, "Got screensaver activate event with no "				"screensavers defined\n");		return;	}	activate_screensaver(state);	if(state->rotatess) {		state->ssrotatetimer = GrCreateTimer(state->main_window,				state->rotatess * 1000 /*, GR_TRUE*/);	} else state->ssrotatetimer = -1;}void handle_timer_event(lstate *state){	GR_EVENT_TIMER *event = &state->event.timer;	if(event->tid != state->ssrotatetimer) return;	deactivate_screensaver(state);	activate_screensaver(state);}void handle_event(lstate *state){	switch(state->event.type) {		case GR_EVENT_TYPE_EXPOSURE:			handle_exposure_event(state);			break;		case GR_EVENT_TYPE_BUTTON_DOWN:			handle_mouse_event(state);			break;		case GR_EVENT_TYPE_CLOSE_REQ:			break;		case GR_EVENT_TYPE_SCREENSAVER:			handle_screensaver_event(state);			break;		case GR_EVENT_TYPE_TIMER:			handle_timer_event(state);			break;		case GR_EVENT_TYPE_NONE:			break;		default:			fprintf(stderr, "Got unknown event type %d\n",							state->event.type);			break;	}}void do_event_loop(lstate *state){	do {		GrGetNextEvent(&state->event);		handle_event(state);	} while(state->event.type != GR_EVENT_TYPE_CLOSE_REQ);}void do_startups(lstate *state){	stitem *tmp, *st = state->stitems;	while(st) {		launch_program(st->prog);		tmp = st;		st = st->next;		free_prog_item(tmp->prog);		free(tmp);	}}void initialise(lstate *state){	GR_SCREEN_INFO si;	GR_IMAGE_ID back_image;	GR_IMAGE_INFO imageinfo;	int rows = 1, columns = 1, width, height, x = 0, y = 0;	GR_WM_PROPERTIES props;	litem *i;	if(GrOpen() < 0) {		fprintf(stderr, "Couldn't connect to Nano-X server\n");		exit(4);	}	state->window_background_mode = 0;	state->window_background_image = NULL;	sspid = -1;	read_config(state);	GrGetScreenInfo(&si);	if(si.rows > si.cols) {		rows = state->numlitems;		while((((rows / columns) + rows % columns) * ITEM_HEIGHT) >								si.rows) {			columns++;		}		if((columns * ITEM_WIDTH) > si.cols) goto toomany;		rows = (rows / columns) + (rows % columns);		width = columns * ITEM_WIDTH + 1 + columns;		height = rows * ITEM_HEIGHT + 1 + rows;	} else {		columns = state->numlitems;		while((((columns / rows) + (columns % rows)) * ITEM_WIDTH) >								si.cols) {			rows++;		}		if((rows * ITEM_HEIGHT) > si.rows) goto toomany;		columns = (columns / rows) + (columns % rows);		width = columns * ITEM_WIDTH + 1 + columns;		height = (rows * ITEM_HEIGHT) + 1 + rows;		y = si.rows - (rows * ITEM_HEIGHT) - 1 - rows;	}	state->gc = GrNewGC();	GrSetGCForeground(state->gc, ITEM_TEXT_COLOUR);	GrSetGCBackground(state->gc, ITEM_BACKGROUND_COLOUR);	if(state->window_background_image) {		if(!(back_image = GrLoadImageFromFile(					state->window_background_image, 0))) {			fprintf(stderr, "Couldn't load background image\n");		} else {			GrGetImageInfo(back_image, &imageinfo);			if(!(state->background_pixmap = GrNewPixmap(							imageinfo.width,						imageinfo.height, NULL))) {				fprintf(stderr, "Couldn't allocate pixmap "							"for background image\n");			} else {				GrDrawImageToFit(state->background_pixmap,					state->gc, 0, 0, imageinfo.width,					imageinfo.height, back_image);				GrFreeImage(back_image);				GrSetBackgroundPixmap(GR_ROOT_WINDOW_ID,					state->background_pixmap,					state->window_background_mode);				GrClearWindow(GR_ROOT_WINDOW_ID, GR_TRUE);			}		}	}	if(state->ssitems)		GrSelectEvents(GR_ROOT_WINDOW_ID, GR_EVENT_MASK_SCREENSAVER);	state->main_window = GrNewWindow(GR_ROOT_WINDOW_ID, 0, y, width, height,						0, ITEM_BACKGROUND_COLOUR, 0);	GrSelectEvents(state->main_window, GR_EVENT_MASK_CLOSE_REQ |					GR_EVENT_MASK_TIMER);	props.flags = GR_WM_FLAGS_PROPS;	props.props = GR_WM_PROPS_NOMOVE | GR_WM_PROPS_NODECORATE |			GR_WM_PROPS_NOAUTOMOVE | GR_WM_PROPS_NOAUTORESIZE;	GrSetWMProperties(state->main_window, &props);	i = state->lastlitem;	y = 0;	while(i) {		i->wid = GrNewWindow(state->main_window,					(x * ITEM_WIDTH) + x + 1,					(y * ITEM_HEIGHT) + y + 1, ITEM_WIDTH,					ITEM_HEIGHT, 1, ITEM_BACKGROUND_COLOUR,							ITEM_BORDER_COLOUR);		GrSelectEvents(i->wid, GR_EVENT_MASK_EXPOSURE |					GR_EVENT_MASK_BUTTON_DOWN);		GrMapWindow(i->wid);		i = i->prev;		if(++x == columns) {			x = 0;			y++;		}	}	GrMapWindow(state->main_window);	signal(SIGCHLD, &reaper);	do_startups(state);	return;toomany:	fprintf(stderr, "Too many items to fit on screen\n");	exit(6);}int main(int argc, char *argv[]){	lstate *state;	if(argc != 2) usage();	state = my_malloc(sizeof(lstate));	state->config_file = strdup(argv[1]);	initialise(state);	do_event_loop(state);	GrClose();	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -