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;
}