Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/compositor/compositor.c

    rfbb2d0d r3b98311  
    143143static LIST_INITIALIZE(viewport_list);
    144144
    145 static FIBRIL_MUTEX_INITIALIZE(discovery_mtx);
    146 
    147145/** Input server proxy */
    148146static input_t *input;
     
    337335        }
    338336
    339         list_foreach(viewport_list, link, viewport_t, vp) {
     337        list_foreach(viewport_list, link) {
     338                viewport_t *vp = list_get_instance(link, viewport_t, link);
    340339                sysarg_t w_vp, h_vp;
    341340                surface_get_resolution(vp->surface, &w_vp, &h_vp);
     
    355354        fibril_mutex_lock(&pointer_list_mtx);
    356355
    357         list_foreach(pointer_list, link, pointer_t, ptr) {
     356        list_foreach(pointer_list, link) {
     357                pointer_t *ptr = list_get_instance(link, pointer_t, link);
    358358                ptr->pos.x = ptr->pos.x > viewport_bound_rect.x ? ptr->pos.x : viewport_bound_rect.x;
    359359                ptr->pos.y = ptr->pos.y > viewport_bound_rect.y ? ptr->pos.y : viewport_bound_rect.y;
     
    374374        fibril_mutex_lock(&pointer_list_mtx);
    375375
    376         list_foreach(viewport_list, link, viewport_t, vp) {
     376        list_foreach(viewport_list, link) {
     377
    377378                /* Determine what part of the viewport must be updated. */
     379                viewport_t *vp = list_get_instance(link, viewport_t, link);
    378380                sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp;
    379381                surface_get_resolution(vp->surface, &w_dmg_vp, &h_dmg_vp);
     
    444446                        }
    445447
    446                         list_foreach(pointer_list, link, pointer_t, ptr) {
     448                        list_foreach(pointer_list, link) {
     449
     450                                pointer_t *ptr = list_get_instance(link, pointer_t, link);
    447451                                if (ptr->ghost.surface) {
    448452
     
    518522                        }
    519523
    520                         list_foreach(pointer_list, link, pointer_t, ptr) {
     524                        list_foreach(pointer_list, link) {
    521525
    522526                                /* Determine what part of the pointer intersects with the
    523527                                 * updated area of the current viewport. */
     528                                pointer_t *ptr = list_get_instance(link, pointer_t, link);
    524529                                sysarg_t x_dmg_ptr, y_dmg_ptr, w_dmg_ptr, h_dmg_ptr;
    525530                                surface_t *sf_ptr = ptr->cursor.states[ptr->state];
     
    564569
    565570        /* Notify visualizers about updated regions. */
    566         list_foreach(viewport_list, link, viewport_t, vp) {
     571        list_foreach(viewport_list, link) {
     572                viewport_t *vp = list_get_instance(link, viewport_t, link);
    567573                sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp;
    568574                surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp);
     
    625631
    626632        fibril_mutex_lock(&pointer_list_mtx);
    627         list_foreach(pointer_list, link, pointer_t, pointer) {
     633        list_foreach(pointer_list, link) {
     634                pointer_t *pointer = list_get_instance(link, pointer_t, link);
    628635                if (pointer->id == pos_id) {
    629636                        pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY;
     
    703710{
    704711        fibril_mutex_lock(&window_list_mtx);
    705 
    706         list_foreach(window_list, link, window_t, window) {
     712        window_t *window = NULL;
     713        list_foreach(window_list, link) {
     714                window = list_get_instance(link, window_t, link);
    707715                if (window == target) {
    708716                        prodcons_produce(&window->queue, &event->link);
    709                         fibril_mutex_unlock(&window_list_mtx);
    710                         return;
    711                 }
    712         }
    713 
     717                }
     718        }
     719        if (!window) {
     720                free(event);
     721        }
    714722        fibril_mutex_unlock(&window_list_mtx);
    715         free(event);
    716723}
    717724
     
    856863        window_t *win = NULL;
    857864        fibril_mutex_lock(&window_list_mtx);
    858         list_foreach(window_list, link, window_t, cur) {
     865        list_foreach(window_list, link) {
     866                window_t *cur = list_get_instance(link, window_t, link);
    859867                if (cur->in_dsid == service_id || cur->out_dsid == service_id) {
    860868                        win = cur;
     
    9991007                /* Close all clients and their windows. */
    10001008                fibril_mutex_lock(&window_list_mtx);
    1001                 list_foreach(window_list, link, window_t, win) {
     1009                list_foreach(window_list, link) {
     1010                        window_t *win = list_get_instance(link, window_t, link);
    10021011                        window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
    10031012                        if (event) {
     
    10251034        viewport_t *vp = NULL;
    10261035        fibril_mutex_lock(&viewport_list_mtx);
    1027         list_foreach(viewport_list, link, viewport_t, cur) {
     1036        list_foreach(viewport_list, link) {
     1037                viewport_t *cur = list_get_instance(link, viewport_t, link);
    10281038                if (cur->dsid == (service_id_t) IPC_GET_ARG1(*icall)) {
    10291039                        vp = cur;
     
    15611571
    15621572        /* Determine the window which the mouse click belongs to. */
    1563         list_foreach(window_list, link, window_t, cw) {
    1564                 win = cw;
     1573        list_foreach(window_list, link) {
     1574                win = list_get_instance(link, window_t, link);
    15651575                if (win->surface) {
    15661576                        surface_get_resolution(win->surface, &width, &height);
     
    21162126}
    21172127
    2118 static int discover_viewports(void)
    2119 {
     2128static int compositor_srv_init(char *input_svc, char *name)
     2129{
     2130        /* Coordinates of the central pixel. */
     2131        coord_origin = UINT32_MAX / 4;
     2132       
     2133        /* Color of the viewport background. Must be opaque. */
     2134        bg_color = PIXEL(255, 75, 70, 75);
     2135       
     2136        /* Register compositor server. */
     2137        async_set_client_connection(client_connection);
     2138        int rc = loc_server_register(NAME);
     2139        if (rc != EOK) {
     2140                printf("%s: Unable to register server (%s)\n", NAME, str_error(rc));
     2141                return -1;
     2142        }
     2143       
     2144        /* Register interrupt handler to switch back from kconsole. */
     2145        async_set_interrupt_received(interrupt_received);
     2146        rc = event_subscribe(EVENT_KCONSOLE, 0);
     2147        if (rc != EOK) {
     2148                printf("%s: Failed to register kconsole notifications (%s)\n",
     2149                    NAME, str_error(rc));
     2150        }
     2151       
     2152        server_name = name;
     2153       
     2154        char svc[LOC_NAME_MAXLEN + 1];
     2155        snprintf(svc, LOC_NAME_MAXLEN, "%s/%s", NAMESPACE, server_name);
     2156       
     2157        service_id_t service_id;
     2158        rc = loc_service_register(svc, &service_id);
     2159        if (rc != EOK) {
     2160                printf("%s: Unable to register service %s\n", NAME, svc);
     2161                return rc;
     2162        }
     2163       
     2164        /* Prepare window registrator (entrypoint for clients). */
     2165        char winreg[LOC_NAME_MAXLEN + 1];
     2166        snprintf(winreg, LOC_NAME_MAXLEN, "%s%s/winreg", NAMESPACE, server_name);
     2167        if (loc_service_register(winreg, &winreg_id) != EOK) {
     2168                printf("%s: Unable to register service %s\n", NAME, winreg);
     2169                return -1;
     2170        }
     2171
     2172        /* Establish input bidirectional connection. */
     2173        rc = input_connect(input_svc);
     2174        if (rc != EOK)
     2175                return rc;
     2176
    21202177        /* Create viewports and connect them to visualizers. */
    21212178        category_id_t cat_id;
    2122         int rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING);
     2179        rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING);
    21232180        if (rc != EOK) {
    2124                 printf("%s: Failed to get visualizer category.\n", NAME);
     2181                input_disconnect();
    21252182                return -1;
    21262183        }
     
    21302187        rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt);
    21312188        if (rc != EOK || svcs_cnt == 0) {
    2132                 printf("%s: Failed to get visualizer category services.\n", NAME);
     2189                input_disconnect();
    21332190                return -1;
    21342191        }
    2135 
    2136         fibril_mutex_lock(&viewport_list_mtx); 
     2192       
    21372193        for (size_t i = 0; i < svcs_cnt; ++i) {
    2138                 bool exists = false;
    2139                 list_foreach(viewport_list, link, viewport_t, vp) {
    2140                         if (vp->dsid == svcs[i]) {
    2141                                 exists = true;
    2142                                 break;
    2143                         }
    2144                 }
    2145                
    2146                 if (exists)
    2147                         continue;
    2148                
    21492194                char *svc_name;
    21502195                rc = loc_service_get_name(svcs[i], &svc_name);
     
    21562201                }
    21572202        }
    2158         fibril_mutex_unlock(&viewport_list_mtx);
    2159        
    2160         /* TODO damage only newly added viewports */
    2161         comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    2162         return EOK;
    2163 }
    2164 
    2165 static void category_change_cb(void)
    2166 {
    2167         fibril_mutex_lock(&discovery_mtx);
    2168         discover_viewports();
    2169         fibril_mutex_unlock(&discovery_mtx);
    2170 }
    2171 
    2172 static int compositor_srv_init(char *input_svc, char *name)
    2173 {
    2174         /* Coordinates of the central pixel. */
    2175         coord_origin = UINT32_MAX / 4;
    2176        
    2177         /* Color of the viewport background. Must be opaque. */
    2178         bg_color = PIXEL(255, 69, 51, 103);
    2179        
    2180         /* Register compositor server. */
    2181         async_set_client_connection(client_connection);
    2182         int rc = loc_server_register(NAME);
    2183         if (rc != EOK) {
    2184                 printf("%s: Unable to register server (%s)\n", NAME, str_error(rc));
    2185                 return -1;
    2186         }
    2187        
    2188         /* Register interrupt handler to switch back from kconsole. */
    2189         async_set_interrupt_received(interrupt_received);
    2190         rc = event_subscribe(EVENT_KCONSOLE, 0);
    2191         if (rc != EOK) {
    2192                 printf("%s: Failed to register kconsole notifications (%s)\n",
    2193                     NAME, str_error(rc));
    2194         }
    2195        
    2196         server_name = name;
    2197        
    2198         char svc[LOC_NAME_MAXLEN + 1];
    2199         snprintf(svc, LOC_NAME_MAXLEN, "%s/%s", NAMESPACE, server_name);
    2200        
    2201         service_id_t service_id;
    2202         rc = loc_service_register(svc, &service_id);
    2203         if (rc != EOK) {
    2204                 printf("%s: Unable to register service %s\n", NAME, svc);
    2205                 return rc;
    2206         }
    2207        
    2208         /* Prepare window registrator (entrypoint for clients). */
    2209         char winreg[LOC_NAME_MAXLEN + 1];
    2210         snprintf(winreg, LOC_NAME_MAXLEN, "%s%s/winreg", NAMESPACE, server_name);
    2211         if (loc_service_register(winreg, &winreg_id) != EOK) {
    2212                 printf("%s: Unable to register service %s\n", NAME, winreg);
    2213                 return -1;
    2214         }
    2215 
    2216         /* Establish input bidirectional connection. */
    2217         rc = input_connect(input_svc);
    2218         if (rc != EOK) {
    2219                 printf("%s: Failed to connect to input service.\n", NAME);
    2220                 return rc;
    2221         }
    2222 
    2223         rc = loc_register_cat_change_cb(category_change_cb);
    2224         if (rc != EOK) {
    2225                 printf("%s: Failed to register category change callback\n", NAME);
    2226                 input_disconnect();
    2227                 return rc;
    2228         }       
    2229 
    2230         rc = discover_viewports();
    2231         if (rc != EOK) {
    2232                 input_disconnect();
    2233                 return rc;
    2234         }
    22352203       
    22362204        if (list_empty(&viewport_list)) {
    2237                 printf("%s: Failed to get viewports.\n", NAME);
    22382205                input_disconnect();
    22392206                return -1;
     
    22422209        comp_restrict_pointers();
    22432210        comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    2244        
    22452211       
    22462212        return EOK;
Note: See TracChangeset for help on using the changeset viewer.