Beispiel #1
0
static inline void ep_write_var(struct dstr *shader, struct ep_var *var)
{
	if (var->var_type == EP_VAR_INOUT)
		dstr_cat(shader, "inout ");
	else if (var->var_type == EP_VAR_OUT)
		dstr_cat(shader, "out ");
	else if (var->var_type == EP_VAR_UNIFORM)
		dstr_cat(shader, "uniform ");
	// The "in" input modifier is implied by default, so leave it blank
	// in that case.

	dstr_cat(shader, var->type);
	dstr_cat(shader, " ");
	dstr_cat(shader, var->name);

	if (var->mapping) {
		dstr_cat(shader, " : ");
		dstr_cat(shader, var->mapping);
	}
}
char *obs_find_module_file(obs_module_t *module, const char *file)
{
	struct dstr output = {0};

	if (!file)
		file = "";

	if (!module)
		return NULL;

	dstr_copy(&output, module->data_path);
	if (!dstr_is_empty(&output) && dstr_end(&output) != '/' && *file)
		dstr_cat_ch(&output, '/');
	dstr_cat(&output, file);

	if (!os_file_exists(output.array))
		dstr_free(&output);
	return output.array;
}
Beispiel #3
0
/* FIXME */
void qc_command(client c) {
	char buf[64];
	dstr rid;
	struct crss *crss;

	snprintf(buf, sizeof buf, "%p,", c);
	rid = dstr_new(buf);
	rid = dstr_cat(rid, c->argv[1]);
	if (rids == NULL)
		rids = table_new(cmpstr, hashmurmur2, kfree, NULL);
	table_lock(rids);
	if ((crss = table_get_value(rids, rid))) {
		crss->cancel = 1;
		xcb_log(XCB_LOG_DEBUG, "Query with rid '%s' got cancelled", c->argv[1]);
	}
	table_unlock(rids);
	add_reply_string(c, "\r\n", 2);
	dstr_free(rid);
}
Beispiel #4
0
void dstr_insert(struct dstr *dst, const size_t idx, const char *array)
{
	size_t new_len, len;
	if (!array || !*array)
		return;
	if (idx == dst->len) {
		dstr_cat(dst, array);
		return;
	}

	len = strlen(array);
	new_len = dst->len + len;

	dstr_ensure_capacity(dst, new_len + 1);
	dst->len   = new_len;

	memmove(dst->array+idx+len, dst->array+idx, dst->len - idx + 1);
	memcpy(dst->array+idx, array, len);
}
Beispiel #5
0
static void gl_write_main_storage_assign(struct gl_shader_parser *glsp,
		struct shader_var *var, const char *dst, const char *src,
		bool input)
{
	struct shader_struct *st;
	struct dstr dst_copy = {0};
	char ch_left  = input ? '.' : '_';
	char ch_right = input ? '_' : '.';

	if (dst) {
		dstr_copy(&dst_copy, dst);
		dstr_cat_ch(&dst_copy, ch_left);
	} else {
		dstr_copy(&dst_copy, "\t");
	}

	dstr_cat(&dst_copy, var->name);

	st = shader_parser_getstruct(&glsp->parser, var->type);
	if (st) {
		struct dstr src_copy = {0};
		size_t i;

		if (src)
			dstr_copy(&src_copy, src);
		dstr_cat(&src_copy, var->name);
		dstr_cat_ch(&src_copy, ch_right);

		for (i = 0; i < st->vars.num; i++) {
			struct shader_var *st_var = st->vars.array+i;
			gl_write_main_storage_assign(glsp, st_var,
					dst_copy.array, src_copy.array, input);
		}

		dstr_free(&src_copy);
	} else {
		if (!dstr_isempty(&dst_copy))
			dstr_cat_dstr(&glsp->gl_string, &dst_copy);
		dstr_cat(&glsp->gl_string, " = ");
		if (src)
			dstr_cat(&glsp->gl_string, src);
		dstr_cat(&glsp->gl_string, var->name);
		dstr_cat(&glsp->gl_string, ";\n");

		if (!input)
			gl_write_main_interface_assign(glsp, var, src);
	}

	dstr_free(&dst_copy);
}
static inline void ep_write_var(struct dstr *shader, struct ep_var *var)
{
	if (var->uniform)
		dstr_cat(shader, "uniform ");

	dstr_cat(shader, var->type);
	dstr_cat(shader, " ");
	dstr_cat(shader, var->name);

	if (var->mapping) {
		dstr_cat(shader, " : ");
		dstr_cat(shader, var->mapping);
	}
}
bool load_graphics_offsets(bool is32bit)
{
	char *offset_exe_path = NULL;
	struct dstr offset_exe = {0};
	struct dstr str = {0};
	os_process_pipe_t *pp;
	bool success = false;
	char data[128];

	dstr_copy(&offset_exe, "get-graphics-offsets");
	dstr_cat(&offset_exe, is32bit ? "32.exe" : "64.exe");
	offset_exe_path = obs_module_file(offset_exe.array);

	pp = os_process_pipe_create(offset_exe_path, "r");
	if (!pp) {
		blog(LOG_INFO, "load_graphics_offsets: Failed to start '%s'",
				offset_exe.array);
		goto error;
	}

	for (;;) {
		size_t len = os_process_pipe_read(pp, (uint8_t*)data, 128);
		if (!len)
			break;

		dstr_ncat(&str, data, len);
	}

	success = load_offsets_from_string(is32bit ? &offsets32 : &offsets64,
			str.array);
	if (!success) {
		blog(LOG_INFO, "load_graphics_offsets: Failed to load string");
	}

	os_process_pipe_destroy(pp);

error:
	bfree(offset_exe_path);
	dstr_free(&offset_exe);
	dstr_free(&str);
	return success;
}
void *os_dlopen(const char *path)
{
	struct dstr dll_name;
	wchar_t *wpath;
	HMODULE h_library = NULL;

	dstr_init_copy(&dll_name, path);
	dstr_cat(&dll_name, ".dll");

	os_utf8_to_wcs(dll_name.array, 0, &wpath);
	h_library = LoadLibraryW(wpath);
	bfree(wpath);
	dstr_free(&dll_name);

	if (!h_library)
		blog(LOG_INFO, "LoadLibrary failed for '%s', error: %u",
				path, GetLastError());

	return h_library;
}
Beispiel #9
0
/* writes mapped vars used by the call as parameters for main */
static void ep_write_main_params(struct effect_parser *ep,
		struct dstr *shader, struct dstr *param_str,
		struct ep_func *func)
{
	size_t i;
	bool empty_params = dstr_is_empty(param_str);

	for (i = 0; i < func->param_vars.num; i++) {
		struct ep_var *var = func->param_vars.array+i;
		struct ep_struct *st = NULL;
		bool mapped = (var->mapping != NULL);

		if (!mapped) {
			st = ep_getstruct(ep, var->type);
			if (st)
				mapped = ep_struct_mapped(st);
		}

		if (mapped) {
			dstr_cat(shader, var->type);
			dstr_cat(shader, " ");
			dstr_cat(shader, var->name);

			if (!st) {
				dstr_cat(shader, " : ");
				dstr_cat(shader, var->mapping);
			}

			if (!dstr_is_empty(param_str))
				dstr_cat(param_str, ", ");
			dstr_cat(param_str, var->name);
		}
	}

	if (!empty_params)
		dstr_cat(param_str, ", ");
}
Beispiel #10
0
dstr dstr_cat_vprintf(dstr ds, const char *fmt, va_list ap) {
	char *buf, *tmp;
	size_t len = 16;
	va_list cpy;

	for (;;) {
		if ((buf = ALLOC(len)) == NULL)
			return NULL;
		buf[len - 2] = '\0';
		va_copy(cpy, ap);
		vsnprintf(buf, len, fmt, cpy);
		if (buf[len - 2] != '\0') {
			FREE(buf);
			len *= 2;
			continue;
		}
		break;
	}
	tmp = dstr_cat(ds, buf);
	FREE(buf);
	return tmp;
}
static void find_modules_in_path(struct obs_module_path *omp,
		obs_find_module_callback_t callback, void *param)
{
	struct dstr search_path = {0};
	char *module_start;
	bool search_directories = false;
	os_glob_t *gi;

	dstr_copy(&search_path, omp->bin);

	module_start = strstr(search_path.array, "%module%");
	if (module_start) {
		dstr_resize(&search_path, module_start - search_path.array);
		search_directories = true;
	}

	if (!dstr_is_empty(&search_path) && dstr_end(&search_path) != '/')
		dstr_cat_ch(&search_path, '/');

	dstr_cat_ch(&search_path, '*');
	if (!search_directories)
		dstr_cat(&search_path, get_module_extension());

	if (os_glob(search_path.array, 0, &gi) == 0) {
		for (size_t i = 0; i < gi->gl_pathc; i++) {
			if (search_directories == gi->gl_pathv[i].directory)
				process_found_module(omp,
						gi->gl_pathv[i].path,
						search_directories,
						callback, param);
		}

		os_globfree(gi);
	}

	dstr_free(&search_path);
}
Beispiel #12
0
static void gl_write_struct(struct gl_shader_parser *glsp,
		struct shader_struct *st)
{
	size_t i;
	dstr_cat(&glsp->gl_string, "struct ");
	dstr_cat(&glsp->gl_string, st->name);
	dstr_cat(&glsp->gl_string, " {\n");

	for (i = 0; i < st->vars.num; i++) {
		struct shader_var *var = st->vars.array+i;

		dstr_cat(&glsp->gl_string, "\t");
		gl_write_var(glsp, var);
		dstr_cat(&glsp->gl_string, ";\n");
	}

	dstr_cat(&glsp->gl_string, "};\n\n");
}
Beispiel #13
0
static void ep_write_struct(struct dstr *shader, struct ep_struct *st)
{
	size_t i;

	if (st->written)
		return;

	dstr_cat(shader, "struct ");
	dstr_cat(shader, st->name);
	dstr_cat(shader, " {");

	for (i = 0; i < st->vars.num; i++) {
		dstr_cat(shader, "\n\t");
		ep_write_var(shader, st->vars.array+i);
		dstr_cat(shader, ";");
	}

	dstr_cat(shader, "\n};\n");
	st->written = true;
}
static bool gl_write_intrinsic(struct gl_shader_parser *glsp,
		struct cf_token **p_token)
{
	struct cf_token *token = *p_token;
	bool written = true;

	if (strref_cmp(&token->str, "atan2") == 0) {
		dstr_cat(&glsp->gl_string, "atan2");
	} else if (strref_cmp(&token->str, "ddx") == 0) {
		dstr_cat(&glsp->gl_string, "dFdx");
	} else if (strref_cmp(&token->str, "ddy") == 0) {
		dstr_cat(&glsp->gl_string, "dFdy");
	} else if (strref_cmp(&token->str, "frac") == 0) {
		dstr_cat(&glsp->gl_string, "fract");
	} else if (strref_cmp(&token->str, "lerp") == 0) {
		dstr_cat(&glsp->gl_string, "mix");
	} else if (strref_cmp(&token->str, "fmod") == 0) {
		dstr_cat(&glsp->gl_string, "mod");
	} else if (strref_cmp(&token->str, "rsqrt") == 0) {
		dstr_cat(&glsp->gl_string, "inversesqrt");
	} else if (strref_cmp(&token->str, "saturate") == 0) {
		written = gl_write_saturate(glsp, &token);
	} else if (strref_cmp(&token->str, "mul") == 0) {
		written = gl_write_mul(glsp, &token);
	} else {
		struct shader_var *var = sp_getparam(glsp, token);
		if (var && astrcmp_n(var->type, "texture", 7) == 0)
			written = gl_write_texture_code(glsp, &token, var);
		else
			written = false;
	}

	if (written)
		*p_token = token;
	return written;
}
Beispiel #15
0
static inline bool ep_compile_pass_shader(struct effect_parser *ep,
		struct gs_effect_technique *tech,
		struct gs_effect_pass *pass, struct ep_pass *pass_in,
		size_t pass_idx, enum gs_shader_type type)
{
	struct dstr shader_str;
	struct dstr location;
	struct darray used_params; /* struct dstr */
	struct darray *pass_params = NULL; /* struct pass_shaderparam */
	gs_shader_t *shader = NULL;
	bool success = true;

	dstr_init(&shader_str);
	darray_init(&used_params);
	dstr_init(&location);

	dstr_copy(&location, ep->cfp.lex.file);
	if (type == GS_SHADER_VERTEX)
		dstr_cat(&location, " (Vertex ");
	else if (type == GS_SHADER_PIXEL)
		dstr_cat(&location, " (Pixel ");
	/*else if (type == SHADER_GEOMETRY)
		dstr_cat(&location, " (Geometry ");*/

	assert(pass_idx <= UINT_MAX);
	dstr_catf(&location, "shader, technique %s, pass %u)", tech->name,
			(unsigned)pass_idx);

	if (type == GS_SHADER_VERTEX) {
		ep_makeshaderstring(ep, &shader_str,
				&pass_in->vertex_program.da, &used_params);

		pass->vertshader = gs_vertexshader_create(shader_str.array,
				location.array, NULL);

		shader = pass->vertshader;
		pass_params = &pass->vertshader_params.da;
	} else if (type == GS_SHADER_PIXEL) {
		ep_makeshaderstring(ep, &shader_str,
				&pass_in->fragment_program.da, &used_params);

		pass->pixelshader = gs_pixelshader_create(shader_str.array,
				location.array, NULL);

		shader = pass->pixelshader;
		pass_params = &pass->pixelshader_params.da;
	}

#if 0
	blog(LOG_DEBUG, "+++++++++++++++++++++++++++++++++++");
	blog(LOG_DEBUG, "  %s", location.array);
	blog(LOG_DEBUG, "-----------------------------------");
	blog(LOG_DEBUG, "%s", shader_str.array);
	blog(LOG_DEBUG, "+++++++++++++++++++++++++++++++++++");
#endif

	if (shader)
		success = ep_compile_pass_shaderparams(ep, pass_params,
				&used_params, shader);
	else
		success = false;

	dstr_free(&location);
	dstr_array_free(used_params.array, used_params.num);
	darray_free(&used_params);
	dstr_free(&shader_str);

	return success;
}
Beispiel #16
0
static void *recv_thread(void *data) {
	NOT_USED(data);

	while (loop) {
		struct pollfd rfd[1];
		char buf[256];
		int nread;

		rfd[0].fd     = tcpsock;
		rfd[0].events = POLLIN;
		if (poll(rfd, 1, -1) == -1) {
			if (execute) {
				fprintf(stderr, "Reading from server: %s\n", strerror(errno));
				exit(1);
			} else {
				snprintf(buf, sizeof buf, "Reading from server: %s", strerror(errno));
				CLIPRINT(buf);
				break;
			}
		}
		if ((nread = read(tcpsock, inbuf + inpos, sizeof inbuf - inpos)) == -1) {
			if (errno == EAGAIN || errno == EINTR)
				nread = 0;
			else {
				if (execute) {
					fprintf(stderr, "Reading from server: %s\n", strerror(errno));
					exit(1);
				} else {
					snprintf(buf, sizeof buf, "Reading from server: %s", strerror(errno));
					CLIPRINT(buf);
					break;
				}
			}
		} else if (nread == 0) {
			if (execute) {
				fprintf(stderr, "Server closed connection\n");
				exit(1);
			} else {
				snprintf(buf, sizeof buf, "Server closed connection");
				CLIPRINT(buf);
				break;
			}
		}
		if (nread)
			inpos += nread;
		else
			continue;
		inbuf[inpos] = '\0';
		while (inpos > 0) {
			char *newline;
			size_t len;

			if ((newline = strstr(inbuf, "\r\n")) == NULL) {
				if (inpos == sizeof inbuf - 1) {
					if (execute) {
						fprintf(stderr, "Server error: too big reply\n");
						exit(1);
					} else {
						snprintf(buf, sizeof buf, "Server error: too big reply");
						CLIPRINT(buf);
						inpos = 0;
					}
				}
				break;
			}
			if ((len = newline - inbuf) == 0) {
				const char one = '1';

				if (execute && write(proceed_pipe[1], &one, sizeof(one)) == -1) {
					fprintf(stderr, "Error writing: %s", strerror(errno));
					exit(1);
				}
			} else {
				/* FIXME */
				*newline = '\0';
				if (timestamp) {
					struct timeval tv;
					char datestr[64];
					int off;
					dstr res;

					gettimeofday(&tv, NULL);
					off = strftime(datestr, sizeof datestr, "[%b %e %T.",
						localtime(&tv.tv_sec));
					snprintf(datestr + off, sizeof datestr - off, "%06d]",
						(int)tv.tv_usec);
					res = dstr_new(datestr);
					res = dstr_cat(res, inbuf);
					if (execute) {
						if (strncasecmp(inbuf, "HEARTBEAT", 9) &&
							strncasecmp(inbuf, "INDICES", 7))
							fprintf(stdout, "%s\n", res);
					} else
						CLIPRINT(res);
					dstr_free(res);
				} else {
					if (execute) {
						if (strncasecmp(inbuf, "HEARTBEAT", 9) &&
							strncasecmp(inbuf, "INDICES", 7))
							fprintf(stdout, "%s\n", inbuf);
					} else
						CLIPRINT(inbuf);
				}
			}
			memmove(inbuf, inbuf + len + 2, sizeof inbuf - len - 2);
			inpos -= len + 2;
		}
	}
	close(tcpsock);
	tcpsock = -1;
	return NULL;
}
Beispiel #17
0
int main(int argc, char **argv) {
	int opt, count = 1;
	pthread_t thread;

	/* FIXME */
	ip = dstr_new("127.0.0.1");
	port = 33330;
	while ((opt = getopt(argc, argv, "h:p:xt?")) != -1)
		switch (opt) {
		case 'h':
			dstr_free(ip);
			ip = dstr_new(optarg);
			count += 2;
			break;
		case 'p':
			port = atoi(optarg);
			count += 2;
			break;
		case 'x':
			execute = 1;
			count += 1;
			break;
		case 't':
			timestamp = 1;
			count += 1;
			break;
		case '?':
		default:
			usage();
		}
	if ((tcpsock = net_tcp_nonblock_connect(ip, port, neterr, sizeof neterr)) == -1) {
		fprintf(stderr, "Connecting %s:%d: %s\n", ip, port, neterr);
		exit(1);
	}
	if (errno == EINPROGRESS) {
		struct pollfd wfd[1];
		int res, err = 0;
		socklen_t errlen = sizeof err;

		wfd[0].fd     = tcpsock;
		wfd[0].events = POLLOUT;
		/* wait for 5 seconds */
		if ((res = poll(wfd, 1, 5000)) == -1) {
			fprintf(stderr, "Connecting %s:%d: %s\n", ip, port, strerror(errno));
			exit(1);
		} else if (res == 0) {
			errno = ETIMEDOUT;
			fprintf(stderr, "Connecting %s:%d: %s\n", ip, port, strerror(errno));
			exit(1);
		}
		if (getsockopt(tcpsock, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
			fprintf(stderr, "Connecting %s:%d: %s\n", ip, port, strerror(errno));
			exit(1);
		}
		if (err) {
			errno = err;
			fprintf(stderr, "Connecting %s:%d: %s\n", ip, port, strerror(errno));
			exit(1);
		}
	}
	if (execute && pipe(proceed_pipe) != 0) {
		fprintf(stderr, "Error creating pipe: %s\n", strerror(errno));
		exit(1);
	}
	if (execute) {
		argc -= count;
		argv += count;
		if (argc > 0) {
			dstr cmd;
			int i;
			struct pollfd rfd[1];

			if (pthread_create(&thread, NULL, recv_thread, NULL) != 0) {
				fprintf(stderr, "Error initializing receiver thread\n");
				exit(1);
			}
			cmd = dstr_new(argv[0]);
			for (i = 1; i < argc; ++i) {
				cmd = dstr_cat(cmd, " ");
				cmd = dstr_cat(cmd, argv[i]);
			}
			cmd = dstr_cat(cmd, "\r\n");
			net_try_write(tcpsock, cmd, dstr_length(cmd), 100, NET_NONBLOCK);
			/* dstr_free(cmd); */
			rfd[0].fd     = proceed_pipe[0];
			rfd[0].events = POLLIN;
			if (poll(rfd, 1, -1) == -1) {
				fprintf(stderr, "Error polling: %s\n", strerror(errno));
				exit(1);
			}
		}
	} else {
		fprintf(stdout, "XCUBE CLI, Copyright (c) 2013-2015, "
			"Dalian Futures Information Technology Co., Ltd.\n");
		fprintf(stdout, "Type 'help' or '?' for help.\n");
		init_readline();
		stifle_history(100);
		if (pthread_create(&thread, NULL, recv_thread, NULL) != 0) {
			fprintf(stderr, "Error initializing receiver thread\n");
			exit(1);
		}
		while (loop) {
			char *line;

			line = readline(prompt);
			if (rl_inited == 0)
				rl_inited = 1;
			if (line == NULL)
				continue;
			LTRIM(line);
			RTRIM(line);
			if (*line) {
				add_history(line);
				if (tcpsock == -1)
					execute_line(line);
				else {
					net_try_write(tcpsock, line, strlen(line), 100, NET_NONBLOCK);
					net_try_write(tcpsock, "\r\n", 2, 100, NET_NONBLOCK);
					if (!strncasecmp(line, "quit", 4))
						com_quit(NULL);
				}
			}
			FREE(line);
		}
	}
	return 0;
}
Beispiel #18
0
static bool build_flv_meta_data(obs_output_t *context,
		uint8_t **output, size_t *size, size_t a_idx)
{
	obs_encoder_t *vencoder = obs_output_get_video_encoder(context);
	obs_encoder_t *aencoder = obs_output_get_audio_encoder(context, a_idx);
	video_t       *video    = obs_encoder_video(vencoder);
	audio_t       *audio    = obs_encoder_audio(aencoder);
	char buf[4096];
	char *enc = buf;
	char *end = enc+sizeof(buf);
	struct dstr encoder_name = {0};

	if (a_idx > 0 && !aencoder)
		return false;

	enc_str(&enc, end, "onMetaData");

	*enc++ = AMF_ECMA_ARRAY;
	enc    = AMF_EncodeInt32(enc, end, a_idx == 0 ? 14 : 9);

	enc_num_val(&enc, end, "duration", 0.0);
	enc_num_val(&enc, end, "fileSize", 0.0);

	if (a_idx == 0) {
		enc_num_val(&enc, end, "width",
				(double)obs_encoder_get_width(vencoder));
		enc_num_val(&enc, end, "height",
				(double)obs_encoder_get_height(vencoder));

		enc_str_val(&enc, end, "videocodecid", "avc1");
		enc_num_val(&enc, end, "videodatarate",
				encoder_bitrate(vencoder));
		enc_num_val(&enc, end, "framerate",
				video_output_get_frame_rate(video));
	}

	enc_str_val(&enc, end, "audiocodecid", "mp4a");
	enc_num_val(&enc, end, "audiodatarate", encoder_bitrate(aencoder));
	enc_num_val(&enc, end, "audiosamplerate",
			(double)obs_encoder_get_sample_rate(aencoder));
	enc_num_val(&enc, end, "audiosamplesize", 16.0);
	enc_num_val(&enc, end, "audiochannels",
			(double)audio_output_get_channels(audio));

	enc_bool_val(&enc, end, "stereo",
			audio_output_get_channels(audio) == 2);
	enc_bool_val(&enc, end, "2.1",
			audio_output_get_channels(audio) == 3);
	enc_bool_val(&enc, end, "3.1",
			audio_output_get_channels(audio) == 4);
	enc_bool_val(&enc, end, "4.0",
			audio_output_get_channels(audio) == 4);
	enc_bool_val(&enc, end, "4.1",
			audio_output_get_channels(audio) == 5);
	enc_bool_val(&enc, end, "5.1",
			audio_output_get_channels(audio) == 6);
	enc_bool_val(&enc, end, "7.1",
			audio_output_get_channels(audio) == 8);

	dstr_printf(&encoder_name, "%s (libobs version ",
			MODULE_NAME);

#ifdef HAVE_OBSCONFIG_H
	dstr_cat(&encoder_name, OBS_VERSION);
#else
	dstr_catf(&encoder_name, "%d.%d.%d",
			LIBOBS_API_MAJOR_VER,
			LIBOBS_API_MINOR_VER,
			LIBOBS_API_PATCH_VER);
#endif

	dstr_cat(&encoder_name, ")");

	enc_str_val(&enc, end, "encoder", encoder_name.array);
	dstr_free(&encoder_name);

	*enc++  = 0;
	*enc++  = 0;
	*enc++  = AMF_OBJECT_END;

	*size   = enc-buf;
	*output = bmemdup(buf, *size);
	return true;
}
Beispiel #19
0
static int server_cron(event_loop el, unsigned long id, void *data) {
	dlist_iter_t iter;
	dlist_node_t node;
	NOT_USED(el);
	NOT_USED(id);
	NOT_USED(data);

	if (log_reload) {
		close_logger();
		if (init_logger("/var/log/xcb/xcb-dp2.log", __LOG_DEBUG) == 0) {
			const char *tmp;

			pthread_mutex_lock(&cfg_lock);
			if ((tmp = variable_retrieve(cfg, "general", "log_level"))) {
				if (!strcasecmp(tmp, "debug"))
					set_logger_level(__LOG_DEBUG);
				else if (!strcasecmp(tmp, "info"))
					set_logger_level(__LOG_INFO);
				else if (!strcasecmp(tmp, "notice"))
					set_logger_level(__LOG_NOTICE);
				else if (!strcasecmp(tmp, "warning"))
					set_logger_level(__LOG_WARNING);
			}
			pthread_mutex_unlock(&cfg_lock);
			log_reload = 0;
		}
		/* FIXME */
		if (addms)
			table_clear(times);
	}
	if (shut_down) {
		if (prepare_for_shutdown() == 0)
			exit(0);
		xcb_log(XCB_LOG_WARNING, "SIGTERM received, but errors trying to shutdown the server");
	}
	/* FIXME */
	iter = dlist_iter_new(clients_to_close, DLIST_START_HEAD);
	while ((node = dlist_next(iter))) {
		client c = (client)dlist_node_value(node);

		if (c->refcount == 0)
			client_free(c);
	}
	dlist_iter_free(&iter);
	/* FIXME */
	if (cronloops % 200 == 0) {
		char meme[] = "SU OT GNOLEB ERA ESAB RUOY LLA";
		int status;

		/* heartbeat */
		dlist_lock(clients);
		if (dlist_length(clients) > 0) {
			dstr res = dstr_new("HEARTBEAT|");
			dstr ip = getipv4();

			res = dstr_cat(res, ip);
			res = dstr_cat(res, "\r\n");
			iter = dlist_iter_new(clients, DLIST_START_HEAD);
			while ((node = dlist_next(iter))) {
				client c = (client)dlist_node_value(node);

				pthread_spin_lock(&c->lock);
				if (net_try_write(c->fd, res, dstr_length(res), 100, NET_NONBLOCK) == -1)
					xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s",
						c, strerror(errno));
				pthread_spin_unlock(&c->lock);
			}
			dlist_iter_free(&iter);
			dstr_free(ip);
			dstr_free(res);
		}
		dlist_unlock(clients);
		/* FIXME: trying to lower the high CPU load while idle */
		if ((status = pgm_send(pgm_sender, meme, sizeof meme, NULL)) != PGM_IO_STATUS_NORMAL)
			xcb_log(XCB_LOG_WARNING, "Communication test failed");
	}
	++cronloops;
	return 100;
}
Beispiel #20
0
static inline void gl_write_type(struct gl_shader_parser *glsp,
		const char *type)
{
	if (!gl_write_type_n(glsp, type, strlen(type)))
		dstr_cat(&glsp->gl_string, type);
}
Beispiel #21
0
/* FIXME */
void q_command(client c) {
	struct tm tm;
	char *end;
	char buf[64];
	dstr rid;
	struct crss *crss;

	if (!persistence) {
		add_reply_error(c, "database not open\r\n");
		return;
	}
	if (dstr_length(c->argv[0]) == 1) {
		add_reply_error(c, "index can't be empty\r\n");
		return;
	}
	if ((end = strptime(c->argv[3], "%F %T", &tm)) && *end == '\0')
		c->argv[3] = dstr_cat(c->argv[3], ".000");
	else if ((end = strptime(c->argv[3], "%F %R", &tm)) && *end == '\0')
		c->argv[3] = dstr_cat(c->argv[3], ":00.000");
	else {
		add_reply_error(c, "invalid time format, "
			"please use 'YYYY-mm-dd HH:MM:SS' or 'YYYY-mm-dd HH:MM'.\r\n");
		return;
	}
	if ((end = strptime(c->argv[4], "%F %T", &tm)) && *end == '\0')
		c->argv[4] = dstr_cat(c->argv[4], ".999");
	else if ((end = strptime(c->argv[4], "%F %R", &tm)) && *end == '\0')
		c->argv[4] = dstr_cat(c->argv[4], ":59.999");
	else {
		add_reply_error(c, "invalid time format, "
			"please use 'YYYY-mm-dd HH:MM:SS' or 'YYYY-mm-dd HH:MM'.\r\n");
		return;
	}
	snprintf(buf, sizeof buf, "%p,", c);
	rid = dstr_new(buf);
	rid = dstr_cat(rid, c->argv[1]);
	if (rids == NULL)
		rids = table_new(cmpstr, hashmurmur2, kfree, NULL);
	table_lock(rids);
	if ((crss = table_get_value(rids, rid))) {
		add_reply_error_format(c, "query with rid '%s' already exists\r\n", c->argv[1]);
		dstr_free(rid);
	} else if (NEW(crss)) {
		pthread_t thread;

		crss->c      = c;
		crss->rid    = dstr_new(c->argv[1]);
		crss->match  = dstr_new(c->argv[2]);
		crss->start  = dstr_new(c->argv[0] + 1);
		crss->start  = dstr_cat(crss->start, ",");
		crss->start  = dstr_cat(crss->start, c->argv[3]);
		crss->stop   = dstr_new(c->argv[0] + 1);
		crss->stop   = dstr_cat(crss->stop, ",");
		crss->stop   = dstr_cat(crss->stop, c->argv[4]);
		crss->cancel = 0;
		if (pthread_create(&thread, NULL, q_thread, crss) != 0) {
			add_reply_error(c, strerror(errno));
			add_reply_string(c, "\r\n", 2);
			dstr_free(crss->rid);
			dstr_free(crss->match);
			dstr_free(crss->start);
			dstr_free(crss->stop);
			FREE(crss);
			dstr_free(rid);
		} else {
			client_incr(crss->c);
			table_insert(rids, rid, crss);
		}
	} else {
		add_reply_error(c, "error allocating memory for crss\r\n");
		dstr_free(rid);
	}
	table_unlock(rids);
}
Beispiel #22
0
static int try_connect(struct rtmp_stream *stream)
{
	if (dstr_is_empty(&stream->path)) {
		warn("URL is empty");
		return OBS_OUTPUT_BAD_PATH;
	}

	info("Connecting to RTMP URL %s...", stream->path.array);

	memset(&stream->rtmp.Link, 0, sizeof(stream->rtmp.Link));
	if (!RTMP_SetupURL(&stream->rtmp, stream->path.array))
		return OBS_OUTPUT_BAD_PATH;

	RTMP_EnableWrite(&stream->rtmp);

	dstr_copy(&stream->encoder_name, "FMLE/3.0 (compatible; obs-studio/");

#ifdef HAVE_OBSCONFIG_H
	dstr_cat(&stream->encoder_name, OBS_VERSION);
#else
	dstr_catf(&stream->encoder_name, "%d.%d.%d",
			LIBOBS_API_MAJOR_VER,
			LIBOBS_API_MINOR_VER,
			LIBOBS_API_PATCH_VER);
#endif

	dstr_cat(&stream->encoder_name, "; FMSc/1.0)");

	set_rtmp_dstr(&stream->rtmp.Link.pubUser,   &stream->username);
	set_rtmp_dstr(&stream->rtmp.Link.pubPasswd, &stream->password);
	set_rtmp_dstr(&stream->rtmp.Link.flashVer,  &stream->encoder_name);
	stream->rtmp.Link.swfUrl = stream->rtmp.Link.tcUrl;

	RTMP_AddStream(&stream->rtmp, stream->key.array);

	for (size_t idx = 1;; idx++) {
		obs_encoder_t *encoder = obs_output_get_audio_encoder(
				stream->output, idx);
		const char *encoder_name;

		if (!encoder)
			break;

		encoder_name = obs_encoder_get_name(encoder);
		RTMP_AddStream(&stream->rtmp, encoder_name);
	}

	stream->rtmp.m_outChunkSize       = 4096;
	stream->rtmp.m_bSendChunkSizeInfo = true;
	stream->rtmp.m_bUseNagle          = true;

#ifdef _WIN32
	win32_log_interface_type(stream);
#endif

	if (!RTMP_Connect(&stream->rtmp, NULL))
		return OBS_OUTPUT_CONNECT_FAILED;
	if (!RTMP_ConnectStream(&stream->rtmp, 0))
		return OBS_OUTPUT_INVALID_STREAM;

	info("Connection to %s successful", stream->path.array);

	return init_send(stream);
}
Beispiel #23
0
static obs_properties_t *ffmpeg_source_getproperties(void *data)
{
	struct ffmpeg_source *s = data;
	struct dstr filter = {0};
	struct dstr path = {0};
	UNUSED_PARAMETER(data);

	obs_properties_t *props = obs_properties_create();

	obs_properties_set_flags(props, OBS_PROPERTIES_DEFER_UPDATE);

	obs_property_t *prop;
	// use this when obs allows non-readonly paths
	prop = obs_properties_add_bool(props, "is_local_file",
			obs_module_text("LocalFile"));

	obs_property_set_modified_callback(prop, is_local_file_modified);

	dstr_copy(&filter, obs_module_text("MediaFileFilter.AllMediaFiles"));
	dstr_cat(&filter, media_filter);
	dstr_cat(&filter, obs_module_text("MediaFileFilter.VideoFiles"));
	dstr_cat(&filter, video_filter);
	dstr_cat(&filter, obs_module_text("MediaFileFilter.AudioFiles"));
	dstr_cat(&filter, audio_filter);
	dstr_cat(&filter, obs_module_text("MediaFileFilter.AllFiles"));
	dstr_cat(&filter, " (*.*)");

	if (s && s->input && *s->input) {
		const char *slash;

		dstr_copy(&path, s->input);
		dstr_replace(&path, "\\", "/");
		slash = strrchr(path.array, '/');
		if (slash)
			dstr_resize(&path, slash - path.array + 1);
	}

	obs_properties_add_path(props, "local_file",
			obs_module_text("LocalFile"), OBS_PATH_FILE,
			filter.array, path.array);
	dstr_free(&filter);
	dstr_free(&path);

	prop = obs_properties_add_bool(props, "looping",
			obs_module_text("Looping"));

	obs_properties_add_bool(props, "restart_on_activate",
			obs_module_text("RestartWhenActivated"));

	obs_properties_add_text(props, "input",
			obs_module_text("Input"), OBS_TEXT_DEFAULT);

	obs_properties_add_text(props, "input_format",
			obs_module_text("InputFormat"), OBS_TEXT_DEFAULT);

#ifndef __APPLE__
	obs_properties_add_bool(props, "hw_decode",
			obs_module_text("HardwareDecode"));
#endif

	obs_properties_add_bool(props, "clear_on_media_end",
			obs_module_text("ClearOnMediaEnd"));

	prop = obs_properties_add_bool(props, "close_when_inactive",
			obs_module_text("CloseFileWhenInactive"));

	obs_property_set_long_description(prop,
			obs_module_text("CloseFileWhenInactive.ToolTip"));

	prop = obs_properties_add_list(props, "color_range",
			obs_module_text("ColorRange"), OBS_COMBO_TYPE_LIST,
			OBS_COMBO_FORMAT_INT);
	obs_property_list_add_int(prop, obs_module_text("ColorRange.Auto"),
			VIDEO_RANGE_DEFAULT);
	obs_property_list_add_int(prop, obs_module_text("ColorRange.Partial"),
			VIDEO_RANGE_PARTIAL);
	obs_property_list_add_int(prop, obs_module_text("ColorRange.Full"),
			VIDEO_RANGE_FULL);

	return props;
}
static bool gl_write_type_n(struct gl_shader_parser *glsp,
		const char *type, size_t len)
{
	if (cmp_type(type, len, "float2", 6) == 0)
		dstr_cat(&glsp->gl_string, "vec2");
	else if (cmp_type(type, len, "float3", 6) == 0)
		dstr_cat(&glsp->gl_string, "vec3");
	else if (cmp_type(type, len, "float4", 6) == 0)
		dstr_cat(&glsp->gl_string, "vec4");
	else if (cmp_type(type, len, "int2", 4) == 0)
		dstr_cat(&glsp->gl_string, "ivec2");
	else if (cmp_type(type, len, "int3", 4) == 0)
		dstr_cat(&glsp->gl_string, "ivec3");
	else if (cmp_type(type, len, "int4", 4) == 0)
		dstr_cat(&glsp->gl_string, "ivec4");
	else if (cmp_type(type, len, "float3x3", 8) == 0)
		dstr_cat(&glsp->gl_string, "mat3x3");
	else if (cmp_type(type, len, "float3x4", 8) == 0)
		dstr_cat(&glsp->gl_string, "mat3x4");
	else if (cmp_type(type, len, "float4x4", 8) == 0)
		dstr_cat(&glsp->gl_string, "mat4x4");
	else if (cmp_type(type, len, "texture2d", 9) == 0)
		dstr_cat(&glsp->gl_string, "sampler2D");
	else if (cmp_type(type, len, "texture3d", 9) == 0)
		dstr_cat(&glsp->gl_string, "sampler3D");
	else if (cmp_type(type, len, "texture_cube", 12) == 0)
		dstr_cat(&glsp->gl_string, "samplerCube");
	else if (cmp_type(type, len, "texture_rect", 12) == 0)
		dstr_cat(&glsp->gl_string, "sampler2DRect");
	else
		return false;

	return true;
}
Beispiel #25
0
/* FIXME */
void s_command(client c) {
	dstr pkey, skey;
	int i;
	dlist_t dlist;
	struct kvd *kvd;

	if (dstr_length(c->argv[0]) == 1) {
		add_reply_error(c, "index can't be empty\r\n");
		return;
	}
	pkey = dstr_new(c->argv[0] + 1);
	skey = dstr_new(pkey);
//------------------------------------------------------------------------
dstr pre = dstr_new(pkey);
dstr rest = dstr_new("");
//------------------------------------------------------------------------
	if (c->argc > 1)
		for (i = 1; i < c->argc; ++i) {
			skey = dstr_cat(skey, ",");
			skey = dstr_cat(skey, c->argv[i]);
//------------------------------------------------------------------------
			rest = dstr_cat(rest,c->argv[i]);
//------------------------------------------------------------------------
		}
/*
	table_lock(cache);
	if ((dlist = table_get_value(cache, pkey))) {
		dlist_iter_t iter = dlist_iter_new(dlist, DLIST_START_HEAD);
		dlist_node_t node;
*/
		/* FIXME: still has room to improve */
/*		while ((node = dlist_next(iter))) {
			kvd = (struct kvd *)dlist_node_value(node);
			if (dstr_length(kvd->key) >= dstr_length(skey) &&
				!memcmp(kvd->key, skey, dstr_length(skey))) {
				dstr *fields = NULL;
				int nfield = 0;
				dstr res, contracts = NULL;

				fields = dstr_split_len(kvd->key, dstr_length(kvd->key), ",", 1, &nfield);
				res = dstr_new(fields[0]);
				if (nfield > 1) {
					contracts = dstr_new(fields[1]);
					for (i = 2; i < nfield; ++i) {
						contracts = dstr_cat(contracts, ",");
						contracts = dstr_cat(contracts, fields[i]);
					}
				}
				dstr_free_tokens(fields, nfield);
				fields = NULL, nfield = 0;
				fields = dstr_split_len(kvd->u.value, dstr_length(kvd->u.value),
					",", 1, &nfield);
				res = dstr_cat(res, ",");
				res = dstr_cat(res, fields[0]);
				if (contracts) {
					res = dstr_cat(res, ",");
					res = dstr_cat(res, contracts);
				}
				for (i = 1; i < nfield; ++i) {
					res = dstr_cat(res, ",");
					res = dstr_cat(res, fields[i]);
				}
				res = dstr_cat(res, "\r\n");
				pthread_spin_lock(&c->lock);
				if (!(c->flags & CLIENT_CLOSE_ASAP)) {
					if (net_try_write(c->fd, res, dstr_length(res),
						10, NET_NONBLOCK) == -1) {
						xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s",
							c, strerror(errno));
						if (++c->eagcount >= 3) {
							client_free_async(c);
							pthread_spin_unlock(&c->lock);
							dstr_free(contracts);
							dstr_free(res);
							dstr_free_tokens(fields, nfield);
							table_unlock(cache);
							dstr_free(skey);
							dstr_free(pkey);
							return;
						}
					} else if (c->eagcount)
						c->eagcount = 0;
				}
				pthread_spin_unlock(&c->lock);
				dstr_free(contracts);
				dstr_free(res);
				dstr_free_tokens(fields, nfield);
			}
		}
		dlist_iter_free(&iter);
	}
	table_unlock(cache);
*/
//---------------------------------------------------------------------------------------------------
/*	table_rwlock_wrlock(subscribers);
	if ((dlist = table_get_value(subscribers, pkey)) == NULL) {
		if (NEW(kvd)) {
			kvd->key     = skey;
			kvd->u.dlist = dlist_new(NULL, NULL);
			dlist_insert_tail(kvd->u.dlist, c);
			dlist = dlist_new(cmpkvd, kdfree);
			dlist_insert_sort(dlist, kvd);
			table_insert(subscribers, pkey, dlist);
		} else {
			add_reply_error(c, "error allocating memory for kvd\r\n");
			dstr_free(skey);
			dstr_free(pkey);
		}
	} else {
		if (NEW(kvd)) {
			dlist_node_t node;

			kvd->key     = skey;
			kvd->u.dlist = dlist_new(NULL, NULL);
			if ((node = dlist_find(dlist, kvd)) == NULL) {
				dlist_insert_tail(kvd->u.dlist, c);
				dlist_insert_sort(dlist, kvd);
			} else {
				kdfree(kvd);
				kvd = (struct kvd *)dlist_node_value(node);
				if (dlist_find(kvd->u.dlist, c) == NULL)
					dlist_insert_tail(kvd->u.dlist, c);
			}
		} else {
			add_reply_error(c, "error allocating memory for kvd\r\n");
			dstr_free(skey);
		}
		dstr_free(pkey);
	}
	table_rwlock_unlock(subscribers);
*/
//--------------------------------------------------------------------------------------------------------------------
//	table_rwlock_wrlock(subscribers_radix);
	radix_block_insert(pre, ",", subscribers_radix->head);
	radix_insert(rest, radix_match(pre, subscribers_radix->head, subscribers_radix->head));
	pre = dstr_cat(pre,rest);
	insert_value(pre, c, subscribers_radix->head);
	dstr_free(pre);
	dstr_free(rest);

//	table_rwlock_unlock(subscribers_radix);
//---------------------------------------------------------------------------------------------------
}
static bool update_remote_files(void *param, obs_data_t *remote_file)
{
	struct update_info *info = param;

	struct file_update_data data = {
		.name = obs_data_get_string(remote_file, "name"),
		.version = (int)obs_data_get_int(remote_file, "version")
	};

	enum_files(info->cache_package, newer_than_cache, &data);
	if (!data.newer && data.found)
		return true;

	if (!do_relative_http_request(info, info->remote_url, data.name))
		return true;

	if (info->callback) {
		struct file_download_data download_data;
		bool confirm;

		download_data.name = data.name;
		download_data.version = data.version;
		download_data.buffer.da = info->file_data.da;

		confirm = info->callback(info->param, &download_data);

		info->file_data.da = download_data.buffer.da;

		if (!confirm) {
			info("Update file '%s' (version %d) rejected",
					data.name, data.version);
			return true;
		}
	}

	write_file_data(info, info->temp, data.name);
	replace_file(info->temp, info->cache, data.name);

	info("Successfully updated file '%s' (version %d)",
			data.name, data.version);
	return true;
}

static void update_save_metadata(struct update_info *info)
{
	struct dstr path = { 0 };

	if (!info->etag_remote)
		return;

	dstr_copy(&path, info->cache);
	dstr_cat(&path, "meta.json");

	obs_data_t *data;
	data = obs_data_create();
	obs_data_set_string(data, "etag", info->etag_remote);
	obs_data_save_json(data, path.array);
	obs_data_release(data);
}

static void update_remote_version(struct update_info *info, int cur_version)
{
	int remote_version;
	long response_code;

	if (!do_http_request(info, info->url, &response_code))
		return;

	if (response_code == 304)
		return;

	if (!info->file_data.array || info->file_data.array[0] != '{') {
		warn("Remote package does not exist or is not valid json");
		return;
	}

	update_save_metadata(info);

	info->remote_package = obs_data_create_from_json(
			(char*)info->file_data.array);
	if (!info->remote_package) {
		warn("Failed to initialize remote package json");
		return;
	}

	remote_version = (int)obs_data_get_int(info->remote_package, "version");
	if (remote_version <= cur_version)
		return;

	write_file_data(info, info->temp, "package.json");

	info->remote_url = obs_data_get_string(info->remote_package, "url");
	if (!info->remote_url) {
		warn("No remote url in package file");
		return;
	}

	/* download new files */
	enum_files(info->remote_package, update_remote_files, info);

	replace_file(info->temp, info->cache, "package.json");

	info("Successfully updated package (version %d)", remote_version);
	return;
}
static obs_properties_t *ffmpeg_source_getproperties(void *data)
{
	struct dstr filter = {0};
	UNUSED_PARAMETER(data);

	obs_properties_t *props = obs_properties_create();

	obs_properties_set_flags(props, OBS_PROPERTIES_DEFER_UPDATE);

	obs_property_t *prop;
	// use this when obs allows non-readonly paths
	prop = obs_properties_add_bool(props, "is_local_file",
			obs_module_text("LocalFile"));

	obs_property_set_modified_callback(prop, is_local_file_modified);

	dstr_copy(&filter, obs_module_text("MediaFileFilter.AllMediaFiles"));
	dstr_cat(&filter, media_filter);
	dstr_cat(&filter, obs_module_text("MediaFileFilter.VideoFiles"));
	dstr_cat(&filter, video_filter);
	dstr_cat(&filter, obs_module_text("MediaFileFilter.AudioFiles"));
	dstr_cat(&filter, audio_filter);
	dstr_cat(&filter, obs_module_text("MediaFileFilter.AllFiles"));
	dstr_cat(&filter, " (*.*)");

	obs_properties_add_path(props, "local_file",
			obs_module_text("LocalFile"), OBS_PATH_FILE,
			filter.array, NULL);
	dstr_free(&filter);

	obs_properties_add_bool(props, "looping", obs_module_text("Looping"));

	obs_properties_add_bool(props, "restart_on_activate",
			obs_module_text("RestartWhenActivated"));

	obs_properties_add_text(props, "input",
			obs_module_text("Input"), OBS_TEXT_DEFAULT);

	obs_properties_add_text(props, "input_format",
			obs_module_text("InputFormat"), OBS_TEXT_DEFAULT);

	obs_properties_add_bool(props, "hw_decode",
			obs_module_text("HardwareDecode"));

	obs_properties_add_bool(props, "clear_on_media_end",
			obs_module_text("ClearOnMediaEnd"));

	prop = obs_properties_add_bool(props, "advanced",
			obs_module_text("Advanced"));

	obs_property_set_modified_callback(prop, is_advanced_modified);

	obs_properties_add_bool(props, "force_scale",
			obs_module_text("ForceFormat"));

	prop = obs_properties_add_int(props, "audio_buffer_size",
			obs_module_text("AudioBufferSize"), 1, 9999, 1);

	obs_property_set_visible(prop, false);

	prop = obs_properties_add_int(props, "video_buffer_size",
			obs_module_text("VideoBufferSize"), 1, 9999, 1);

	obs_property_set_visible(prop, false);

	prop = obs_properties_add_list(props, "frame_drop",
			obs_module_text("FrameDropping"), OBS_COMBO_TYPE_LIST,
			OBS_COMBO_FORMAT_INT);

	obs_property_list_add_int(prop, obs_module_text("DiscardNone"),
			AVDISCARD_NONE);
	obs_property_list_add_int(prop, obs_module_text("DiscardDefault"),
			AVDISCARD_DEFAULT);
	obs_property_list_add_int(prop, obs_module_text("DiscardNonRef"),
			AVDISCARD_NONREF);
	obs_property_list_add_int(prop, obs_module_text("DiscardBiDir"),
			AVDISCARD_BIDIR);
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 67, 100)
	obs_property_list_add_int(prop, obs_module_text("DiscardNonIntra"),
			AVDISCARD_NONINTRA);
#endif
	obs_property_list_add_int(prop, obs_module_text("DiscardNonKey"),
			AVDISCARD_NONKEY);
	obs_property_list_add_int(prop, obs_module_text("DiscardAll"),
			AVDISCARD_ALL);

	obs_property_set_visible(prop, false);

	return props;
}
Beispiel #28
0
void obs_hotkeys_set_translations_s(
		struct obs_hotkeys_translations *translations, size_t size)
{
#define ADD_TRANSLATION(key_name, var_name) \
	if (t.var_name) \
		obs_set_key_translation(key_name, t.var_name);

	struct obs_hotkeys_translations t = {0};
	struct dstr numpad = {0};
	struct dstr mouse = {0};
	struct dstr button = {0};

	if (!translations) {
		return;
	}

	memcpy(&t, translations, (size < sizeof(t)) ? size : sizeof(t));

	ADD_TRANSLATION(OBS_KEY_INSERT, insert);
	ADD_TRANSLATION(OBS_KEY_DELETE, del);
	ADD_TRANSLATION(OBS_KEY_HOME, home);
	ADD_TRANSLATION(OBS_KEY_END, end);
	ADD_TRANSLATION(OBS_KEY_PAGEUP, page_up);
	ADD_TRANSLATION(OBS_KEY_PAGEDOWN, page_down);
	ADD_TRANSLATION(OBS_KEY_NUMLOCK, num_lock);
	ADD_TRANSLATION(OBS_KEY_SCROLLLOCK, scroll_lock);
	ADD_TRANSLATION(OBS_KEY_CAPSLOCK, caps_lock);
	ADD_TRANSLATION(OBS_KEY_BACKSPACE, backspace);
	ADD_TRANSLATION(OBS_KEY_TAB, tab);
	ADD_TRANSLATION(OBS_KEY_PRINT, print);
	ADD_TRANSLATION(OBS_KEY_PAUSE, pause);
	ADD_TRANSLATION(OBS_KEY_SHIFT, shift);
	ADD_TRANSLATION(OBS_KEY_ALT, alt);
	ADD_TRANSLATION(OBS_KEY_CONTROL, control);
	ADD_TRANSLATION(OBS_KEY_META, meta);
	ADD_TRANSLATION(OBS_KEY_MENU, menu);
	ADD_TRANSLATION(OBS_KEY_SPACE, space);
#ifdef __APPLE__
	const char *numpad_str = t.apple_keypad_num;
	ADD_TRANSLATION(OBS_KEY_NUMSLASH, apple_keypad_divide);
	ADD_TRANSLATION(OBS_KEY_NUMASTERISK, apple_keypad_multiply);
	ADD_TRANSLATION(OBS_KEY_NUMMINUS, apple_keypad_minus);
	ADD_TRANSLATION(OBS_KEY_NUMPLUS, apple_keypad_plus);
	ADD_TRANSLATION(OBS_KEY_NUMPERIOD, apple_keypad_decimal);
	ADD_TRANSLATION(OBS_KEY_NUMEQUAL, apple_keypad_equal);
#else
	const char *numpad_str = t.numpad_num;
	ADD_TRANSLATION(OBS_KEY_NUMSLASH, numpad_divide);
	ADD_TRANSLATION(OBS_KEY_NUMASTERISK, numpad_multiply);
	ADD_TRANSLATION(OBS_KEY_NUMMINUS, numpad_minus);
	ADD_TRANSLATION(OBS_KEY_NUMPLUS, numpad_plus);
	ADD_TRANSLATION(OBS_KEY_NUMPERIOD, numpad_decimal);
#endif

	if (numpad_str) {
		dstr_copy(&numpad, numpad_str);
		dstr_depad(&numpad);

		if (dstr_find(&numpad, "%1") == NULL) {
			dstr_cat(&numpad, " %1");
		}

#define ADD_NUMPAD_NUM(idx) \
		dstr_copy_dstr(&button, &numpad); \
		dstr_replace(&button, "%1", #idx); \
		obs_set_key_translation(OBS_KEY_NUM ## idx, button.array)

		ADD_NUMPAD_NUM(0);
		ADD_NUMPAD_NUM(1);
		ADD_NUMPAD_NUM(2);
		ADD_NUMPAD_NUM(3);
		ADD_NUMPAD_NUM(4);
		ADD_NUMPAD_NUM(5);
		ADD_NUMPAD_NUM(6);
		ADD_NUMPAD_NUM(7);
		ADD_NUMPAD_NUM(8);
		ADD_NUMPAD_NUM(9);
	}

	if (t.mouse_num) {
		dstr_copy(&mouse, t.mouse_num);
		dstr_depad(&mouse);

		if (dstr_find(&mouse, "%1") == NULL) {
			dstr_cat(&mouse, " %1");
		}

#define ADD_MOUSE_NUM(idx) \
		dstr_copy_dstr(&button, &mouse); \
		dstr_replace(&button, "%1", #idx); \
		obs_set_key_translation(OBS_KEY_MOUSE ## idx, button.array)

		ADD_MOUSE_NUM(1);
		ADD_MOUSE_NUM(2);
		ADD_MOUSE_NUM(3);
		ADD_MOUSE_NUM(4);
		ADD_MOUSE_NUM(5);
		ADD_MOUSE_NUM(6);
		ADD_MOUSE_NUM(7);
		ADD_MOUSE_NUM(8);
		ADD_MOUSE_NUM(9);
		ADD_MOUSE_NUM(10);
		ADD_MOUSE_NUM(11);
		ADD_MOUSE_NUM(12);
		ADD_MOUSE_NUM(13);
		ADD_MOUSE_NUM(14);
		ADD_MOUSE_NUM(15);
		ADD_MOUSE_NUM(16);
		ADD_MOUSE_NUM(17);
		ADD_MOUSE_NUM(18);
		ADD_MOUSE_NUM(19);
		ADD_MOUSE_NUM(20);
		ADD_MOUSE_NUM(21);
		ADD_MOUSE_NUM(22);
		ADD_MOUSE_NUM(23);
		ADD_MOUSE_NUM(24);
		ADD_MOUSE_NUM(25);
		ADD_MOUSE_NUM(26);
		ADD_MOUSE_NUM(27);
		ADD_MOUSE_NUM(28);
		ADD_MOUSE_NUM(29);
	}

	dstr_free(&numpad);
	dstr_free(&mouse);
	dstr_free(&button);
}
Beispiel #29
0
/*
 * List available devices
 */
static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings)
{
	DIR *dirp;
	struct dirent *dp;
	struct dstr device;
	bool cur_device_found;
	size_t cur_device_index;
	const char *cur_device_name;

#ifdef __FreeBSD__
	dirp = opendir("/dev");
#else
	dirp = opendir("/sys/class/video4linux");
#endif
	if (!dirp)
		return;

	cur_device_found = false;
	cur_device_name  = obs_data_get_string(settings, "device_id");

	obs_property_list_clear(prop);

	dstr_init_copy(&device, "/dev/");

	while ((dp = readdir(dirp)) != NULL) {
		int fd;
		uint32_t caps;
		struct v4l2_capability video_cap;

#ifdef __FreeBSD__
		if (strstr(dp->d_name, "video") == NULL)
			continue;
#endif

		if (dp->d_type == DT_DIR)
			continue;

		dstr_resize(&device, 5);
		dstr_cat(&device, dp->d_name);

		if ((fd = v4l2_open(device.array, O_RDWR | O_NONBLOCK)) == -1) {
			blog(LOG_INFO, "Unable to open %s", device.array);
			continue;
		}

		if (v4l2_ioctl(fd, VIDIOC_QUERYCAP, &video_cap) == -1) {
			blog(LOG_INFO, "Failed to query capabilities for %s",
			     device.array);
			v4l2_close(fd);
			continue;
		}

#ifndef V4L2_CAP_DEVICE_CAPS
		caps = video_cap.capabilities;
#else
		/* ... since Linux 3.3 */
		caps = (video_cap.capabilities & V4L2_CAP_DEVICE_CAPS)
			? video_cap.device_caps
			: video_cap.capabilities;
#endif

		if (!(caps & V4L2_CAP_VIDEO_CAPTURE)) {
			blog(LOG_INFO, "%s seems to not support video capture",
			     device.array);
			v4l2_close(fd);
			continue;
		}

		obs_property_list_add_string(prop, (char *) video_cap.card,
				device.array);
		blog(LOG_INFO, "Found device '%s' at %s", video_cap.card,
				device.array);

		/* check if this is the currently used device */
		if (cur_device_name && !strcmp(cur_device_name, device.array))
			cur_device_found = true;

		v4l2_close(fd);
	}

	/* add currently selected device if not present, but disable it ... */
	if (!cur_device_found && cur_device_name && strlen(cur_device_name)) {
		cur_device_index = obs_property_list_add_string(prop,
				cur_device_name, cur_device_name);
		obs_property_list_item_disable(prop, cur_device_index, true);
	}

	closedir(dirp);
	dstr_free(&device);
}
Beispiel #30
0
/* FIXME */
static void *q_thread(void *data) {
	struct crss *crss = (struct crss *)data;
	char buf[64];
	dstr rid, res = NULL;
	db_iterator_t *it;
	const char *key, *value;
	size_t klen, vlen;

	snprintf(buf, sizeof buf, "%p,", crss->c);
	rid = dstr_new(buf);
	rid = dstr_cat(rid, crss->rid);
	it = db_iterator_create(db, db_ro);
	db_iterator_seek(it, crss->start, dstr_length(crss->start));
	/* seek failed */
	if (!db_iterator_valid(it)) {
		res = dstr_new(crss->rid);
		res = dstr_cat(res, ",1\r\n\r\n");
		pthread_spin_lock(&crss->c->lock);
		if (net_try_write(crss->c->fd, res, dstr_length(res), 10, NET_NONBLOCK) == -1)
			xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s", crss->c, strerror(errno));
		pthread_spin_unlock(&crss->c->lock);
		goto end;
	}
	key = db_iterator_key(it, &klen);
	while (memcmp(key, crss->stop, dstr_length(crss->stop)) <= 0) {
		if (crss->cancel)
			break;
		if (!strcmp(crss->match, "") || strstr(key, crss->match)) {
			value = db_iterator_value(it, &vlen);
			res = dstr_new(crss->rid);
			res = dstr_cat(res, ",0,");
			res = dstr_cat_len(res, key, klen);
			res = dstr_cat(res, ",");
			res = dstr_cat_len(res, value, vlen);
			res = dstr_cat(res, "\r\n");
			pthread_spin_lock(&crss->c->lock);
			if (net_try_write(crss->c->fd, res, dstr_length(res), 10, NET_NONBLOCK) == -1) {
				xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s",
					crss->c, strerror(errno));
				pthread_spin_unlock(&crss->c->lock);
				goto end;
			}
			pthread_spin_unlock(&crss->c->lock);
			dstr_free(res);
		}
		db_iterator_next(it);
		if (!db_iterator_valid(it) || crss->cancel)
			break;
		key = db_iterator_key(it, &klen);
	}
	res = dstr_new(crss->rid);
	res = dstr_cat(res, ",1\r\n\r\n");
	pthread_spin_lock(&crss->c->lock);
	if (net_try_write(crss->c->fd, res, dstr_length(res), 10, NET_NONBLOCK) == -1)
		xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s", crss->c, strerror(errno));
	pthread_spin_unlock(&crss->c->lock);

end:
	db_iterator_destroy(&it);
	dstr_free(res);
	table_lock(rids);
	table_remove(rids, rid);
	table_unlock(rids);
	dstr_free(rid);
	client_decr(crss->c);
	dstr_free(crss->rid);
	dstr_free(crss->match);
	dstr_free(crss->start);
	dstr_free(crss->stop);
	FREE(crss);
	return NULL;
}