Changes in uspace/lib/tbarcfg/src/tbarcfg.c [e63e74a:ee3b28a9] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/tbarcfg/src/tbarcfg.c
re63e74a ree3b28a9 34 34 */ 35 35 36 #include <async.h> 36 37 #include <errno.h> 37 38 #include <sif.h> 39 #include <ipc/tbarcfg.h> 40 #include <loc.h> 41 #include <task.h> 38 42 #include <tbarcfg/tbarcfg.h> 43 #include <stdio.h> 39 44 #include <stdlib.h> 40 45 #include <str.h> 41 46 #include "../private/tbarcfg.h" 47 48 static void tbarcfg_notify_conn(ipc_call_t *, void *); 42 49 43 50 /** Create taskbar configuration. … … 784 791 } 785 792 793 /** Create taskbar configuration listener. 794 * 795 * Listens for taskbar configuration change notifications. 796 * 797 * @param nchan Notification channel (TBARCFG_NOTIFY_DEFAULT) 798 * @param rlst Place to store pointer to new listener 799 * @return EOK on success or an error code 800 */ 801 errno_t tbarcfg_listener_create(const char *nchan, void (*cb)(void *), 802 void *arg, tbarcfg_listener_t **rlst) 803 { 804 tbarcfg_listener_t *lst; 805 service_id_t svcid = 0; 806 loc_srv_t *srv = NULL; 807 task_id_t taskid; 808 char *svcname = NULL; 809 category_id_t catid; 810 port_id_t port; 811 int rv; 812 errno_t rc; 813 814 lst = calloc(1, sizeof(tbarcfg_listener_t)); 815 if (lst == NULL) 816 return ENOMEM; 817 818 lst->cb = cb; 819 lst->arg = arg; 820 821 rc = async_create_port(INTERFACE_TBARCFG_NOTIFY, 822 tbarcfg_notify_conn, (void *)lst, &port); 823 if (rc != EOK) 824 goto error; 825 826 rc = loc_server_register("tbarcfg-listener", &srv); 827 if (rc != EOK) 828 goto error; 829 830 taskid = task_get_id(); 831 832 rv = asprintf(&svcname, "tbarcfg/%u", (unsigned)taskid); 833 if (rv < 0) { 834 rc = ENOMEM; 835 goto error; 836 } 837 838 rc = loc_service_register(srv, svcname, &svcid); 839 if (rc != EOK) 840 goto error; 841 842 rc = loc_category_get_id(nchan, &catid, 0); 843 if (rc != EOK) 844 goto error; 845 846 rc = loc_service_add_to_cat(srv, svcid, catid); 847 if (rc != EOK) 848 goto error; 849 850 *rlst = lst; 851 return EOK; 852 error: 853 if (svcid != 0) 854 loc_service_unregister(srv, svcid); 855 if (srv != NULL) 856 loc_server_unregister(srv); 857 if (svcname != NULL) 858 free(svcname); 859 return rc; 860 } 861 862 /** Destroy taskbar configuration listener. 863 * 864 * @param lst Listener 865 */ 866 void tbarcfg_listener_destroy(tbarcfg_listener_t *lst) 867 { 868 free(lst); 869 } 870 871 /** Send taskbar configuration notification to a particular service ID. 872 * 873 * @param svcid Service ID 874 * @return EOK on success or an error code 875 */ 876 static errno_t tbarcfg_notify_svc(service_id_t svcid) 877 { 878 async_sess_t *sess; 879 async_exch_t *exch; 880 errno_t rc; 881 882 sess = loc_service_connect(svcid, INTERFACE_TBARCFG_NOTIFY, 0); 883 if (sess == NULL) 884 return EIO; 885 886 exch = async_exchange_begin(sess); 887 rc = async_req_0_0(exch, TBARCFG_NOTIFY_NOTIFY); 888 if (rc != EOK) { 889 async_exchange_end(exch); 890 async_hangup(sess); 891 return rc; 892 } 893 894 async_exchange_end(exch); 895 async_hangup(sess); 896 return EOK; 897 } 898 899 /** Send taskbar configuration change notification. 900 * 901 * @param nchan Notification channel (TBARCFG_NOTIFY_DEFAULT) 902 */ 903 errno_t tbarcfg_notify(const char *nchan) 904 { 905 errno_t rc; 906 category_id_t catid; 907 service_id_t *svcs = NULL; 908 size_t count, i; 909 910 rc = loc_category_get_id(nchan, &catid, 0); 911 if (rc != EOK) 912 return rc; 913 914 rc = loc_category_get_svcs(catid, &svcs, &count); 915 if (rc != EOK) 916 return rc; 917 918 for (i = 0; i < count; i++) { 919 rc = tbarcfg_notify_svc(svcs[i]); 920 if (rc != EOK) 921 goto error; 922 } 923 924 free(svcs); 925 return EOK; 926 error: 927 free(svcs); 928 return rc; 929 } 930 931 /** Taskbar configuration connection handler. 932 * 933 * @param icall Initial call 934 * @param arg Argument (tbarcfg_listener_t *) 935 */ 936 static void tbarcfg_notify_conn(ipc_call_t *icall, void *arg) 937 { 938 tbarcfg_listener_t *lst = (tbarcfg_listener_t *)arg; 939 940 /* Accept the connection */ 941 async_accept_0(icall); 942 943 while (true) { 944 ipc_call_t call; 945 async_get_call(&call); 946 sysarg_t method = ipc_get_imethod(&call); 947 948 if (!method) { 949 /* The other side has hung up */ 950 async_answer_0(&call, EOK); 951 return; 952 } 953 954 switch (method) { 955 case TBARCFG_NOTIFY_NOTIFY: 956 lst->cb(lst->arg); 957 async_answer_0(&call, EOK); 958 break; 959 default: 960 async_answer_0(&call, EINVAL); 961 } 962 } 963 } 964 786 965 /** @} 787 966 */
Note:
See TracChangeset
for help on using the changeset viewer.