Ignore:
File:
1 edited

Legend:

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

    r5877de74 rededdc4  
    11/*
    2  * Copyright (c) 2022 Jiri Svoboda
     2 * Copyright (c) 2023 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"
     52#include "wmclient.h"
    5053
    5154static void ds_window_invalidate_cb(void *, gfx_rect_t *);
     
    6467 * @param client Client owning the window
    6568 * @param params Window parameters
    66  * @param rgc Place to store pointer to new GC.
     69 * @param rwnd Place to store pointer to new window.
    6770 *
    6871 * @return EOK on success or an error code
    6972 */
    7073errno_t ds_window_create(ds_client_t *client, display_wnd_params_t *params,
    71     ds_window_t **rgc)
     74    ds_window_t **rwnd)
    7275{
    7376        ds_window_t *wnd = NULL;
     
    8184        wnd = calloc(1, sizeof(ds_window_t));
    8285        if (wnd == NULL) {
     86                rc = ENOMEM;
     87                goto error;
     88        }
     89
     90        wnd->caption = str_dup(params->caption);
     91        if (wnd->caption == NULL) {
    8392                rc = ENOMEM;
    8493                goto error;
     
    133142        }
    134143
     144        // TODO Multi-seat: which seat should own the new window?
    135145        seat = ds_display_first_seat(client->display);
    136146
     
    140150                ds_seat_set_focus(seat, wnd);
    141151
     152        if ((params->flags & wndf_avoid) != 0)
     153                ds_display_update_max_rect(wnd->display);
     154
    142155        (void) ds_display_paint(wnd->display, NULL);
    143156
    144         *rgc = wnd;
     157        *rwnd = wnd;
    145158        return EOK;
    146159error:
     
    152165                if (wnd->bitmap != NULL)
    153166                        gfx_bitmap_destroy(wnd->bitmap);
     167                if (wnd->caption != NULL)
     168                        free(wnd->caption);
    154169                free(wnd);
    155170        }
     
    167182
    168183        disp = wnd->display;
     184
     185        ds_window_unfocus(wnd);
    169186
    170187        ds_client_remove_window(wnd);
    171188        ds_display_remove_window(wnd);
    172189
     190        if ((wnd->flags & wndf_avoid) != 0)
     191                ds_display_update_max_rect(disp);
     192
    173193        mem_gc_delete(wnd->mgc);
    174194
     
    176196                gfx_bitmap_destroy(wnd->bitmap);
    177197
     198        free(wnd->caption);
    178199        free(wnd);
    179200
     
    187208void ds_window_bring_to_top(ds_window_t *wnd)
    188209{
    189         ds_display_t *disp = wnd->display;
    190 
    191         ds_display_remove_window(wnd);
    192         ds_display_add_window(disp, wnd);
     210        ds_display_window_to_top(wnd);
    193211        (void) ds_display_paint(wnd->display, NULL);
    194212}
     
    202220{
    203221        return wnd->gc;
     222}
     223
     224/** Determine if window is visible.
     225 *
     226 * @param wnd Window
     227 * @return @c true iff window is visible
     228 */
     229bool ds_window_is_visible(ds_window_t *wnd)
     230{
     231        return (wnd->flags & wndf_minimized) == 0;
    204232}
    205233
     
    216244        gfx_rect_t crect;
    217245
    218         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_paint");
     246        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_paint");
     247
     248        /* Skip painting the window if not visible */
     249        if (!ds_window_is_visible(wnd))
     250                return EOK;
    219251
    220252        if (rect != NULL) {
     
    361393        bool newr;
    362394
    363         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_repaint_preview");
     395        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_repaint_preview");
    364396
    365397        /*
     
    459491        gfx_rect_t old_rect;
    460492
    461         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_move (%d, %d)",
     493        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_update_move (%d, %d)",
    462494            (int) pos->x, (int) pos->y);
    463495
     
    496528        wnd->preview_rect = wnd->rect;
    497529
    498         // XXX Need client to tell us which seat started the resize!
     530        // TODO Multi-seat: need client to tell us which seat started the resize!
    499531        seat = ds_display_first_seat(wnd->display);
    500532        ctype = display_cursor_from_wrsz(rsztype);
     
    527559        ds_client_post_resize_event(wnd->client, wnd, &nrect);
    528560
    529         // XXX Need to know which seat started the resize!
     561        // TODO Multi-seat: Need to know which seat started the resize!
    530562        seat = ds_display_first_seat(wnd->display);
    531563        ds_seat_set_wm_cursor(seat, NULL);
     
    545577        gfx_rect_t old_rect;
    546578
    547         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_resize (%d, %d)",
     579        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_update_resize (%d, %d)",
    548580            (int) pos->x, (int) pos->y);
    549581
     
    594626        bool inside;
    595627
    596         log_msg(LOG_DEFAULT, LVL_DEBUG,
     628        log_msg(LOG_DEFAULT, LVL_DEBUG2,
    597629            "ds_window_post_pos_event type=%d pos=%d,%d", event->type,
    598630            (int) event->hpos, (int) event->vpos);
     
    648680errno_t ds_window_post_focus_event(ds_window_t *wnd)
    649681{
     682        errno_t rc;
     683        ds_wmclient_t *wmclient;
     684
    650685        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_focus_event");
    651686
    652         return ds_client_post_focus_event(wnd->client, wnd);
     687        rc = ds_client_post_focus_event(wnd->client, wnd);
     688        if (rc != EOK)
     689                return rc;
     690
     691        /* Increase focus counter */
     692        ++wnd->nfocus;
     693
     694        /* Notify window managers about window information change */
     695        wmclient = ds_display_first_wmclient(wnd->display);
     696        while (wmclient != NULL) {
     697                ds_wmclient_post_wnd_changed_event(wmclient, wnd->id);
     698                wmclient = ds_display_next_wmclient(wmclient);
     699        }
     700
     701        return EOK;
    653702}
    654703
     
    660709errno_t ds_window_post_unfocus_event(ds_window_t *wnd)
    661710{
     711        errno_t rc;
     712        ds_wmclient_t *wmclient;
     713
    662714        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_unfocus_event");
    663715
    664         return ds_client_post_unfocus_event(wnd->client, wnd);
     716        rc = ds_client_post_unfocus_event(wnd->client, wnd);
     717        if (rc != EOK)
     718                return rc;
     719
     720        /* Decrease focus counter */
     721        --wnd->nfocus;
     722
     723        /* Notify window managers about window information change */
     724        wmclient = ds_display_first_wmclient(wnd->display);
     725        while (wmclient != NULL) {
     726                ds_wmclient_post_wnd_changed_event(wmclient, wnd->id);
     727                wmclient = ds_display_next_wmclient(wmclient);
     728        }
     729
     730        return EOK;
    665731}
    666732
     
    708774void ds_window_get_max_rect(ds_window_t *wnd, gfx_rect_t *rect)
    709775{
    710         *rect = wnd->display->rect;
     776        *rect = wnd->display->max_rect;
    711777}
    712778
     
    785851        wnd->rect = *nrect;
    786852
     853        if ((wnd->flags & wndf_avoid) != 0)
     854                ds_display_update_max_rect(wnd->display);
     855
     856        (void) ds_display_paint(wnd->display, NULL);
     857        return EOK;
     858}
     859
     860/** Minimize window.
     861 *
     862 * @param wnd Window
     863 * @return EOK on success or an error code
     864 */
     865errno_t ds_window_minimize(ds_window_t *wnd)
     866{
     867        /* If already minimized, do nothing and return success. */
     868        if ((wnd->flags & wndf_minimized) != 0)
     869                return EOK;
     870
     871        ds_window_unfocus(wnd);
     872
     873        wnd->flags |= wndf_minimized;
     874        (void) ds_display_paint(wnd->display, NULL);
     875        return EOK;
     876}
     877
     878/** Unminimize window.
     879 *
     880 * @param wnd Window
     881 * @return EOK on success or an error code
     882 */
     883errno_t ds_window_unminimize(ds_window_t *wnd)
     884{
     885        /* If not minimized, do nothing and return success. */
     886        if ((wnd->flags & wndf_minimized) == 0)
     887                return EOK;
     888
     889        wnd->flags &= ~wndf_minimized;
    787890        (void) ds_display_paint(wnd->display, NULL);
    788891        return EOK;
     
    9021005 *
    9031006 * @param wnd Window
     1007 * @param cursor New cursor
    9041008 * @return EOK on success, EINVAL if @a cursor is invalid
    9051009 */
     
    9151019}
    9161020
     1021/** Set window caption.
     1022 *
     1023 * @param wnd Window
     1024 * @param caption New caption
     1025 *
     1026 * @return EOK on success, EINVAL if @a cursor is invalid
     1027 */
     1028errno_t ds_window_set_caption(ds_window_t *wnd, const char *caption)
     1029{
     1030        char *dcaption;
     1031        ds_wmclient_t *wmclient;
     1032
     1033        dcaption = str_dup(caption);
     1034        if (dcaption == NULL)
     1035                return ENOMEM;
     1036
     1037        free(wnd->caption);
     1038        wnd->caption = dcaption;
     1039
     1040        /* Notify window managers about window information change */
     1041        wmclient = ds_display_first_wmclient(wnd->display);
     1042        while (wmclient != NULL) {
     1043                ds_wmclient_post_wnd_changed_event(wmclient, wnd->id);
     1044                wmclient = ds_display_next_wmclient(wmclient);
     1045        }
     1046
     1047        return EOK;
     1048}
     1049
     1050/** Find alternate window with the allowed flags.
     1051 *
     1052 * An alternate window is a *different* window that is preferably previous
     1053 * in the display order and only has the @a allowed flags.
     1054 *
     1055 * @param wnd Window
     1056 * @param allowed_flags Bitmask of flags that the window is allowed to have
     1057 *
     1058 * @return Alternate window matching the criteria or @c NULL if there is none
     1059 */
     1060ds_window_t *ds_window_find_alt(ds_window_t *wnd,
     1061    display_wnd_flags_t allowed_flags)
     1062{
     1063        ds_window_t *nwnd;
     1064
     1065        /* Try preceding windows in display order */
     1066        nwnd = ds_display_prev_window(wnd);
     1067        while (nwnd != NULL && (nwnd->flags & ~allowed_flags) != 0) {
     1068                nwnd = ds_display_prev_window(nwnd);
     1069        }
     1070
     1071        /* Do we already have a matching window? */
     1072        if (nwnd != NULL && (nwnd->flags & ~allowed_flags) == 0) {
     1073                return nwnd;
     1074        }
     1075
     1076        /* Try succeeding windows in display order */
     1077        nwnd = ds_display_last_window(wnd->display);
     1078        while (nwnd != NULL && nwnd != wnd &&
     1079            (nwnd->flags & ~allowed_flags) != 0) {
     1080                nwnd = ds_display_prev_window(nwnd);
     1081        }
     1082
     1083        if (nwnd == wnd)
     1084                return NULL;
     1085
     1086        return nwnd;
     1087}
     1088
     1089/** Remove focus from window.
     1090 *
     1091 * Used to switch focus to another window when closing or minimizing window.
     1092 *
     1093 * @param wnd Window
     1094 */
     1095void ds_window_unfocus(ds_window_t *wnd)
     1096{
     1097        ds_seat_t *seat;
     1098
     1099        /* Make sure window is no longer focused in any seat */
     1100        seat = ds_display_first_seat(wnd->display);
     1101        while (seat != NULL) {
     1102                ds_seat_unfocus_wnd(seat, wnd);
     1103                seat = ds_display_next_seat(seat);
     1104        }
     1105}
     1106
    9171107/** Window memory GC invalidate callback.
    9181108 *
Note: See TracChangeset for help on using the changeset viewer.