`
sipgreen
  • 浏览: 26632 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

linux在用户程序中如何向操作系统发送按键事件

 
阅读更多

 转自:http://blog.csdn.net/xiangpengmeng/article/details/6396589

 考虑到很多人也可能都需要这些类似的功能, 尤其是搞嵌入式的, 我解决这个问题的思路也是从android系统中借鉴的,这个功能需要首先在内核中添加uinput模块, 大家也可以将这个模块直接编译进内核里面, 编译内核大家都熟悉, 我就不在说了, 都是整天配置编译的人啊。。。

 

下面两个文件直接取自我们一个使用手机远程控制系统, 下面是代码, 代码中已经有了注释, 不在解释了, 希望以上代码会对你有所帮助。

/**
 * @file  The file is using for (>>> function<<<)
 * @author imxiangpeng
 * @time  
 *
 * Copyright (C) imxiangpeng@gmail.com, Inc. All Rights Reserved.
 * Written by imxiangpeng@gmail.com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */
#ifndef RCBOARDMOUSE_H
#define RCBOARDMOUSE_H
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
static void kbdms_open_dev();
static int kbdms_init_dev(char *dev);
extern void kbdms_close_dev(void); /* you can call the function explicitly if you no need the function anymore*/
/* only the following functions which you can called, we initialise the device when you call the following function firstly */
/* key_code: referce to linux/input.h
   is_pressed_or_release: 1 if the key is pressed , 0 :release
   注意按键有按下,就必然会有释放,如果没有释放,再次调用按下函数是没有反映的
*/
extern void kbdms_send_button_event(unsigned short key_code, int is_pressed_or_release);
/* is_rel:1--relative move, else--absolutely
   if you want to send left or right mouse button , please call kbdms_send_button_event
*/
//extern void kbdms_send_mouse_move_events(unsigned short is_rel, unsigned short pos_x, unsigned short pos_y);
extern void kbdms_send_mouse_move_events(unsigned short is_rel, short pos_x, short pos_y);
extern void kbdms_send_wheel_events(short wheel_value);
#endif  /* RCBOARDMOUSE_H */

 

/**
 * @file  The file is using for (>>> function<<<)
 * @author imxiangpeng
 * @time  
 *
 * Copyright (C) imxiangpeng@gmail.com, Inc. All Rights Reserved.
 * Written by imxiangpeng@gmail.com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */
 
#include "rcboardmouse.h"
static int uinput_fd = -1;
static struct uinput_user_dev uinput;
static struct input_event event;
static void kbdms_open_dev(){
  int ret = -1;
  ret = kbdms_init_dev("/dev/uinput");
  if(ret < 0){
    ret = kbdms_init_dev("/dev/input/uinput");
    if(ret < 0){
      printf("call kbdms_open_dev failure/n");
      return;
    }
  }
}
static int kbdms_init_dev(char *dev){
  int i = 0;
  if(dev == NULL){
    printf("The device is null/n");
    return -1;
  }
  uinput_fd = open(dev, O_WRONLY | O_NDELAY);
  if(uinput_fd < 0){
    perror("open uinput device failure:");
    return -1;
  }
  memset(&uinput, 0, sizeof(uinput));
  strncpy(uinput.name,"xiangpeng's virtual device",UINPUT_MAX_NAME_SIZE);
  uinput.id.version = 4;
  uinput.id.bustype = BUS_USB;
  ioctl(uinput_fd, UI_SET_EVBIT, EV_KEY);
  ioctl(uinput_fd, UI_SET_EVBIT, EV_REL);
  ioctl(uinput_fd, UI_SET_RELBIT, REL_X);
  ioctl(uinput_fd, UI_SET_RELBIT, REL_Y);
  ioctl(uinput_fd, UI_SET_RELBIT, REL_WHEEL);
  
  for(i = 0; i < 256; i++){
    ioctl(uinput_fd, UI_SET_KEYBIT, i);
  } /* end for */
  ioctl(uinput_fd, UI_SET_KEYBIT, BTN_MOUSE);
  ioctl(uinput_fd, UI_SET_KEYBIT, BTN_TOUCH);
  ioctl(uinput_fd, UI_SET_KEYBIT, BTN_LEFT);
  ioctl(uinput_fd, UI_SET_KEYBIT, BTN_MIDDLE);
  ioctl(uinput_fd, UI_SET_KEYBIT, BTN_RIGHT);
  ioctl(uinput_fd, UI_SET_KEYBIT, BTN_FORWARD);
  ioctl(uinput_fd, UI_SET_KEYBIT, BTN_BACK);
  /* Create input device into input sub-system */
  write(uinput_fd, &uinput, sizeof(uinput));
  if(ioctl(uinput_fd, UI_DEV_CREATE)){
    perror("create uinput device");
    return -1;
  }
  return 0;                     /* success */
  
} /* end init_uinput_dev function */
/* is_rel:1--relative move, else--absolutely
   which_button_pressed: 0--no button press, 1--left button press, 2--right button press 3--middle button press
   
 */
void kbdms_send_mouse_move_events(unsigned short is_rel, short pos_x, short pos_y){
  if(uinput_fd <= 0){
    
    printf("RC : %s please call dbdms_init_dev first/n",__FUNCTION__);
    kbdms_open_dev();
    if(uinput_fd <= 0)
      return;
  }
  /* Move pointer to (0,0) location */
  memset(&event, 0, sizeof(event));
  gettimeofday(&event.time, NULL);
  event.type = (is_rel == 1)?EV_REL:EV_ABS;
  event.code = (is_rel == 1)?REL_X:ABS_X;
  event.value = pos_x;
  write(uinput_fd, &event, sizeof(event));  
  event.type = EV_SYN;
  event.code = SYN_REPORT;
  event.value = 0;
  write(uinput_fd, &event, sizeof(event));
  memset(&event, 0, sizeof(event));
  gettimeofday(&event.time, NULL);
  event.type = (is_rel == 1)?EV_REL:EV_ABS;
  event.code = (is_rel == 1)?REL_Y:ABS_Y;
  event.value = pos_y;
  write(uinput_fd, &event, sizeof(event));
  /* 鼠标点击事件我们也通过 kbdms_send_button_event 来发送*/
  
} /* end send_click_events function */
/* key_code: referce to linux/input.h
   is_pressed_or_release: 1 if the key is pressed , 0 :release
 */
void kbdms_send_button_event(unsigned short key_code, int is_pressed_or_release){
  
  if(uinput_fd <= 0){
    printf("RC : %s please call dbdms_init_dev first/n",__FUNCTION__);
    kbdms_open_dev();
    if(uinput_fd <= 0)
      return;
  }
  /* report button click --press event */
  
  memset(&event, 0, sizeof(event));
  gettimeofday(&event.time, NULL);
  event.type = EV_KEY;
  event.code = key_code;
  event.value = is_pressed_or_release;
  write(uinput_fd, &event, sizeof(event));
  event.type = EV_SYN;
  event.code = SYN_REPORT;
  event.value = 0;
  write(uinput_fd, &event, sizeof(event));
  
}
void kbdms_send_wheel_events(short wheel_value){
  if(uinput_fd <= 0){
    printf("RC : %s please call dbdms_init_dev first/n",__FUNCTION__);
    kbdms_open_dev();    
    if(uinput_fd <= 0)
      return;
   
  }
  /* Move pointer to (0,0) location */
  memset(&event, 0, sizeof(event));
  gettimeofday(&event.time, NULL);
  event.type = EV_REL;
  event.code = REL_WHEEL;
  event.value = wheel_value;
  write(uinput_fd, &event, sizeof(event));  
  event.type = EV_SYN;
  event.code = SYN_REPORT;
  event.value = 0;
  write(uinput_fd, &event, sizeof(event));
  
} /* end send_click_events function */
void kbdms_close_dev(void){
  if(uinput_fd > 0){
    ioctl(uinput_fd, UI_DEV_DESTROY);
    close(uinput_fd);
  }
}
#if 0                           /* using for test all the functions */
int main(int argc, char **argv){
  if(argc <2){
    printf("Please specified the uinput device path/n");
    return -1;
  }
  printf("The device is :%s/n",argv[1]);
  if(kbdms_init_dev(argv[1]) < 0){
    printf("Call init_uinput_dev failure/n");
    return -1;
  }
  
  while(1){
    printf("we will send a click and a button event/n");
    //send_click_events();
    kbdms_send_button_event(KEY_LEFT, 1);
    kbdms_send_button_event(KEY_LEFT, 0);
    sleep(3);
    kbdms_send_button_event(KEY_DOWN,1);
    kbdms_send_button_event(KEY_DOWN,0);
    sleep(2);
    kbdms_send_button_event(KEY_DOWN,1);
    kbdms_send_button_event(KEY_DOWN,0);
    sleep(2);
    printf("we will call kbdms_send_wheel_events/n");
    kbdms_send_wheel_events(10);
    printf("We will wheel back up/n");
    sleep(2);
    
    kbdms_send_wheel_events(-10);
  }
  kbdms_close_dev();
  return 0;
}
#endif

 希望以上代码会对你有所帮助, 如果有什么疑问也可以给我发邮件, 邮件地址在每个文件的头部

当然, 本人计算机都是自学的, 如果各位看着在编程风格和代码书写上如果有什么不足, 希望大家可以提出来

 

 

分享到:
评论

相关推荐

    嵌入式Linux按键驱动,支持短按和长按检测

    在嵌入式Linux系统中,按键驱动是与用户交互的重要组成部分。本文将深入探讨如何实现一个支持短按和长按检测的按键驱动,利用平台驱动框架、按键中断、内核定时器以及POLL机制,确保在休眠-唤醒场景下也能高效工作,...

    linux下支持触屏,按键功能的monkey程序,系统稳定性测试工具

    Monkey程序的核心是生成和发送事件到操作系统。它首先会根据预设的参数(如事件频率、持续时间等)生成一系列随机事件序列。这些事件可能包括点击坐标、按键值等信息。然后,Monkey将这些事件模拟成真实的用户操作,...

    嵌入式linux按键驱动程序源代码和Makefile编译文件源代码

    在嵌入式Linux系统开发中,驱动程序是连接硬件与操作系统的重要桥梁,它使得操作系统能够控制和管理硬件设备。本文将深入探讨嵌入式Linux下的按键驱动程序源代码及其Makefile编译文件,帮助理解如何在这样的环境中...

    android系统按键驱动

    在Android系统中,按键驱动是连接硬件按键与操作系统之间的桥梁,负责将硬件按键的物理事件转化为软件可识别的输入事件。本主题主要聚焦于Linux内核2.6.35.7版本下的按键驱动,该驱动已经过测试,并且能够在Android...

    linux input子系统 内核与应用 接口 分析详解

    Linux 输入子系统是操作系统核心中一个关键的部分,它负责处理来自各种输入设备的事件,如键盘、鼠标、触摸屏等。这个子系统为内核和用户空间应用提供了一个高效的交互接口,使得应用程序能够方便地获取并响应用户的...

    btn_drv.rar_Linux QT_QT2410_linux 2410 驱动_linux 按键驱动 _按键驱动

    在嵌入式Linux系统中,编写特定设备(如按键)的驱动程序是实现硬件功能的基础。 2. **QT2410**: QT2410是一款基于ARM9处理器的嵌入式系统开发板,常用于嵌入式设备的设计和开发。它集成了LCD控制器、GPIO(通用...

    S3c2440 linux 按键中断 驱动

    **中断服务函数** 是处理按键事件的核心,它会读取GPIO状态,判断是否是有效的按键中断,并根据按键状态执行相应操作,比如向用户空间发送信号或数据。 **字符驱动** 在这里是指Linux内核中的字符设备驱动,它为...

    Android 9.0 10.0 framework添加KeyEvent按键事件流程.rar

    本资料主要探讨在Android 9.0 (Pie) 和 Android 10.0 (Q) 操作系统版本中,在framework层添加KeyEvent事件的详细流程。了解这一流程对于系统开发者或定制ROM的工程师至关重要,因为这涉及到对硬件按键行为的自定义和...

    全志系列芯片android与Linux内核按键驱动源码

    全志系列芯片在Android和Linux内核中的按键驱动源码是理解嵌入式系统硬件交互与操作系统内核之间桥梁的关键。这些源码提供了详细的实现细节,帮助开发者了解如何在底层处理硬件事件,如按键按下和释放,从而在上层...

    arm linux 按键实验.rar <三星 2440>

    通过这个实验,开发者可以学习如何在Linux操作系统下读取和处理硬件按键输入,这对于任何涉及用户交互的嵌入式项目都是至关重要的。 首先,让我们了解三星S3C2440。这是一款由三星电子制造的高性能、低功耗的ARM...

    串口通讯-按键识别-ping程序-我的linux应用程序

    开发这样的程序,你需要掌握C/C++编程语言,理解操作系统I/O模型(如阻塞与非阻塞I/O、异步I/O),熟悉设备驱动编程,以及网络编程知识。同时,良好的代码组织和错误处理策略也是必要的。 为了实现这样的程序,你...

    树莓派按键驱动和用户侧程序

    在本文中,我们将深入探讨如何在树莓派3B+上实现按键驱动和用户侧程序。树莓派,一种基于Linux的小型计算机,被广泛用于DIY项目和嵌入式系统开发。对于树莓派上的硬件交互,如按键操作,需要编写特定的驱动程序来...

    linuxqudong.rar_linux 2410 驱动_linux 按键

    当检测到按键按下,驱动程序会向内核发送一个事件,然后由内核或其他用户空间程序处理这个事件。这通常涉及到中断服务例程和底半部处理机制,以确保系统的实时性和响应性。 在"www.pudn.com.txt"文件中,可能是关于...

    嵌入式Linux应用程序开发标准教程(第2版全)

    1.1.2 Linux作为嵌入式操作系统的优势 1.1.3 Linux发行版本 1.1.4 如何学习Linux 1.2 Linux安装 1.2.1 基础概念 1.2.2 硬件需求 1.2.3 安装准备 1.3 Linux文件及文件系统 1.3.1 文件类型及文件属性 1.3.2 文件系统...

    linux按键驱动 轮询input上报可做linux 矩阵键盘的按键驱动

    在Linux操作系统中,驱动程序是连接硬件设备与操作系统内核的关键部分。对于按键驱动,特别是矩阵键盘,Linux提供了input子系统来处理这类设备的输入事件。本教程将深入讲解如何利用轮询机制实现一个Linux矩阵键盘的...

    将游戏手柄按键映射到键盘

    标题中的“将游戏手柄按键映射到键盘”是指在Linux操作系统中,通过编程技术实现游戏手柄的输入控制转化为键盘输入,使得原本只支持键盘操作的游戏也能通过游戏手柄来玩。这一过程通常涉及到对硬件输入设备的读取、...

    C++按键工具,设置按键

    在Linux环境下,可能需要用到`write`函数向 `/dev/input/event*` 设备发送键盘事件。 描述中提到“包含键盘上大部分按键”,这意味着这个工具能够覆盖标准键盘上的各种按键,包括字母键、数字键、特殊符号键以及...

    linux输入子系统

    这个子系统的设计目的是为了提供一个统一的接口,让操作系统可以方便地管理和处理来自不同类型的输入设备的数据。下面将详细讨论输入子系统的各个关键方面。 1、为何引入input system? 在早期的Linux系统中,每种...

Global site tag (gtag.js) - Google Analytics