Ignore:
File:
1 edited

Legend:

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

    r5d380b6 r2ab8ab3  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2019 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4545#include "cursimg.h"
    4646#include "cursor.h"
    47 #include "display.h"
    4847#include "seat.h"
    4948#include "window.h"
    50 #include "wmclient.h"
     49#include "display.h"
    5150
    5251static gfx_context_t *ds_display_get_unbuf_gc(ds_display_t *);
    5352static void ds_display_invalidate_cb(void *, gfx_rect_t *);
    5453static void ds_display_update_cb(void *);
    55 
    56 static mem_gc_cb_t ds_display_mem_gc_cb = {
    57         .invalidate = ds_display_invalidate_cb,
    58         .update = ds_display_update_cb
    59 };
    6054
    6155/** Create display.
     
    9791        fibril_mutex_initialize(&disp->lock);
    9892        list_initialize(&disp->clients);
    99         list_initialize(&disp->wmclients);
    100         list_initialize(&disp->cfgclients);
    10193        disp->next_wnd_id = 1;
    10294        list_initialize(&disp->ddevs);
    103         list_initialize(&disp->idevcfgs);
    10495        list_initialize(&disp->seats);
    10596        list_initialize(&disp->windows);
     
    118109void ds_display_destroy(ds_display_t *disp)
    119110{
    120         int i;
    121 
    122111        assert(list_empty(&disp->clients));
    123         assert(list_empty(&disp->wmclients));
    124         assert(list_empty(&disp->cfgclients));
    125112        assert(list_empty(&disp->seats));
    126         assert(list_empty(&disp->ddevs));
    127         assert(list_empty(&disp->idevcfgs));
    128         assert(list_empty(&disp->seats));
    129         assert(list_empty(&disp->windows));
    130 
    131         /* Destroy cursors */
    132         for (i = 0; i < dcurs_limit; i++) {
    133                 ds_cursor_destroy(disp->cursor[i]);
    134                 disp->cursor[i] = NULL;
    135         }
    136 
     113        /* XXX destroy cursors */
    137114        gfx_color_delete(disp->bg_color);
    138115        free(disp);
     
    221198
    222199        return list_get_instance(link, ds_client_t, lclients);
    223 }
    224 
    225 /** Add WM client to display.
    226  *
    227  * @param disp Display
    228  * @param wmclient WM client
    229  */
    230 void ds_display_add_wmclient(ds_display_t *disp, ds_wmclient_t *wmclient)
    231 {
    232         assert(wmclient->display == NULL);
    233         assert(!link_used(&wmclient->lwmclients));
    234 
    235         wmclient->display = disp;
    236         list_append(&wmclient->lwmclients, &disp->wmclients);
    237 }
    238 
    239 /** Remove WM client from display.
    240  *
    241  * @param wmclient WM client
    242  */
    243 void ds_display_remove_wmclient(ds_wmclient_t *wmclient)
    244 {
    245         list_remove(&wmclient->lwmclients);
    246         wmclient->display = NULL;
    247 }
    248 
    249 /** Add CFG client to display.
    250  *
    251  * @param disp Display
    252  * @param cfgclient CFG client
    253  */
    254 void ds_display_add_cfgclient(ds_display_t *disp, ds_cfgclient_t *cfgclient)
    255 {
    256         assert(cfgclient->display == NULL);
    257         assert(!link_used(&cfgclient->lcfgclients));
    258 
    259         cfgclient->display = disp;
    260         list_append(&cfgclient->lcfgclients, &disp->cfgclients);
    261 }
    262 
    263 /** Remove CFG client from display.
    264  *
    265  * @param cfgclient CFG client
    266  */
    267 void ds_display_remove_cfgclient(ds_cfgclient_t *cfgclient)
    268 {
    269         list_remove(&cfgclient->lcfgclients);
    270         cfgclient->display = NULL;
    271 }
    272 
    273 /** Get first WM client in display.
    274  *
    275  * @param disp Display
    276  * @return First WM client or @c NULL if there is none
    277  */
    278 ds_wmclient_t *ds_display_first_wmclient(ds_display_t *disp)
    279 {
    280         link_t *link = list_first(&disp->wmclients);
    281 
    282         if (link == NULL)
    283                 return NULL;
    284 
    285         return list_get_instance(link, ds_wmclient_t, lwmclients);
    286 }
    287 
    288 /** Get next WM client in display.
    289  *
    290  * @param wmclient Current WM client
    291  * @return Next WM client or @c NULL if there is none
    292  */
    293 ds_wmclient_t *ds_display_next_wmclient(ds_wmclient_t *wmclient)
    294 {
    295         link_t *link = list_next(&wmclient->lwmclients,
    296             &wmclient->display->wmclients);
    297 
    298         if (link == NULL)
    299                 return NULL;
    300 
    301         return list_get_instance(link, ds_wmclient_t, lwmclients);
    302200}
    303201
     
    343241                gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
    344242
    345                 if (gfx_pix_inside_rect(pos, &drect) &&
    346                     ds_window_is_visible(wnd))
     243                if (gfx_pix_inside_rect(pos, &drect))
    347244                        return wnd;
    348245
     
    353250}
    354251
    355 /** Add window to window list.
    356  *
    357  * Topmost windows are enlisted before any other window. Non-topmost
    358  * windows are enlisted before any other non-topmost window.
     252/** Add window to display.
    359253 *
    360254 * @param display Display
    361255 * @param wnd Window
    362256 */
    363 void ds_display_enlist_window(ds_display_t *display, ds_window_t *wnd)
    364 {
    365         ds_window_t *w;
    366 
    367         assert(wnd->display == display);
    368         assert(!link_used(&wnd->ldwindows));
    369 
    370         if ((wnd->flags & wndf_topmost) == 0) {
    371                 /* Find the first non-topmost window */
    372                 w = ds_display_first_window(display);
    373                 while (w != NULL && (w->flags & wndf_topmost) != 0)
    374                         w = ds_display_next_window(w);
    375 
    376                 if (w != NULL)
    377                         list_insert_before(&wnd->ldwindows, &w->ldwindows);
    378                 else
    379                         list_append(&wnd->ldwindows, &display->windows);
    380         } else {
    381                 /* Insert at the beginning */
    382                 list_prepend(&wnd->ldwindows, &display->windows);
    383         }
    384 
    385 }
    386 
    387 /** Add window to display.
    388  *
    389  * @param display Display
    390  * @param wnd Window
    391  */
    392257void ds_display_add_window(ds_display_t *display, ds_window_t *wnd)
    393258{
    394         ds_wmclient_t *wmclient;
    395 
    396259        assert(wnd->display == NULL);
    397260        assert(!link_used(&wnd->ldwindows));
    398261
    399262        wnd->display = display;
    400         ds_display_enlist_window(display, wnd);
    401 
    402         /* Notify window managers about the new window */
    403         wmclient = ds_display_first_wmclient(display);
    404         while (wmclient != NULL) {
    405                 ds_wmclient_post_wnd_added_event(wmclient, wnd->id);
    406                 wmclient = ds_display_next_wmclient(wmclient);
    407         }
     263        list_prepend(&wnd->ldwindows, &display->windows);
    408264}
    409265
     
    414270void ds_display_remove_window(ds_window_t *wnd)
    415271{
    416         ds_wmclient_t *wmclient;
    417         ds_display_t *display;
    418 
    419         display = wnd->display;
    420 
    421272        list_remove(&wnd->ldwindows);
    422273        wnd->display = NULL;
    423 
    424         /* Notify window managers about the removed window */
    425         wmclient = ds_display_first_wmclient(display);
    426         while (wmclient != NULL) {
    427                 ds_wmclient_post_wnd_removed_event(wmclient, wnd->id);
    428                 wmclient = ds_display_next_wmclient(wmclient);
    429         }
    430 }
    431 
    432 /** Move window to top.
    433  *
    434  * @param display Display
    435  * @param wnd Window
    436  */
    437 void ds_display_window_to_top(ds_window_t *wnd)
    438 {
    439         assert(wnd->display != NULL);
    440         assert(link_used(&wnd->ldwindows));
    441 
    442         list_remove(&wnd->ldwindows);
    443         ds_display_enlist_window(wnd->display, wnd);
    444274}
    445275
     
    517347        ds_seat_t *seat;
    518348
    519         /* Determine which seat the event belongs to */
    520         seat = ds_display_seat_by_idev(display, event->kbd_id);
     349        // TODO Determine which seat the event belongs to
     350        seat = ds_display_first_seat(display);
    521351        if (seat == NULL)
    522352                return EOK;
     
    534364        ds_seat_t *seat;
    535365
    536         /* Determine which seat the event belongs to */
    537         seat = ds_display_seat_by_idev(display, event->pos_id);
     366        // TODO Determine which seat the event belongs to
     367        seat = ds_display_first_seat(display);
    538368        if (seat == NULL)
    539369                return EOK;
     
    553383
    554384        seat->display = disp;
    555         seat->id = disp->next_seat_id++;
    556385        list_append(&seat->lseats, &disp->seats);
    557386}
     
    595424
    596425        return list_get_instance(link, ds_seat_t, lseats);
    597 }
    598 
    599 /** Get default seat in display.
    600  *
    601  * @param disp Display
    602  * @return First seat or @c NULL if there is none
    603  */
    604 ds_seat_t *ds_display_default_seat(ds_display_t *disp)
    605 {
    606         /* XXX Probably not the best solution */
    607         return ds_display_first_seat(disp);
    608 }
    609 
    610 /** Find seat by ID.
    611  *
    612  * @param display Display
    613  * @param id Seat ID
    614  */
    615 ds_seat_t *ds_display_find_seat(ds_display_t *display, ds_seat_id_t id)
    616 {
    617         ds_seat_t *seat;
    618 
    619         seat = ds_display_first_seat(display);
    620         while (seat != NULL) {
    621                 if (seat->id == id)
    622                         return seat;
    623 
    624                 seat = ds_display_next_seat(seat);
    625         }
    626 
    627         return NULL;
    628 }
    629 
    630 /** Get seat which owns the specified input device.
    631  *
    632  * @param disp Display
    633  * @param idev_id Input device ID
    634  * @return Seat which owns device with ID @a idev_id or @c NULL if not found
    635  */
    636 ds_seat_t *ds_display_seat_by_idev(ds_display_t *disp, ds_idev_id_t idev_id)
    637 {
    638         ds_idevcfg_t *idevcfg;
    639 
    640         /*
    641          * Find input device configuration entry that maps this input device
    642          * to a seat.
    643          */
    644         idevcfg = ds_display_first_idevcfg(disp);
    645         while (idevcfg != NULL) {
    646                 if (idevcfg->svc_id == idev_id)
    647                         return idevcfg->seat;
    648 
    649                 idevcfg = ds_display_next_idevcfg(idevcfg);
    650         }
    651 
    652         /* If none was found, return the default seat */
    653         return ds_display_default_seat(disp);
    654426}
    655427
     
    687459                goto error;
    688460
    689         rc = mem_gc_create(&disp->rect, &alloc, &ds_display_mem_gc_cb,
    690             (void *) disp, &disp->bbgc);
     461        rc = mem_gc_create(&disp->rect, &alloc,
     462            ds_display_invalidate_cb, ds_display_update_cb, (void *) disp,
     463            &disp->bbgc);
    691464        if (rc != EOK)
    692465                goto error;
     
    716489{
    717490        errno_t rc;
    718         gfx_rect_t old_disp_rect;
    719491
    720492        assert(ddev->display == NULL);
    721493        assert(!link_used(&ddev->lddevs));
    722 
    723         old_disp_rect = disp->rect;
    724494
    725495        ddev->display = disp;
     
    733503                /* Create cloning GC */
    734504                rc = ds_clonegc_create(ddev->gc, &disp->fbgc);
    735                 if (rc != EOK)
    736                         goto error;
     505                if (rc != EOK) {
     506                        // XXX Remove output
     507                        return ENOMEM;
     508                }
    737509
    738510                /* Allocate backbuffer */
    739511                rc = ds_display_alloc_backbuf(disp);
    740512                if (rc != EOK) {
    741                         ds_clonegc_delete(disp->fbgc);
    742                         disp->fbgc = NULL;
     513                        // XXX Remove output
     514                        // XXX Delete clone GC
    743515                        goto error;
    744516                }
     
    750522        }
    751523
    752         ds_display_update_max_rect(disp);
    753 
    754524        return EOK;
    755525error:
    756         disp->rect = old_disp_rect;
     526        disp->rect.p0.x = 0;
     527        disp->rect.p0.y = 0;
     528        disp->rect.p1.x = 0;
     529        disp->rect.p1.y = 0;
    757530        list_remove(&ddev->lddevs);
    758531        return rc;
     
    799572}
    800573
    801 /** Add input device configuration entry to display.
    802  *
    803  * @param disp Display
    804  * @param idevcfg Input device configuration
    805  */
    806 void ds_display_add_idevcfg(ds_display_t *disp, ds_idevcfg_t *idevcfg)
    807 {
    808         assert(idevcfg->display == NULL);
    809         assert(!link_used(&idevcfg->ldispidcfgs));
    810 
    811         idevcfg->display = disp;
    812         list_append(&idevcfg->ldispidcfgs, &disp->idevcfgs);
    813 }
    814 
    815 /** Remove input device configuration entry from display.
    816  *
    817  * @param idevcfg Input device configuration entry
    818  */
    819 void ds_display_remove_idevcfg(ds_idevcfg_t *idevcfg)
    820 {
    821         list_remove(&idevcfg->ldispidcfgs);
    822         idevcfg->display = NULL;
    823 }
    824 
    825 /** Get first input device configuration entry in display.
    826  *
    827  * @param disp Display
    828  * @return First input device configuration entry or @c NULL if there is none
    829  */
    830 ds_idevcfg_t *ds_display_first_idevcfg(ds_display_t *disp)
    831 {
    832         link_t *link = list_first(&disp->idevcfgs);
    833 
    834         if (link == NULL)
    835                 return NULL;
    836 
    837         return list_get_instance(link, ds_idevcfg_t, ldispidcfgs);
    838 }
    839 
    840 /** Get next input device configuration entry in display.
    841  *
    842  * @param idevcfg Current input device configuration entry
    843  * @return Next input device configuration entry or @c NULL if there is none
    844  */
    845 ds_idevcfg_t *ds_display_next_idevcfg(ds_idevcfg_t *idevcfg)
    846 {
    847         link_t *link = list_next(&idevcfg->ldispidcfgs, &idevcfg->display->idevcfgs);
    848 
    849         if (link == NULL)
    850                 return NULL;
    851 
    852         return list_get_instance(link, ds_idevcfg_t, ldispidcfgs);
    853 }
    854 
    855574/** Add cursor to display.
    856575 *
     
    875594        list_remove(&cursor->ldisplay);
    876595        cursor->display = NULL;
    877 }
    878 
    879 /** Update display maximize rectangle.
    880  *
    881  * Recalculate the maximize rectangle (the rectangle used for maximized
    882  * windows).
    883  *
    884  * @param display Display
    885  */
    886 void ds_display_update_max_rect(ds_display_t *display)
    887 {
    888         ds_window_t *wnd;
    889         gfx_rect_t max_rect;
    890         gfx_rect_t drect;
    891 
    892         /* Start with the entire display */
    893         max_rect = display->rect;
    894 
    895         wnd = ds_display_first_window(display);
    896         while (wnd != NULL) {
    897                 /* Should maximized windows avoid this window? */
    898                 if ((wnd->flags & wndf_avoid) != 0) {
    899                         /* Window bounding rectangle on display */
    900                         gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
    901 
    902                         /* Crop maximized rectangle */
    903                         ds_display_crop_max_rect(&drect, &max_rect);
    904                 }
    905 
    906                 wnd = ds_display_next_window(wnd);
    907         }
    908 
    909         /* Update the maximize rectangle */
    910         display->max_rect = max_rect;
    911 }
    912 
    913 /** Crop maximize rectangle.
    914  *
    915  * Use the avoid rectangle @a arect to crop off maximization rectangle
    916  * @a mrect. If @a arect covers the top, bottom, left or right part
    917  * of @a mrect, it will be cropped off. Otherwise there will be
    918  * no effect.
    919  *
    920  * @param arect Avoid rectangle
    921  * @param mrect Maximize rectangle to be modified
    922  */
    923 void ds_display_crop_max_rect(gfx_rect_t *arect, gfx_rect_t *mrect)
    924 {
    925         if (arect->p0.x == mrect->p0.x && arect->p0.y == mrect->p0.y &&
    926             arect->p1.x == mrect->p1.x) {
    927                 /* Cropp off top part */
    928                 mrect->p0.y = arect->p1.y;
    929         } else if (arect->p0.x == mrect->p0.x && arect->p1.x == mrect->p1.x &&
    930             arect->p1.y == mrect->p1.y) {
    931                 /* Cropp off bottom part */
    932                 mrect->p1.y = arect->p0.y;
    933         } else if (arect->p0.x == mrect->p0.x && arect->p0.y == mrect->p0.y &&
    934             arect->p1.y == mrect->p1.y) {
    935                 /* Cropp off left part */
    936                 mrect->p0.x = arect->p1.x;
    937         } else if (arect->p0.y == mrect->p0.y && arect->p1.x == mrect->p1.x &&
    938             arect->p1.y == mrect->p1.y) {
    939                 /* Cropp off right part */
    940                 mrect->p1.x = arect->p0.x;
    941         }
    942596}
    943597
Note: See TracChangeset for help on using the changeset viewer.