source: mainline/uspace/lib/ui/src/clickmatic.c@ 7cc30e9

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7cc30e9 was 8965860c, checked in by Jiri Svoboda <jiri@…>, 3 years ago

Clickmatic

A class that periodically generates when held, after initial delay.
This is quite similar to the typematic feature found in PC keyboards.
We use it to automatically scroll when scrollbar button or through
is held.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 * Copyright (c) 2022 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 libui
30 * @{
31 */
32/**
33 * @file Clickmatic.
34 *
35 * Clickmatic is used to periodically generate events in particular cases
36 * when a mouse button is held down, such as when holding the button or
37 * through of a scrollbar.
38 */
39
40#include <fibril_synch.h>
41#include <stdlib.h>
42#include <ui/clickmatic.h>
43#include <ui/ui.h>
44#include "../private/clickmatic.h"
45
46enum {
47 /** Initial clickmatic delay in MS */
48 clickmatic_delay_ms = 500,
49 /** Clickmatic repeat rate in clicks per second */
50 clickmatic_rate = 10
51};
52
53static void ui_clickmatic_timer_fun(void *);
54
55/** Create clickmatic.
56 *
57 * @param ui UI
58 * @param rclickmatic Place to store pointer to new clickmatic
59 * @return EOK on success or an error code
60 */
61errno_t ui_clickmatic_create(ui_t *ui, ui_clickmatic_t **rclickmatic)
62{
63 ui_clickmatic_t *clickmatic;
64
65 clickmatic = calloc(1, sizeof(ui_clickmatic_t));
66 if (clickmatic == NULL)
67 return ENOMEM;
68
69 clickmatic->ui = ui;
70 clickmatic->timer = fibril_timer_create(NULL);
71 if (clickmatic->timer == NULL) {
72 free(clickmatic);
73 return ENOMEM;
74 }
75
76 *rclickmatic = clickmatic;
77 return EOK;
78}
79
80/** Set clickmatick callbacks.
81 *
82 * @param clickmatic Clickmatic
83 * @param cb Callbacks
84 * @param arg Argument to callbacks
85 */
86void ui_clickmatic_set_cb(ui_clickmatic_t *clickmatic, ui_clickmatic_cb_t *cb,
87 void *arg)
88{
89 clickmatic->cb = cb;
90 clickmatic->arg = arg;
91}
92
93/** Destroy clickmatic.
94 *
95 * @param clickmatic Clickmatic or @c NULL
96 */
97void ui_clickmatic_destroy(ui_clickmatic_t *clickmatic)
98{
99 if (clickmatic == NULL)
100 return;
101
102 fibril_timer_destroy(clickmatic->timer);
103 free(clickmatic);
104}
105
106/** Activate clickmatic.
107 *
108 * This generates one click event, then starts repeating after delay.
109 *
110 * @param clickmatic Clickmatic
111 */
112void ui_clickmatic_press(ui_clickmatic_t *clickmatic)
113{
114 ui_clickmatic_clicked(clickmatic);
115
116 fibril_timer_set(clickmatic->timer, 1000 * clickmatic_delay_ms,
117 ui_clickmatic_timer_fun, (void *)clickmatic);
118}
119
120/** Deactivate clickmatic.
121 *
122 * Stops generating events.
123 *
124 * @param clickmatic Clickmatic
125 */
126void ui_clickmatic_release(ui_clickmatic_t *clickmatic)
127{
128 (void) fibril_timer_clear(clickmatic->timer);
129}
130
131/** Clickmatic clicked event.
132 *
133 * @param clickmatic Clickmatic
134 */
135void ui_clickmatic_clicked(ui_clickmatic_t *clickmatic)
136{
137 if (clickmatic->cb != NULL && clickmatic->cb->clicked != NULL)
138 clickmatic->cb->clicked(clickmatic, clickmatic->arg);
139}
140
141/** Clickmatic timer function.
142 *
143 * @param arg Argument (ui_clickmatic_t *)
144 */
145static void ui_clickmatic_timer_fun(void *arg)
146{
147 ui_clickmatic_t *clickmatic = (ui_clickmatic_t *)arg;
148
149 /*
150 * Because we are operating in a different fibril, we must lock
151 * the UI to ensure mutual exclusion with normal UI events
152 */
153
154 ui_lock(clickmatic->ui);
155 ui_clickmatic_clicked(clickmatic);
156 ui_unlock(clickmatic->ui);
157
158 fibril_timer_set(clickmatic->timer, 1000000 / clickmatic_rate,
159 ui_clickmatic_timer_fun, (void *)clickmatic);
160}
161
162/** @}
163 */
Note: See TracBrowser for help on using the repository browser.