简体   繁体   English

带和不带参数的功能XOpenDisplay

[英]Function XOpenDisplay with and without parameter

I have little issue with XOpenDisplay function. 我对XOpenDisplay函数没有什么疑问。 In school I can run program and it works good when using XOpenDisplay("ip:0"), but on my local machine in home when I run program (changed ip on current) got "Segmentation fault (core dumped)", but with empy string XOpenDisplay("") it works fine. 在学校里,我可以运行程序,并且在使用XOpenDisplay(“ ip:0”)时可以很好地运行,但是当我运行程序(当前更改为ip)时,我在家里的本地计算机上出现了“分段错误(内核已转储)”,但是empy字符串XOpenDisplay(“”)可以正常工作。 I need to be able to use ip. 我需要能够使用ip。 Used host +, but nothing changes. 使用主机+,但没有任何变化。 My system is Kubuntu 14.04.1: 3.16.0-30-generic #40~14.04.1-Ubuntu SMP Thu Jan 15 17:43:14 UTC 2015 我的系统是Kubuntu 14.04.1:3.16.0-30-generic#40〜14.04.1-Ubuntu SMP Thu Jan 15 17:43:14 UTC 2015

Here is code of program: 这是程序代码:

#include <X11/Xlib.h>
#include <X11/X.h>
#include <stdio.h>

Display *mydisplay;
Window mywindow;
XSetWindowAttributes mywindowattributes;
XGCValues mygcvalues;
GC mygc;
Visual *myvisual;
int mydepth;
int myscreen;
Colormap mycolormap;
XColor mycolor,mycolor1,dummy;
int i;

main()

{
  mydisplay = XOpenDisplay("192.168.0.12:0");
  myscreen = DefaultScreen(mydisplay);
  myvisual = DefaultVisual(mydisplay,myscreen);
  mydepth = DefaultDepth(mydisplay,myscreen);
  mywindowattributes.background_pixel = XWhitePixel(mydisplay,myscreen);
  mywindowattributes.override_redirect = True;

  mywindow = XCreateWindow(mydisplay,XRootWindow(mydisplay,myscreen),
                        0,0,500,500,10,mydepth,InputOutput,
                        myvisual,CWBackPixel|CWOverrideRedirect,
                        &mywindowattributes);

  mycolormap = DefaultColormap(mydisplay,myscreen);                 

  XAllocNamedColor(mydisplay,mycolormap,"cyan",&mycolor,&dummy);

    XAllocNamedColor(mydisplay,mycolormap,"red",&mycolor1,&dummy);                 

  XMapWindow(mydisplay,mywindow);

  mygc = DefaultGC(mydisplay,myscreen);

  XSetForeground(mydisplay,mygc,mycolor.pixel);

  XFillRectangle(mydisplay,mywindow,mygc,100,100,300,300);

  XSetForeground(mydisplay,mygc,mycolor1.pixel);

  XSetFunction(mydisplay,mygc,GXcopy);

  XSetLineAttributes(mydisplay,mygc,10,LineSolid,CapProjecting,JoinMiter);

  XDrawLine(mydisplay,mywindow,mygc,100,100,400,400);

  XDrawLine(mydisplay,mywindow,mygc,100,400,400,100);

  XFlush(mydisplay);

  sleep(10);

  XCloseDisplay(mydisplay);

  exit(0);
}

I can only guess that need to set something, but have no idea where is that option. 我只能猜测这需要设置一些内容,但不知道该选项在哪里。

You shall always check whether functions returned successfully, or not. 您应始终检查函数是否成功返回。 It is not a Haskell, where all the checking done for you by monad, it is C. As for your particular case, the problem is that the function XOpenDisplay fails and returns null for you. 它不是Haskell,其中monad为您完成的所有检查都是C。对于您的特殊情况,问题在于函数XOpenDisplay失败并为您返回null。 In the next line you're trying to use DefaultScreen with the result. 在下一行中,您尝试将DefaultScreen与结果一起使用。 The DefaultScreen is defined as DefaultScreen定义为

#define DefaultScreen(dpy)  ((dpy)->default_screen)

Ie it just a macro, which using the first argument as a pointer. 即它只是一个宏,它使用第一个参数作为指针。 In your case it does ((0)->default_screen) , ie it dereferencing the null pointer, and that leads to the segfault you see. 在您的情况下,它会执行((0)->default_screen) ,即它取消引用空指针,并导致您看到的段错误。

Also, about the XOpenDisplay("192.168.0.12:0"); 另外,关于XOpenDisplay("192.168.0.12:0"); — you didn't mentioned that you're trying to connect to another PC, so, if it's the same computer where the app running, try to call the function as XOpenDisplay("127.0.0.1:0"); —您没有提到要连接到另一台PC,因此,如果该应用运行的是同一台计算机,请尝试将该函数调用为XOpenDisplay("127.0.0.1:0");

UPD: okay, I tried to run the code at my PC, and the function doesn't work for me too. UPD:好的,我尝试在PC上运行代码,但该功能也对我不起作用。 To find the reason I started the code under strace app, and saw 为了找到我在strace app下启动代码的原因,并看到了

…
connect(3, {sa_family=AF_INET, sin_port=htons(6000), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 ECONNREFUSED (Connection refused)
…

Aha! 啊哈! So, the app trying to connect to XServer, but Xserver refuses the connection. 因此,该应用程序尝试连接到XServer,但是Xserver拒绝连接。 Actually, it have a security reason to disable it by default — so, that nobody would connect to your XServer from a network unless you specifically allowed it. 实际上,出于安全原因,默认情况下会禁用它-因此,除非您明确允许,否则没有人会从网络连接到XServer。 For the function to work you need to launch your XServer with the option that allows such a connection. 为了使该功能正常工作,您需要使用允许此类连接的选项启动XServer。 Right now DisplayManagers are the ones, who manages xsessions, so you need to set some option depending on your DM. 现在,DisplayManager是管理xsession的对象,因此您需要根据DM设置一些选项。

The solution for lightdm lightdm的解决方案

Open the /etc/lightdm/lightdm.conf , and paste the line xserver-allow-tcp=true in the section [SeatDefaults] (you will see it) . 打开/etc/lightdm/lightdm.conf ,并将行xserver-allow-tcp=true粘贴到[SeatDefaults]部分(您将看到它)

The solution for gdm gdm解决方案

Edit the file /etc/gdm/gdm.schemas , you will find there something like 编辑文件/etc/gdm/gdm.schemas ,您会发现类似

<schema>
<key>security/DisallowTCP</key>
<signature>b</signature>
<default>true</default>
</schema>

Change the true to false . true更改为false

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM