source: mainline/uspace/lib/gui/connection.c@ 38d150e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 38d150e was 38d150e, checked in by Jiri Svoboda <jiri@…>, 8 years ago

Prefer to get memory allocation functions through the standard stdlib header.

  • Property mode set to 100644
File size: 5.4 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 <stdlib.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, signal_node_t, cur) {
68 if (cur->signal == signal) {
69 sig_node = cur;
70 break;
71 }
72 }
73
74 if (!sig_node) {
75 sig_node = (signal_node_t *) malloc(sizeof(signal_node_t));
76 if (!sig_node) {
77 fibril_rwlock_write_unlock(&connection_guard);
78 return;
79 }
80
81 sig_node->signal = signal;
82 link_initialize(&sig_node->link);
83 list_initialize(&sig_node->slots);
84
85 list_append(&sig_node->link, &connection_list);
86 }
87
88 slot_node_t *slt_node = NULL;
89 list_foreach(sig_node->slots, link, slot_node_t, cur) {
90 if (cur->widget == widget && cur->slot == slot) {
91 slt_node = cur;
92 fibril_rwlock_write_unlock(&connection_guard);
93 break;
94 }
95 }
96
97 if (!slt_node) {
98 slt_node = (slot_node_t *) malloc(sizeof(slot_node_t));
99 if (!slt_node) {
100 fibril_rwlock_write_unlock(&connection_guard);
101 return;
102 }
103
104 slt_node->widget = widget;
105 slt_node->slot = slot;
106 link_initialize(&slt_node->link);
107
108 list_append(&slt_node->link, &sig_node->slots);
109 } else {
110 /* Already connected. */
111 }
112
113 fibril_rwlock_write_unlock(&connection_guard);
114}
115
116void sig_disconnect(signal_t *signal, widget_t *widget, slot_t slot)
117{
118 fibril_rwlock_write_lock(&connection_guard);
119
120 signal_node_t *sig_node = NULL;
121 list_foreach(connection_list, link, signal_node_t, cur) {
122 if (cur->signal == signal) {
123 sig_node = cur;
124 break;
125 }
126 }
127
128 if (!sig_node) {
129 fibril_rwlock_write_unlock(&connection_guard);
130 return;
131 }
132
133 slot_node_t *slt_node = NULL;
134 list_foreach(sig_node->slots, link, slot_node_t, cur) {
135 if (cur->widget == widget && cur->slot == slot) {
136 slt_node = cur;
137 break;
138 }
139 }
140
141 if (!slt_node) {
142 fibril_rwlock_write_unlock(&connection_guard);
143 return;
144 }
145
146 list_remove(&slt_node->link);
147 free(slt_node);
148
149 if (list_empty(&sig_node->slots)) {
150 list_remove(&sig_node->link);
151 free(sig_node);
152 }
153
154 fibril_rwlock_write_unlock(&connection_guard);
155}
156
157void sig_send(signal_t *signal, void *data)
158{
159 fibril_rwlock_read_lock(&connection_guard);
160
161 signal_node_t *sig_node = NULL;
162 list_foreach(connection_list, link, signal_node_t, cur) {
163 if (cur->signal == signal) {
164 sig_node = cur;
165 break;
166 }
167 }
168
169 if (!sig_node) {
170 fibril_rwlock_read_unlock(&connection_guard);
171 return;
172 }
173
174 list_foreach(sig_node->slots, link, slot_node_t, cur) {
175 cur->slot(cur->widget, data);
176 }
177
178 fibril_rwlock_read_unlock(&connection_guard);
179}
180
181void sig_post(signal_t *signal, void *data, size_t data_size)
182{
183 fibril_rwlock_read_lock(&connection_guard);
184
185 signal_node_t *sig_node = NULL;
186 list_foreach(connection_list, link, signal_node_t, cur) {
187 if (cur->signal == signal) {
188 sig_node = cur;
189 break;
190 }
191 }
192
193 if (!sig_node) {
194 fibril_rwlock_read_unlock(&connection_guard);
195 return;
196 }
197
198 list_foreach(sig_node->slots, link, slot_node_t, cur) {
199 void *data_copy = NULL;
200 if (data != NULL)
201 data_copy = malloc(data_size);
202
203 if (data_copy != NULL)
204 memcpy(data_copy, data, data_size);
205
206 window_event_t *event =
207 (window_event_t *) malloc(sizeof(window_event_t));
208
209 if (event) {
210 link_initialize(&event->link);
211 event->type = ET_SIGNAL_EVENT;
212 event->data.signal.object = (sysarg_t) cur->widget;
213 event->data.signal.slot = (sysarg_t) cur->slot;
214 event->data.signal.argument = (sysarg_t) data_copy;
215 prodcons_produce(&cur->widget->window->events, &event->link);
216 } else {
217 if (data_copy != NULL)
218 free(data_copy);
219 }
220 }
221
222 fibril_rwlock_read_unlock(&connection_guard);
223}
224
225/** @}
226 */
Note: See TracBrowser for help on using the repository browser.