Changes in uspace/srv/hid/display/window.c [be0ec50:1215db9] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/display/window.c
rbe0ec50 r1215db9 1 1 /* 2 * Copyright (c) 202 3Jiri Svoboda2 * Copyright (c) 2021 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 44 44 #include <memgfx/memgc.h> 45 45 #include <stdlib.h> 46 #include <str.h>47 #include <wndmgt.h>48 46 #include "client.h" 49 47 #include "display.h" 50 48 #include "seat.h" 51 49 #include "window.h" 52 #include "wmclient.h"53 50 54 51 static void ds_window_invalidate_cb(void *, gfx_rect_t *); … … 67 64 * @param client Client owning the window 68 65 * @param params Window parameters 69 * @param r wnd Place to store pointer to new window.66 * @param rgc Place to store pointer to new GC. 70 67 * 71 68 * @return EOK on success or an error code 72 69 */ 73 70 errno_t ds_window_create(ds_client_t *client, display_wnd_params_t *params, 74 ds_window_t **r wnd)71 ds_window_t **rgc) 75 72 { 76 73 ds_window_t *wnd = NULL; … … 88 85 } 89 86 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 99 87 ds_client_add_window(client, wnd); 100 88 ds_display_add_window(client->display, wnd); … … 102 90 gfx_bitmap_params_init(&bparams); 103 91 bparams.rect = params->rect; 104 105 /* Allocate window bitmap */106 92 107 93 dgc = ds_display_get_gc(wnd->display); … … 136 122 wnd->gc = mem_gc_get_ctx(wnd->mgc); 137 123 wnd->cursor = wnd->display->cursor[dcurs_arrow]; 124 wnd->flags = params->flags; 138 125 139 126 if ((params->flags & wndf_setpos) != 0) { … … 146 133 } 147 134 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? */ 135 seat = ds_display_first_seat(client->display); 136 155 137 if ((params->flags & wndf_popup) != 0) 156 138 ds_seat_set_popup(seat, wnd); … … 158 140 ds_seat_set_focus(seat, wnd); 159 141 160 /* Is this window a panel? */161 if ((params->flags & wndf_avoid) != 0)162 ds_display_update_max_rect(wnd->display);163 164 142 (void) ds_display_paint(wnd->display, NULL); 165 143 166 *r wnd= wnd;144 *rgc = wnd; 167 145 return EOK; 168 146 error: 169 147 if (wnd != NULL) { 170 ds_client_remove_window(wnd);171 ds_display_remove_window(wnd);172 if (wnd->mgc != NULL)173 mem_gc_delete(wnd->mgc);174 148 if (wnd->bitmap != NULL) 175 149 gfx_bitmap_destroy(wnd->bitmap); 176 if (wnd->caption != NULL)177 free(wnd->caption);178 150 free(wnd); 179 151 } … … 191 163 192 164 disp = wnd->display; 193 194 ds_window_unfocus(wnd);195 165 196 166 ds_client_remove_window(wnd); 197 167 ds_display_remove_window(wnd); 198 168 199 if ((wnd->flags & wndf_avoid) != 0)200 ds_display_update_max_rect(disp);201 202 169 mem_gc_delete(wnd->mgc); 203 170 … … 205 172 gfx_bitmap_destroy(wnd->bitmap); 206 173 207 free(wnd->caption);208 174 free(wnd); 209 175 … … 217 183 void ds_window_bring_to_top(ds_window_t *wnd) 218 184 { 219 ds_display_window_to_top(wnd); 185 ds_display_t *disp = wnd->display; 186 187 ds_display_remove_window(wnd); 188 ds_display_add_window(disp, wnd); 220 189 (void) ds_display_paint(wnd->display, NULL); 221 190 } … … 229 198 { 230 199 return wnd->gc; 231 }232 233 /** Determine if window is visible.234 *235 * @param wnd Window236 * @return @c true iff window is visible237 */238 bool ds_window_is_visible(ds_window_t *wnd)239 {240 return (wnd->flags & wndf_minimized) == 0;241 200 } 242 201 … … 253 212 gfx_rect_t crect; 254 213 255 log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_paint"); 256 257 /* Skip painting the window if not visible */ 258 if (!ds_window_is_visible(wnd)) 259 return EOK; 214 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_paint"); 260 215 261 216 if (rect != NULL) { … … 402 357 bool newr; 403 358 404 log_msg(LOG_DEFAULT, LVL_DEBUG 2, "ds_window_repaint_preview");359 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_repaint_preview"); 405 360 406 361 /* … … 446 401 * @param wnd Window 447 402 * @param pos Position where mouse button was pressed 448 * @param pos_id Positioning device ID 449 */ 450 static void ds_window_start_move(ds_window_t *wnd, gfx_coord2_t *pos, 451 sysarg_t pos_id) 403 */ 404 static void ds_window_start_move(ds_window_t *wnd, gfx_coord2_t *pos) 452 405 { 453 406 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_move (%d, %d)", … … 458 411 459 412 wnd->orig_pos = *pos; 460 wnd->orig_pos_id = pos_id;461 413 wnd->state = dsw_moving; 462 414 wnd->preview_pos = wnd->dpos; … … 488 440 wnd->dpos = nwpos; 489 441 wnd->state = dsw_idle; 490 wnd->orig_pos_id = 0;491 442 492 443 (void) ds_display_paint(wnd->display, NULL); … … 504 455 gfx_rect_t old_rect; 505 456 506 log_msg(LOG_DEFAULT, LVL_DEBUG 2, "ds_window_update_move (%d, %d)",457 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_move (%d, %d)", 507 458 (int) pos->x, (int) pos->y); 508 459 … … 523 474 * @param rsztype Resize type (which part of window is being dragged) 524 475 * @param pos Position where mouse button was pressed 525 * @param pos_id Positioning device ID526 476 */ 527 477 static void ds_window_start_resize(ds_window_t *wnd, 528 display_wnd_rsztype_t rsztype, gfx_coord2_t *pos , sysarg_t pos_id)478 display_wnd_rsztype_t rsztype, gfx_coord2_t *pos) 529 479 { 530 480 ds_seat_t *seat; … … 537 487 return; 538 488 539 /* Determine which seat started the resize */540 seat = ds_display_seat_by_idev(wnd->display, pos_id);541 if (seat == NULL)542 return;543 544 489 wnd->orig_pos = *pos; 545 wnd->orig_pos_id = pos_id;546 490 wnd->state = dsw_resizing; 547 491 wnd->rsztype = rsztype; 548 492 wnd->preview_rect = wnd->rect; 549 493 494 // XXX Need client to tell us which seat started the resize! 495 seat = ds_display_first_seat(wnd->display); 550 496 ctype = display_cursor_from_wrsz(rsztype); 551 497 ds_seat_set_wm_cursor(seat, wnd->display->cursor[ctype]); … … 577 523 ds_client_post_resize_event(wnd->client, wnd, &nrect); 578 524 579 /* Determine which seat started the resize */ 580 seat = ds_display_seat_by_idev(wnd->display, wnd->orig_pos_id); 581 if (seat != NULL) 582 ds_seat_set_wm_cursor(seat, NULL); 583 584 wnd->orig_pos_id = 0; 525 // XXX Need to know which seat started the resize! 526 seat = ds_display_first_seat(wnd->display); 527 ds_seat_set_wm_cursor(seat, NULL); 585 528 586 529 (void) ds_display_paint(wnd->display, NULL); … … 598 541 gfx_rect_t old_rect; 599 542 600 log_msg(LOG_DEFAULT, LVL_DEBUG 2, "ds_window_update_resize (%d, %d)",543 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_resize (%d, %d)", 601 544 (int) pos->x, (int) pos->y); 602 545 … … 637 580 * @param wnd Window 638 581 * @param event Position event 639 *640 * @return EOK on success or an error code641 582 */ 642 583 errno_t ds_window_post_pos_event(ds_window_t *wnd, pos_event_t *event) … … 644 585 pos_event_t tevent; 645 586 gfx_coord2_t pos; 646 sysarg_t pos_id;647 587 gfx_rect_t drect; 648 588 bool inside; 649 589 650 log_msg(LOG_DEFAULT, LVL_DEBUG 2,590 log_msg(LOG_DEFAULT, LVL_DEBUG, 651 591 "ds_window_post_pos_event type=%d pos=%d,%d", event->type, 652 592 (int) event->hpos, (int) event->vpos); … … 654 594 pos.x = event->hpos; 655 595 pos.y = event->vpos; 656 pos_id = event->pos_id;657 596 gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect); 658 597 inside = gfx_pix_inside_rect(&pos, &drect); 659 598 660 if (event->type == POS_PRESS && event->btn_num == 2 && inside && 661 (wnd->flags & wndf_maximized) == 0) { 662 ds_window_start_move(wnd, &pos, pos_id); 599 if (event->type == POS_PRESS && event->btn_num == 2 && inside) { 600 ds_window_start_move(wnd, &pos); 663 601 return EOK; 664 602 } 665 603 666 604 if (event->type == POS_RELEASE) { 667 /* Finish move/resize if they were started by the same seat */ 668 if (wnd->state == dsw_moving && 669 ds_window_orig_seat(wnd, pos_id)) { 605 if (wnd->state == dsw_moving) { 670 606 ds_window_finish_move(wnd, &pos); 671 607 return EOK; 672 608 } 673 609 674 if (wnd->state == dsw_resizing && 675 ds_window_orig_seat(wnd, pos_id)) { 610 if (wnd->state == dsw_resizing) { 676 611 ds_window_finish_resize(wnd, &pos); 677 612 return EOK; … … 680 615 681 616 if (event->type == POS_UPDATE) { 682 /* Update move/resize if they were started by the same seat */ 683 if (wnd->state == dsw_moving && 684 ds_window_orig_seat(wnd, pos_id)) { 617 if (wnd->state == dsw_moving) { 685 618 ds_window_update_move(wnd, &pos); 686 619 return EOK; 687 620 } 688 621 689 if (wnd->state == dsw_resizing && 690 ds_window_orig_seat(wnd, pos_id)) { 622 if (wnd->state == dsw_resizing) { 691 623 ds_window_update_resize(wnd, &pos); 692 624 return EOK; … … 705 637 * 706 638 * @param wnd Window 707 * @return EOK on success or an error code708 639 */ 709 640 errno_t ds_window_post_focus_event(ds_window_t *wnd) 710 641 { 711 display_wnd_focus_ev_t efocus;712 errno_t rc;713 ds_wmclient_t *wmclient;714 715 642 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_focus_event"); 716 643 717 /* Increase focus counter */ 718 ++wnd->nfocus; 719 efocus.nfocus = wnd->nfocus; 720 721 rc = ds_client_post_focus_event(wnd->client, wnd, &efocus); 722 if (rc != EOK) 723 return rc; 724 725 /* Notify window managers about window information change */ 726 wmclient = ds_display_first_wmclient(wnd->display); 727 while (wmclient != NULL) { 728 ds_wmclient_post_wnd_changed_event(wmclient, wnd->id); 729 wmclient = ds_display_next_wmclient(wmclient); 730 } 731 732 return EOK; 644 return ds_client_post_focus_event(wnd->client, wnd); 733 645 } 734 646 … … 736 648 * 737 649 * @param wnd Window 738 * @return EOK on success or an error code739 650 */ 740 651 errno_t ds_window_post_unfocus_event(ds_window_t *wnd) 741 652 { 742 display_wnd_unfocus_ev_t eunfocus;743 errno_t rc;744 ds_wmclient_t *wmclient;745 746 653 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_unfocus_event"); 747 654 748 /* Decrease focus counter */ 749 --wnd->nfocus; 750 eunfocus.nfocus = wnd->nfocus; 751 752 rc = ds_client_post_unfocus_event(wnd->client, wnd, &eunfocus); 753 if (rc != EOK) 754 return rc; 755 756 /* Notify window managers about window information change */ 757 wmclient = ds_display_first_wmclient(wnd->display); 758 while (wmclient != NULL) { 759 ds_wmclient_post_wnd_changed_event(wmclient, wnd->id); 760 wmclient = ds_display_next_wmclient(wmclient); 761 } 762 763 return EOK; 655 return ds_client_post_unfocus_event(wnd->client, wnd); 764 656 } 765 657 … … 769 661 * @param pos Position where the pointer was when the move started 770 662 * relative to the window 771 * @param pos_id Positioning device ID772 663 * @param event Button press event 773 664 */ 774 void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos , sysarg_t pos_id)665 void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos) 775 666 { 776 667 gfx_coord2_t orig_pos; … … 780 671 781 672 gfx_coord2_add(&wnd->dpos, pos, &orig_pos); 782 ds_window_start_move(wnd, &orig_pos , pos_id);673 ds_window_start_move(wnd, &orig_pos); 783 674 } 784 675 … … 800 691 { 801 692 *dpos = wnd->dpos; 802 }803 804 /** Get maximized window rectangle.805 *806 * @param wnd Window807 */808 void ds_window_get_max_rect(ds_window_t *wnd, gfx_rect_t *rect)809 {810 *rect = wnd->display->max_rect;811 693 } 812 694 … … 817 699 * @param pos Position where the pointer was when the resize started 818 700 * relative to the window 819 * @param pos_id Positioning device ID820 701 * @param event Button press event 821 702 */ 822 703 void ds_window_resize_req(ds_window_t *wnd, display_wnd_rsztype_t rsztype, 823 gfx_coord2_t *pos , sysarg_t pos_id)704 gfx_coord2_t *pos) 824 705 { 825 706 gfx_coord2_t orig_pos; 826 707 827 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_resize_req (%d, %d, %d , %d)",828 (int) rsztype, (int)pos->x, (int)pos->y, (int)pos_id);708 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_resize_req (%d, %d, %d)", 709 (int) rsztype, (int) pos->x, (int) pos->y); 829 710 830 711 gfx_coord2_add(&wnd->dpos, pos, &orig_pos); 831 ds_window_start_resize(wnd, rsztype, &orig_pos , pos_id);712 ds_window_start_resize(wnd, rsztype, &orig_pos); 832 713 } 833 714 … … 835 716 * 836 717 * @param wnd Window 837 * @return EOK on success or an error code838 718 */ 839 719 errno_t ds_window_resize(ds_window_t *wnd, gfx_coord2_t *offs, … … 886 766 wnd->rect = *nrect; 887 767 888 if ((wnd->flags & wndf_avoid) != 0)889 ds_display_update_max_rect(wnd->display);890 891 768 (void) ds_display_paint(wnd->display, NULL); 892 return EOK;893 }894 895 /** Minimize window.896 *897 * @param wnd Window898 * @return EOK on success or an error code899 */900 errno_t ds_window_minimize(ds_window_t *wnd)901 {902 /* If already minimized, do nothing and return success. */903 if ((wnd->flags & wndf_minimized) != 0)904 return EOK;905 906 ds_window_unfocus(wnd);907 908 wnd->flags |= wndf_minimized;909 (void) ds_display_paint(wnd->display, NULL);910 return EOK;911 }912 913 /** Unminimize window.914 *915 * @param wnd Window916 * @return EOK on success or an error code917 */918 errno_t ds_window_unminimize(ds_window_t *wnd)919 {920 /* If not minimized, do nothing and return success. */921 if ((wnd->flags & wndf_minimized) == 0)922 return EOK;923 924 wnd->flags &= ~wndf_minimized;925 (void) ds_display_paint(wnd->display, NULL);926 return EOK;927 }928 929 /** Maximize window.930 *931 * @param wnd Window932 * @return EOK on success or an error code933 */934 errno_t ds_window_maximize(ds_window_t *wnd)935 {936 gfx_coord2_t old_dpos;937 gfx_rect_t old_rect;938 gfx_coord2_t offs;939 gfx_rect_t max_rect;940 gfx_rect_t nrect;941 errno_t rc;942 943 /* If already maximized, do nothing and return success. */944 if ((wnd->flags & wndf_maximized) != 0)945 return EOK;946 947 /* Remember the old window rectangle and display position */948 old_rect = wnd->rect;949 old_dpos = wnd->dpos;950 951 ds_window_get_max_rect(wnd, &max_rect);952 953 /* Keep window contents on the same position on the screen */954 offs.x = max_rect.p0.x - wnd->dpos.x;955 offs.y = max_rect.p0.y - wnd->dpos.y;956 957 /* Maximized window's coordinates will start at 0,0 */958 gfx_rect_rtranslate(&max_rect.p0, &max_rect, &nrect);959 960 rc = ds_window_resize(wnd, &offs, &nrect);961 if (rc != EOK)962 return rc;963 964 /* Set window flags, remember normal rectangle */965 wnd->flags |= wndf_maximized;966 wnd->normal_rect = old_rect;967 wnd->normal_dpos = old_dpos;968 969 return EOK;970 }971 972 /** Unmaximize window.973 *974 * @param wnd Window975 * @return EOK on success or an error code976 */977 errno_t ds_window_unmaximize(ds_window_t *wnd)978 {979 gfx_coord2_t offs;980 errno_t rc;981 982 /* If not maximized, do nothing and return success. */983 if ((wnd->flags & wndf_maximized) == 0)984 return EOK;985 986 /* Keep window contents on the same position on the screen */987 offs.x = wnd->normal_dpos.x - wnd->dpos.x;988 offs.y = wnd->normal_dpos.y - wnd->dpos.y;989 990 rc = ds_window_resize(wnd, &offs, &wnd->normal_rect);991 if (rc != EOK)992 return rc;993 994 /* Clear maximized flag */995 wnd->flags &= ~wndf_maximized;996 997 769 return EOK; 998 770 } … … 1040 812 * 1041 813 * @param wnd Window 1042 * @param cursor New cursor1043 814 * @return EOK on success, EINVAL if @a cursor is invalid 1044 815 */ … … 1054 825 } 1055 826 1056 /** Set window caption.1057 *1058 * @param wnd Window1059 * @param caption New caption1060 *1061 * @return EOK on success, EINVAL if @a cursor is invalid1062 */1063 errno_t ds_window_set_caption(ds_window_t *wnd, const char *caption)1064 {1065 char *dcaption;1066 ds_wmclient_t *wmclient;1067 1068 dcaption = str_dup(caption);1069 if (dcaption == NULL)1070 return ENOMEM;1071 1072 free(wnd->caption);1073 wnd->caption = dcaption;1074 1075 /* Notify window managers about window information change */1076 wmclient = ds_display_first_wmclient(wnd->display);1077 while (wmclient != NULL) {1078 ds_wmclient_post_wnd_changed_event(wmclient, wnd->id);1079 wmclient = ds_display_next_wmclient(wmclient);1080 }1081 1082 return EOK;1083 }1084 1085 /** Find alternate window with the allowed flags.1086 *1087 * An alternate window is a *different* window that is preferably previous1088 * in the display order and only has the @a allowed flags.1089 *1090 * @param wnd Window1091 * @param allowed_flags Bitmask of flags that the window is allowed to have1092 *1093 * @return Alternate window matching the criteria or @c NULL if there is none1094 */1095 ds_window_t *ds_window_find_prev(ds_window_t *wnd,1096 display_wnd_flags_t allowed_flags)1097 {1098 ds_window_t *nwnd;1099 1100 /* Try preceding windows in display order */1101 nwnd = ds_display_next_window(wnd);1102 while (nwnd != NULL && (nwnd->flags & ~allowed_flags) != 0) {1103 nwnd = ds_display_next_window(nwnd);1104 }1105 1106 /* Do we already have a matching window? */1107 if (nwnd != NULL && (nwnd->flags & ~allowed_flags) == 0) {1108 return nwnd;1109 }1110 1111 /* Try succeeding windows in display order */1112 nwnd = ds_display_first_window(wnd->display);1113 while (nwnd != NULL && nwnd != wnd &&1114 (nwnd->flags & ~allowed_flags) != 0) {1115 nwnd = ds_display_next_window(nwnd);1116 }1117 1118 if (nwnd == wnd)1119 return NULL;1120 1121 return nwnd;1122 }1123 1124 /** Find alternate window with the allowed flags.1125 *1126 * An alternate window is a *different* window that is preferably previous1127 * in the display order and only has the @a allowed flags.1128 *1129 * @param wnd Window1130 * @param allowed_flags Bitmask of flags that the window is allowed to have1131 *1132 * @return Alternate window matching the criteria or @c NULL if there is none1133 */1134 ds_window_t *ds_window_find_next(ds_window_t *wnd,1135 display_wnd_flags_t allowed_flags)1136 {1137 ds_window_t *nwnd;1138 1139 /* Try preceding windows in display order */1140 nwnd = ds_display_prev_window(wnd);1141 while (nwnd != NULL && (nwnd->flags & ~allowed_flags) != 0) {1142 nwnd = ds_display_prev_window(nwnd);1143 }1144 1145 /* Do we already have a matching window? */1146 if (nwnd != NULL && (nwnd->flags & ~allowed_flags) == 0) {1147 return nwnd;1148 }1149 1150 /* Try succeeding windows in display order */1151 nwnd = ds_display_last_window(wnd->display);1152 while (nwnd != NULL && nwnd != wnd &&1153 (nwnd->flags & ~allowed_flags) != 0) {1154 nwnd = ds_display_prev_window(nwnd);1155 }1156 1157 if (nwnd == wnd)1158 return NULL;1159 1160 return nwnd;1161 }1162 1163 /** Remove focus from window.1164 *1165 * Used to switch focus to another window when closing or minimizing window.1166 *1167 * @param wnd Window1168 */1169 void ds_window_unfocus(ds_window_t *wnd)1170 {1171 ds_seat_t *seat;1172 1173 /* Make sure window is no longer focused in any seat */1174 seat = ds_display_first_seat(wnd->display);1175 while (seat != NULL) {1176 ds_seat_unfocus_wnd(seat, wnd);1177 seat = ds_display_next_seat(seat);1178 }1179 }1180 1181 /** Determine if input device belongs to the same seat as the original device.1182 *1183 * Compare the seat ownning @a idev_id with the seat owning @a wnd->orig_pos_id1184 * (the device that started the window move or resize).1185 *1186 * This is used to make sure that, when two seats focus the same window,1187 * only devices owned by the seat that started the resize or move can1188 * affect it. Otherwise moving the other pointer(s) would disrupt the1189 * resize or move operation.1190 *1191 * @param wnd Window (that is currently being resized or moved)1192 * @param idev_id Input device ID1193 * @return @c true iff idev_id is owned by the same seat as the input1194 * device that started the resize or move1195 */1196 bool ds_window_orig_seat(ds_window_t *wnd, sysarg_t idev_id)1197 {1198 ds_seat_t *orig_seat;1199 ds_seat_t *seat;1200 1201 /* Window must be in state such that wnd->orig_pos_id is valid */1202 assert(wnd->state == dsw_moving || wnd->state == dsw_resizing);1203 1204 orig_seat = ds_display_seat_by_idev(wnd->display, wnd->orig_pos_id);1205 seat = ds_display_seat_by_idev(wnd->display, idev_id);1206 1207 return seat == orig_seat;1208 }1209 1210 827 /** Window memory GC invalidate callback. 1211 828 *
Note:
See TracChangeset
for help on using the changeset viewer.