1

对于XNextEvent(display,&e)某些窗口的返回,我需要访问它window所属的类,在网络和书籍上进行一些搜索后,XSaveContextXFindContext看起来很有用,但我没有找到任何使用示例。所以让我们试试:

我有 a class Metallica,我想在 a 中调用aMetallica object时保存 a 的地址:constructorXContext

class Metallica{
  private:
    Window window;
    int i;
    .
    .
  public:
    Metallica(...,int j, XContext *context){
      .
      .
      i=j;
      //XSaveContext(display, this->window, *context, this); // don't work
      XSaveContext(display, this->window, *context, XPointer(this));
      .
      .
      void MasterOfPuppet(){
        cout << i << endl;
      };
      void FadeToBlack(){
        cout << "OK" << endl;
      };
    };

};

所以现在在我的 xevent 循环中,我想取回一个 Metallica 对象的地址,

// at the declaration area :
// XContext Metallica_Context;
// XPointer *XPointerToOneMetallicaObject;

XFindContext(display,
             e.xany.window,
             Metallica_Context,
             XPointerToOneMetallicaObject );

Metallica *SandMan = (Metallica*)(*XPointerToOneMetallicaObject);

SandMan->FadeToBlack();    // no problem
SandMan->MasterOfPuppet(); // return a segmentation fault

所以我做错了什么,但是什么?

4

1 回答 1

0

我发现我错了,当我调用XFindContext()参数时e.xany.window,'any'窗口可以调用参数,所以即使不是由 a调用的Metallica,然后调用MasterOfPuppet()do shit...所以我需要保护调用就是这样!

好吧,这里有一个基本的(我不保护调用,但在这种情况下不做狗屎)工作代码(你可以使用这个代码来看看如何XContext使用,幸运你......):

//g++ test.cc -lX11
#include<iostream>
#include<unistd.h>
#include<X11/Xlib.h>
#include<X11/Xutil.h>

Display *display;


class Metallica{
  private:
    Window window;
    int i;

  public:
    Metallica(int j, XContext *context){
      i=j;
      this->window = XCreateSimpleWindow(display,DefaultRootWindow(display),100,100,100,100,0,0,0);
      XSelectInput(display, this->window, ExposureMask|ButtonReleaseMask|KeyReleaseMask);
      XMapWindow(display,this->window);
      XSaveContext(display, this->window, *context, XPointer(this));
    };
    void MasterOfPuppet(){
      std::cout << i << std::endl;
    };
    void FadeToBlack(){
      std::cout << "ok" << std::endl;
    };
};

int main(){
  XContext Metallica_context;
  XPointer *XPointerToOneMetallicaObject;
  XEvent e;
  int DoNotStop=1;

  display = XOpenDisplay(0);

  Metallica OneMetallicaObject(2,&Metallica_context);
  Metallica *SandMan;

  while(DoNotStop){
    XNextEvent(display, &e);
    switch(e.type){
    case Expose : XFlush(display); break;
    case ButtonRelease : XFindContext(display,e.xany.window,Metallica_context,XPointerToOneMetallicaObject);
                         SandMan = (Metallica*)(*XPointerToOneMetallicaObject);
                         SandMan->MasterOfPuppet();
                         break;
    case KeyRelease    : DoNotStop=0; break;
    }
  }

  return 0;
}
于 2013-06-12T02:04:58.993 回答