-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathmce.h
617 lines (501 loc) · 18.9 KB
/
mce.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
/**
* @file mce.h
* Generic headers for Mode Control Entity
* <p>
* Copyright (c) 2004 - 2011 Nokia Corporation and/or its subsidiary(-ies).
* Copyright (c) 2012 - 2021 Jolla Ltd.
* Copyright (c) 2019 - 2020 Open Mobile Platform LLC.
* <p>
* @author David Weinehall <[email protected]>
* @author Irina Bezruk <[email protected]>
* @author Santtu Lakkala <[email protected]>
* @author Vesa Halttunen <[email protected]>
* @author Simo Piiroinen <[email protected]>
*
* mce is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*
* mce is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mce. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _MCE_H_
#define _MCE_H_
#include "musl-compatibility.h"
#include "datapipe.h"
/** Indicate enabled (sub)mode */
#define DISABLED_STRING "yes"
/** Indicate disabled (sub)mode */
#define ENABLED_STRING "no"
/* Names of LED patterns */
/** LED pattern used when powering on the device */
#define MCE_LED_PATTERN_POWER_ON "PatternPowerOn"
/** LED pattern used when powering off the device */
#define MCE_LED_PATTERN_POWER_OFF "PatternPowerOff"
/** LED pattern used when camera is active */
#define MCE_LED_PATTERN_CAMERA "PatternWebcamActive"
/** LED pattern used to indicate that the device is on when idle */
#define MCE_LED_PATTERN_DEVICE_ON "PatternDeviceOn"
/** LED pattern used when charging the battery */
#define MCE_LED_PATTERN_BATTERY_CHARGING "PatternBatteryCharging"
/** LED pattern used when the battery is full */
#define MCE_LED_PATTERN_BATTERY_FULL "PatternBatteryFull"
/** Binary LED pattern used by CSD that should always use sw breathing */
#define MCE_LED_PATTERN_CSD_BINARY_BLINK "PatternCsdLedBlink"
/** Rgb LED pattern used by CSD that should always use sw breathing */
#define MCE_LED_PATTERN_CSD_WHITE_BLINK "PatternCsdWhiteBlink"
/** LED pattern used when the battery is low */
#define MCE_LED_PATTERN_BATTERY_LOW "PatternBatteryLow"
/** LED pattern used when XXX */
#define MCE_LED_PATTERN_BATTERY_CHARGING_FLAT "PatternBatteryChargingFlat"
/** LED pattern used by messaging mw */
#define MCE_LED_PATTERN_COMMON_NOTIFICATION "PatternCommonNotification"
/** LED pattern used by messaging mw */
#define MCE_LED_PATTERN_COMMUNICATION_CALL "PatternCommunicationCall"
/** LED pattern used by messaging mw */
#define MCE_LED_PATTERN_COMMUNICATION_EMAIL "PatternCommunicationEmail"
/** LED pattern used by messaging mw */
#define MCE_LED_PATTERN_COMMUNICATION_IM "PatternCommunicationIM"
/** LED pattern used by messaging mw */
#define MCE_LED_PATTERN_COMMUNICATION_SMS "PatternCommunicationSMS"
/** LED pattern used by CSD application */
#define MCE_LED_PATTERN_CSD_WHITE "PatternCsdWhite"
/** LED pattern used when blanking fails due to dbus ipc */
#define MCE_LED_PATTERN_DISPLAY_BLANK_FAILED "PatternDisplayBlankFailed"
/** LED pattern used when unblanking fails due to dbus ipc */
#define MCE_LED_PATTERN_DISPLAY_UNBLANK_FAILED "PatternDisplayUnblankFailed"
/** LED pattern used when frame buffer suspend fails */
#define MCE_LED_PATTERN_DISPLAY_SUSPEND_FAILED "PatternDisplaySuspendFailed"
/** LED pattern used when frame buffer resume fails */
#define MCE_LED_PATTERN_DISPLAY_RESUME_FAILED "PatternDisplayResumeFailed"
/** LED pattern used when mce kills unresponsive lipstick */
#define MCE_LED_PATTERN_KILLING_LIPSTICK "PatternKillingLipstick"
/** LED pattern used when display is on, but mce holds touch input */
#define MCE_LED_PATTERN_TOUCH_INPUT_BLOCKED "PatternTouchInputBlocked"
/** LED pattern used when XXX */
#define MCE_LED_PATTERN_DISPLAY_DIMMED "PatternDisplayDimmed"
/** LED pattern used for communication events */
#define MCE_LED_PATTERN_COMMUNICATION_EVENT "PatternCommunication"
/** LED pattern used for communication events when battery is full */
#define MCE_LED_PATTERN_COMMUNICATION_EVENT_BATTERY_FULL "PatternCommunicationAndBatteryFull"
/** LED pattern used when fingerprint scanner is active */
#define MCE_LED_PATTERN_SCANNING_FINGERPRINT "PatternScanningFingerprint"
/** LED pattern used when fingerprint acquisition events are seen */
#define MCE_LED_PATTERN_FINGERPRINT_ACQUIRED "PatternFingerprintAcquired"
/** LED pattern used when proximity sensor is covered */
#define MCE_LED_PATTERN_PROXIMITY_COVERED "PatternProximityCovered"
/** LED pattern used during proximity sensor uncover hysteresis */
#define MCE_LED_PATTERN_PROXIMITY_UNCOVERING "PatternProximityUncovering"
/** LED pattern used when proximity sensor is uncovered */
#define MCE_LED_PATTERN_PROXIMITY_UNCOVERED "PatternProximityUncovered"
/** LED pattern used as feedback for user activity */
#define MCE_LED_PATTERN_USER_FEEDBACK "PatternUserFeedback"
/** Persistent lock file for backups */
#define MCE_SETTINGS_LOCK_FILE_PATH G_STRINGIFY(MCE_RUN_DIR) "/restored"
/** Path for system MALF state indicator file */
#define MALF_FILENAME "/var/malf"
/** Path for MCE MALF state indicator file */
#define MCE_MALF_FILENAME G_STRINGIFY(MCE_RUN_DIR) "/malf"
/** Module information */
typedef struct {
/** Name of the module */
const gchar *const name;
/** Module dependencies */
const gchar *const *const depends;
/** Module recommends */
const gchar *const *const recommends;
/** Module provides */
const gchar *const *const provides;
/** Module provides */
const gchar *const *const enhances;
/** Module conflicts */
const gchar *const *const conflicts;
/** Module replaces */
const gchar *const *const replaces;
/** Module priority:
* lower value == higher priority
* This value is only used when modules conflict
*/
const gint priority;
} module_info_struct;
/** Used for invalid translations and values */
#define MCE_INVALID_TRANSLATION -1
/** Alarm UI states; integer representations */
typedef enum {
/** Alarm UI state not valid */
MCE_ALARM_UI_INVALID_INT32 = MCE_INVALID_TRANSLATION,
/** Alarm UI not visible */
MCE_ALARM_UI_OFF_INT32 = 0,
/** Alarm UI visible and ringing */
MCE_ALARM_UI_RINGING_INT32 = 1,
/** Alarm UI visible but not ringing */
MCE_ALARM_UI_VISIBLE_INT32 = 2,
} alarm_ui_state_t;
const char *alarm_state_repr(alarm_ui_state_t state);
/** System sub-modes; several of these can be active at once */
typedef enum {
/** Submode invalid */
MCE_SUBMODE_INVALID = (1 << 31),
/** No submodes enabled */
MCE_SUBMODE_NORMAL = 0,
/** Touchscreen/Keypad lock enabled */
MCE_SUBMODE_TKLOCK = (1 << 0),
/** Event eater enabled */
MCE_SUBMODE_EVEATER = (1 << 1),
/** Bootup in progress */
MCE_SUBMODE_BOOTUP = (1 << 3),
/** State transition in progress */
MCE_SUBMODE_TRANSITION = (1 << 4),
/** Touchscreen/Keypad autorelock active */
MCE_SUBMODE_AUTORELOCK = (1 << 5),
/** Visual Touchscreen/Keypad active */
MCE_SUBMODE_VISUAL_TKLOCK = (1 << 6),
/** Proximity is used to protect from accidental events */
MCE_SUBMODE_POCKET = (1 << 7),
/** Touchscreen/Keypad lock is enabled based on proximity state */
MCE_SUBMODE_PROXIMITY_TKLOCK = (1 << 8),
/** Device is in MALF state */
MCE_SUBMODE_MALF = (1 << 9),
} submode_t;
const char *submode_change_repr(submode_t prev, submode_t curr);
const char *submode_repr(submode_t submode);
/** System state */
typedef enum {
MCE_SYSTEM_STATE_UNDEF = -1, /**< System state not set */
MCE_SYSTEM_STATE_SHUTDOWN = 0, /**< System is in shutdown state */
MCE_SYSTEM_STATE_USER = 2, /**< System is in user state */
MCE_SYSTEM_STATE_ACTDEAD = 5, /**< System is in acting dead state */
MCE_SYSTEM_STATE_REBOOT = 6, /**< System is in reboot state */
MCE_SYSTEM_STATE_BOOT = 9, /**< System is in bootup state */
} system_state_t;
const char *system_state_repr(system_state_t state);
/** Call state */
typedef enum {
/** Invalid call state */
CALL_STATE_INVALID = MCE_INVALID_TRANSLATION,
/** No call on-going */
CALL_STATE_NONE = 0,
/** There's an incoming call ringing */
CALL_STATE_RINGING = 1,
/** There's an active call */
CALL_STATE_ACTIVE = 2,
/** The device is in service state */
CALL_STATE_SERVICE = 3,
/** Ringing call that is ignored by call ui and mce */
CALL_STATE_IGNORED = 4,
} call_state_t;
const char *call_state_repr(call_state_t state);
const char *call_state_to_dbus(call_state_t state);
call_state_t call_state_from_dbus(const char *name);
/** Call type */
typedef enum {
/** Invalid call type */
CALL_TYPE_INVALID = MCE_INVALID_TRANSLATION,
/** The call is a normal call */
CALL_TYPE_NORMAL = 0,
/** The call is an emergency call */
CALL_TYPE_EMERGENCY = 1
} call_type_t;
const char *call_type_repr(call_type_t type);
call_type_t call_type_parse(const char *name);
/** Display state */
typedef enum {
MCE_DISPLAY_UNDEF, /**< Display state not set */
MCE_DISPLAY_OFF, /**< Display is off */
MCE_DISPLAY_LPM_OFF, /**< Display is off in low power mode */
MCE_DISPLAY_LPM_ON, /**< Display is on in low power mode */
MCE_DISPLAY_DIM, /**< Display is dimmed */
MCE_DISPLAY_ON, /**< Display is on */
MCE_DISPLAY_POWER_UP, /**< Display is resuming */
MCE_DISPLAY_POWER_DOWN, /**< Display is suspending */
MCE_DISPLAY_NUMSTATES /**< Number of display states */
} display_state_t;
const char *display_state_repr(display_state_t state);
/** Cover state */
typedef enum {
COVER_UNDEF = -1, /**< Cover state not set */
COVER_CLOSED = 0, /**< Cover is closed */
COVER_OPEN = 1 /**< Cover is open */
} cover_state_t;
const char *cover_state_repr(cover_state_t state);
const char *proximity_state_repr(cover_state_t state);
/** Lock state */
typedef enum {
/** Lock state not set */
TKLOCK_REQUEST_UNDEF = -1,
/** Lock is disabled */
TKLOCK_REQUEST_OFF = 0,
/** Delayed unlock; write only */
TKLOCK_REQUEST_OFF_DELAYED = 1,
/** Lock is disabled, but autorelock isn't disabled; write only */
TKLOCK_REQUEST_OFF_PROXIMITY = 2,
/** Lock is enabled */
TKLOCK_REQUEST_ON = 3,
/** Dimmed lock; write only */
TKLOCK_REQUEST_ON_DIMMED = 4,
/** Enable proximity lock (no UI); write only */
TKLOCK_REQUEST_ON_PROXIMITY = 5,
/** Toggle lock state; write only */
TKLOCK_REQUEST_TOGGLE = 6,
/** Delayed lock; write only */
TKLOCK_REQUEST_ON_DELAYED = 7,
} tklock_request_t;
const char *tklock_request_repr(tklock_request_t state);
const char *tklock_status_repr(int status);
/** Raw udev battery status */
typedef enum
{
BATTERY_STATE_UNKNOWN,
BATTERY_STATE_CHARGING,
BATTERY_STATE_DISCHARGING,
BATTERY_STATE_NOT_CHARGING,
BATTERY_STATE_FULL,
} battery_state_t;
const char *battery_state_repr(battery_state_t state);
const char *battery_state_to_dbus(battery_state_t state);
/** Battery status */
typedef enum {
BATTERY_STATUS_UNDEF = -1, /**< Battery status not known */
BATTERY_STATUS_FULL = 0, /**< Battery full */
BATTERY_STATUS_OK = 1, /**< Battery ok */
BATTERY_STATUS_LOW = 2, /**< Battery low */
BATTERY_STATUS_EMPTY = 3, /**< Battery empty */
} battery_status_t;
const char *battery_status_repr(battery_status_t state);
const char *battery_status_to_dbus(battery_status_t state);
/** Charging status */
typedef enum {
CHARGER_STATE_UNDEF = -1, /**< Not known yet */
CHARGER_STATE_OFF = 0, /**< Not charging */
CHARGER_STATE_ON = 1, /**< Charging */
} charger_state_t;
const char *charger_state_repr(charger_state_t state);
const char *charger_state_to_dbus(charger_state_t state);
/** Known charger types
*
* Note that the ordering is:
*
* a) significant in the sense that in case there are several chargers
* connected and active at the same time, maximum numerical value is
* exposed as effective charger type on D-Bus
*
* b) internal to mce, so that values can and should be rearranged if
* there should be changes in what makes sense to ui side.
*/
typedef enum
{
/* Placeholder value for lookup failures etc
*/
CHARGER_TYPE_INVALID,
/* Value that signifies that no charger is connected
*/
CHARGER_TYPE_NONE,
/* Charger types that do not carry special meaning from
* sfos UI point of view.
*/
CHARGER_TYPE_OTHER,
CHARGER_TYPE_WIRELESS,
CHARGER_TYPE_CDP, // Charging Downstream Port
/* Wall chargers imply notification on disconnect
*/
CHARGER_TYPE_DCP, // Dedicated Charging Port
CHARGER_TYPE_HVDCP, // High Voltage DCP
/* PC connection implies usb mode management
*/
CHARGER_TYPE_USB, // Standard Downstream Port
} charger_type_t;
charger_type_t charger_type_parse(const char *name);
const char *charger_type_repr(charger_type_t type);
const char *charger_type_to_dbus(charger_type_t type);
/** Camera button state */
typedef enum {
CAMERA_BUTTON_UNDEF = -1, /**< Camera button state not set */
CAMERA_BUTTON_UNPRESSED = 0, /**< Camera button not pressed */
CAMERA_BUTTON_LAUNCH = 1, /**< Camera button fully pressed */
} camera_button_state_t;
const char *camera_button_state_repr(camera_button_state_t state);
/** Audio route */
typedef enum {
/** Audio route not defined */
AUDIO_ROUTE_UNDEF = -1,
/** Audio routed to handset */
AUDIO_ROUTE_HANDSET = 0,
/** Audio routed to speaker */
AUDIO_ROUTE_SPEAKER = 1,
/** Audio routed to headset */
AUDIO_ROUTE_HEADSET = 2,
} audio_route_t;
const char *audio_route_repr(audio_route_t state);
/** USB cable state */
typedef enum {
USB_CABLE_UNDEF = -1, /**< Usb cable state not set */
USB_CABLE_DISCONNECTED = 0, /**< Cable is not connected */
USB_CABLE_CONNECTED = 1, /**< Cable is connected */
USB_CABLE_ASK_USER = 2, /**< Ask mode from user */
} usb_cable_state_t;
const char *usb_cable_state_repr(usb_cable_state_t state);
const char *usb_cable_state_to_dbus(usb_cable_state_t state);
/** Thermal status */
typedef enum {
/** Thermal state not set */
THERMAL_STATE_UNDEF = -1,
/** Thermal state ok */
THERMAL_STATE_OK = 0,
/** Thermal sensors indicate overheating */
THERMAL_STATE_OVERHEATED = 1,
} thermal_state_t;
const char *thermal_state_repr(thermal_state_t state);
/** Exceptional UI status */
typedef enum {
UIEXCEPTION_TYPE_NONE = 0,
UIEXCEPTION_TYPE_LINGER = 1<<0,
UIEXCEPTION_TYPE_CALL = 1<<1,
UIEXCEPTION_TYPE_ALARM = 1<<2,
UIEXCEPTION_TYPE_NOTIF = 1<<3,
UIEXCEPTION_TYPE_NOANIM = 1<<4,
} uiexception_type_t;
const char *uiexception_type_repr(uiexception_type_t type);
const char *uiexception_type_to_dbus(uiexception_type_t type);
/** D-Bus service availability */
typedef enum {
SERVICE_STATE_UNDEF = -1,
SERVICE_STATE_STOPPED = 0,
SERVICE_STATE_RUNNING = 1,
} service_state_t;
const char *service_state_repr(service_state_t state);
/** These must match with what sensorfw uses */
typedef enum
{
MCE_ORIENTATION_UNDEFINED = 0, /**< Orientation is unknown. */
MCE_ORIENTATION_LEFT_UP = 1, /**< Device left side is up */
MCE_ORIENTATION_RIGHT_UP = 2, /**< Device right side is up */
MCE_ORIENTATION_BOTTOM_UP = 3, /**< Device bottom is up */
MCE_ORIENTATION_BOTTOM_DOWN = 4, /**< Device bottom is down */
MCE_ORIENTATION_FACE_DOWN = 5, /**< Device face is down */
MCE_ORIENTATION_FACE_UP = 6, /**< Device face is up */
} orientation_state_t;
const char *orientation_state_repr(orientation_state_t state);
/** Key pressed/realease state */
typedef enum {
KEY_STATE_UNDEF = -1,
KEY_STATE_RELEASED = 0,
KEY_STATE_PRESSED = 1,
} key_state_t;
const char *key_state_repr(key_state_t state);
/** Generic "extended boolean" type */
typedef enum
{
TRISTATE_UNKNOWN = -1,
TRISTATE_FALSE = 0,
TRISTATE_TRUE = 1,
} tristate_t;
const char *tristate_repr(tristate_t state);
/** Fingerprint daemon state */
typedef enum fpstate_t
{
FPSTATE_UNSET,
FPSTATE_ENUMERATING,
FPSTATE_IDLE,
FPSTATE_ENROLLING,
FPSTATE_IDENTIFYING,
FPSTATE_REMOVING,
FPSTATE_VERIFYING,
FPSTATE_ABORTING,
FPSTATE_TERMINATING,
} fpstate_t;
fpstate_t fpstate_parse(const char *name);
const char *fpstate_repr (fpstate_t state);
/* ========================================================================= *
* MEMORY_LEVELS
* ========================================================================= */
/** Supported memory usage levels
*
* Note: The ordering must match:
* 1) memnotify_limit[] array
* 2) memnotify_dev[] array
*/
typedef enum
{
/** No excess memory pressure */
MEMNOTIFY_LEVEL_NORMAL,
/** Non-essential caches etc should be released */
MEMNOTIFY_LEVEL_WARNING,
/** Non-essential prosesses should be terminated */
MEMNOTIFY_LEVEL_CRITICAL,
/* Not initialized yet or memnotify is not supported */
MEMNOTIFY_LEVEL_UNKNOWN,
MEMNOTIFY_LEVEL_COUNT
} memnotify_level_t;
const char *memnotify_level_repr(memnotify_level_t lev);
/** Does the device have a flicker key? */
extern gboolean has_flicker_key;
/**
* Default inactivity timeout, in seconds;
* dim timeout: 30 seconds
* blank timeout: 3 seconds
*
* Used in case the display module doesn't load for some reason
*/
#define DEFAULT_INACTIVITY_DELAY 33
submode_t mce_get_submode_int32(void);
gboolean mce_add_submode_int32(const submode_t submode);
gboolean mce_rem_submode_int32(const submode_t submode);
bool mce_in_valgrind_mode(void);
bool mce_in_sensortest_mode(void);
void mce_abort(void) __attribute__((noreturn));
void mce_quit_mainloop(void);
void mce_signal_handlers_remove(void);
#define display_state_get() ({\
gint res = datapipe_get_gint(display_state_curr_pipe);\
mce_log(LL_DEBUG, "display_state_curr=%s",\
display_state_repr(res));\
res;\
})
/** Clip integer value to given range
*
* @param range_lo minimum value
* @param range_hi maximum value
* @param val value to clip
*
* @return val clipped to the range
*/
static inline int
mce_clip_int(int range_lo, int range_hi, int val)
{
return val < range_lo ? range_lo : val > range_hi ? range_hi : val;
}
/** Translate integer value from one range to another
*
* Linear conversion of a value in [src_lo, src_hi] range
* to [dst_lo, dst_hi] range.
*
* Uses rounding, so that 55 [0,100] -> 6 [0, 10].
*
* @param src_lo lower bound for source range
* @param src_hi upper bound for source range
* @param dst_lo lower bound for destination range
* @param dst_hi upper bound for destination range
* @param val value in source range to be translated
*
* @return input value mapped to destination range
*/
static inline int
mce_xlat_int(int src_lo, int src_hi, int dst_lo, int dst_hi, int val)
{
/* Deal with empty ranges first; assume that the
* low bound is sanest choise available */
if( src_lo >= src_hi || dst_lo >= dst_hi )
return dst_lo;
int src_range = src_hi - src_lo;
int dst_range = dst_hi - dst_lo;
val -= src_lo;
val = (val * dst_range + src_range / 2) / src_range;
val += dst_lo;
return mce_clip_int(dst_lo, dst_hi, val);
}
#endif /* _MCE_H_ */