Ignore:
File:
1 edited

Legend:

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

    r2e0a2e7 r0d00e53  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4444#include <memgfx/memgc.h>
    4545#include <stdlib.h>
     46#include <str.h>
     47#include <wndmgt.h>
    4648#include "client.h"
    4749#include "display.h"
    4850#include "seat.h"
    4951#include "window.h"
    50 
    51 static void ds_window_update_cb(void *, gfx_rect_t *);
     52#include "wmclient.h"
     53
     54static void ds_window_invalidate_cb(void *, gfx_rect_t *);
     55static void ds_window_update_cb(void *);
    5256static void ds_window_get_preview_rect(ds_window_t *, gfx_rect_t *);
     57
     58static mem_gc_cb_t ds_window_mem_gc_cb = {
     59        .invalidate = ds_window_invalidate_cb,
     60        .update = ds_window_update_cb
     61};
    5362
    5463/** Create window.
     
    5867 * @param client Client owning the window
    5968 * @param params Window parameters
    60  * @param rgc Place to store pointer to new GC.
     69 * @param rwnd Place to store pointer to new window.
    6170 *
    6271 * @return EOK on success or an error code
    6372 */
    6473errno_t ds_window_create(ds_client_t *client, display_wnd_params_t *params,
    65     ds_window_t **rgc)
     74    ds_window_t **rwnd)
    6675{
    6776        ds_window_t *wnd = NULL;
     77        ds_seat_t *seat;
    6878        gfx_context_t *dgc;
    6979        gfx_coord2_t dims;
     
    7888        }
    7989
     90        /* Caption */
     91        wnd->caption = str_dup(params->caption);
     92        if (wnd->caption == NULL) {
     93                rc = ENOMEM;
     94                goto error;
     95        }
     96
     97        wnd->flags = params->flags;
     98
    8099        ds_client_add_window(client, wnd);
    81100        ds_display_add_window(client->display, wnd);
     
    83102        gfx_bitmap_params_init(&bparams);
    84103        bparams.rect = params->rect;
     104
     105        /* Allocate window bitmap */
    85106
    86107        dgc = ds_display_get_gc(wnd->display);
     
    106127        }
    107128
    108         rc = mem_gc_create(&params->rect, &alloc, ds_window_update_cb,
     129        rc = mem_gc_create(&params->rect, &alloc, &ds_window_mem_gc_cb,
    109130            (void *)wnd, &wnd->mgc);
    110131        if (rc != EOK)
     
    115136        wnd->gc = mem_gc_get_ctx(wnd->mgc);
    116137        wnd->cursor = wnd->display->cursor[dcurs_arrow];
    117         *rgc = wnd;
     138
     139        if ((params->flags & wndf_setpos) != 0) {
     140                /* Specific window position */
     141                wnd->dpos = params->pos;
     142        } else {
     143                /* Automatic window placement */
     144                wnd->dpos.x = ((wnd->id - 1) & 1) * 400;
     145                wnd->dpos.y = ((wnd->id - 1) & 2) / 2 * 300;
     146        }
     147
     148        /* Determine which seat should own the window */
     149        if (params->idev_id != 0)
     150                seat = ds_display_seat_by_idev(wnd->display, params->idev_id);
     151        else
     152                seat = ds_display_default_seat(wnd->display);
     153
     154        /* Is this a popup window? */
     155        if ((params->flags & wndf_popup) != 0) {
     156                ds_seat_set_popup(seat, wnd);
     157        } else {
     158                if ((params->flags & wndf_nofocus) == 0)
     159                        ds_seat_set_focus(seat, wnd);
     160        }
     161
     162        /* Is this window a panel? */
     163        if ((params->flags & wndf_avoid) != 0)
     164                ds_display_update_max_rect(wnd->display);
     165
     166        (void) ds_display_paint(wnd->display, NULL);
     167
     168        *rwnd = wnd;
    118169        return EOK;
    119170error:
    120171        if (wnd != NULL) {
     172                ds_client_remove_window(wnd);
     173                ds_display_remove_window(wnd);
     174                if (wnd->mgc != NULL)
     175                        mem_gc_delete(wnd->mgc);
    121176                if (wnd->bitmap != NULL)
    122177                        gfx_bitmap_destroy(wnd->bitmap);
     178                if (wnd->caption != NULL)
     179                        free(wnd->caption);
    123180                free(wnd);
    124181        }
     
    136193
    137194        disp = wnd->display;
     195
     196        ds_window_unfocus(wnd);
    138197
    139198        ds_client_remove_window(wnd);
    140199        ds_display_remove_window(wnd);
    141200
     201        if ((wnd->flags & wndf_avoid) != 0)
     202                ds_display_update_max_rect(disp);
     203
    142204        mem_gc_delete(wnd->mgc);
    143205
     
    145207                gfx_bitmap_destroy(wnd->bitmap);
    146208
     209        free(wnd->caption);
    147210        free(wnd);
    148211
     
    156219void ds_window_bring_to_top(ds_window_t *wnd)
    157220{
    158         ds_display_t *disp = wnd->display;
    159 
    160         ds_display_remove_window(wnd);
    161         ds_display_add_window(disp, wnd);
     221        ds_display_window_to_top(wnd);
    162222        (void) ds_display_paint(wnd->display, NULL);
    163223}
     
    171231{
    172232        return wnd->gc;
     233}
     234
     235/** Determine if window is visible.
     236 *
     237 * @param wnd Window
     238 * @return @c true iff window is visible
     239 */
     240bool ds_window_is_visible(ds_window_t *wnd)
     241{
     242        return (wnd->flags & wndf_minimized) == 0;
    173243}
    174244
     
    185255        gfx_rect_t crect;
    186256
    187         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_paint");
     257        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_paint");
     258
     259        /* Skip painting the window if not visible */
     260        if (!ds_window_is_visible(wnd))
     261                return EOK;
    188262
    189263        if (rect != NULL) {
     
    330404        bool newr;
    331405
    332         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_repaint_preview");
     406        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_repaint_preview");
    333407
    334408        /*
     
    374448 * @param wnd Window
    375449 * @param pos Position where mouse button was pressed
    376  */
    377 static void ds_window_start_move(ds_window_t *wnd, gfx_coord2_t *pos)
     450 * @param pos_id Positioning device ID
     451 */
     452static void ds_window_start_move(ds_window_t *wnd, gfx_coord2_t *pos,
     453    sysarg_t pos_id)
    378454{
    379455        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_move (%d, %d)",
     
    384460
    385461        wnd->orig_pos = *pos;
     462        wnd->orig_pos_id = pos_id;
    386463        wnd->state = dsw_moving;
    387464        wnd->preview_pos = wnd->dpos;
     
    413490        wnd->dpos = nwpos;
    414491        wnd->state = dsw_idle;
     492        wnd->orig_pos_id = 0;
    415493
    416494        (void) ds_display_paint(wnd->display, NULL);
     
    428506        gfx_rect_t old_rect;
    429507
    430         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_move (%d, %d)",
     508        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_update_move (%d, %d)",
    431509            (int) pos->x, (int) pos->y);
    432510
     
    447525 * @param rsztype Resize type (which part of window is being dragged)
    448526 * @param pos Position where mouse button was pressed
     527 * @param pos_id Positioning device ID
    449528 */
    450529static void ds_window_start_resize(ds_window_t *wnd,
    451     display_wnd_rsztype_t rsztype, gfx_coord2_t *pos)
     530    display_wnd_rsztype_t rsztype, gfx_coord2_t *pos, sysarg_t pos_id)
    452531{
    453532        ds_seat_t *seat;
     
    460539                return;
    461540
     541        /* Determine which seat started the resize */
     542        seat = ds_display_seat_by_idev(wnd->display, pos_id);
     543        if (seat == NULL)
     544                return;
     545
    462546        wnd->orig_pos = *pos;
     547        wnd->orig_pos_id = pos_id;
    463548        wnd->state = dsw_resizing;
    464549        wnd->rsztype = rsztype;
    465550        wnd->preview_rect = wnd->rect;
    466551
    467         // XXX Need client to tell us which seat started the resize!
    468         seat = ds_display_first_seat(wnd->display);
    469552        ctype = display_cursor_from_wrsz(rsztype);
    470553        ds_seat_set_wm_cursor(seat, wnd->display->cursor[ctype]);
     
    496579        ds_client_post_resize_event(wnd->client, wnd, &nrect);
    497580
    498         // XXX Need to know which seat started the resize!
    499         seat = ds_display_first_seat(wnd->display);
    500         ds_seat_set_wm_cursor(seat, NULL);
     581        /* Determine which seat started the resize */
     582        seat = ds_display_seat_by_idev(wnd->display, wnd->orig_pos_id);
     583        if (seat != NULL)
     584                ds_seat_set_wm_cursor(seat, NULL);
     585
     586        wnd->orig_pos_id = 0;
    501587
    502588        (void) ds_display_paint(wnd->display, NULL);
     
    514600        gfx_rect_t old_rect;
    515601
    516         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_resize (%d, %d)",
     602        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_update_resize (%d, %d)",
    517603            (int) pos->x, (int) pos->y);
    518604
     
    553639 * @param wnd Window
    554640 * @param event Position event
     641 *
     642 * @return EOK on success or an error code
    555643 */
    556644errno_t ds_window_post_pos_event(ds_window_t *wnd, pos_event_t *event)
     
    558646        pos_event_t tevent;
    559647        gfx_coord2_t pos;
     648        sysarg_t pos_id;
    560649        gfx_rect_t drect;
    561650        bool inside;
    562651
    563         log_msg(LOG_DEFAULT, LVL_DEBUG,
     652        log_msg(LOG_DEFAULT, LVL_DEBUG2,
    564653            "ds_window_post_pos_event type=%d pos=%d,%d", event->type,
    565654            (int) event->hpos, (int) event->vpos);
     
    567656        pos.x = event->hpos;
    568657        pos.y = event->vpos;
     658        pos_id = event->pos_id;
    569659        gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
    570660        inside = gfx_pix_inside_rect(&pos, &drect);
    571661
    572         if (event->type == POS_PRESS && event->btn_num == 2 && inside) {
    573                 ds_window_start_move(wnd, &pos);
     662        if (event->type == POS_PRESS && event->btn_num == 2 && inside &&
     663            (wnd->flags & wndf_maximized) == 0) {
     664                ds_window_start_move(wnd, &pos, pos_id);
    574665                return EOK;
    575666        }
    576667
    577668        if (event->type == POS_RELEASE) {
    578                 if (wnd->state == dsw_moving) {
     669                /* Finish move/resize if they were started by the same seat */
     670                if (wnd->state == dsw_moving &&
     671                    ds_window_orig_seat(wnd, pos_id)) {
    579672                        ds_window_finish_move(wnd, &pos);
    580673                        return EOK;
    581674                }
    582675
    583                 if (wnd->state == dsw_resizing) {
     676                if (wnd->state == dsw_resizing &&
     677                    ds_window_orig_seat(wnd, pos_id)) {
    584678                        ds_window_finish_resize(wnd, &pos);
    585679                        return EOK;
     
    588682
    589683        if (event->type == POS_UPDATE) {
    590                 if (wnd->state == dsw_moving) {
     684                /* Update move/resize if they were started by the same seat */
     685                if (wnd->state == dsw_moving &&
     686                    ds_window_orig_seat(wnd, pos_id)) {
    591687                        ds_window_update_move(wnd, &pos);
    592688                        return EOK;
    593689                }
    594690
    595                 if (wnd->state == dsw_resizing) {
     691                if (wnd->state == dsw_resizing &&
     692                    ds_window_orig_seat(wnd, pos_id)) {
    596693                        ds_window_update_resize(wnd, &pos);
    597694                        return EOK;
     
    610707 *
    611708 * @param wnd Window
     709 * @return EOK on success or an error code
    612710 */
    613711errno_t ds_window_post_focus_event(ds_window_t *wnd)
    614712{
     713        display_wnd_focus_ev_t efocus;
     714        errno_t rc;
     715        ds_wmclient_t *wmclient;
     716
    615717        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_focus_event");
    616718
    617         return ds_client_post_focus_event(wnd->client, wnd);
     719        /* Increase focus counter */
     720        ++wnd->nfocus;
     721        efocus.nfocus = wnd->nfocus;
     722
     723        rc = ds_client_post_focus_event(wnd->client, wnd, &efocus);
     724        if (rc != EOK)
     725                return rc;
     726
     727        /* Notify window managers about window information change */
     728        wmclient = ds_display_first_wmclient(wnd->display);
     729        while (wmclient != NULL) {
     730                ds_wmclient_post_wnd_changed_event(wmclient, wnd->id);
     731                wmclient = ds_display_next_wmclient(wmclient);
     732        }
     733
     734        return EOK;
    618735}
    619736
     
    621738 *
    622739 * @param wnd Window
     740 * @return EOK on success or an error code
    623741 */
    624742errno_t ds_window_post_unfocus_event(ds_window_t *wnd)
    625743{
     744        display_wnd_unfocus_ev_t eunfocus;
     745        errno_t rc;
     746        ds_wmclient_t *wmclient;
     747
    626748        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_unfocus_event");
    627749
    628         return ds_client_post_unfocus_event(wnd->client, wnd);
     750        /* Decrease focus counter */
     751        --wnd->nfocus;
     752        eunfocus.nfocus = wnd->nfocus;
     753
     754        rc = ds_client_post_unfocus_event(wnd->client, wnd, &eunfocus);
     755        if (rc != EOK)
     756                return rc;
     757
     758        /* Notify window managers about window information change */
     759        wmclient = ds_display_first_wmclient(wnd->display);
     760        while (wmclient != NULL) {
     761                ds_wmclient_post_wnd_changed_event(wmclient, wnd->id);
     762                wmclient = ds_display_next_wmclient(wmclient);
     763        }
     764
     765        return EOK;
    629766}
    630767
     
    634771 * @param pos Position where the pointer was when the move started
    635772 *            relative to the window
     773 * @param pos_id Positioning device ID
    636774 * @param event Button press event
    637775 */
    638 void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos)
     776void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos, sysarg_t pos_id)
    639777{
    640778        gfx_coord2_t orig_pos;
     
    644782
    645783        gfx_coord2_add(&wnd->dpos, pos, &orig_pos);
    646         ds_window_start_move(wnd, &orig_pos);
     784        ds_window_start_move(wnd, &orig_pos, pos_id);
    647785}
    648786
     
    655793        wnd->dpos = *dpos;
    656794        (void) ds_display_paint(wnd->display, NULL);
     795}
     796
     797/** Get window position.
     798 *
     799 * @param wnd Window
     800 */
     801void ds_window_get_pos(ds_window_t *wnd, gfx_coord2_t *dpos)
     802{
     803        *dpos = wnd->dpos;
     804}
     805
     806/** Get maximized window rectangle.
     807 *
     808 * @param wnd Window
     809 */
     810void ds_window_get_max_rect(ds_window_t *wnd, gfx_rect_t *rect)
     811{
     812        *rect = wnd->display->max_rect;
    657813}
    658814
     
    663819 * @param pos Position where the pointer was when the resize started
    664820 *            relative to the window
     821 * @param pos_id Positioning device ID
    665822 * @param event Button press event
    666823 */
    667824void ds_window_resize_req(ds_window_t *wnd, display_wnd_rsztype_t rsztype,
    668     gfx_coord2_t *pos)
     825    gfx_coord2_t *pos, sysarg_t pos_id)
    669826{
    670827        gfx_coord2_t orig_pos;
    671828
    672         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_resize_req (%d, %d, %d)",
    673             (int) rsztype, (int) pos->x, (int) pos->y);
     829        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_resize_req (%d, %d, %d, %d)",
     830            (int)rsztype, (int)pos->x, (int)pos->y, (int)pos_id);
    674831
    675832        gfx_coord2_add(&wnd->dpos, pos, &orig_pos);
    676         ds_window_start_resize(wnd, rsztype, &orig_pos);
     833        ds_window_start_resize(wnd, rsztype, &orig_pos, pos_id);
    677834}
    678835
     
    680837 *
    681838 * @param wnd Window
     839 * @return EOK on success or an error code
    682840 */
    683841errno_t ds_window_resize(ds_window_t *wnd, gfx_coord2_t *offs,
     
    730888        wnd->rect = *nrect;
    731889
     890        if ((wnd->flags & wndf_avoid) != 0)
     891                ds_display_update_max_rect(wnd->display);
     892
    732893        (void) ds_display_paint(wnd->display, NULL);
     894        return EOK;
     895}
     896
     897/** Minimize window.
     898 *
     899 * @param wnd Window
     900 * @return EOK on success or an error code
     901 */
     902errno_t ds_window_minimize(ds_window_t *wnd)
     903{
     904        /* If already minimized, do nothing and return success. */
     905        if ((wnd->flags & wndf_minimized) != 0)
     906                return EOK;
     907
     908        ds_window_unfocus(wnd);
     909
     910        wnd->flags |= wndf_minimized;
     911        (void) ds_display_paint(wnd->display, NULL);
     912        return EOK;
     913}
     914
     915/** Unminimize window.
     916 *
     917 * @param wnd Window
     918 * @return EOK on success or an error code
     919 */
     920errno_t ds_window_unminimize(ds_window_t *wnd)
     921{
     922        /* If not minimized, do nothing and return success. */
     923        if ((wnd->flags & wndf_minimized) == 0)
     924                return EOK;
     925
     926        wnd->flags &= ~wndf_minimized;
     927        (void) ds_display_paint(wnd->display, NULL);
     928        return EOK;
     929}
     930
     931/** Maximize window.
     932 *
     933 * @param wnd Window
     934 * @return EOK on success or an error code
     935 */
     936errno_t ds_window_maximize(ds_window_t *wnd)
     937{
     938        gfx_coord2_t old_dpos;
     939        gfx_rect_t old_rect;
     940        gfx_coord2_t offs;
     941        gfx_rect_t max_rect;
     942        gfx_rect_t nrect;
     943        errno_t rc;
     944
     945        /* If already maximized, do nothing and return success. */
     946        if ((wnd->flags & wndf_maximized) != 0)
     947                return EOK;
     948
     949        /* Remember the old window rectangle and display position */
     950        old_rect = wnd->rect;
     951        old_dpos = wnd->dpos;
     952
     953        ds_window_get_max_rect(wnd, &max_rect);
     954
     955        /* Keep window contents on the same position on the screen */
     956        offs.x = max_rect.p0.x - wnd->dpos.x;
     957        offs.y = max_rect.p0.y - wnd->dpos.y;
     958
     959        /* Maximized window's coordinates will start at 0,0 */
     960        gfx_rect_rtranslate(&max_rect.p0, &max_rect, &nrect);
     961
     962        rc = ds_window_resize(wnd, &offs, &nrect);
     963        if (rc != EOK)
     964                return rc;
     965
     966        /* Set window flags, remember normal rectangle */
     967        wnd->flags |= wndf_maximized;
     968        wnd->normal_rect = old_rect;
     969        wnd->normal_dpos = old_dpos;
     970
     971        return EOK;
     972}
     973
     974/** Unmaximize window.
     975 *
     976 * @param wnd Window
     977 * @return EOK on success or an error code
     978 */
     979errno_t ds_window_unmaximize(ds_window_t *wnd)
     980{
     981        gfx_coord2_t offs;
     982        errno_t rc;
     983
     984        /* If not maximized, do nothing and return success. */
     985        if ((wnd->flags & wndf_maximized) == 0)
     986                return EOK;
     987
     988        /* Keep window contents on the same position on the screen */
     989        offs.x = wnd->normal_dpos.x - wnd->dpos.x;
     990        offs.y = wnd->normal_dpos.y - wnd->dpos.y;
     991
     992        rc = ds_window_resize(wnd, &offs, &wnd->normal_rect);
     993        if (rc != EOK)
     994                return rc;
     995
     996        /* Clear maximized flag */
     997        wnd->flags &= ~wndf_maximized;
     998
    733999        return EOK;
    7341000}
     
    7761042 *
    7771043 * @param wnd Window
     1044 * @param cursor New cursor
    7781045 * @return EOK on success, EINVAL if @a cursor is invalid
    7791046 */
     
    7891056}
    7901057
    791 /** Window memory GC update callback.
    792  *
    793  * This is called by the window's memory GC when a rectangle us updated.
    794  */
    795 static void ds_window_update_cb(void *arg, gfx_rect_t *rect)
     1058/** Set window caption.
     1059 *
     1060 * @param wnd Window
     1061 * @param caption New caption
     1062 *
     1063 * @return EOK on success, EINVAL if @a cursor is invalid
     1064 */
     1065errno_t ds_window_set_caption(ds_window_t *wnd, const char *caption)
     1066{
     1067        char *dcaption;
     1068        ds_wmclient_t *wmclient;
     1069
     1070        dcaption = str_dup(caption);
     1071        if (dcaption == NULL)
     1072                return ENOMEM;
     1073
     1074        free(wnd->caption);
     1075        wnd->caption = dcaption;
     1076
     1077        /* Notify window managers about window information change */
     1078        wmclient = ds_display_first_wmclient(wnd->display);
     1079        while (wmclient != NULL) {
     1080                ds_wmclient_post_wnd_changed_event(wmclient, wnd->id);
     1081                wmclient = ds_display_next_wmclient(wmclient);
     1082        }
     1083
     1084        return EOK;
     1085}
     1086
     1087/** Find alternate window with the allowed flags.
     1088 *
     1089 * An alternate window is a *different* window that is preferably previous
     1090 * in the display order and only has the @a allowed flags.
     1091 *
     1092 * @param wnd Window
     1093 * @param allowed_flags Bitmask of flags that the window is allowed to have
     1094 *
     1095 * @return Alternate window matching the criteria or @c NULL if there is none
     1096 */
     1097ds_window_t *ds_window_find_prev(ds_window_t *wnd,
     1098    display_wnd_flags_t allowed_flags)
     1099{
     1100        ds_window_t *nwnd;
     1101
     1102        /* Try preceding windows in display order */
     1103        nwnd = ds_display_next_window(wnd);
     1104        while (nwnd != NULL && (nwnd->flags & ~allowed_flags) != 0) {
     1105                nwnd = ds_display_next_window(nwnd);
     1106        }
     1107
     1108        /* Do we already have a matching window? */
     1109        if (nwnd != NULL && (nwnd->flags & ~allowed_flags) == 0) {
     1110                return nwnd;
     1111        }
     1112
     1113        /* Try succeeding windows in display order */
     1114        nwnd = ds_display_first_window(wnd->display);
     1115        while (nwnd != NULL && nwnd != wnd &&
     1116            (nwnd->flags & ~allowed_flags) != 0) {
     1117                nwnd = ds_display_next_window(nwnd);
     1118        }
     1119
     1120        if (nwnd == wnd)
     1121                return NULL;
     1122
     1123        return nwnd;
     1124}
     1125
     1126/** Find alternate window with the allowed flags.
     1127 *
     1128 * An alternate window is a *different* window that is preferably previous
     1129 * in the display order and only has the @a allowed flags.
     1130 *
     1131 * @param wnd Window
     1132 * @param allowed_flags Bitmask of flags that the window is allowed to have
     1133 *
     1134 * @return Alternate window matching the criteria or @c NULL if there is none
     1135 */
     1136ds_window_t *ds_window_find_next(ds_window_t *wnd,
     1137    display_wnd_flags_t allowed_flags)
     1138{
     1139        ds_window_t *nwnd;
     1140
     1141        /* Try preceding windows in display order */
     1142        nwnd = ds_display_prev_window(wnd);
     1143        while (nwnd != NULL && (nwnd->flags & ~allowed_flags) != 0) {
     1144                nwnd = ds_display_prev_window(nwnd);
     1145        }
     1146
     1147        /* Do we already have a matching window? */
     1148        if (nwnd != NULL && (nwnd->flags & ~allowed_flags) == 0) {
     1149                return nwnd;
     1150        }
     1151
     1152        /* Try succeeding windows in display order */
     1153        nwnd = ds_display_last_window(wnd->display);
     1154        while (nwnd != NULL && nwnd != wnd &&
     1155            (nwnd->flags & ~allowed_flags) != 0) {
     1156                nwnd = ds_display_prev_window(nwnd);
     1157        }
     1158
     1159        if (nwnd == wnd)
     1160                return NULL;
     1161
     1162        return nwnd;
     1163}
     1164
     1165/** Remove focus from window.
     1166 *
     1167 * Used to switch focus to another window when closing or minimizing window.
     1168 *
     1169 * @param wnd Window
     1170 */
     1171void ds_window_unfocus(ds_window_t *wnd)
     1172{
     1173        ds_seat_t *seat;
     1174
     1175        /* Make sure window is no longer focused in any seat */
     1176        seat = ds_display_first_seat(wnd->display);
     1177        while (seat != NULL) {
     1178                ds_seat_unfocus_wnd(seat, wnd);
     1179                seat = ds_display_next_seat(seat);
     1180        }
     1181}
     1182
     1183/** Determine if input device belongs to the same seat as the original device.
     1184 *
     1185 * Compare the seat ownning @a idev_id with the seat owning @a wnd->orig_pos_id
     1186 * (the device that started the window move or resize).
     1187 *
     1188 * This is used to make sure that, when two seats focus the same window,
     1189 * only devices owned by the seat that started the resize or move can
     1190 * affect it. Otherwise moving the other pointer(s) would disrupt the
     1191 * resize or move operation.
     1192 *
     1193 * @param wnd Window (that is currently being resized or moved)
     1194 * @param idev_id Input device ID
     1195 * @return @c true iff idev_id is owned by the same seat as the input
     1196 *         device that started the resize or move
     1197 */
     1198bool ds_window_orig_seat(ds_window_t *wnd, sysarg_t idev_id)
     1199{
     1200        ds_seat_t *orig_seat;
     1201        ds_seat_t *seat;
     1202
     1203        /* Window must be in state such that wnd->orig_pos_id is valid */
     1204        assert(wnd->state == dsw_moving || wnd->state == dsw_resizing);
     1205
     1206        orig_seat = ds_display_seat_by_idev(wnd->display, wnd->orig_pos_id);
     1207        seat = ds_display_seat_by_idev(wnd->display, idev_id);
     1208
     1209        return seat == orig_seat;
     1210}
     1211
     1212/** Window memory GC invalidate callback.
     1213 *
     1214 * This is called by the window's memory GC when a rectangle is modified.
     1215 */
     1216static void ds_window_invalidate_cb(void *arg, gfx_rect_t *rect)
    7961217{
    7971218        ds_window_t *wnd = (ds_window_t *)arg;
     
    8061227}
    8071228
     1229/** Window memory GC update callback.
     1230 *
     1231 * This is called by the window's memory GC when it is to be updated.
     1232 */
     1233static void ds_window_update_cb(void *arg)
     1234{
     1235        ds_window_t *wnd = (ds_window_t *)arg;
     1236
     1237        (void) wnd;
     1238}
     1239
    8081240/** @}
    8091241 */
Note: See TracChangeset for help on using the changeset viewer.