source: mainline/uspace/app/display-cfg/seats.c

Last change on this file was 8a4ceaa, checked in by Jiri Svoboda <jiri@…>, 2 years ago

Refuse to delete the last seat

  • Property mode set to 100644
File size: 26.4 KB
Line 
1/*
2 * Copyright (c) 2023 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup display-cfg
30 * @{
31 */
32/** @file Seat configuration tab
33 */
34
35#include <gfx/coord.h>
36#include <loc.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <str.h>
40#include <ui/control.h>
41#include <ui/label.h>
42#include <ui/list.h>
43#include <ui/pbutton.h>
44#include <ui/promptdialog.h>
45#include <ui/resource.h>
46#include <ui/selectdialog.h>
47#include <ui/tab.h>
48#include <ui/window.h>
49#include "display-cfg.h"
50#include "seats.h"
51
52static errno_t dcfg_seats_asgn_dev_list_populate(dcfg_seats_t *);
53static errno_t dcfg_seats_avail_dev_list_populate(dcfg_seats_t *,
54 ui_select_dialog_t *);
55static dcfg_seats_entry_t *dcfg_seats_get_selected(dcfg_seats_t *);
56static void dcfg_seats_list_selected(ui_list_entry_t *, void *);
57static void dcfg_add_seat_clicked(ui_pbutton_t *, void *);
58static void dcfg_remove_seat_clicked(ui_pbutton_t *, void *);
59static void dcfg_add_device_clicked(ui_pbutton_t *, void *);
60static void dcfg_remove_device_clicked(ui_pbutton_t *, void *);
61
62/** Seat list callbacks */
63ui_list_cb_t dcfg_seats_list_cb = {
64 .selected = dcfg_seats_list_selected
65};
66
67/** Add seat button callbacks */
68ui_pbutton_cb_t dcfg_add_seat_button_cb = {
69 .clicked = dcfg_add_seat_clicked
70};
71
72/** Remove seat button callbacks */
73ui_pbutton_cb_t dcfg_remove_seat_button_cb = {
74 .clicked = dcfg_remove_seat_clicked
75};
76
77/** Add device button callbacks */
78ui_pbutton_cb_t dcfg_add_device_button_cb = {
79 .clicked = dcfg_add_device_clicked
80};
81
82/** Remove device button callbacks */
83ui_pbutton_cb_t dcfg_remove_device_button_cb = {
84 .clicked = dcfg_remove_device_clicked
85};
86
87static void add_seat_dialog_bok(ui_prompt_dialog_t *, void *, const char *);
88static void add_seat_dialog_bcancel(ui_prompt_dialog_t *, void *);
89static void add_seat_dialog_close(ui_prompt_dialog_t *, void *);
90
91/** Add seat dialog callbacks */
92ui_prompt_dialog_cb_t add_seat_dialog_cb = {
93 .bok = add_seat_dialog_bok,
94 .bcancel = add_seat_dialog_bcancel,
95 .close = add_seat_dialog_close
96};
97
98static void add_device_dialog_bok(ui_select_dialog_t *, void *, void *);
99static void add_device_dialog_bcancel(ui_select_dialog_t *, void *);
100static void add_device_dialog_close(ui_select_dialog_t *, void *);
101
102/** Add device dialog callbacks */
103ui_select_dialog_cb_t add_device_dialog_cb = {
104 .bok = add_device_dialog_bok,
105 .bcancel = add_device_dialog_bcancel,
106 .close = add_device_dialog_close
107};
108
109/** Create seat configuration tab
110 *
111 * @param dcfg Display configuration dialog
112 * @param rseats Place to store pointer to new seat configuration tab
113 * @return EOK on success or an error code
114 */
115errno_t dcfg_seats_create(display_cfg_t *dcfg, dcfg_seats_t **rseats)
116{
117 ui_resource_t *ui_res;
118 dcfg_seats_t *seats;
119 gfx_rect_t rect;
120 errno_t rc;
121
122 ui_res = ui_window_get_res(dcfg->window);
123
124 seats = calloc(1, sizeof(dcfg_seats_t));
125 if (dcfg == NULL) {
126 printf("Out of memory.\n");
127 return ENOMEM;
128 }
129
130 seats->dcfg = dcfg;
131
132 /* 'Seats' tab */
133
134 rc = ui_tab_create(dcfg->tabset, "Seats", &seats->tab);
135 if (rc != EOK)
136 goto error;
137
138 rc = ui_fixed_create(&seats->fixed);
139 if (rc != EOK) {
140 printf("Error creating fixed layout.\n");
141 goto error;
142 }
143
144 /* 'Configured seats:' label */
145
146 rc = ui_label_create(ui_res, "Configured seats:", &seats->seats_label);
147 if (rc != EOK) {
148 printf("Error creating label.\n");
149 goto error;
150 }
151
152 if (ui_resource_is_textmode(ui_res)) {
153 rect.p0.x = 4;
154 rect.p0.y = 4;
155 rect.p1.x = 36;
156 rect.p1.y = 5;
157 } else {
158 rect.p0.x = 20;
159 rect.p0.y = 60;
160 rect.p1.x = 360;
161 rect.p1.y = 80;
162 }
163
164 ui_label_set_rect(seats->seats_label, &rect);
165
166 rc = ui_fixed_add(seats->fixed, ui_label_ctl(seats->seats_label));
167 if (rc != EOK) {
168 printf("Error adding control to layout.\n");
169 goto error;
170 }
171
172 /* List of seats */
173
174 rc = ui_list_create(dcfg->window, false, &seats->seat_list);
175 if (rc != EOK) {
176 printf("Error creating list.\n");
177 goto error;
178 }
179
180 if (ui_resource_is_textmode(ui_res)) {
181 rect.p0.x = 4;
182 rect.p0.y = 5;
183 rect.p1.x = 56;
184 rect.p1.y = 10;
185 } else {
186 rect.p0.x = 20;
187 rect.p0.y = 80;
188 rect.p1.x = 360;
189 rect.p1.y = 180;
190 }
191
192 ui_list_set_rect(seats->seat_list, &rect);
193
194 rc = ui_fixed_add(seats->fixed, ui_list_ctl(seats->seat_list));
195 if (rc != EOK) {
196 printf("Error adding control to layout.\n");
197 goto error;
198 }
199
200 ui_list_set_cb(seats->seat_list, &dcfg_seats_list_cb, (void *)seats);
201
202 /* 'Add...' seat button */
203
204 rc = ui_pbutton_create(ui_res, "Add...", &seats->add_seat);
205 if (rc != EOK) {
206 printf("Error creating button.\n");
207 goto error;
208 }
209
210 if (ui_resource_is_textmode(ui_res)) {
211 rect.p0.x = 58;
212 rect.p0.y = 5;
213 rect.p1.x = 68;
214 rect.p1.y = 6;
215 } else {
216 rect.p0.x = 370;
217 rect.p0.y = 80;
218 rect.p1.x = 450;
219 rect.p1.y = 105;
220 }
221
222 ui_pbutton_set_rect(seats->add_seat, &rect);
223
224 rc = ui_fixed_add(seats->fixed, ui_pbutton_ctl(seats->add_seat));
225 if (rc != EOK) {
226 printf("Error adding control to layout.\n");
227 goto error;
228 }
229
230 ui_pbutton_set_cb(seats->add_seat, &dcfg_add_seat_button_cb,
231 (void *)seats);
232
233 /* 'Remove' seat button */
234
235 rc = ui_pbutton_create(ui_res, "Remove", &seats->remove_seat);
236 if (rc != EOK) {
237 printf("Error creating button.\n");
238 goto error;
239 }
240
241 if (ui_resource_is_textmode(ui_res)) {
242 rect.p0.x = 58;
243 rect.p0.y = 7;
244 rect.p1.x = 68;
245 rect.p1.y = 8;
246 } else {
247 rect.p0.x = 370;
248 rect.p0.y = 110;
249 rect.p1.x = 450;
250 rect.p1.y = 135;
251 }
252
253 ui_pbutton_set_rect(seats->remove_seat, &rect);
254
255 rc = ui_fixed_add(seats->fixed, ui_pbutton_ctl(seats->remove_seat));
256 if (rc != EOK) {
257 printf("Error adding control to layout.\n");
258 goto error;
259 }
260
261 ui_pbutton_set_cb(seats->remove_seat, &dcfg_remove_seat_button_cb,
262 (void *)seats);
263
264 /* 'Devices assigned to seat 'xxx':' label */
265
266 rc = ui_label_create(ui_res, "Devices assigned to seat 'xxx':",
267 &seats->devices_label);
268 if (rc != EOK) {
269 printf("Error creating label.\n");
270 goto error;
271 }
272
273 if (ui_resource_is_textmode(ui_res)) {
274 rect.p0.x = 4;
275 rect.p0.y = 11;
276 rect.p1.x = 36;
277 rect.p1.y = 12;
278 } else {
279 rect.p0.x = 20;
280 rect.p0.y = 200;
281 rect.p1.x = 360;
282 rect.p1.y = 220;
283 }
284
285 ui_label_set_rect(seats->devices_label, &rect);
286
287 rc = ui_fixed_add(seats->fixed, ui_label_ctl(seats->devices_label));
288 if (rc != EOK) {
289 printf("Error adding control to layout.\n");
290 goto error;
291 }
292
293 /* List of devices */
294
295 rc = ui_list_create(dcfg->window, false, &seats->device_list);
296 if (rc != EOK) {
297 printf("Error creating list.\n");
298 goto error;
299 }
300
301 if (ui_resource_is_textmode(ui_res)) {
302 rect.p0.x = 4;
303 rect.p0.y = 12;
304 rect.p1.x = 56;
305 rect.p1.y = 17;
306 } else {
307 rect.p0.x = 20;
308 rect.p0.y = 220;
309 rect.p1.x = 360;
310 rect.p1.y = 320;
311 }
312
313 ui_list_set_rect(seats->device_list, &rect);
314
315 rc = ui_fixed_add(seats->fixed, ui_list_ctl(seats->device_list));
316 if (rc != EOK) {
317 printf("Error adding control to layout.\n");
318 goto error;
319 }
320
321 /* 'Add...' device button */
322
323 rc = ui_pbutton_create(ui_res, "Add...", &seats->add_device);
324 if (rc != EOK) {
325 printf("Error creating button.\n");
326 goto error;
327 }
328
329 if (ui_resource_is_textmode(ui_res)) {
330 rect.p0.x = 58;
331 rect.p0.y = 12;
332 rect.p1.x = 68;
333 rect.p1.y = 13;
334 } else {
335 rect.p0.x = 370;
336 rect.p0.y = 220;
337 rect.p1.x = 450;
338 rect.p1.y = 245;
339 }
340
341 ui_pbutton_set_rect(seats->add_device, &rect);
342
343 rc = ui_fixed_add(seats->fixed, ui_pbutton_ctl(seats->add_device));
344 if (rc != EOK) {
345 printf("Error adding control to layout.\n");
346 goto error;
347 }
348
349 ui_pbutton_set_cb(seats->add_device, &dcfg_add_device_button_cb,
350 (void *)seats);
351
352 /* 'Remove' device button */
353
354 rc = ui_pbutton_create(ui_res, "Remove", &seats->remove_device);
355 if (rc != EOK) {
356 printf("Error creating button.\n");
357 goto error;
358 }
359
360 if (ui_resource_is_textmode(ui_res)) {
361 rect.p0.x = 58;
362 rect.p0.y = 14;
363 rect.p1.x = 68;
364 rect.p1.y = 15;
365 } else {
366 rect.p0.x = 370;
367 rect.p0.y = 250;
368 rect.p1.x = 450;
369 rect.p1.y = 275;
370 }
371
372 ui_pbutton_set_rect(seats->remove_device, &rect);
373
374 rc = ui_fixed_add(seats->fixed, ui_pbutton_ctl(seats->remove_device));
375 if (rc != EOK) {
376 printf("Error adding control to layout.\n");
377 goto error;
378 }
379
380 ui_pbutton_set_cb(seats->remove_device, &dcfg_remove_device_button_cb,
381 (void *)seats);
382
383 ui_tab_add(seats->tab, ui_fixed_ctl(seats->fixed));
384
385 *rseats = seats;
386 return EOK;
387error:
388 if (seats->remove_device != NULL)
389 ui_pbutton_destroy(seats->remove_device);
390 if (seats->add_device != NULL)
391 ui_pbutton_destroy(seats->add_device);
392 if (seats->devices_label != NULL)
393 ui_label_destroy(seats->devices_label);
394 if (seats->device_list != NULL)
395 ui_list_destroy(seats->device_list);
396 if (seats->remove_seat != NULL)
397 ui_pbutton_destroy(seats->remove_seat);
398 if (seats->add_seat != NULL)
399 ui_pbutton_destroy(seats->add_seat);
400 if (seats->seats_label != NULL)
401 ui_label_destroy(seats->seats_label);
402 if (seats->seat_list != NULL)
403 ui_list_destroy(seats->seat_list);
404 if (seats->fixed != NULL)
405 ui_fixed_destroy(seats->fixed);
406 free(dcfg);
407 return rc;
408}
409
410/** Populate seats tab with display configuration service data
411 *
412 * @param dcfg Display configuration dialog
413 * @param rseats Place to store pointer to new seat configuration tab
414 * @return EOK on success or an error code
415 */
416errno_t dcfg_seats_populate(dcfg_seats_t *seats)
417{
418 dcfg_seats_entry_t *entry;
419 errno_t rc;
420
421 rc = dcfg_seats_list_populate(seats);
422 if (rc != EOK)
423 return rc;
424
425 /*
426 * Update "Devices assigned to seat 'xxx'" label and populate
427 * assigned devices list.
428 */
429 entry = dcfg_seats_get_selected(seats);
430 dcfg_seats_list_selected(entry->lentry, (void *)entry);
431 return EOK;
432}
433
434/** Destroy display configuration dialog.
435 *
436 * @param dcfg Display configuration dialog
437 */
438void dcfg_seats_destroy(dcfg_seats_t *seats)
439{
440 ui_list_entry_t *lentry;
441 dcfg_seats_entry_t *entry;
442 dcfg_devices_entry_t *dentry;
443
444 lentry = ui_list_first(seats->device_list);
445 while (lentry != NULL) {
446 dentry = (dcfg_devices_entry_t *)ui_list_entry_get_arg(lentry);
447 free(dentry->name);
448 free(dentry);
449 ui_list_entry_delete(lentry);
450 lentry = ui_list_first(seats->device_list);
451 }
452
453 lentry = ui_list_first(seats->seat_list);
454 while (lentry != NULL) {
455 entry = (dcfg_seats_entry_t *)ui_list_entry_get_arg(lentry);
456 free(entry->name);
457 free(entry);
458 ui_list_entry_delete(lentry);
459 lentry = ui_list_first(seats->seat_list);
460 }
461
462 /* This will automatically destroy all controls in the tab */
463 ui_tab_destroy(seats->tab);
464 free(seats);
465}
466
467/** Insert new entry into seats list.
468 *
469 * @param seats Seat configuration tab
470 * @param name Seat name
471 * @param seat_id Seat ID
472 * @param rentry Place to store pointer to new entry or NULL
473 * @return EOK on success or an error code
474 */
475errno_t dcfg_seats_insert(dcfg_seats_t *seats, const char *name,
476 sysarg_t seat_id, dcfg_seats_entry_t **rentry)
477{
478 dcfg_seats_entry_t *entry;
479 ui_list_entry_attr_t attr;
480 errno_t rc;
481
482 entry = calloc(1, sizeof(dcfg_seats_entry_t));
483 if (entry == NULL)
484 return ENOMEM;
485
486 entry->seats = seats;
487 entry->seat_id = seat_id;
488 entry->name = str_dup(name);
489 if (entry->name == NULL) {
490 free(entry);
491 return ENOMEM;
492 }
493
494 ui_list_entry_attr_init(&attr);
495 attr.caption = name;
496 attr.arg = (void *)entry;
497 rc = ui_list_entry_append(seats->seat_list, &attr, &entry->lentry);
498 if (rc != EOK) {
499 free(entry->name);
500 free(entry);
501 return rc;
502 }
503
504 if (rentry != NULL)
505 *rentry = entry;
506 return EOK;
507}
508
509/** Populate seat list.
510 *
511 * @param seats Seat configuration tab
512 * @return EOK on success or an error code
513 */
514errno_t dcfg_seats_list_populate(dcfg_seats_t *seats)
515{
516 size_t i;
517 dispcfg_seat_list_t *seat_list = NULL;
518 dispcfg_seat_info_t *sinfo = NULL;
519 errno_t rc;
520
521 rc = dispcfg_get_seat_list(seats->dcfg->dispcfg, &seat_list);
522 if (rc != EOK)
523 goto error;
524
525 for (i = 0; i < seat_list->nseats; i++) {
526 rc = dispcfg_get_seat_info(seats->dcfg->dispcfg,
527 seat_list->seats[i], &sinfo);
528 if (rc != EOK)
529 goto error;
530
531 rc = dcfg_seats_insert(seats, sinfo->name, seat_list->seats[i],
532 NULL);
533 if (rc != EOK)
534 goto error;
535
536 dispcfg_free_seat_info(sinfo);
537 sinfo = NULL;
538 }
539
540 dispcfg_free_seat_list(seat_list);
541 return EOK;
542error:
543 if (sinfo != NULL)
544 dispcfg_free_seat_info(sinfo);
545 if (seat_list != NULL)
546 dispcfg_free_seat_list(seat_list);
547 return rc;
548}
549
550/** Insert new entry into devices list.
551 *
552 * @param seats Seat configuration tab
553 * @param name Device name
554 * @param svc_id Service ID
555 * @return EOK on success or an error code
556 */
557errno_t dcfg_devices_insert(dcfg_seats_t *seats, const char *name,
558 service_id_t svc_id)
559{
560 dcfg_devices_entry_t *entry;
561 ui_list_entry_attr_t attr;
562 errno_t rc;
563
564 entry = calloc(1, sizeof(dcfg_devices_entry_t));
565 if (entry == NULL)
566 return ENOMEM;
567
568 entry->seats = seats;
569 entry->svc_id = svc_id;
570 entry->name = str_dup(name);
571 if (entry->name == NULL) {
572 free(entry);
573 return ENOMEM;
574 }
575
576 ui_list_entry_attr_init(&attr);
577 attr.caption = name;
578 attr.arg = (void *)entry;
579 rc = ui_list_entry_append(seats->device_list, &attr, &entry->lentry);
580 if (rc != EOK) {
581 free(entry->name);
582 free(entry);
583 return rc;
584 }
585
586 return EOK;
587}
588
589/** Insert new entry into available devices list.
590 *
591 * @param seats Seat configuration tab
592 * @param dialog 'Add Device' dialog
593 * @param name Device name
594 * @param svc_id Service ID
595 * @return EOK on success or an error code
596 */
597errno_t dcfg_avail_devices_insert(dcfg_seats_t *seats,
598 ui_select_dialog_t *dialog, const char *name, service_id_t svc_id)
599{
600 dcfg_devices_entry_t *entry;
601 ui_list_entry_attr_t attr;
602 errno_t rc;
603
604 entry = calloc(1, sizeof(dcfg_devices_entry_t));
605 if (entry == NULL)
606 return ENOMEM;
607
608 entry->seats = seats;
609 entry->svc_id = svc_id;
610 entry->name = str_dup(name);
611 if (entry->name == NULL) {
612 free(entry);
613 return ENOMEM;
614 }
615
616 ui_list_entry_attr_init(&attr);
617 attr.caption = name;
618 attr.arg = (void *)entry;
619 rc = ui_select_dialog_append(dialog, &attr);
620 if (rc != EOK) {
621 free(entry->name);
622 free(entry);
623 return rc;
624 }
625
626 return EOK;
627}
628
629/** Populate assigned device list.
630 *
631 * @param seats Seat configuration tab
632 * @return EOK on success or an error code
633 */
634static errno_t dcfg_seats_asgn_dev_list_populate(dcfg_seats_t *seats)
635{
636 size_t i;
637 dispcfg_dev_list_t *dev_list = NULL;
638 char *svc_name = NULL;
639 dcfg_seats_entry_t *seats_entry;
640 sysarg_t seat_id;
641 errno_t rc;
642
643 /* Get active seat entry */
644 seats_entry = dcfg_seats_get_selected(seats);
645 seat_id = seats_entry->seat_id;
646
647 rc = dispcfg_get_asgn_dev_list(seats->dcfg->dispcfg, seat_id, &dev_list);
648 if (rc != EOK)
649 goto error;
650
651 for (i = 0; i < dev_list->ndevs; i++) {
652 rc = loc_service_get_name(dev_list->devs[i], &svc_name);
653 if (rc != EOK)
654 goto error;
655
656 rc = dcfg_devices_insert(seats, svc_name, dev_list->devs[i]);
657 if (rc != EOK)
658 goto error;
659
660 free(svc_name);
661 svc_name = NULL;
662 }
663
664 dispcfg_free_dev_list(dev_list);
665 return EOK;
666error:
667 if (svc_name != NULL)
668 free(svc_name);
669 if (dev_list != NULL)
670 dispcfg_free_dev_list(dev_list);
671 return rc;
672}
673
674/** Populate available device list in 'Add Device' dialog.
675 *
676 * @param seats Seat configuration tab
677 * @param dialog 'Add Device' dialog
678 * @return EOK on success or an error code
679 */
680static errno_t dcfg_seats_avail_dev_list_populate(dcfg_seats_t *seats,
681 ui_select_dialog_t *dialog)
682{
683 size_t i, j, k;
684 category_id_t cat_id;
685 service_id_t *kbd_svcs = NULL;
686 size_t nkbd_svcs;
687 service_id_t *mouse_svcs = NULL;
688 size_t nmouse_svcs;
689 dispcfg_seat_list_t *seat_list = NULL;
690 dispcfg_dev_list_t *adev_list;
691 char *svc_name = NULL;
692 errno_t rc;
693
694 /* Get list of keyboard devices */
695
696 rc = loc_category_get_id("keyboard", &cat_id, 0);
697 if (rc != EOK) {
698 printf("Error getting category ID.\n");
699 goto error;
700 }
701
702 rc = loc_category_get_svcs(cat_id, &kbd_svcs, &nkbd_svcs);
703 if (rc != EOK) {
704 printf("Error getting service list.\n");
705 goto error;
706 }
707
708 /* Get list of mouse devices */
709
710 rc = loc_category_get_id("mouse", &cat_id, 0);
711 if (rc != EOK) {
712 printf("Error getting category ID.\n");
713 goto error;
714 }
715
716 rc = loc_category_get_svcs(cat_id, &mouse_svcs, &nmouse_svcs);
717 if (rc != EOK) {
718 printf("Error getting service list.\n");
719 goto error;
720 }
721
722 /* Filter out assigned devices */
723 rc = dispcfg_get_seat_list(seats->dcfg->dispcfg, &seat_list);
724 if (rc != EOK) {
725 printf("Error getting seat list.\n");
726 goto error;
727 }
728
729 for (i = 0; i < seat_list->nseats; i++) {
730 rc = dispcfg_get_asgn_dev_list(seats->dcfg->dispcfg,
731 seat_list->seats[i], &adev_list);
732 if (rc != EOK) {
733 printf("Error getting device list.\n");
734 goto error;
735 }
736
737 for (j = 0; j < adev_list->ndevs; j++) {
738 /* Filter out assigned keyboard devices */
739 for (k = 0; k < nkbd_svcs; k++) {
740 if (kbd_svcs[k] == adev_list->devs[j])
741 kbd_svcs[k] = 0;
742 }
743
744 /* Filter out assigned mouse devices */
745 for (k = 0; k < nmouse_svcs; k++) {
746 if (mouse_svcs[k] == adev_list->devs[j])
747 mouse_svcs[k] = 0;
748 }
749 }
750
751 dispcfg_free_dev_list(adev_list);
752 }
753
754 dispcfg_free_seat_list(seat_list);
755 seat_list = NULL;
756
757 /* Add keyboard devices */
758
759 for (i = 0; i < nkbd_svcs; i++) {
760 if (kbd_svcs[i] == 0)
761 continue;
762
763 rc = loc_service_get_name(kbd_svcs[i], &svc_name);
764 if (rc != EOK)
765 goto error;
766
767 rc = dcfg_avail_devices_insert(seats, dialog, svc_name,
768 kbd_svcs[i]);
769 if (rc != EOK)
770 goto error;
771
772 free(svc_name);
773 svc_name = NULL;
774 }
775
776 /* Add mouse devices */
777
778 for (i = 0; i < nmouse_svcs; i++) {
779 if (mouse_svcs[i] == 0)
780 continue;
781
782 rc = loc_service_get_name(mouse_svcs[i], &svc_name);
783 if (rc != EOK)
784 goto error;
785
786 rc = dcfg_avail_devices_insert(seats, dialog, svc_name,
787 mouse_svcs[i]);
788 if (rc != EOK)
789 goto error;
790
791 free(svc_name);
792 svc_name = NULL;
793 }
794
795 free(kbd_svcs);
796 free(mouse_svcs);
797 return EOK;
798error:
799 if (svc_name != NULL)
800 free(svc_name);
801 if (seat_list != NULL)
802 dispcfg_free_seat_list(seat_list);
803 if (kbd_svcs != NULL)
804 free(kbd_svcs);
805 if (mouse_svcs != NULL)
806 free(mouse_svcs);
807 return rc;
808}
809
810/** Get selected seat entry.
811 *
812 * @param seats Seat configuration tab
813 * @return Selected entry
814 */
815static dcfg_seats_entry_t *dcfg_seats_get_selected(dcfg_seats_t *seats)
816{
817 ui_list_entry_t *lentry;
818
819 lentry = ui_list_get_cursor(seats->seat_list);
820 return (dcfg_seats_entry_t *)ui_list_entry_get_arg(lentry);
821}
822
823/** Get selected device entry.
824 *
825 * @param seats Seat configuration tab
826 * @return Selected entry
827 */
828static dcfg_devices_entry_t *dcfg_devices_get_selected(dcfg_seats_t *seats)
829{
830 ui_list_entry_t *lentry;
831
832 lentry = ui_list_get_cursor(seats->device_list);
833 return (dcfg_devices_entry_t *)ui_list_entry_get_arg(lentry);
834}
835
836/** Entry in seats list is selected.
837 *
838 * @param lentry UI list entry
839 * @param arg Argument (dcfg_seats_entry_t *)
840 */
841static void dcfg_seats_list_selected(ui_list_entry_t *lentry, void *arg)
842{
843 dcfg_seats_entry_t *entry = (dcfg_seats_entry_t *)arg;
844 dcfg_devices_entry_t *dentry;
845 ui_list_entry_t *le;
846 char *caption;
847 errno_t rc;
848 int rv;
849
850 (void) lentry;
851
852 /* Update 'Devices assigned to seat 'xxx':' label */
853
854 rv = asprintf(&caption, "Devices assigned to seat '%s':", entry->name);
855 if (rv < 0) {
856 printf("Out of memory.\n");
857 return;
858 }
859
860 rc = ui_label_set_text(entry->seats->devices_label, caption);
861 if (rc != EOK) {
862 printf("Error setting label.\n");
863 return;
864 }
865
866 free(caption);
867
868 (void) ui_control_paint(ui_label_ctl(entry->seats->devices_label));
869
870 /* Clear device list */
871 le = ui_list_first(entry->seats->device_list);
872 while (le != NULL) {
873 dentry = (dcfg_devices_entry_t *)ui_list_entry_get_arg(le);
874 free(dentry->name);
875 free(dentry);
876 ui_list_entry_delete(le);
877 le = ui_list_first(entry->seats->device_list);
878 }
879
880 /* Re-populate it */
881 (void) dcfg_seats_asgn_dev_list_populate(entry->seats);
882 (void) ui_control_paint(ui_list_ctl(entry->seats->device_list));
883}
884
885/** "Add' seat button clicked.
886 *
887 * @param pbutton Push button
888 * @param arg Argument (dcfg_seats_entry_t *)
889 */
890static void dcfg_add_seat_clicked(ui_pbutton_t *pbutton, void *arg)
891{
892 dcfg_seats_t *seats = (dcfg_seats_t *)arg;
893 ui_prompt_dialog_params_t pdparams;
894 errno_t rc;
895
896 ui_prompt_dialog_params_init(&pdparams);
897 pdparams.caption = "Add Seat";
898 pdparams.prompt = "New Seat Name";
899
900 rc = ui_prompt_dialog_create(seats->dcfg->ui, &pdparams,
901 &seats->add_seat_dlg);
902 if (rc != EOK)
903 printf("Error creating dialog.\n");
904
905 ui_prompt_dialog_set_cb(seats->add_seat_dlg, &add_seat_dialog_cb,
906 (void *)seats);
907}
908
909/** "Remove' seat button clicked.
910 *
911 * @param pbutton Push button
912 * @param arg Argument (dcfg_seats_entry_t *)
913 */
914static void dcfg_remove_seat_clicked(ui_pbutton_t *pbutton, void *arg)
915{
916 dcfg_seats_t *seats = (dcfg_seats_t *)arg;
917 dcfg_seats_entry_t *entry;
918 errno_t rc;
919
920 (void)pbutton;
921 entry = dcfg_seats_get_selected(seats);
922
923 rc = dispcfg_seat_delete(seats->dcfg->dispcfg, entry->seat_id);
924 if (rc != EOK) {
925 /*
926 * EBUSY is returned when we attempt to delete the last
927 * seat. No need to complain about it.
928 */
929 if (rc == EBUSY)
930 return;
931
932 printf("Error removing seat '%s'.\n", entry->name);
933 return;
934 }
935
936 ui_list_entry_delete(entry->lentry);
937 free(entry->name);
938 free(entry);
939
940 (void) ui_control_paint(ui_list_ctl(seats->seat_list));
941
942 /* Since selected seat changed we need to update device list */
943 entry = dcfg_seats_get_selected(seats);
944 dcfg_seats_list_selected(entry->lentry, (void *)entry);
945}
946
947/** Add seat dialog OK button was pressed.
948 *
949 * @param dialog Add seat dialog
950 * @param arg Argument (dcfg_seats_t *)
951 * @param text Submitted text
952 */
953void add_seat_dialog_bok(ui_prompt_dialog_t *dialog, void *arg,
954 const char *text)
955{
956 dcfg_seats_t *seats = (dcfg_seats_t *)arg;
957 sysarg_t seat_id;
958 dcfg_seats_entry_t *entry;
959 errno_t rc;
960
961 seats->add_seat_dlg = NULL;
962 ui_prompt_dialog_destroy(dialog);
963
964 rc = dispcfg_seat_create(seats->dcfg->dispcfg, text, &seat_id);
965 if (rc != EOK) {
966 printf("Error creating seat '%s'.\n", text);
967 return;
968 }
969
970 rc = dcfg_seats_insert(seats, text, seat_id, &entry);
971 if (rc != EOK)
972 return;
973
974 (void) ui_control_paint(ui_list_ctl(seats->seat_list));
975
976 /* Select new seat and update device list */
977 ui_list_set_cursor(seats->seat_list, entry->lentry);
978 dcfg_seats_list_selected(entry->lentry, (void *)entry);
979}
980
981/** Add seat dialog Cancel button was pressed.
982 *
983 * @param dialog Add seat dialog
984 * @param arg Argument (dcfg_seats_t *)
985 */
986void add_seat_dialog_bcancel(ui_prompt_dialog_t *dialog, void *arg)
987{
988 dcfg_seats_t *seats = (dcfg_seats_t *)arg;
989
990 seats->add_seat_dlg = NULL;
991 ui_prompt_dialog_destroy(dialog);
992}
993
994/** Add seat dialog close request.
995 *
996 * @param dialog Add seat dialog
997 * @param arg Argument (dcfg_seats_t *)
998 */
999void add_seat_dialog_close(ui_prompt_dialog_t *dialog, void *arg)
1000{
1001 dcfg_seats_t *seats = (dcfg_seats_t *)arg;
1002
1003 seats->add_seat_dlg = NULL;
1004 ui_prompt_dialog_destroy(dialog);
1005}
1006
1007/** "Add' device button clicked.
1008 *
1009 * @param pbutton Push button
1010 * @param arg Argument (dcfg_seats_entry_t *)
1011 */
1012static void dcfg_add_device_clicked(ui_pbutton_t *pbutton, void *arg)
1013{
1014 dcfg_seats_t *seats = (dcfg_seats_t *)arg;
1015 ui_select_dialog_params_t sdparams;
1016 errno_t rc;
1017
1018 ui_select_dialog_params_init(&sdparams);
1019 sdparams.caption = "Add Device";
1020 sdparams.prompt = "Device Name";
1021
1022 rc = ui_select_dialog_create(seats->dcfg->ui, &sdparams,
1023 &seats->add_device_dlg);
1024 if (rc != EOK)
1025 printf("Error creating dialog.\n");
1026
1027 ui_select_dialog_set_cb(seats->add_device_dlg, &add_device_dialog_cb,
1028 (void *)seats);
1029
1030 (void) dcfg_seats_avail_dev_list_populate(seats,
1031 seats->add_device_dlg);
1032 ui_select_dialog_paint(seats->add_device_dlg);
1033}
1034
1035/** "Remove' device button clicked.
1036 *
1037 * @param pbutton Push button
1038 * @param arg Argument (dcfg_seats_entry_t *)
1039 */
1040static void dcfg_remove_device_clicked(ui_pbutton_t *pbutton, void *arg)
1041{
1042 dcfg_seats_t *seats = (dcfg_seats_t *)arg;
1043 dcfg_devices_entry_t *entry;
1044 errno_t rc;
1045
1046 (void)pbutton;
1047 entry = dcfg_devices_get_selected(seats);
1048
1049 rc = dispcfg_dev_unassign(seats->dcfg->dispcfg, entry->svc_id);
1050 if (rc != EOK) {
1051 printf("Error removing device '%s'.\n", entry->name);
1052 return;
1053 }
1054
1055 ui_list_entry_delete(entry->lentry);
1056 free(entry->name);
1057 free(entry);
1058
1059 (void) ui_control_paint(ui_list_ctl(seats->device_list));
1060}
1061
1062/** Add device dialog OK button was pressed.
1063 *
1064 * @param dialog Add device dialog
1065 * @param arg Argument (dcfg_seats_t *)
1066 * @param text Submitted text
1067 */
1068void add_device_dialog_bok(ui_select_dialog_t *dialog, void *arg,
1069 void *earg)
1070{
1071 dcfg_seats_t *seats = (dcfg_seats_t *)arg;
1072 dcfg_devices_entry_t *entry;
1073 dcfg_seats_entry_t *seat;
1074 errno_t rc;
1075
1076 seat = dcfg_seats_get_selected(seats);
1077 entry = (dcfg_devices_entry_t *)earg;
1078
1079 seats->add_device_dlg = NULL;
1080 ui_select_dialog_destroy(dialog);
1081
1082 rc = dispcfg_dev_assign(seats->dcfg->dispcfg, entry->svc_id,
1083 seat->seat_id);
1084 if (rc != EOK) {
1085 printf("Error assigning device '%s' seat '%s'.\n",
1086 entry->name, seat->name);
1087 return;
1088 }
1089
1090 rc = dcfg_devices_insert(seats, entry->name, entry->svc_id);
1091 if (rc != EOK) {
1092 printf("Error inserting device to list.\n");
1093 return;
1094 }
1095
1096 (void) ui_control_paint(ui_list_ctl(seats->device_list));
1097}
1098
1099/** Add device dialog Cancel button was pressed.
1100 *
1101 * @param dialog Add device dialog
1102 * @param arg Argument (dcfg_seats_t *)
1103 */
1104void add_device_dialog_bcancel(ui_select_dialog_t *dialog, void *arg)
1105{
1106 dcfg_seats_t *seats = (dcfg_seats_t *)arg;
1107
1108 seats->add_device_dlg = NULL;
1109 ui_select_dialog_destroy(dialog);
1110}
1111
1112/** Add device dialog close request.
1113 *
1114 * @param dialog Add device dialog
1115 * @param arg Argument (dcfg_seats_t *)
1116 */
1117void add_device_dialog_close(ui_select_dialog_t *dialog, void *arg)
1118{
1119 dcfg_seats_t *seats = (dcfg_seats_t *)arg;
1120
1121 seats->add_device_dlg = NULL;
1122 ui_select_dialog_destroy(dialog);
1123}
1124
1125/** @}
1126 */
Note: See TracBrowser for help on using the repository browser.