0

I want to register the client on the session manager and handle the save-yourself callback when a user logs out from the session. The session manager should request all registered clients to call the save-yourself callback - what is incorrect with my code that the method never invokes. I am also interested how could the callback execute is I start the infinite loop? Should I create another thread, which will check smth and call the callback? I also understand that the session manager detects the new client because the value is assigned to the clientId variable. I have checked vim sources - there the xsmp_icefd variable was used and without it being (with the help of the IceConnectionNumber() func) assigned callbacks were not invoke either. Would greatly appreciate sources to learn from!

#include <X11/Xlib.h>
#include <X11/SM/SMlib.h>
#include <X11/ICE/ICElib.h>

static void save_yourself_cb(SmcConn smcConn,
                         SmPointer smdata,
                         int /* saveType */,
                         Bool /* shutdown */,
                         int /* interactStyle */,
                         Bool /* fast */)
 {
   char *data = (char *)smdata;
   printf("DataSave = %s\n", data);
   SmcSaveYourselfDone(smcConn, 0);
 }

 static void shutdown_c_cb(SmcConn smcConn /* smcConn */,
                      SmPointer smdata /* clientData */)
 {
   char *data = (char *)smdata;
   printf("DataSave = %s\n", data);
 }

 int main()
 {
   Display *display = XOpenDisplay(NULL);
   if (display == NULL)
   {
      return 1;
   }

int screenNum = DefaultScreen(display);
Window rootWindow = RootWindow(display, screenNum);

unsigned int windowWidth = 400;
unsigned int windowHeight = 300;
unsigned int borderWidth = 2;
int windowX = 100;
int windowY = 100;

Window window = XCreateSimpleWindow(display, rootWindow, windowX, windowY,
                                    windowWidth, windowHeight, borderWidth,
                                    BlackPixel(display, screenNum),
                                    WhitePixel(display, screenNum));

XStoreName(display, window, "Simple X11 Window");
XSelectInput(display, window, ExposureMask | KeyPressMask);

XMapWindow(display, window);

SmcConn smcConnection;
SmcCallbacks callbacks;
char *clientId;
char *previousId = NULL;

const char *msg = "Passed data";
callbacks.save_yourself.callback = save_yourself_cb;
callbacks.save_yourself.client_data = (SmPointer)msg;
callbacks.shutdown_cancelled.callback = shutdown_c_cb;
callbacks.shutdown_cancelled.client_data = (SmPointer)msg;
callbacks.die.callback = shutdown_c_cb; 
callbacks.die.client_data = (SmPointer)msg;
callbacks.save_complete.callback = shutdown_c_cb;
callbacks.save_complete.client_data = (SmPointer)msg;

// Open a connection to the session manager
smcConnection = SmcOpenConnection(NULL, NULL, SmProtoMajor, SmProtoMajor,
                                  SmcSaveYourselfProcMask,
                                  &callbacks, previousId, &clientId, 0, NULL);


vector<SmProp*> props;
SmProp* prop = new SmProp;
SmPropValue val;
val.length = 7;
val.value =(SmPointer)"window";

prop->name=clientId;
prop->num_vals=1;
prop->type=(char*)"window";
prop->vals=&val;

props.push_back(move(prop));

SmcSetProperties(smcConnection, 1, props.data());

XEvent loop;
XEvent event;
while (XNextEvent(display, &event) == 0)
{
}

return 0;
}
XoDefender
  • 33
  • 6

0 Answers0