Changes in uspace/srv/hid/display/seat.c [9546146:554a5f1] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/display/seat.c
r9546146 r554a5f1 1 1 /* 2 * Copyright (c) 20 24Jiri Svoboda2 * Copyright (c) 2019 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 38 38 #include <gfx/color.h> 39 39 #include <gfx/render.h> 40 #include <sif.h>41 #include <stdio.h>42 40 #include <stdlib.h> 43 #include <str.h>44 41 #include "client.h" 45 42 #include "cursor.h" 46 43 #include "display.h" 47 #include "idevcfg.h"48 44 #include "seat.h" 49 45 #include "window.h" … … 55 51 * 56 52 * @param display Parent display 57 * @param name Seat name58 53 * @param rseat Place to store pointer to new seat. 59 54 * @return EOK on success, ENOMEM if out of memory 60 55 */ 61 errno_t ds_seat_create(ds_display_t *display, const char *name, 62 ds_seat_t **rseat) 56 errno_t ds_seat_create(ds_display_t *display, ds_seat_t **rseat) 63 57 { 64 58 ds_seat_t *seat; 65 ds_seat_t *s0;66 67 s0 = ds_display_first_seat(display);68 while (s0 != NULL) {69 if (str_cmp(s0->name, name) == 0)70 return EEXIST;71 s0 = ds_display_next_seat(s0);72 }73 59 74 60 seat = calloc(1, sizeof(ds_seat_t)); … … 76 62 return ENOMEM; 77 63 78 seat->name = str_dup(name);79 if (seat->name == NULL) {80 free(seat);81 return ENOMEM;82 }83 84 list_initialize(&seat->idevcfgs);85 86 64 ds_display_add_seat(display, seat); 87 65 seat->pntpos.x = 0; … … 90 68 seat->client_cursor = display->cursor[dcurs_arrow]; 91 69 seat->wm_cursor = NULL; 92 seat->focus = ds_display_first_window(display);93 70 94 71 *rseat = seat; … … 102 79 void ds_seat_destroy(ds_seat_t *seat) 103 80 { 104 ds_idevcfg_t *idevcfg;105 106 /* Remove all input device configuration entries pointing to this seat */107 idevcfg = ds_seat_first_idevcfg(seat);108 while (idevcfg != NULL) {109 ds_idevcfg_destroy(idevcfg);110 idevcfg = ds_seat_first_idevcfg(seat);111 }112 113 /* Remove this seat's focus */114 if (seat->focus != NULL)115 ds_window_post_unfocus_event(seat->focus);116 117 81 ds_display_remove_seat(seat); 118 119 free(seat->name);120 82 free(seat); 121 83 } 122 84 123 /** Load seat from SIF node.124 *125 * @param display Display126 * @param snode Seat node from which to load the seat127 * @param rseat Place to store pointer to the newly loaded seat128 *129 * @return EOK on success or an error code130 */131 errno_t ds_seat_load(ds_display_t *display, sif_node_t *snode,132 ds_seat_t **rseat)133 {134 const char *sid;135 const char *name;136 char *endptr;137 unsigned long id;138 errno_t rc;139 140 sid = sif_node_get_attr(snode, "id");141 if (sid == NULL)142 return EIO;143 144 name = sif_node_get_attr(snode, "name");145 if (name == NULL)146 return EIO;147 148 id = strtoul(sid, &endptr, 10);149 if (*endptr != '\0')150 return EIO;151 152 rc = ds_seat_create(display, name, rseat);153 if (rc != EOK)154 return EIO;155 156 (*rseat)->id = id;157 return EOK;158 }159 160 /** Save seat to SIF node.161 *162 * @param seat Seat163 * @param snode Seat node into which the seat should be saved164 *165 * @return EOK on success or an error code166 */167 errno_t ds_seat_save(ds_seat_t *seat, sif_node_t *snode)168 {169 char *sid;170 errno_t rc;171 int rv;172 173 rv = asprintf(&sid, "%lu", (unsigned long)seat->id);174 if (rv < 0) {175 rc = ENOMEM;176 return rc;177 }178 179 rc = sif_node_set_attr(snode, "id", sid);180 if (rc != EOK) {181 free(sid);182 return rc;183 }184 185 free(sid);186 187 rc = sif_node_set_attr(snode, "name", seat->name);188 if (rc != EOK)189 return rc;190 191 return EOK;192 }193 194 85 /** Set seat focus to a window. 195 86 * … … 199 90 void ds_seat_set_focus(ds_seat_t *seat, ds_window_t *wnd) 200 91 { 201 errno_t rc;202 203 92 if (wnd == seat->focus) { 204 93 /* Focus is not changing */ … … 206 95 } 207 96 208 if (wnd != NULL) {209 rc = ds_window_unminimize(wnd);210 if (rc != EOK)211 return;212 }213 214 97 if (seat->focus != NULL) 215 98 ds_window_post_unfocus_event(seat->focus); … … 221 104 ds_window_bring_to_top(wnd); 222 105 } 223 224 /* When focus changes, popup window should be closed */ 225 ds_seat_set_popup(seat, NULL); 226 } 227 228 /** Set seat popup window. 229 * 230 * @param seat Seat 231 * @param wnd Popup window 232 */ 233 void ds_seat_set_popup(ds_seat_t *seat, ds_window_t *wnd) 234 { 235 if (wnd == seat->popup) 236 return; 237 238 if (seat->popup != NULL) { 239 /* Window is no longer the popup window, send close request */ 240 ds_client_post_close_event(seat->popup->client, 241 seat->popup); 242 } 243 244 seat->popup = wnd; 245 } 246 247 /** Evacuate seat references to window. 248 * 249 * If seat's focus is @a wnd, it will be set to NULL. 250 * If seat's popup window is @a wnd, it will be set to NULL. 251 * 252 * @param seat Seat 253 * @param wnd Window to evacuate references from 254 */ 255 void ds_seat_evac_wnd_refs(ds_seat_t *seat, ds_window_t *wnd) 256 { 257 if (seat->focus == wnd) 258 ds_seat_set_focus(seat, NULL); 259 260 if (seat->popup == wnd) 261 ds_seat_set_popup(seat, NULL); 262 } 263 264 /** Unfocus window. 265 * 266 * If seat's focus is @a wnd, it will be set to a different window 267 * that is not minimized, preferably not a system window. 268 * 269 * @param seat Seat 270 * @param wnd Window to remove focus from 271 */ 272 void ds_seat_unfocus_wnd(ds_seat_t *seat, ds_window_t *wnd) 106 } 107 108 /** Evacuate focus from window. 109 * 110 * If seat's focus is @a wnd, it will be set to a different window. 111 * 112 * @param seat Seat 113 * @param wnd Window to evacuate focus from 114 */ 115 void ds_seat_evac_focus(ds_seat_t *seat, ds_window_t *wnd) 273 116 { 274 117 ds_window_t *nwnd; 275 118 276 if (seat->focus != wnd) 277 return; 278 279 /* Find alternate window that is neither system nor minimized */ 280 nwnd = ds_window_find_prev(wnd, ~(wndf_minimized | wndf_system)); 281 282 if (nwnd == NULL) { 283 /* Find alternate window that is not minimized */ 284 nwnd = ds_window_find_prev(wnd, ~wndf_minimized); 285 } 286 287 ds_seat_set_focus(seat, nwnd); 288 } 289 290 /** Switch focus to another window. 291 * 292 * @param seat Seat 293 * @param wnd Window to evacuate focus from 294 */ 295 void ds_seat_switch_focus(ds_seat_t *seat) 296 { 297 ds_window_t *nwnd; 298 299 if (seat->focus != NULL) { 300 /* Find alternate window that is not a system window */ 301 nwnd = ds_window_find_next(seat->focus, ~wndf_system); 302 } else { 303 /* Currently no focus. Focus topmost window. */ 304 nwnd = ds_display_first_window(seat->display); 305 } 306 307 /* Only switch focus if there is another window */ 308 if (nwnd != NULL) 119 if (seat->focus == wnd) { 120 nwnd = ds_display_next_window(wnd); 121 if (nwnd == NULL) 122 nwnd = ds_display_first_window(wnd->display); 123 if (nwnd == wnd) 124 nwnd = NULL; 125 309 126 ds_seat_set_focus(seat, nwnd); 127 } 310 128 } 311 129 … … 325 143 if (event->type == KEY_PRESS && alt_or_shift && event->key == KC_TAB) { 326 144 /* On Alt-Tab or Shift-Tab, switch focus to next window */ 327 ds_seat_ switch_focus(seat);145 ds_seat_evac_focus(seat, seat->focus); 328 146 return EOK; 329 147 } 330 148 331 dwindow = seat->popup; 332 if (dwindow == NULL) 333 dwindow = seat->focus; 334 149 dwindow = seat->focus; 335 150 if (dwindow == NULL) 336 151 return EOK; … … 492 307 /* Focus window on button press */ 493 308 if (event->type == PTD_PRESS && event->btn_num == 1) { 494 if (wnd != NULL && (wnd->flags & wndf_popup) == 0) {309 if (wnd != NULL) { 495 310 ds_seat_set_focus(seat, wnd); 496 311 } 497 312 } 498 313 499 if (event->type == PTD_PRESS || event->type == PTD_RELEASE || 500 event->type == PTD_DCLICK) { 501 pevent.pos_id = event->pos_id; 502 switch (event->type) { 503 case PTD_PRESS: 504 pevent.type = POS_PRESS; 505 break; 506 case PTD_RELEASE: 507 pevent.type = POS_RELEASE; 508 break; 509 case PTD_DCLICK: 510 pevent.type = POS_DCLICK; 511 break; 512 default: 513 assert(false); 514 } 515 314 if (event->type == PTD_PRESS || event->type == PTD_RELEASE) { 315 pevent.pos_id = 0; 316 pevent.type = (event->type == PTD_PRESS) ? 317 POS_PRESS : POS_RELEASE; 516 318 pevent.btn_num = event->btn_num; 517 319 pevent.hpos = seat->pntpos.x; … … 530 332 seat->pntpos = npos; 531 333 532 pevent.pos_id = event->pos_id;334 pevent.pos_id = 0; 533 335 pevent.type = POS_UPDATE; 534 336 pevent.btn_num = 0; … … 558 360 seat->pntpos = npos; 559 361 560 pevent.pos_id = event->pos_id;362 pevent.pos_id = 0; 561 363 pevent.type = POS_UPDATE; 562 364 pevent.btn_num = 0; … … 583 385 errno_t ds_seat_post_pos_event(ds_seat_t *seat, pos_event_t *event) 584 386 { 585 ds_window_t *pwindow; 586 ds_window_t *cwindow; 387 ds_window_t *wnd; 587 388 errno_t rc; 588 389 589 /* Window under pointer */ 590 pwindow = ds_display_window_by_pos(seat->display, &seat->pntpos); 591 592 /* Current window: popup or focused */ 593 cwindow = seat->popup; 594 if (cwindow == NULL) 595 cwindow = seat->focus; 596 597 /* 598 * Deliver move and release event to current window if different 599 * from pwindow 600 */ 601 if (event->type != POS_PRESS && cwindow != NULL && 602 cwindow != pwindow) { 603 rc = ds_window_post_pos_event(cwindow, event); 604 if (rc != EOK) 605 return rc; 606 } 607 608 if (pwindow != NULL) { 390 wnd = ds_display_window_by_pos(seat->display, &seat->pntpos); 391 392 if (seat->focus != wnd) { 393 rc = ds_window_post_pos_event(seat->focus, event); 394 if (rc != EOK) 395 return rc; 396 397 /* Only deliver release events to the focused window */ 398 if (event->type == POS_RELEASE) 399 return EOK; 400 } 401 402 if (wnd != NULL) { 609 403 /* Moving over a window */ 610 ds_seat_set_client_cursor(seat, pwindow->cursor);611 612 rc = ds_window_post_pos_event( pwindow, event);404 ds_seat_set_client_cursor(seat, wnd->cursor); 405 406 rc = ds_window_post_pos_event(wnd, event); 613 407 if (rc != EOK) 614 408 return rc; 615 409 } else { 616 410 /* Not over a window */ 617 ds_seat_set_client_cursor(seat, 618 seat->display->cursor[dcurs_arrow]); 619 } 620 621 /* Click outside popup window */ 622 if (event->type == POS_PRESS && pwindow != seat->popup) { 623 /* Close popup window */ 624 ds_seat_set_popup(seat, NULL); 411 ds_seat_set_client_cursor(seat, seat->display->cursor[dcurs_arrow]); 625 412 } 626 413 … … 641 428 } 642 429 643 /** Add input device configuration entry to seat.644 *645 * @param seat Seat646 * @param idevcfg Input device configuration647 */648 void ds_seat_add_idevcfg(ds_seat_t *seat, ds_idevcfg_t *idevcfg)649 {650 assert(idevcfg->seat == NULL);651 assert(!link_used(&idevcfg->lseatidcfgs));652 653 idevcfg->seat = seat;654 list_append(&idevcfg->lseatidcfgs, &seat->idevcfgs);655 }656 657 /** Remove input device configuration entry from seat.658 *659 * @param idevcfg Input device configuration entry660 */661 void ds_seat_remove_idevcfg(ds_idevcfg_t *idevcfg)662 {663 list_remove(&idevcfg->lseatidcfgs);664 idevcfg->seat = NULL;665 }666 667 /** Get first input device configuration entry in seat.668 *669 * @param disp Display670 * @return First input device configuration entry or @c NULL if there is none671 */672 ds_idevcfg_t *ds_seat_first_idevcfg(ds_seat_t *seat)673 {674 link_t *link = list_first(&seat->idevcfgs);675 676 if (link == NULL)677 return NULL;678 679 return list_get_instance(link, ds_idevcfg_t, lseatidcfgs);680 }681 682 /** Get next input device configuration entry in seat.683 *684 * @param idevcfg Current input device configuration entry685 * @return Next input device configuration entry or @c NULL if there is none686 */687 ds_idevcfg_t *ds_seat_next_idevcfg(ds_idevcfg_t *idevcfg)688 {689 link_t *link = list_next(&idevcfg->lseatidcfgs, &idevcfg->seat->idevcfgs);690 691 if (link == NULL)692 return NULL;693 694 return list_get_instance(link, ds_idevcfg_t, lseatidcfgs);695 }696 697 430 /** @} 698 431 */
Note:
See TracChangeset
for help on using the changeset viewer.