Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/tbarcfg/src/tbarcfg.c

    ree3b28a9 re63e74a  
    3434 */
    3535
    36 #include <async.h>
    3736#include <errno.h>
    3837#include <sif.h>
    39 #include <ipc/tbarcfg.h>
    40 #include <loc.h>
    41 #include <task.h>
    4238#include <tbarcfg/tbarcfg.h>
    43 #include <stdio.h>
    4439#include <stdlib.h>
    4540#include <str.h>
    4641#include "../private/tbarcfg.h"
    47 
    48 static void tbarcfg_notify_conn(ipc_call_t *, void *);
    4942
    5043/** Create taskbar configuration.
     
    791784}
    792785
    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 
    965786/** @}
    966787 */
Note: See TracChangeset for help on using the changeset viewer.