Loading...
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 | // SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2019 Google LLC * Written by Simon Glass <sjg@chromium.org> */ #include <dm.h> #include <errno.h> #include <mouse.h> #include <video.h> int mouse_get_event(struct udevice *dev, struct mouse_event *evt) { struct mouse_uc_priv *uc_priv = dev_get_uclass_priv(dev); struct mouse_ops *ops = mouse_get_ops(dev); int ret; if (!ops->get_event) return -ENOSYS; ret = ops->get_event(dev, evt); if (ret) return ret; /* Update last position for motion events */ if (evt->type == MOUSE_EV_MOTION) { uc_priv->last_pos.x = evt->motion.x; uc_priv->last_pos.y = evt->motion.y; } /* Update last position for button events and detect clicks */ if (evt->type == MOUSE_EV_BUTTON) { uc_priv->last_pos.x = evt->button.x; uc_priv->last_pos.y = evt->button.y; /* Process left-button clicks */ if (evt->button.button == BUTTON_LEFT) { /* Detect press->release transition (click) */ if (uc_priv->left_pressed && !evt->button.pressed) { uc_priv->click_pending = true; uc_priv->click_pos.x = evt->button.x; uc_priv->click_pos.y = evt->button.y; } /* Update button state */ uc_priv->left_pressed = evt->button.pressed; } } return 0; } int mouse_get_click(struct udevice *dev, struct vid_pos *pos) { struct mouse_uc_priv *uc_priv = dev_get_uclass_priv(dev); struct mouse_event event; /* Process all available events until we find a click */ while (true) { if (uc_priv->click_pending) { *pos = uc_priv->click_pos; uc_priv->click_pending = false; break; } if (mouse_get_event(dev, &event)) return -EAGAIN; /* No more events */ } return 0; } int mouse_get_pos(struct udevice *dev, struct vid_pos *pos) { struct mouse_uc_priv *uc_priv = dev_get_uclass_priv(dev); *pos = uc_priv->last_pos; return 0; } int mouse_set_ptr_visible(struct udevice *dev, bool visible) { struct mouse_ops *ops = mouse_get_ops(dev); if (!ops->set_ptr_visible) return -ENOSYS; return ops->set_ptr_visible(dev, visible); } int mouse_set_video(struct udevice *dev, struct udevice *video_dev) { struct mouse_uc_priv *uc_priv = dev_get_uclass_priv(dev); uc_priv->video_dev = video_dev; if (video_dev) { uc_priv->video_width = video_get_xsize(video_dev); uc_priv->video_height = video_get_ysize(video_dev); uc_priv->last_pos.x = uc_priv->video_width / 2; uc_priv->last_pos.y = uc_priv->video_height / 2; } else { uc_priv->video_width = 0; uc_priv->video_height = 0; } return 0; } int mouse_queue_click_for_test(struct udevice *dev, int x, int y) { struct mouse_uc_priv *uc_priv = dev_get_uclass_priv(dev); uc_priv->click_pending = true; uc_priv->click_pos.x = x; uc_priv->click_pos.y = y; uc_priv->last_pos.x = x; uc_priv->last_pos.y = y; return 0; } UCLASS_DRIVER(mouse) = { .id = UCLASS_MOUSE, .name = "mouse", .per_device_auto = sizeof(struct mouse_uc_priv), }; |