XTranslateCoordinates(dpy, win, DefaultRootWindow(dpy), 0, 0, &pos_x, &pos_y, &child);

log

x: 38, y: 103

代码

/*** Phase 04 - Make the window move when you press the arrow keys, just because.** This code won't be structured very well, just trying to get stuff working.*/
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>// ~16.6 ms between frames is ~60 fps.
#define RATE_LIMIT 16.6#define _NET_WM_STATE_TOGGLE 2
#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10
// Forward declaration of this function so we can use it in main().
double timespec_diff(struct timespec *a, struct timespec *b);int main(int argc, char *argv[])
{// Create application display.Display *dpy = XOpenDisplay(NULL);if (dpy == NULL) {return EXIT_FAILURE;}// Create the application Window.unsigned long black = BlackPixel(dpy, DefaultScreen(dpy));Window win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 800, 600, 0, black, black);// Setup the Window Manager hints.XWMHints *wmhints = XAllocWMHints();// This basically tells other functions that this contains a value for input and initial state.wmhints->flags = InputHint | StateHint;// And these are the values for input and initial state.wmhints->input = True;wmhints->initial_state = NormalState;// Setup the Size Hints (also for the Window Manager).XSizeHints *sizehints = XAllocSizeHints();// This tells other functions that the value for min width and height.sizehints->flags = PMinSize | PWinGravity;// And these are the values for min width and height.sizehints->min_width = 400;sizehints->min_height = 300;sizehints->win_gravity = StaticGravity;/** This particular function does some allocating that doesn't ever get freed.* Valgrind reports 27,262 bytes in 384 blocks as still reachable because of this.* It's possible that this "leak" could be avoided by using XSetWMProperties()* and creating our own XTextProperty's.*/// Sets Window properties that are used by the Window Manager.Xutf8SetWMProperties(dpy, win, "Phase 01", "", NULL, 0, sizehints, wmhints, NULL);// Tell X that we want to be notified of the Exposure event, so we can know when our window is initially visible.XSelectInput(dpy, win, ExposureMask);// Grab a copy of X's representation of WM_PROTOCOLS, used in checking for window closed events.Atom wm_protocol = XInternAtom(dpy, "WM_PROTOCOLS", True);// Let the Window Manager know that we want the event when a user closes the window.Atom wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", True);XSetWMProtocols(dpy, win, &wm_delete, 1);// Map the window to the display.XMapWindow(dpy, win);// This variable will be used to examine events thrown to our application window.XEvent e;// Block execution until the window is exposed.XWindowEvent(dpy, win, ExposureMask, &e);// Variables needed to get the window's starting position.int pos_x = 0;int pos_y = 0;// This is needed for some reason, not sure what though.Window child;// This translates the 0,0 position of the window to a screen position.XTranslateCoordinates(dpy, win, DefaultRootWindow(dpy), 0, 0, &pos_x, &pos_y, &child);// Output the initial x and y position.printf("x: %d, y: %d\n", pos_x, pos_y);// After being exposed, we'll tell X what input events we want to know about here.XSelectInput(dpy, win, KeyPressMask);// The loop// @TODO: Use sleeping to avoid taking up all CPU cycles.Bool done = False;// We need to track very small periods of time (nanoseconds), so we use the struct timespec.struct timespec prev, curr;/** Get the current time with CLOCK_MONOTONIC_RAW, which gets the time past since a certain time.* CLOCK_MONOTONIC_RAW is not subject to adjustments to the system clock.*/clock_gettime(CLOCK_MONOTONIC_RAW, &curr);// Initialize the previous time with the current time, that way our current vs. previous comparison is valid.prev.tv_sec = curr.tv_sec;prev.tv_nsec = curr.tv_nsec;// This variable will be used to normalize our loop to a specific rate.double mill_store = 0;// A couple of variables used to deal with KeyPress and KeyRelease events.KeySym event_key_0, event_key_1, lookup_keysym;char *key_0_string = NULL, *key_1_string = NULL, lookup_buffer[20];int lookup_buffer_size = 20, charcount = 0;Bool chatting = False;while(!done) {// Get the current time.clock_gettime(CLOCK_MONOTONIC_RAW, &curr);// Store the difference in ms between curr and prev, store it in mill_store for use later.mill_store += timespec_diff(&curr, &prev);// @TODO: Determine if this should happen before updating curr.// Handle events in the event queue.while(XPending(dpy) > 0) {XNextEvent(dpy, &e);switch(e.type) {case ClientMessage:// This client message is a window manager protocol.if (e.xclient.message_type == wm_protocol) {// Somehow this checks if the protocol was a WM_DELETE protocol, so we can exit the loop and be done.if (e.xclient.data.l[0] == wm_delete) {done = True;}}break;case KeyPress:/** So there are two ways to deal with keypress events that I can find:** 1. Use XLookupString to get the "string" value of the keypress. That will return the proper value*    when considering things like holding shift, caps lock enabled, numlock enabled, etc.*    It will not return a string value if you do a keypress combination that doesn't type a "character".*    This method probably works great for when you need a user to enter text.* 2. Use XLookupKeysym to get two Keysyms for index 0 and 1 (0 is normal click, 1 is shift or caps lock).*    Then, based on the key mask in e.xkey.state determine what was pressed (Like Ctrl + Shift + Up).*    This method wouldn't work well for when a user is entering text.*    This method probably works best for game controls.*/// Handle KeyPress events.// @TODO: set the second value (index) properlycharcount = XLookupString(&(e.xkey), lookup_buffer, lookup_buffer_size, &lookup_keysym, NULL);event_key_0 = XLookupKeysym(&(e.xkey), 0);event_key_1 = XLookupKeysym(&(e.xkey), 1);key_0_string = XKeysymToString(event_key_0);key_1_string = XKeysymToString(event_key_1);if (XK_Return == event_key_0) {if (chatting) {printf("\n-Done Chatting-\n");chatting = False;} else {printf("Message: \n");chatting = True;}} else if (event_key_0 == XK_Escape ) {done = True;printf("Pressed Escape, quitting.\n");continue;} else if (XK_q == event_key_0 && e.xkey.state & ControlMask) {done = True;printf("Pressed Ctrl+q, quitting.\n");continue;} else if (XK_Left == event_key_0) {pos_x -= 50;XMoveWindow(dpy, win, pos_x, pos_y);} else if (XK_Right == event_key_0) {pos_x += 50;XMoveWindow(dpy, win, pos_x, pos_y);} else if (XK_Up == event_key_0) {pos_y -= 50;XMoveWindow(dpy, win, pos_x, pos_y);} else if (XK_Down == event_key_0) {pos_y += 50;XMoveWindow(dpy, win, pos_x, pos_y);}if (chatting) {printf("%s", lookup_buffer);} else {printf("Key pressed: %s - %s", key_0_string, key_1_string);if (e.xkey.state & ShiftMask) {printf(" | Shift");}if (e.xkey.state & LockMask) {printf(" | Lock");}if (e.xkey.state & ControlMask) {printf(" | Ctrl");}if (e.xkey.state & Mod1Mask) {printf(" | Alt");}if (e.xkey.state & Mod2Mask) {printf(" | Num Lock");}if (e.xkey.state & Mod3Mask) {printf(" | Mod3");}if (e.xkey.state & Mod4Mask) {printf(" | Mod4");}if (e.xkey.state & Mod5Mask) {printf(" | Mod5");}if (IsCursorKey(event_key_0)) {printf(" | Cursor Key (0)");}if (IsCursorKey(event_key_1)) {printf(" | Cursor Key (1)");}if (IsFunctionKey(event_key_0)) {printf(" | Function key (0)");}if (IsFunctionKey(event_key_1)) {printf(" | Function key (1)");}if (IsKeypadKey(event_key_0)) {printf(" | keypad (0)");}if (IsKeypadKey(event_key_1)) {printf(" | keypad (1)");}if (IsMiscFunctionKey(event_key_0)) {printf(" | Fn (0)");}if (IsMiscFunctionKey(event_key_1)) {printf(" | Fn (1)");}if (IsModifierKey(event_key_0)) {printf(" | Modifier (0)");}if (IsModifierKey(event_key_1)) {printf(" | Modifier (1)");}printf("\n");}break;}}// Only do stuff if the ms passed is greater than our rate limit.if (mill_store > RATE_LIMIT && !done) {/** This loop counts down the mill_store, so if we have more ms stored than the Rate limit,* we run all the processes once. If we have three times the rate limit, we run all the* processes thrice. If the mill_store is less than the rate limit, then we pass on* processing for this time around the loop (which shouldn't really happen).** This helps us have predictable numbers when we do things dependent on numbers, like physics.*/for (; mill_store > RATE_LIMIT && ! done; mill_store -= RATE_LIMIT) {// Things that should run once per tick/frame will go here.}}// Update the previous timespec with the most recent timespec so we can calculate the diff next time around.prev.tv_sec = curr.tv_sec;prev.tv_nsec = curr.tv_nsec;/*** Make our process sleep to avoid locking up the CPU.** From what I understand, the following sleep code will not work on Windows.* It works on Linux, it probably works on OSX, but a different approach is needed* for Windows.*/if (mill_store < RATE_LIMIT && !done) {// We'll need a couple of timespecs, and an int to check for errors.struct timespec sleep_required, sleep_remaining;int was_error = 0;// initialize the remaining sleep time with the value in mill_store.sleep_remaining.tv_sec = mill_store / 1000.0;sleep_remaining.tv_nsec = ((int)mill_store % 1000) * 1000000;do {// Set the required sleep time using the remaining time, so we can continue sleeping if nanosleep is interrupted.sleep_required.tv_sec = sleep_remaining.tv_sec;sleep_required.tv_nsec = sleep_remaining.tv_nsec;// Clear out the errno variable before calling nanosleep so we can catch errors.errno = 0;// Try sleeping for the required time, if nanosleep is interrupted, sleep_remaining will have the time left to sleep.was_error = nanosleep(&sleep_required, &sleep_remaining);// Keep looping if nanosleep was interrupted and there is some sleep time remaining.} while (was_error == -1 && errno == EINTR);}}// Free all the things.XFree(sizehints);sizehints = NULL;XFree(wmhints);wmhints = NULL;XDestroyWindow(dpy, win);XCloseDisplay(dpy);dpy = NULL;return EXIT_SUCCESS;
}/*** This returns the difference between the values of two timespecs.*/
double timespec_diff(struct timespec *a, struct timespec *b)
{return (((a->tv_sec * 1000000000) + a->tv_nsec) - ((b->tv_sec * 1000000000) + b->tv_nsec)) / 1000000.0;
}

编译

$ gcc main.c -std=gnu99 -g -Wall `pkg-config x11 --cflags --libs`

xlib/x11:创建一个监测键盘事件的窗口-4-箭头控制窗口移动相关推荐

  1. xlib/x11:创建一个监测键盘事件的窗口-3-fullscreen-windowed

    传送门:上一篇https://blog.csdn.net/Rong_Toa/article/details/85725642 首先给出二者区别 /*** Phase 03 - Switch to wi ...

  2. 10个用来处理键盘事件的JQuery插件和JS类库

    通常在web应用或者网站中,我们使用鼠标来控制元素或者执行导航,相对于桌面应用来说,使用web应用的快捷键次数可能会相对比较少,但是对于熟 练的专业人员来说,使用键盘可能更加容易并且更加快速,在今天这 ...

  3. Android创建自定义系统键盘

    原文标题:Create A Custom Keyboard on Android 原文链接:http://code.tutsplus.com/tutorials/create-a-custom-key ...

  4. 简单的鼠标和键盘事件+阻止默认阻止冒泡+dom0,dom2

    什么是事件 在我们学习DOM之后,事件就是我们必不可少的一块知识点了,事件其实就是我们的一些操作需要在用户来完成之后才执行的.比如我们PC端的点击事件,键盘事件,以及我们移动端的的触屏事件.接下来咱们 ...

  5. React Native - Keyboard API使用详解(监听处理键盘事件)

    参考: React Native - Keyboard API使用详解(监听处理键盘事件) 当我们点击输入框时,手机的软键盘会自动弹出,以便用户进行输入. 但有时我们想在键盘弹出时对页面布局做个调整, ...

  6. c++ 读文件_第十六节:读文件,文件的创建,写文件,文件的读写以及鼠标键盘事件和图形绘制...

    读文件 //读文件 文件的创建 public 写文件 public 文件的读写 重点: 文件类主要功能:创建,读属性,写属性,删除等 文件读写操作 File类 File类的对象 用来获取文件本身的信息 ...

  7. 基于OpenGL编写一个简易的2D渲染框架-07 鼠标事件和键盘事件

    这次为程序添加鼠标事件和键盘事件 当检测到鼠标事件和键盘事件的信息时,捕获其信息并将信息传送到需要信息的对象处理.为此,需要一个可以分派信息的对象,这个对象能够正确的把信息交到正确的对象. 实现思路: ...

  8. 创建一个storageevent事件_事件循环:微任务和宏任务

    浏览器中 JavaScript 的执行流程和 Node.js 中的流程都是基于 事件循环 的. 理解事件循环的工作方式对于代码优化很重要,有时对于正确的架构也很重要. 在本章中,我们首先介绍有关事物工 ...

  9. for 创建一个方法:键盘录入一个数 ,求它的 阶乘 及 阶乘的和

    package Way_chongzai; //创建一个方法:键盘录入一个数 求它的阶乘 import java.util.Scanner; public class Test_03 { public ...

最新文章

  1. 强烈推荐10个新媒体运营必备工具,极大提高工作效率
  2. Opera在本博客的发文方法,fedora8下
  3. flink on yarn部分源码解析 (FLIP-6 new mode)
  4. 实现strstr库函数功能
  5. 敏捷开发回顾:使团队更强大pdf
  6. 使用Spring Data R2DBC进行异步RDBMS访问
  7. 链表面试题1:反转单链表,不带头结点。
  8. 730阵列卡支持多大硬盘_730元/瓶的光瓶李渡酒销售过亿后,李渡还有哪些大招?...
  9. 设计人的33个好习惯
  10. 【ML小结6】关联分析与序列模式关联分析
  11. Abaqus相关报错合集
  12. 曲线坐标系与直角坐标系转换(一)——基础:matlab插值函数简介
  13. Excel 2016: 录制宏入门
  14. qqxml图片代码_动态图的QQXML代码示例——篮球规范动作示范!
  15. 在java语言中所有类都是,【填空题】(10-1)Java语言中,( )是所有 类的祖先类。
  16. matlab 矩阵列运算,MATLAB矩阵及其运算
  17. C# 滑块/滑杆/拖动条控件trackBar
  18. 情人节有哪些礼物可以送给男朋友的,情人节送礼推荐
  19. 关于支持电脑登录选项设置
  20. Latex Zotero导出格式化Bibtex条目

热门文章

  1. 启动docker容器报错 driver failed programming external connectivity on endpoint
  2. leetcode题解767-重构字符串
  3. Spring框架----自动按照类型注入的Autowired注解
  4. 2019.08.27BOM的六个子对象(1)
  5. visual studio Code配置C++环境:
  6. vue动态加载静态资源
  7. pythrch 启动 visdom可视化
  8. 基于QGraphics的简易画板1
  9. 无限递归替换文件内的某个字符串
  10. 《Linux内核分析》期末总结及学习心得