X11中如何存储事件产生的数据? [英] How to store the data generated by an event in X11?

查看:23
本文介绍了X11中如何存储事件产生的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个在 x 窗口上绘制形状的事件驱动项目.每当我在屏幕上单击鼠标时,就会生成 x 和 y 的新值.我的问题是:假设每次单击鼠标时,都会生成 x 和 y 的新值,我如何在下面的代码中存储 x 和 y 的不同值.

I am working on an event-driven project that draws shape on an x-window. Whenever I click a mouse on the screen, new values of x and y are generated. My question is: how can I store the different values of x and y in the code below assuming each time you click a mouse, new values of x and y are generated.

int x, y;
x = report.xbutton.x;
y = report.xbutton.y;

if (report.xbutton.button == Button1) {
    XFillArc(display_ptr, win, gc_red, 
             x - win_height/80, y - win_height/80,
             win_height/60, win_height/60, 0, 360*64);
}

推荐答案

一个版本的代码可能是:

One version of the code might be:

typedef struct Position
{
    int x;
    int y;
} Position;

typedef struct PosnList
{
    size_t     num_pts;
    size_t     max_pts;
    Position  *points;
} PosnList;

void add_point(int x, int y, PosnList *p)
{
    if (p->num_pts >= p->max_pts)
    {
        size_t new_num = (p->max_pts + 2) * 2;
        Position *new_pts = realloc(p->points, new_num * sizeof(Position));
        if (new_pts == 0)
            ...handle out of memory error...
        p->max_pts = new_num;
        p->points  = new_pts;
    }
    p->points[p->num_pts++] = (Position){ x, y };
}

void zap_posnlist(PosnList *p)
{
     free(p->points);
     p->num_pts = 0;
     p->max_pts = 0;
     p->points  = 0;
}

然后你的代码会做:

int x, y;
x = report.xbutton.x;
y = report.xbutton.y;

if (report.xbutton.button == Button1) {
    XFillArc(display_ptr, win, gc_red, 
             x - win_height/80, y - win_height/80,
             win_height/60, win_height/60, 0, 360*64);
    add_point(x, y, &positions);
}

哪里有变量:

PosnList positions = { 0, 0, 0 };

请注意,add_point() 函数使用 realloc() 进行初始内存分配和增量内存分配.该代码使用 C99 复合文字将值 xy 分配给数组中的下一个 Position.如果您没有 C99,则需要做两个单独的作业.

Note that the add_point() function uses realloc() to do both the initial memory allocation and incremental memory allocations. The code uses a C99 compound literal to assign the values x and y to the next Position in the array. If you don't have C99, you'll need to do two separate assignments.

zap_posnlist() 函数释放先前初始化的 PosnList.您可能仍然需要一个正式的初始化函数——除非您乐于在任何地方使用 PosnList xxx = { 0, 0, 0 }; 符号.

The zap_posnlist() function releases a previously initialized PosnList. You might still need a formal initializer function — unless you're happy to use the PosnList xxx = { 0, 0, 0 }; notation everywhere.

此代码现已被 GCC 清理;原始版本不是,并且其中存在错误 - 导致编译器错误的错误.

This code has now been sanitized by GCC; the original edition was not and there were bugs in it — bugs that generated compiler errors.

测试代码——请注意,"stderr.h" 不是标准头,而是我习惯使用的错误报告代码.它提供了 err_error()err_setarg0() 函数.

Tested code — note that "stderr.h" is not a standard header but is the error reporting code I habitually use. It provides the err_error() and err_setarg0() functions.

#include <stdlib.h>
#include "stderr.h"

typedef struct Position
{
    int x;
    int y;
} Position;

typedef struct PosnList
{
    size_t     num_pts;
    size_t     max_pts;
    Position  *points;
} PosnList;

extern void add_point(int x, int y, PosnList *p);
extern void zap_posnlist(PosnList *p);

void add_point(int x, int y, PosnList *p)
{
    if (p->num_pts >= p->max_pts)
    {
        size_t new_num = (p->max_pts + 2) * 2;
        Position *new_pts = realloc(p->points, new_num * sizeof(Position));
        if (new_pts == 0)
            err_error("Out of memory (%s:%d - %zu bytes)\n",
                       __FILE__, __LINE__, new_num * sizeof(Position));
        p->max_pts = new_num;
        p->points  = new_pts;
    }
    p->points[p->num_pts++] = (Position){ x, y };
}

void zap_posnlist(PosnList *p)
{
    free(p->points);
    p->num_pts = 0;
    p->max_pts = 0;
    p->points  = 0;
}

#include <stdio.h>

int main(int argc, char **argv)
{
    PosnList positions = { 0, 0, 0 };

    err_setarg0(argv[0]);

    if (argc > 1)
        srand(atoi(argv[1]));

    for (size_t i = 0; i < 37; i++)
        add_point(rand(), rand(), &positions);

    for (size_t i = 0; i < positions.num_pts; i++)
        printf("%2zu: (%5d, %5d)\n", i, positions.points[i].x, positions.points[i].y);

    zap_posnlist(&positions);
    return(0);
}

<小时>

如果您需要 stderr.hstderr.c 的源代码,请联系我(请参阅我的个人资料).


Contact me (see my profile) if you want source for stderr.h and stderr.c.

这篇关于X11中如何存储事件产生的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆