4 #include <sys/socket.h>
12 static int pulse_init_count = 0;
14 int PULSE_EVENT_CONNECTED = -1;
15 int PULSE_EVENT_DISCONNECTED = -1;
16 int PULSE_EVENT_CHANGE = -1;
17 Eina_Hash *pulse_sinks = NULL;
18 Eina_Hash *pulse_sources = NULL;
21 pulse_fake_free(void *d __UNUSED__, void *d2 __UNUSED__)
25 proplist_init(Pulse_Tag *tag)
33 tag->props = eina_hash_string_superfast_new((void*)eina_stringshare_del);
37 "tapplication.process.id\0"
38 "L\0\0\0\5x\0\0\0\0052742\0"
39 "tapplication.process.user\0"
40 "L\0\0\0\5x\0\0\0\5root\0"
41 "tapplication.process.host\0"
42 "L\0\0\0\fx\0\0\0\fdarc.ath.cx\0"
43 "tapplication.process.binary\0"
44 "L\0\0\0\6x\0\0\0\6pactl\0"
46 "L\0\0\0\6x\0\0\0\6pactl\0"
47 "tapplication.language\0"
48 "L\0\0\0\vx\0\0\0\ven_US.utf8\0"
49 "twindow.x11.display\0"
50 "L\0\0\0\5x\0\0\0\5:0.0\0"
51 "tapplication.process.machine_id\0"
52 "L\0\0\0!x\0\0\0!16ebb73850fbfdfff2b0079400000030\0"
55 tag->dsize += PA_TAG_SIZE_PROPLIST;
56 snprintf(pid, sizeof(pid), "%"PRIu32, getpid());
57 eina_hash_add(tag->props, "application.process.id", eina_stringshare_add(pid));
58 tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.id") + strlen(pid) + 2 + PA_TAG_SIZE_U32;
61 eina_hash_add(tag->props, "application.process.user", eina_stringshare_add(str));
62 tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.user") + strlen(str) + 2 + PA_TAG_SIZE_U32;
64 file = eina_file_open("/etc/hostname", EINA_FALSE);
67 size = eina_file_size_get(file);
68 str = (const char*)eina_file_map_all(file, EINA_FILE_POPULATE);
69 eina_hash_add(tag->props, "application.process.host", eina_stringshare_add_length(str, size - 1));
70 tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.host") + size + 1 + PA_TAG_SIZE_U32;
71 eina_file_map_free(file, (void*)str);
72 eina_file_close(file);
76 eina_hash_add(tag->props, "application.process.host", eina_stringshare_add(""));
77 tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.host") + 2 + PA_TAG_SIZE_U32;
80 ecore_app_args_get(&argc, &argv);
81 str = strrchr(argv[0], '/');
82 str = (str) ? str + 1 : argv[0];
83 eina_hash_add(tag->props, "application.process.binary", eina_stringshare_add(str));
84 tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.binary") + strlen(str) + 2 + PA_TAG_SIZE_U32;
85 eina_hash_add(tag->props, "application.name", eina_stringshare_add(str));
86 tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.name") + strlen(str) + 2 + PA_TAG_SIZE_U32;
91 eina_hash_add(tag->props, "application.language", eina_stringshare_add(str));
92 tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.language") + strlen(str) + 2 + PA_TAG_SIZE_U32;
95 str = getenv("DISPLAY");
98 eina_hash_add(tag->props, "window.x11.display", eina_stringshare_add(str));
99 tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("window.x11.display") + strlen(str) + 2 + PA_TAG_SIZE_U32;
102 file = eina_file_open(PA_MACHINE_ID, EINA_FALSE);
105 size = eina_file_size_get(file);
106 str = (const char*)eina_file_map_all(file, EINA_FILE_POPULATE);
107 eina_hash_add(tag->props, "application.process.machine_id", eina_stringshare_add_length(str, size - 1));
108 tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.machine_id") + size + 1 + PA_TAG_SIZE_U32;
109 eina_file_map_free(file, (void*)str);
110 eina_file_close(file);
117 gethostname(buf, sizeof(buf));
120 eina_hash_add(tag->props, "application.process.machine_id", eina_stringshare_add(buf));
121 tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.machine_id") + strlen(buf) + 2 + PA_TAG_SIZE_U32;
124 snprintf(buf, sizeof(buf), "%08lx", (unsigned long)gethostid());
125 eina_hash_add(tag->props, "application.process.machine_id", eina_stringshare_add(buf));
126 tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.machine_id") + strlen(buf) + 2 + PA_TAG_SIZE_U32;
131 cookie_file(uint8_t *cookie)
138 snprintf(buf, sizeof(buf), "%s/.pulse-cookie", getenv("HOME"));
139 file = eina_file_open(buf, EINA_FALSE);
140 size = eina_file_size_get(file);
141 cookie_data = eina_file_map_all(file, EINA_FILE_WILLNEED);
142 memcpy(cookie, cookie_data, size);
143 eina_file_map_free(file, cookie_data);
144 eina_file_close(file);
148 login_setup(Pulse *conn)
152 uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
154 tag = calloc(1, sizeof(Pulse_Tag));
155 tag->dsize = 4 * PA_TAG_SIZE_U32 + sizeof(cookie);
156 tag->data = malloc(tag->dsize);
157 tag_simple_init(conn, tag, PA_COMMAND_AUTH, PA_TAG_U32);
158 DBG("%zu bytes", tag->dsize);
161 x = PA_PROTOCOL_VERSION;
163 x = PA_PROTOCOL_VERSION | 0x80000000U;
165 DBG("%zu bytes", tag->dsize);
168 tag_arbitrary(tag, cookie, sizeof(cookie));
169 DBG("%zu bytes", tag->dsize);
177 pulse_recv(Pulse *conn, Ecore_Fd_Handler *fdh)
182 tag = eina_list_data_get(conn->iq);
185 tag = calloc(1, sizeof(Pulse_Tag));
186 conn->iq = eina_list_append(conn->iq, tag);
190 msg_recv_creds(conn, tag);
191 if (!tag->auth) return NULL;
195 tag->dsize = ntohl(tag->header[PA_PSTREAM_DESCRIPTOR_LENGTH]);
199 conn->state = PA_STATE_INIT;
200 ecore_main_fd_handler_del(conn->fdh);
202 ecore_event_add(PULSE_EVENT_DISCONNECTED, conn, pulse_fake_free, NULL);
205 tag->data = malloc(tag->dsize);
207 if (tag->pos < tag->dsize)
209 if (!msg_recv(conn, tag))
212 untag_uint32(tag, &x);
213 EINA_SAFETY_ON_TRUE_GOTO((x != PA_COMMAND_REPLY) && (x != PA_COMMAND_SUBSCRIBE_EVENT), error);
215 if (x == PA_COMMAND_REPLY)
216 untag_uint32(tag, &tag->tag_count);
218 tag->size += PA_TAG_SIZE_U32;
219 if (conn->state != PA_STATE_CONNECTED)
221 ecore_main_fd_handler_active_set(fdh, ECORE_FD_WRITE);
226 ERR("Received error command %"PRIu32"!", x);
232 login_finish(Pulse *conn, Ecore_Fd_Handler *fdh)
236 tag = calloc(1, sizeof(Pulse_Tag));
237 tag->dsize = 2 * PA_TAG_SIZE_U32; /* tag_simple_init */
239 DBG("prep %zu bytes", tag->dsize);
240 tag->data = malloc(tag->dsize);
241 tag_simple_init(conn, tag, PA_COMMAND_SET_CLIENT_NAME, PA_TAG_U32);
244 msg_send_creds(conn, tag);
246 if (msg_send(conn, tag))
247 ecore_main_fd_handler_active_set(fdh, ECORE_FD_READ);
249 conn->oq = eina_list_append(conn->oq, tag);
253 fdh_func(Pulse *conn, Ecore_Fd_Handler *fdh)
255 Pulse_Tag *rprev, *wprev;
258 if (conn->watching) read = ECORE_FD_READ;
260 read = !!ecore_main_fd_handler_active_get(fdh, ECORE_FD_READ) * ECORE_FD_READ;
261 write = !!ecore_main_fd_handler_active_get(fdh, ECORE_FD_WRITE) * ECORE_FD_WRITE;
262 rprev = eina_list_data_get(conn->iq);
263 wprev = eina_list_data_get(conn->oq);
270 wprev = login_setup(conn);
271 conn->oq = eina_list_append(conn->oq, wprev);
275 msg_sendmsg_creds(conn, wprev);
277 if (wprev->auth && msg_send(conn, wprev))
280 ecore_main_fd_handler_active_set(fdh, ECORE_FD_READ);
284 if (pulse_recv(conn, fdh))
285 login_finish(conn, fdh);
287 case PA_STATE_MOREAUTH:
290 if (msg_send(conn, wprev))
291 ecore_main_fd_handler_active_set(fdh, ECORE_FD_READ);
294 if (pulse_recv(conn, fdh))
297 INF("Login complete!");
298 ecore_main_fd_handler_active_set(fdh, 0);
299 ecore_event_add(PULSE_EVENT_CONNECTED, conn, pulse_fake_free, NULL);
302 case PA_STATE_CONNECTED:
309 msg_send_creds(conn, wprev);
312 if (msg_send(conn, wprev))
313 ecore_main_fd_handler_active_set(conn->fdh, ECORE_FD_READ | (!!conn->oq * ECORE_FD_WRITE));
317 ecore_main_fd_handler_active_set(conn->fdh, ECORE_FD_READ);
322 if ((!rprev) || (!rprev->auth) || (rprev->pos < rprev->dsize))
326 tag = pulse_recv(conn, fdh);
329 command = (uintptr_t)eina_hash_find(conn->tag_handlers, &tag->tag_count);
330 eina_hash_del_by_key(conn->tag_handlers, &tag->tag_count);
331 deserialize_tag(conn, command, tag);
332 if (!eina_list_count(conn->oq))
333 ecore_main_fd_handler_active_set(conn->fdh, write | conn->watching * ECORE_FD_READ);
341 return ECORE_CALLBACK_RENEW;
345 con(Pulse *conn, int type __UNUSED__, Ecore_Con_Event_Server_Add *ev)
349 if (conn != ecore_con_server_data_get(ev->server)) return ECORE_CALLBACK_PASS_ON;
350 INF("connected to %s", ecore_con_server_name_get(ev->server));
352 conn->fd = dup(ecore_con_server_fd_get(ev->server));
354 setsockopt(conn->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
356 setsockopt(conn->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
357 fcntl(conn->fd, F_SETFL, O_NONBLOCK | FD_CLOEXEC);
358 conn->fdh = ecore_main_fd_handler_add(conn->fd, ECORE_FD_WRITE, (Ecore_Fd_Cb)fdh_func, conn, NULL, NULL);
359 ecore_con_server_del(conn->svr);
361 return ECORE_CALLBACK_RENEW;
365 pulse_cards_get(Pulse *conn)
369 uint32_t type = PA_COMMAND_GET_CARD_INFO_LIST;
371 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0);
372 tag = calloc(1, sizeof(Pulse_Tag));
373 EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0);
374 tag->dsize = 2 * PA_TAG_SIZE_U32;
375 tag->data = malloc(tag->dsize);
376 tag->tag_count = conn->tag_count;
377 tag_simple_init(conn, tag, type, PA_TAG_U32);
379 read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ;
380 ecore_main_fd_handler_active_set(conn->fdh, read | ECORE_FD_WRITE);
381 conn->oq = eina_list_append(conn->oq, tag);
382 eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type));
383 return tag->tag_count;
387 pulse_cb_set(Pulse *conn, uint32_t tagnum, Pulse_Cb cb)
389 EINA_SAFETY_ON_NULL_RETURN(conn);
391 if (cb) eina_hash_set(conn->tag_cbs, &tagnum, cb);
392 else eina_hash_del_by_key(conn->tag_cbs, &tagnum);
396 pulse_type_get(Pulse *conn, uint32_t idx, Eina_Bool source)
400 uint32_t type = source ? PA_COMMAND_GET_SOURCE_INFO : PA_COMMAND_GET_SINK_INFO;
402 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0);
403 tag = calloc(1, sizeof(Pulse_Tag));
404 EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0);
405 tag->dsize = 3 * PA_TAG_SIZE_U32 + PA_TAG_SIZE_STRING_NULL;
406 tag->data = malloc(tag->dsize);
407 tag->tag_count = conn->tag_count;
408 tag_simple_init(conn, tag, type, PA_TAG_U32);
409 tag_uint32(tag, idx);
410 tag_string(tag, NULL);
412 read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ;
413 ecore_main_fd_handler_active_set(conn->fdh, read | ECORE_FD_WRITE);
414 conn->oq = eina_list_append(conn->oq, tag);
415 eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type));
416 return tag->tag_count;
420 pulse_types_get(Pulse *conn, Eina_Bool source)
424 uint32_t type = source ? PA_COMMAND_GET_SOURCE_INFO_LIST : PA_COMMAND_GET_SINK_INFO_LIST;
426 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0);
427 tag = calloc(1, sizeof(Pulse_Tag));
428 EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0);
429 tag->dsize = 2 * PA_TAG_SIZE_U32;
430 tag->data = malloc(tag->dsize);
431 tag->tag_count = conn->tag_count;
432 tag_simple_init(conn, tag, type, PA_TAG_U32);
434 read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ;
435 ecore_main_fd_handler_active_set(conn->fdh, read | ECORE_FD_WRITE);
436 conn->oq = eina_list_append(conn->oq, tag);
437 eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type));
438 return tag->tag_count;
442 pulse_type_mute_set(Pulse *conn, uint32_t sink_num, Eina_Bool mute, Eina_Bool source)
446 uint32_t type = source ? PA_COMMAND_SET_SOURCE_MUTE : PA_COMMAND_SET_SINK_MUTE;
449 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0);
450 tag = calloc(1, sizeof(Pulse_Tag));
451 EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0);
452 tag->dsize = 3 * PA_TAG_SIZE_U32 + PA_TAG_SIZE_STRING_NULL + PA_TAG_SIZE_BOOLEAN;
453 tag->data = malloc(tag->dsize);
454 tag->tag_count = conn->tag_count;
455 tag_simple_init(conn, tag, type, PA_TAG_U32);
456 tag_uint32(tag, sink_num);
457 tag_string(tag, NULL);
458 tag_bool(tag, !!mute);
460 read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ;
461 ecore_main_fd_handler_active_set(conn->fdh, read | ECORE_FD_WRITE);
462 conn->oq = eina_list_append(conn->oq, tag);
463 eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type));
464 h = (source) ? pulse_sources : pulse_sinks;
469 sink = eina_hash_find(h, &sink_num);
470 if (sink) sink->mute = !!mute;
472 return tag->tag_count;
476 pulse_type_volume_set(Pulse *conn, uint32_t sink_num, uint8_t channels, double vol, Eina_Bool source)
480 uint32_t type = source ? PA_COMMAND_SET_SOURCE_MUTE : PA_COMMAND_SET_SINK_VOLUME;
482 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0);
483 tag = calloc(1, sizeof(Pulse_Tag));
484 EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0);
485 tag->dsize = 3 * PA_TAG_SIZE_U32 + PA_TAG_SIZE_STRING_NULL + PA_TAG_SIZE_CVOLUME + channels * sizeof(uint32_t);
486 tag->data = malloc(tag->dsize);
487 tag->tag_count = conn->tag_count;
488 tag_simple_init(conn, tag, type, PA_TAG_U32);
489 tag_uint32(tag, sink_num);
490 tag_string(tag, NULL);
491 tag_volume(tag, channels, vol);
493 read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ;
494 ecore_main_fd_handler_active_set(conn->fdh, read | ECORE_FD_WRITE);
495 conn->oq = eina_list_append(conn->oq, tag);
496 eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type));
497 return tag->tag_count;
501 pulse_sink_channel_volume_set(Pulse *conn, Pulse_Sink *sink, uint32_t id, double vol)
507 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0);
508 EINA_SAFETY_ON_TRUE_RETURN_VAL(id >= sink->channel_map.channels, 0);
509 tag = calloc(1, sizeof(Pulse_Tag));
510 EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0);
511 type = sink->source ? PA_COMMAND_SET_SOURCE_VOLUME : PA_COMMAND_SET_SINK_VOLUME;
512 tag->dsize = 3 * PA_TAG_SIZE_U32 + PA_TAG_SIZE_STRING_NULL + PA_TAG_SIZE_CVOLUME + sink->channel_map.channels * sizeof(uint32_t);
513 tag->data = malloc(tag->dsize);
514 tag->tag_count = conn->tag_count;
515 if (vol <= 0.0) sink->volume.values[id] = PA_VOLUME_MUTED;
516 else sink->volume.values[id] = ((vol * PA_VOLUME_NORM) - (PA_VOLUME_NORM / 2)) / 100;
517 tag_simple_init(conn, tag, type, PA_TAG_U32);
518 tag_uint32(tag, sink->index);
519 tag_string(tag, NULL);
520 tag_cvol(tag, &sink->volume);
522 read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ;
523 ecore_main_fd_handler_active_set(conn->fdh, read | ECORE_FD_WRITE);
524 conn->oq = eina_list_append(conn->oq, tag);
525 eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type));
526 return tag->tag_count;
530 pulse_sink_port_set(Pulse *conn, Pulse_Sink *sink, const char *port)
537 Eina_Bool match = EINA_FALSE;
539 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0);
540 EINA_SAFETY_ON_NULL_RETURN_VAL(port, 0);
541 EINA_LIST_FOREACH(sink->ports, l, p)
543 match = !strcmp(p, port);
546 EINA_SAFETY_ON_TRUE_RETURN_VAL(!match, 0);
547 tag = calloc(1, sizeof(Pulse_Tag));
548 EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0);
549 type = sink->source ? PA_COMMAND_SET_SOURCE_PORT : PA_COMMAND_SET_SINK_PORT;
550 tag->dsize = PA_TAG_SIZE_U32 + 2 * PA_TAG_SIZE_STRING + strlen(sink->name) + strlen(port);
551 tag->data = malloc(tag->dsize);
552 tag->tag_count = conn->tag_count;
553 tag_simple_init(conn, tag, type, PA_TAG_U32);
554 tag_uint32(tag, sink->index);
555 tag_string(tag, sink->name);
556 tag_string(tag, port);
558 read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ;
559 ecore_main_fd_handler_active_set(conn->fdh, read | ECORE_FD_WRITE);
560 conn->oq = eina_list_append(conn->oq, tag);
561 eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type));
562 return tag->tag_count;
566 pulse_sinks_watch(Pulse *conn)
569 uint32_t type = PA_COMMAND_SUBSCRIBE;
571 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, EINA_FALSE);
572 tag = calloc(1, sizeof(Pulse_Tag));
573 EINA_SAFETY_ON_NULL_RETURN_VAL(tag, EINA_FALSE);
574 tag->dsize = 3 * PA_TAG_SIZE_U32;
575 tag->data = malloc(tag->dsize);
576 tag->tag_count = conn->tag_count;
577 tag_simple_init(conn, tag, type, PA_TAG_U32);
578 tag_uint32(tag, PA_SUBSCRIPTION_MASK_ALL);
580 ecore_main_fd_handler_active_set(conn->fdh, ECORE_FD_READ | ECORE_FD_WRITE);
581 conn->oq = eina_list_append(conn->oq, tag);
582 eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type));
589 if (pulse_init_count++) return pulse_init_count;
594 pa_log_dom = eina_log_domain_register("pulse", EINA_COLOR_HIGH EINA_COLOR_BLUE);
596 PULSE_EVENT_CONNECTED = ecore_event_type_new();
597 PULSE_EVENT_DISCONNECTED = ecore_event_type_new();
598 PULSE_EVENT_CHANGE = ecore_event_type_new();
600 return pulse_init_count;
606 if ((!pulse_init_count) || (!--pulse_init_count)) return;
608 if (pulse_sinks) eina_hash_free(pulse_sinks);
609 if (pulse_sources) eina_hash_free(pulse_sources);
610 pulse_sinks = pulse_sources = NULL;
611 eina_log_domain_unregister(pa_log_dom);
612 ecore_con_shutdown();
622 const char *prev = NULL, *buf = NULL;;
625 const Eina_File_Direct_Info *info;
627 conn = calloc(1, sizeof(Pulse));
628 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
629 home = getenv("PULSE_RUNTIME_PATH");
633 home = getenv("HOME");
634 snprintf(h, sizeof(h), "%s/.pulse", home);
638 it = eina_file_direct_ls(home);
639 EINA_ITERATOR_FOREACH(it, info)
641 const char *rt = NULL;
643 rt = strrchr(info->path + info->name_start, '-');
646 if (!strcmp(rt + 1, "runtime"))
649 buf = eina_stringshare_printf("%s/native", info->path);
652 eina_stringshare_del(buf);
663 if (time > st.st_atime)
665 eina_stringshare_del(buf);
669 eina_stringshare_del(prev);
676 eina_iterator_free(it);
680 buf = eina_stringshare_add(STATEDIR "/run/pulse/native");
683 INF("could not locate local socket '%s'!", buf);
689 else conn->socket = prev;
690 conn->con = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, (Ecore_Event_Handler_Cb)con, conn);
691 conn->tag_handlers = eina_hash_int32_new(NULL);
692 conn->tag_cbs = eina_hash_int32_new(NULL);
697 pulse_free(Pulse *conn)
701 if (conn->fdh) ecore_main_fd_handler_del(conn->fdh);
702 else if (conn->svr) ecore_con_server_del(conn->svr);
703 ecore_event_handler_del(conn->con);
704 eina_stringshare_del(conn->socket);
705 EINA_LIST_FREE(conn->oq, tag)
707 EINA_LIST_FREE(conn->iq, tag)
709 eina_hash_free(conn->tag_handlers);
710 eina_hash_free(conn->tag_cbs);
715 pulse_connect(Pulse *conn)
717 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, EINA_FALSE);
718 conn->svr = ecore_con_server_connect(ECORE_CON_LOCAL_SYSTEM, conn->socket, -1, conn);