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

📄 launcher.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 2 页
字号:
	}

	new_litem->prev = NULL;
	new_litem->next = NULL;
	if(!state->litems) {
		state->lastlitem = new_litem;
		state->litems = new_litem;
	} else {
		new_litem->next = state->litems;
		state->litems->prev = new_litem;
		state->litems = new_litem;
	}

	state->numlitems++;

	return;

nomem:
	fprintf(stderr, "Out of memory\n");
	exit(1);

premature:
	fprintf(stderr, "Premature end of line on line %d of config file\n",
								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->sitems = NULL;

	while(fgets(buf, 256, fp)) {
		parse_config_line(state, buf, lineno);
		lineno++;
	}

	fclose(fp);
	free(buf);

	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);
}

void 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);
	}
}

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 handle_screensaver_event(lstate *state)
{
	GR_EVENT_SCREENSAVER *event = &state->event.screensaver;

	if(event->activate != GR_TRUE) return;

	if(!state->sitems) {
		fprintf(stderr, "Got screensaver activate event with no "
				"screensavers defined\n");
		return;
	}

	state->cursitem = state->cursitem->next;
	if(!state->cursitem) state->cursitem = state->sitems;

	launch_program(state->cursitem->prog);
}

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_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 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 = 1;
	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;

	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->sitems)
		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);
	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);

	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 + -