source: mainline/uspace/lib/gui/connection.c@ e8d6ce2

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since e8d6ce2 was 6d5e378, checked in by Martin Decky <martin@…>, 13 years ago

cherrypick GUI implementation (originally by Petr Koupy), with several major changes

  • for character-oriented devices a new output server and output protocol was created based on the original fb server
  • DDF visualizer drivers are pixel-oriented only
  • console and compositor can coexist in the same build
  • terminal widget is self-sufficient, no strange console nesting is needed
  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 * Copyright (c) 2012 Petr Koupy
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 gui
30 * @{
31 */
32/**
33 * @file
34 */
35
36#include <mem.h>
37#include <malloc.h>
38#include <adt/list.h>
39#include <adt/prodcons.h>
40#include <fibril_synch.h>
41#include <io/window.h>
42
43#include "window.h"
44#include "widget.h"
45#include "connection.h"
46
47typedef struct {
48 link_t link;
49 widget_t *widget;
50 slot_t slot;
51} slot_node_t;
52
53typedef struct {
54 link_t link;
55 signal_t *signal;
56 list_t slots;
57} signal_node_t;
58
59static FIBRIL_RWLOCK_INITIALIZE(connection_guard);
60static LIST_INITIALIZE(connection_list);
61
62void sig_connect(signal_t *signal, widget_t *widget, slot_t slot)
63{
64 fibril_rwlock_write_lock(&connection_guard);
65
66 signal_node_t *sig_node = NULL;
67 list_foreach(connection_list, link) {
68 signal_node_t *cur = list_get_instance(link, signal_node_t, link);
69 if (cur->signal == signal) {
70 sig_node = cur;
71 break;
72 }
73 }
74
75 if (!sig_node) {
76 sig_node = (signal_node_t *) malloc(sizeof(signal_node_t));
77 if (!sig_node) {
78 fibril_rwlock_write_unlock(&connection_guard);
79 return;
80 }
81
82 sig_node->signal = signal;
83 link_initialize(&sig_node->link);
84 list_initialize(&sig_node->slots);
85
86 list_append(&sig_node->link, &connection_list);
87 }
88
89 slot_node_t *slt_node = NULL;
90 list_foreach(sig_node->slots, link) {
91 slot_node_t *cur = list_get_instance(link, slot_node_t, link);
92 if (cur->widget == widget && cur->slot == slot) {
93 slt_node = cur;
94 fibril_rwlock_write_unlock(&connection_guard);
95 break;
96 }
97 }
98
99 if (!slt_node) {
100 slt_node = (slot_node_t *) malloc(sizeof(slot_node_t));
101 if (!slt_node) {
102 fibril_rwlock_write_unlock(&connection_guard);
103 return;
104 }
105
106 slt_node->widget = widget;
107 slt_node->slot = slot;
108 link_initialize(&slt_node->link);
109
110 list_append(&slt_node->link, &sig_node->slots);
111 } else {
112 /* Already connected. */
113 }
114
115 fibril_rwlock_write_unlock(&connection_guard);
116}
117
118void sig_disconnect(signal_t *signal, widget_t *widget, slot_t slot)
119{
120 fibril_rwlock_write_lock(&connection_guard);
121
122 signal_node_t *sig_node = NULL;
123 list_foreach(connection_list, link) {
124 signal_node_t *cur = list_get_instance(link, signal_node_t, link);
125 if (cur->signal == signal) {
126 sig_node = cur;
127 break;
128 }
129 }
130
131 if (!sig_node) {
132 fibril_rwlock_write_unlock(&connection_guard);
133 return;
134 }
135
136 slot_node_t *slt_node = NULL;
137 list_foreach(sig_node->slots, link) {
138 slot_node_t *cur = list_get_instance(link, slot_node_t, link);
139 if (cur->widget == widget && cur->slot == slot) {
140 slt_node = cur;
141 break;
142 }
143 }
144
145 if (!slt_node) {
146 fibril_rwlock_write_unlock(&connection_guard);
147 return;
148 }
149
150 list_remove(&slt_node->link);
151 free(slt_node);
152
153 if (list_empty(&sig_node->slots)) {
154 list_remove(&sig_node->link);
155 free(sig_node);
156 }
157
158 fibril_rwlock_write_unlock(&connection_guard);
159}
160
161void sig_send(signal_t *signal, void *data)
162{
163 fibril_rwlock_read_lock(&connection_guard);
164
165 signal_node_t *sig_node = NULL;
166 list_foreach(connection_list, link) {
167 signal_node_t *cur = list_get_instance(link, signal_node_t, link);
168 if (cur->signal == signal) {
169 sig_node = cur;
170 break;
171 }
172 }
173
174 if (!sig_node) {
175 fibril_rwlock_read_unlock(&connection_guard);
176 return;
177 }
178
179 list_foreach(sig_node->slots, link) {
180 slot_node_t *cur = list_get_instance(link, slot_node_t, link);
181 cur->slot(cur->widget, data);
182 }
183
184 fibril_rwlock_read_unlock(&connection_guard);
185}
186
187void sig_post(signal_t *signal, void *data, size_t data_size)
188{
189 fibril_rwlock_read_lock(&connection_guard);
190
191 signal_node_t *sig_node = NULL;
192 list_foreach(connection_list, link) {
193 signal_node_t *cur = list_get_instance(link, signal_node_t, link);
194 if (cur->signal == signal) {
195 sig_node = cur;
196 break;
197 }
198 }
199
200 if (!sig_node) {
201 fibril_rwlock_read_unlock(&connection_guard);
202 return;
203 }
204
205 list_foreach(sig_node->slots, link) {
206 slot_node_t *cur = list_get_instance(link, slot_node_t, link);
207
208 void *data_copy = NULL;
209 if (data != NULL) {
210 data_copy = malloc(data_size);
211 }
212 if (data_copy != NULL) {
213 memcpy(data_copy, data, data_size);
214 }
215 window_event_t *event =
216 (window_event_t *) malloc(sizeof(window_event_t));
217
218 if (event) {
219 link_initialize(&event->link);
220 event->type = ET_SIGNAL_EVENT;
221 event->data.sig.object = (sysarg_t) cur->widget;
222 event->data.sig.slot = (sysarg_t) cur->slot;
223 event->data.sig.argument = (sysarg_t) data_copy;
224 prodcons_produce(&cur->widget->window->events, &event->link);
225 } else {
226 if (data_copy != NULL) {
227 free(data_copy);
228 }
229 }
230 }
231
232 fibril_rwlock_read_unlock(&connection_guard);
233}
234
235/** @}
236 */
Note: See TracBrowser for help on using the repository browser.