示例#1
0
void KWM::close(Window w){
  static Atom a = 0;
  if (!a)
    a = XInternAtom(qt_xdisplay(), "WM_DELETE_WINDOW", False);
  static Atom ap = 0;
  if (!ap)
    ap = XInternAtom(qt_xdisplay(), "WM_PROTOCOLS", False);

  // clients with WM_DELETE_WINDOW protocol set are
  // closed via wm_delete_window ClientMessage.
  // Others are destroyed.
  Atom *p;
  int i,n;
  if (XGetWMProtocols(qt_xdisplay(), w, &p, &n)){
    for (i = 0; i < n; i++){
      if (p[i] == a){
	sendClientMessage(w, ap, a);
	XFree((char*)p);
	return;
      }
    }
    if (n>0)
      XFree(p);
  }
  // client will not react on wm_delete_window. We have no choice
  // but destroy his connection to the XServer.
  XKillClient(qt_xdisplay(), w);
}
void
kill_launched_win(Window win)
{
  int i, n, found = 0;
  Atom *protocols;
  XEvent e;
			  
  if (XGetWMProtocols(dpy, win,
		      &protocols, &n))
    {
      for (i=0; i<n; i++)
	if (protocols[i] == atom_wm_delete) found++;
      XFree(protocols);
    }
			  
  if (found)
    {
      e.type = ClientMessage;
      e.xclient.window = win;
      e.xclient.message_type = atom_wm_protos;
      e.xclient.format = 32;
      e.xclient.data.l[0] = atom_wm_delete;
      e.xclient.data.l[1] = CurrentTime;
      XSendEvent(dpy, win, False, NoEventMask, &e);
    }
  else
    {
      XKillClient(dpy, win);
    }
}
示例#3
0
void KWM::enableSessionManagement(Window w){
  static Atom a = 0;
  if (!a)
    a = XInternAtom(qt_xdisplay(), "WM_SAVE_YOURSELF", False);
  static Atom b = 0;
  if (!b)
    b = XInternAtom(qt_xdisplay(), "KWM_SAVE_YOURSELF", False);
  Atom *p;
  int i,n;
  if (XGetWMProtocols(qt_xdisplay(), w, &p, &n)){
    for (i = 0; i < n; i++){
      if (p[i] == a)
	return;
    }
    Atom *pn = new Atom[n+1];
    for (i=0; i<n; i++)
      pn[i] = p[i];
    pn[i] = a;
    XSetWMProtocols(qt_xdisplay(), w, pn, n+1);
    if (n>0)
      XFree((char*)p);
    delete[] pn;	
  }
  else
    XSetWMProtocols(qt_xdisplay(), w, &a, 1);
  setSimpleProperty(w, b, 1);
}
示例#4
0
EAPI Eina_Bool
ecore_x_window_prop_protocol_isset(Ecore_X_Window win,
                                   Ecore_X_WM_Protocol protocol)
{
   Atom proto, *protos = NULL;
   int i, protos_count = 0;
   Eina_Bool ret = EINA_FALSE;

   /* check for invalid values */
   if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
     return EINA_FALSE;

   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   proto = _ecore_x_atoms_wm_protocols[protocol];

   ret = XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count);
   if (_ecore_xlib_sync) ecore_x_sync();
   if (!ret)
     return ret;

   for (i = 0; i < protos_count; i++)
     if (protos[i] == proto)
       {
          ret = EINA_TRUE;
          break;
       }

   XFree(protos);
   return ret;
}
示例#5
0
static void
handle_top_level(Display * display, Window window,
		 Atom protocols_atom, Atom delete_window_atom)
{
	Atom       *prots;
	int         nprots, j;

	if (has_property(display, window, protocols_atom)) {
		XGetWMProtocols(display, window, &prots, &nprots);

		if (err_occurred)
			return;

		for (j = 0; j < nprots; j++)
			if (prots[j] == delete_window_atom) {
				send_delete_message(display, window,
					 protocols_atom, delete_window_atom);
				break;
			}
		if (j == nprots)	/* delete window not found */
			XKillClient(display, window);

		XFree((caddr_t) prots);
	} else
		XKillClient(display, window);
}
示例#6
0
文件: frame.cpp 项目: Fxrh/antico
void Frame::get_wm_protocols()
{
    Atom *protocols;
    int nprot,i;
    prot_delete = false;
    prot_take_focus = false;

    Atom wm_delete_window = XInternAtom(QX11Info::display(), "WM_DELETE_WINDOW", False);
    Atom wm_take_focus = XInternAtom(QX11Info::display(), "WM_TAKE_FOCUS", False);

    if (XGetWMProtocols(QX11Info::display(), c_win, &protocols, &nprot))
    {
        for (i=0; i < nprot; i++)
        {
            if (protocols[i] == wm_delete_window)
            {
                prot_delete = true;
            }
            else if (protocols[i] == wm_take_focus)
            {
                prot_take_focus = true;
            }
        }
        XFree(protocols);
    }
}
示例#7
0
文件: audit.c 项目: Remmy/afterstep
/* protocols_return is really Atom**, but to avoid extra includes, we'll use void* */
Status
count_xgetwmprotocols (const char *fname, int line, Display * display,
					   Window w, void *protocols_return, int *count_return)
{
	Status        val;

	val = XGetWMProtocols (display, w, (Atom **) protocols_return, count_return);
	if (val && *count_return)
		count_alloc (fname, line, *(void **)protocols_return,
					 *count_return * sizeof (Atom), C_XMEM | C_XGETWMPROTOCOLS);
	return val;
}
示例#8
0
文件: client.c 项目: csimons/cswm
Bool
isprotodel(Client *c) {
    int i, n;
    Atom *protocols;
    Bool ret = False;

    if(XGetWMProtocols(dpy, c->win, &protocols, &n)) {
        for(i = 0; !ret && i < n; i++)
            if(protocols[i] == wmatom[WMDelete])
                ret = True;
        XFree(protocols);
    }
    return ret;
}
示例#9
0
void send_wm_delete(Client *c, int kill_client) {
	int i, n, found = 0;
	Atom *protocols;

	if (!kill_client && XGetWMProtocols(dpy, c->window, &protocols, &n)) {
		for (i = 0; i < n; i++)
			if (protocols[i] == xa_wm_delete)
				found++;
		XFree(protocols);
	}
	if (found)
		send_xmessage(c->window, xa_wm_protos, xa_wm_delete);
	else
		XKillClient(dpy, c->window);
}
示例#10
0
文件: mdmwm.c 项目: AlbertJP/mdm
/* stolen from gwmh */
static gboolean
wm_protocol_check_support (Window xwin,
			   Atom   check_atom)
{
  Atom *pdata = NULL;
  guint32 *gdata = NULL;
  int n_pids = 0;
  gboolean is_supported = FALSE;
  guint i, n_gids = 0;

  trap_push ();

  if (!XGetWMProtocols (wm_disp,
			xwin,
			&pdata,
			&n_pids))
    {
      gint size = 0;

      gdata = get_typed_property_data (wm_disp,
				       xwin,
				       XA_WM_PROTOCOLS,
				       XA_WM_PROTOCOLS,
				       &size, 32);
      n_gids = size / 4;
    }

  trap_pop ();

  for (i = 0; i < n_pids; i++)
    if (pdata[i] == check_atom)
      {
	is_supported = TRUE;
	break;
      }
  if (pdata)
    XFree (pdata);
  if (!is_supported)
    for (i = 0; i < n_gids; i++)
      if (gdata[i] == check_atom)
        {
	  is_supported = TRUE;
	  break;
        }
  g_free (gdata);

  return is_supported;
}
示例#11
0
void UpdateWMProtocols(UltimateContext *uc)
{
  Atom *prots;
  int count,a;

  uc->ProtocolFlags=0;
  if(XGetWMProtocols(disp,uc->win,&prots,&count)) {
    for(a=0;a<count;a++){
      if(prots[a]==WM_TAKE_FOCUS) {
        uc->ProtocolFlags|=TAKE_FOCUS;
        if(uc == ActiveWin) SendWMProtocols(uc, WM_TAKE_FOCUS);
      }
      if(prots[a]==WM_DELETE_WINDOW) uc->ProtocolFlags|=DELETE_WINDOW;
    }
    XFree(prots);
  }
}
示例#12
0
void Client::getWMProtocols(void)
{
	Atom *protocols;
	int nprot,i;

	protDelete = false;
	protTakeFocus = false;

	if (XGetWMProtocols(display(), clientId, &protocols, &nprot)) {
		for (i=0; i < nprot; i++) {
            if (protocols[i] == Atoms::atom(Atoms::WM_DELETE_WINDOW)) { 
				protDelete = true;
			} else if (protocols[i] == Atoms::atom(Atoms::WM_TAKE_FOCUS)) {
				protTakeFocus = true;
			}
		}
		XFree(protocols);
	}
}
示例#13
0
void clientwin_get_protocols(WClientWin *cwin)
{
    Atom *protocols=NULL, *p;
    int n;
    
    cwin->flags&=~(CLIENTWIN_P_WM_DELETE|CLIENTWIN_P_WM_TAKE_FOCUS);
    
    if(!XGetWMProtocols(ioncore_g.dpy, cwin->win, &protocols, &n))
        return;
    
    for(p=protocols; n; n--, p++){
        if(*p==ioncore_g.atom_wm_delete)
            cwin->flags|=CLIENTWIN_P_WM_DELETE;
        else if(*p==ioncore_g.atom_wm_take_focus)
            cwin->flags|=CLIENTWIN_P_WM_TAKE_FOCUS;
    }
    
    if(protocols!=NULL)
        XFree((char*)protocols);
}
示例#14
0
文件: client.c 项目: mitake/mysevilwm
void send_wm_delete(Client *c)
{
	int n, found = 0;
	Atom *protocols;

	if (c) {
		if (XGetWMProtocols(dpy, c->window, &protocols, &n)) {
			for (int i = 0; i < n; i++)
				if (protocols[i] == xa_wm_delete) found++;

			XFree(protocols);
		}

		if (found)
			send_xmessage(c->window, xa_wm_protos, xa_wm_delete);
		else
			XKillClient(dpy, c->window);
	}

	next(NULL);
}
示例#15
0
void PropGetProtocols(Window window, WProtocols *prots)
{
	Atom *protocols;
	int count, i;

	memset(prots, 0, sizeof(WProtocols));
	if (!XGetWMProtocols(dpy, window, &protocols, &count)) {
		return;
	}
	for (i = 0; i < count; i++) {
		if (protocols[i] == w_global.atom.wm.take_focus)
			prots->TAKE_FOCUS = 1;
		else if (protocols[i] == w_global.atom.wm.delete_window)
			prots->DELETE_WINDOW = 1;
		else if (protocols[i] == w_global.atom.wm.save_yourself)
			prots->SAVE_YOURSELF = 1;
		else if (protocols[i] == w_global.atom.gnustep.wm_miniaturize_window)
			prots->MINIATURIZE_WINDOW = 1;
	}
	XFree(protocols);
}
示例#16
0
void
icccm_send_client_message(Client *c, Atom msg) {
  int i, n;
  Atom *protocols;
  if (XGetWMProtocols(disp, c->window, &protocols, &n)) {
    for (i = 0; i < n; i++)
      if (protocols[i] == msg) {
        XEvent xcm;

        xcm.type = ClientMessage;
        xcm.xclient.window = c->window;
        xcm.xclient.message_type = XInternAtom(disp, "WM_PROTOCOLS", False);
        xcm.xclient.format = 32;
        xcm.xclient.data.l[0] = msg;
        xcm.xclient.data.l[1] = CurrentTime;

        XSendEvent(disp, c->window, False, NoEventMask, &xcm);
      }
    XFree(protocols);
  }
}
示例#17
0
/**
 * @brief Get a array containing the protocols of @a win
 * @note If there aren't any properties to be counted or any protocols to get
 *       then the function returns NULL.
 * @param win The window for which protocol list will be got.
 * @param num_ret Contains the number of elements of the array to be returned.
 * @return The array that contains the protocols.
 */
EAPI Ecore_X_WM_Protocol *
ecore_x_window_prop_protocol_list_get(Ecore_X_Window win,
                                      int *num_ret)
{
   Atom *protos = NULL;
   int i, protos_count = 0;
   Ecore_X_WM_Protocol *prot_ret = NULL;
   Eina_Bool success;

   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   success = XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count);
   if (_ecore_xlib_sync) ecore_x_sync();
   if (!success)
     return NULL;

   if ((!protos) || (protos_count <= 0))
     return NULL;

   prot_ret = calloc(1, protos_count * sizeof(Ecore_X_WM_Protocol));
   if (!prot_ret)
     {
        XFree(protos);
        return NULL;
     }

   for (i = 0; i < protos_count; i++)
     {
        Ecore_X_WM_Protocol j;

        prot_ret[i] = -1;
        for (j = 0; j < ECORE_X_WM_PROTOCOL_NUM; j++)
          {
             if (_ecore_x_atoms_wm_protocols[j] == protos[i])
               prot_ret[i] = j;
          }
     }
   XFree(protos);
   *num_ret = protos_count;
   return prot_ret;
}
示例#18
0
文件: manager.c 项目: nowylie/space
void manager_interpret_message( Display *conn, XClientMessageEvent event )
{
   frame_t *frame = frame_get( event.window );
   if (event.message_type == EA_NET_CLOSE_WINDOW ) {
      printf( "\t_NET_CLOSE_WINDOW\n" );
      /* Close the application */
      Window window = frame->child->id;
      Atom *protocols;
      int num, i;
      
      XUnmapWindow( conn, window );
      XGetWMProtocols( conn, window, &protocols, &num );
      
      for (i = 0; i < num; i++ ) {
         if ( protocols[i] == XA_WM_DELETE_WINDOW ) {
            XEvent event_send;
            event_send.type = ClientMessage;
            event_send.xclient.type = ClientMessage;
            event_send.xclient.message_type = XA_WM_PROTOCOLS;
            event_send.xclient.format = 32;
            event_send.xclient.data.l[0] = XA_WM_DELETE_WINDOW;
            event_send.xclient.data.l[1] = event.data.l[0];
            
            XSendEvent( conn, window, False, 0, &event_send );
            
            window = None;
         }
      }
      
      if ( window != None )
         XKillClient( conn, window );
   } else if ( event.message_type == EA_NET_MOVERESIZE_WINDOW ) {
      /* Change the window position on client request */
      if ( event.data.l[0] & (MR_FLAG_X | MR_FLAG_Y) )
         frame_move( conn, frame, event.data.l[1], event.data.l[2] );
   } else if ( event.message_type == EA_NET_ACTIVE_WINDOW ) {
      /* Change the window focus on client request */
      frame_focus( conn, frame );
   }
}
示例#19
0
文件: clientlist.c 项目: xiaq/hlwm
// mainly from dwm.c
bool client_sendevent(HSClient *client, Atom proto) {
    int n;
    Atom *protocols;
    bool exists = false;
    XEvent ev;

    if (XGetWMProtocols(g_display, client->window, &protocols, &n)) {
        while (!exists && n--)
            exists = protocols[n] == proto;
        XFree(protocols);
    }
    if (exists) {
        ev.type = ClientMessage;
        ev.xclient.window = client->window;
        ev.xclient.message_type = g_wmatom[WMProtocols];
        ev.xclient.format = 32;
        ev.xclient.data.l[0] = proto;
        ev.xclient.data.l[1] = CurrentTime;
        XSendEvent(g_display, client->window, False, NoEventMask, &ev);
    }
    return exists;
}
示例#20
0
文件: ecore_x_icccm.c 项目: jigpu/efl
/**
 * Set or unset a wm protocol property.
 * @param win The Window
 * @param protocol The protocol to enable/disable
 * @param on On/Off
 */
EAPI void
ecore_x_icccm_protocol_set(Ecore_X_Window win,
                           Ecore_X_WM_Protocol protocol,
                           Eina_Bool on)
{
   Atom *protos = NULL;
   Atom proto;
   int protos_count = 0;
   int already_set = 0;
   int i;

   /* Check for invalid values */
   if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
     return;

   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   proto = _ecore_x_atoms_wm_protocols[protocol];

   if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
     {
        protos = NULL;
        protos_count = 0;
     }
   if (_ecore_xlib_sync) ecore_x_sync();
   for (i = 0; i < protos_count; i++)
     {
        if (protos[i] == proto)
          {
             already_set = 1;
             break;
          }
     }

   if (on)
     {
        Atom *new_protos = NULL;

        if (already_set)
          goto leave;

        new_protos = malloc((protos_count + 1) * sizeof(Atom));
        if (!new_protos)
          goto leave;

        for (i = 0; i < protos_count; i++)
          new_protos[i] = protos[i];
        new_protos[protos_count] = proto;
        XSetWMProtocols(_ecore_x_disp, win, new_protos, protos_count + 1);
        if (_ecore_xlib_sync) ecore_x_sync();
        free(new_protos);
     }
   else
     {
        if (!already_set)
          goto leave;

        for (i = 0; i < protos_count; i++)
          {
             if (protos[i] == proto)
               {
                  int j;

                  for (j = i + 1; j < protos_count; j++)
                    protos[j - 1] = protos[j];
                  if (protos_count > 1)
                    XSetWMProtocols(_ecore_x_disp, win, protos,
                                    protos_count - 1);
                  else
                    XDeleteProperty(_ecore_x_disp, win,
                                    ECORE_X_ATOM_WM_PROTOCOLS);
                  if (_ecore_xlib_sync) ecore_x_sync();

                  goto leave;
               }
          }
     }

leave:
   if (protos)
     XFree(protos);
}
示例#21
0
/**
@brief   This function reparents a framed window to root and then destroys the frame. It is used when the framed window has been unmapped or destroyed, or is about to be.
@param   workspaces list of all workspaces.
@param   index  index of the target frame in the global list of frames
@return  void
**/
void
remove_frame(Display* display, struct Workspace_list *workspaces, int index, int current_workspace, struct Atoms *atoms, struct Themes *themes) {

  struct Frame *frame = &workspaces->frame_list[index];

  XWindowChanges changes;
  Window root = DefaultRootWindow(display);
  unsigned int mask = CWSibling | CWStackMode;

  changes.stack_mode = Below;
  changes.sibling = frame->widgets[frame_parent].widget;

  free_frame_name(frame);
  XDestroyWindow(display, frame->menu.item);
  //make the whole window disappear before the inner frame is unmapped to make it look faster
  XUnmapWindow(display, frame->widgets[frame_parent].widget);
  XSync(display, False);
  #ifdef CRASH_ON_BUG
  XGrabServer(display);
  XSetErrorHandler(supress_xerror);
  #endif

  XDeleteProperty(display, frame->framed_window, atoms->wm_state);
  frame->state = none;
  XReparentWindow(display, frame->framed_window, root
  , frame->x + themes->window_type[frame->theme_type][window].x
  , frame->y + themes->window_type[frame->theme_type][window].y);
  //TODO need to change the frame w,h attributes here

  //keep the stacking order
  XConfigureWindow(display, frame->framed_window, mask, &changes);

  XRemoveFromSaveSet(display, frame->framed_window);

  //this will not destroy the window because it has been reparented to root
  XDestroyWindow(display, frame->widgets[frame_parent].widget);
  XSync(display, False);

  #ifdef CRASH_ON_BUG
  XSetErrorHandler(NULL);
  XUngrabServer(display);
  #endif


  //we want to unconditionally remove references to the frame which is being removed in the current workspace
  if(current_workspace >= 0  &&  workspaces->list[current_workspace].list) {
    for(int i = 0; i < workspaces->list[current_workspace].used; i++) {
      if(workspaces->list[current_workspace].list[i]->framed_window == frame->framed_window) {
        int nested_last = workspaces->list[current_workspace].used - 1;
        if((workspaces->list[current_workspace].used != 1)  && (i != nested_last) ) {
          workspaces->list[current_workspace].list[i] = workspaces->list[current_workspace].list[nested_last];
        }
        workspaces->list[current_workspace].used--;
        break;
      }
    }
  }

  //make sure that the saved states are reset since it is assumed than an empty slot is zeroed by clean realloc etc.
  struct Saved_frame_state blank = { .x =0 , .y = 0 , .w = 0, .h = 0,
  .available = 0, .need_to_tile = 0, .mode = 0, .state = 0 };

  for(int i = 0; i < workspaces->used_workspaces; i++) {
    workspaces->list[i].states[index] = blank;
  }

  //remove it from the global frame list, and also remove it's state references.
  int last = workspaces->used_frames - 1;
  if((workspaces->used_frames != 1) && (index != last)) { //the frame is not alone or the last
    struct Frame* last_fp_pointer = &workspaces->frame_list[last];

    for(int i = 0; i < workspaces->used_workspaces; i++) {
      workspaces->list[i].states[index] = workspaces->list[i].states[last];
      workspaces->list[i].states[last] = blank;
    }

    if(current_workspace >= 0  &&  workspaces->list[current_workspace].list) {
      for(int i = 0; i < workspaces->list[current_workspace].used; i++) {
        //in anticipation of the swap of the last frame we need to update pointers to it.
        //imagine that the removed frame wasn't in the current workspace (in fact the above code guarantees it) but the moved frame was, it's pointer would become invalid.
        if(workspaces->list[current_workspace].list[i] == last_fp_pointer) workspaces->list[current_workspace].list[i] = &workspaces->frame_list[index];
      }
    }
    workspaces->frame_list[index] = workspaces->frame_list[last]; //swap the deleted item with the last item.
  }

  workspaces->used_frames--;
}


/**
@brief   This function is called when the close button on the frame is pressed.
@return  void
**/
void
close_window(Display* display, Window framed_window) {
  int n;
  Bool found = False;
  Atom *protocols;

  //based on windowlab/aewm
  if (XGetWMProtocols(display, framed_window, &protocols, &n)) {
    Atom delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
    for (int i = 0; i < n; i++)
      if (protocols[i] == delete_window) {
        found = True;
        break;
      }
    XFree(protocols);
  }

  if(found)  {
   //from windowlab/aewm
    XClientMessageEvent event;
    event.type = ClientMessage;
    event.window = framed_window;
    event.format = 32;
    event.message_type = XInternAtom(display, "WM_PROTOCOLS", False);
    event.data.l[0] = (long)XInternAtom(display, "WM_DELETE_WINDOW", False);
    event.data.l[1] = CurrentTime;
    XSendEvent(display, framed_window, False, NoEventMask, (XEvent *)&event);
    #ifdef SHOW_UNMAP_NOTIFY_EVENT
    printf("Sent wm_delete_window message\n");
    #endif
  }
  else {
    #ifdef SHOW_UNMAP_NOTIFY_EVENT
    printf("Killed window %lu\n", (unsigned long)framed_window);
    #endif
    XUnmapWindow(display, framed_window);
    XFlush(display);
    XKillClient(display, framed_window);
  }
}
示例#22
0
static void *
winMultiWindowWMProc (void *pArg)
{
  WMProcArgPtr		pProcArg = (WMProcArgPtr)pArg;
  WMInfoPtr		pWMInfo = pProcArg->pWMInfo;
  
  /* Initialize the Window Manager */
  winInitMultiWindowWM (pWMInfo, pProcArg);
  
#if CYGMULTIWINDOW_DEBUG
  ErrorF ("winMultiWindowWMProc ()\n");
#endif

  /* Loop until we explicity break out */
  for (;;)
    {
      WMMsgNodePtr	pNode;

      /* Pop a message off of our queue */
      pNode = PopMessage (&pWMInfo->wmMsgQueue);
      if (pNode == NULL)
	{
	  /* Bail if PopMessage returns without a message */
	  /* NOTE: Remember that PopMessage is a blocking function. */
	  ErrorF ("winMultiWindowWMProc - Queue is Empty?\n");
	  pthread_exit (NULL);
	}

#if CYGMULTIWINDOW_DEBUG
      ErrorF ("winMultiWindowWMProc - %d ms MSG: %d ID: %d\n",
	      GetTickCount (), (int)pNode->msg.msg, (int)pNode->msg.dwID);
#endif
      
      /* Branch on the message type */
      switch (pNode->msg.msg)
	{
#if 0
	case WM_WM_MOVE:
	  ErrorF ("\tWM_WM_MOVE\n");
	  break;

	case WM_WM_SIZE:
	  ErrorF ("\tWM_WM_SIZE\n");
	  break;
#endif

	case WM_WM_RAISE:
#if CYGMULTIWINDOW_DEBUG
	  ErrorF ("\tWM_WM_RAISE\n");
#endif

	  /* Raise the window */
	  XRaiseWindow (pWMInfo->pDisplay, pNode->msg.iWindow);
	  break;

	case WM_WM_LOWER:
#if CYGMULTIWINDOW_DEBUG
	  ErrorF ("\tWM_WM_LOWER\n");
#endif

	  /* Lower the window */
	  XLowerWindow (pWMInfo->pDisplay, pNode->msg.iWindow);
	  break;

	case WM_WM_MAP:
#if CYGMULTIWINDOW_DEBUG
	  ErrorF ("\tWM_WM_MAP\n");
#endif
	  {
	    XWindowAttributes		attr;
	    char			*pszName;
#if 0
	    XWMHints			*pHints;
#endif

	    /* Get the window attributes */
	    XGetWindowAttributes (pWMInfo->pDisplay,
				  pNode->msg.iWindow,
				  &attr);
	    if (!attr.override_redirect)
	      {
		/* Set the Windows window name */
		GetWindowName(pWMInfo->pDisplay, pNode->msg.iWindow, &pszName);
		SetWindowText (pNode->msg.hwndWindow, pszName);
		free (pszName);
	      }
	  }
	  break;

	case WM_WM_UNMAP:
#if CYGMULTIWINDOW_DEBUG
	  ErrorF ("\tWM_WM_UNMAP\n");
#endif
	  
	  /* Unmap the window */
	  XUnmapWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
	  break;

	case WM_WM_KILL:
#if CYGMULTIWINDOW_DEBUG
	  ErrorF ("\tWM_WM_KILL\n");
#endif
	  {
	    int				i, n, found = 0;
	    Atom			*protocols;
	    
	    /* --- */
	    if (XGetWMProtocols (pWMInfo->pDisplay,
				 pNode->msg.iWindow,
				 &protocols,
				 &n))
	      {
		for (i = 0; i < n; ++i)
		  if (protocols[i] == pWMInfo->atmWmDelete)
		    ++found;
		
		XFree (protocols);
	      }

	    /* --- */
	    if (found)
	      SendXMessage (pWMInfo->pDisplay,
			    pNode->msg.iWindow,
			    pWMInfo->atmWmProtos,
			    pWMInfo->atmWmDelete);
	    else
	      XKillClient (pWMInfo->pDisplay,
			   pNode->msg.iWindow);
	  }
	  break;

	case WM_WM_ACTIVATE:
#if CYGMULTIWINDOW_DEBUG
	  ErrorF ("\tWM_WM_ACTIVATE\n");
#endif
	  
	  /* Set the input focus */
	  XSetInputFocus (pWMInfo->pDisplay,
			  pNode->msg.iWindow,
			  RevertToPointerRoot,
			  CurrentTime);
	  break;

	case WM_WM_X_EVENT:
	  /* Process all X events in the Window Manager event queue */
	  FlushXEvents (pWMInfo);
	  break;

	default:
	  ErrorF ("winMultiWindowWMProc - Unknown Message.\n");
	  pthread_exit (NULL);
	  break;
	}

      /* Free the retrieved message */
      free (pNode);

      /* Flush any pending events on our display */
      XFlush (pWMInfo->pDisplay);
    }

  /* Free the condition variable */
  pthread_cond_destroy (&pWMInfo->wmMsgQueue.pcNotEmpty);
  
  /* Free the mutex variable */
  pthread_mutex_destroy (&pWMInfo->wmMsgQueue.pmMutex);
  
  /* Free the passed-in argument */
  free (pProcArg);
  
#if CYGMULTIWINDOW_DEBUG
  ErrorF("-winMultiWindowWMProc ()\n");
#endif
}
示例#23
0
/***********************************************************************
 * Event Handler to reparent client window under plugin window 
 ***********************************************************************/
/* static */ void
SubstructureRedirectHandler (
    Widget widget, 
    XtPointer client_data, 
    XEvent* event, 
    Boolean* cont)
{
    windowrec* new_list;
    PluginInstance* This = (PluginInstance*) client_data;

#ifdef PLUGIN_TRACE
    fprintf (stderr, "%s\n", "SubstructureRedirectHandler");
    fprintf (stderr, "This: 0x%x\n", This);
#endif

    switch (event->type) {
    case ConfigureRequest:
	{
	    XWindowChanges config;
	    config.x = event->xconfigurerequest.x;
	    config.y = event->xconfigurerequest.y;
	    config.width = event->xconfigurerequest.width;
	    config.height = event->xconfigurerequest.height;
	    config.border_width = event->xconfigurerequest.border_width;
	    config.sibling = event->xconfigurerequest.above;
	    config.stack_mode = event->xconfigurerequest.detail;
#if 0
	    fprintf (stderr, "configuring at %dx%d+%d+%d\n", 
		     config.width, config.height, config.x, config.y);
#endif
	    XConfigureWindow (RxGlobal.dpy,
			      event->xconfigurerequest.window,
			      event->xconfigurerequest.value_mask,
			      &config);
	}
	break;

    case MapRequest:

	RxpSetStatusWidget(This, RUNNING);

	{
	    Window for_win;
	    int i;

	    if (XGetTransientForHint (RxGlobal.dpy, event->xmaprequest.window,
				      &for_win)) {
		for (i = 0; i < This->nclient_windows; i++)
		    if (for_win == This->client_windows[i].win)
			XMapWindow (RxGlobal.dpy, event->xmaprequest.window);
		return;
	    }
	}
	new_list = (windowrec*) 
	    NPN_MemAlloc (sizeof (windowrec) * (This->nclient_windows + 1));
	if (new_list) {
	    Position x, y;
	    Dimension width, height;
	    Dimension border_width;
	    Colormap cmap;
	    int n;
	    Atom* wm_proto;
	    windowrec* wp;
	    Window destwin = XtWindow (This->plugin_widget);

	    This->nclient_windows++;
	    if (This->nclient_windows > 1)
		memcpy ((void*) new_list, (void*) This->client_windows,
			(This->nclient_windows - 1) * sizeof (windowrec));
	    if (This->client_windows)
		NPN_MemFree (This->client_windows);
	    This->client_windows = new_list;

	    x = y = 0;
	    width = height = border_width = 0;
	    GetWindowGeometry (RxGlobal.dpy, event->xmaprequest.window, 
			       &x, &y, &width, &height, &border_width, &cmap);

	    wp = &This->client_windows[This->nclient_windows - 1];
	    wp->win = event->xmaprequest.window;
	    wp->x = x; wp->y = y;
	    wp->width = width; wp->height = height;
	    wp->border_width = border_width;
	    wp->flags = RxpMapped;
	    wp->colormap = cmap;

	    if (XGetWMProtocols (RxGlobal.dpy, wp->win, &wm_proto, &n)) {
		int i;
		Atom* ap;

		for (i = 0, ap = wm_proto; i < n; i++, ap++) {
		    if (*ap == RxGlobal.wm_delete_window)
			wp->flags |= RxpWmDelWin;
		}
		if (wm_proto) XFree ((char*) wm_proto);
	    }

	    XSelectInput(RxGlobal.dpy, wp->win,
			 EnterWindowMask | LeaveWindowMask);
	    XtRegisterDrawable (RxGlobal.dpy, wp->win, This->plugin_widget);
	    XReparentWindow (RxGlobal.dpy, wp->win, destwin, wp->x, wp->y);
	    XMapWindow (RxGlobal.dpy, wp->win);
	}
	break;
    }
}
示例#24
0
void KSMServer::performLegacySessionSave()
{
    kdDebug( 1218 ) << "Saving legacy session apps" << endl;
    // Setup error handler
    legacyWindows.clear();
    windowMapPtr = &legacyWindows;
    XErrorHandler oldHandler = XSetErrorHandler(winsErrorHandler);
    // Compute set of leader windows that need legacy session management
    // and determine which style (WM_COMMAND or WM_SAVE_YOURSELF)
    KWinModule module;
    if( wm_save_yourself == (Atom)None ) {
	Atom atoms[ 3 ];
	const char* const names[]
	    = { "WM_SAVE_YOURSELF", "WM_PROTOCOLS", "WM_CLIENT_LEADER" };
	XInternAtoms( tqt_xdisplay(), const_cast< char** >( names ), 3,
	    False, atoms );
	wm_save_yourself = atoms[ 0 ];
	wm_protocols = atoms[ 1 ];
	wm_client_leader = atoms[ 2 ];
    }
    for ( TQValueList<WId>::ConstIterator it = module.windows().begin();
	  it != module.windows().end(); ++it) {
        WId leader = windowWmClientLeader( *it );
        if (!legacyWindows.contains(leader) && windowSessionId( *it, leader ).isEmpty()) {
            SMType wtype = SM_WMCOMMAND;
            int nprotocols = 0;
            Atom *protocols = 0;
            if( XGetWMProtocols(tqt_xdisplay(), leader, &protocols, &nprotocols)) {
                for (int i=0; i<nprotocols; i++)
                    if (protocols[i] == wm_save_yourself) {
                        wtype = SM_WMSAVEYOURSELF;
                        break;
                    }
                XFree((void*) protocols);
            }
	    SMData data;
	    data.type = wtype;
            XClassHint classHint;
            if( XGetClassHint( tqt_xdisplay(), leader, &classHint ) ) {
                data.wmclass1 = classHint.res_name;
                data.wmclass2 = classHint.res_class;
                XFree( classHint.res_name );
                XFree( classHint.res_class );
            }
            legacyWindows.insert(leader, data);
        }
    }
    // Open fresh display for sending WM_SAVE_YOURSELF
    XSync(tqt_xdisplay(), False);
    Display *newdisplay = XOpenDisplay(DisplayString(tqt_xdisplay()));
    if (!newdisplay) {
	windowMapPtr = NULL;
	XSetErrorHandler(oldHandler);
	return;
    }
    WId root = DefaultRootWindow(newdisplay);
    XGrabKeyboard(newdisplay, root, False,
                  GrabModeAsync, GrabModeAsync, CurrentTime);
    XGrabPointer(newdisplay, root, False, Button1Mask|Button2Mask|Button3Mask,
                 GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
    // Send WM_SAVE_YOURSELF messages
    XEvent ev;
    int awaiting_replies = 0;
    for (WindowMap::Iterator it = legacyWindows.begin(); it != legacyWindows.end(); ++it) {
        if ( (*it).type == SM_WMSAVEYOURSELF ) {
            WId w = it.key();
            awaiting_replies += 1;
            memset(&ev, 0, sizeof(ev));
            ev.xclient.type = ClientMessage;
            ev.xclient.window = w;
            ev.xclient.message_type = wm_protocols;
            ev.xclient.format = 32;
            ev.xclient.data.l[0] = wm_save_yourself;
            ev.xclient.data.l[1] = GET_QT_X_TIME();
            XSelectInput(newdisplay, w, PropertyChangeMask|StructureNotifyMask);
            XSendEvent(newdisplay, w, False, 0, &ev);
        }
    }
    // Wait for change in WM_COMMAND with timeout
    XFlush(newdisplay);
    TQTime start = TQTime::currentTime();
    while (awaiting_replies > 0) {
        if (XPending(newdisplay)) {
            /* Process pending event */
            XNextEvent(newdisplay, &ev);
            if ( ( ev.xany.type == UnmapNotify ) ||
                 ( ev.xany.type == PropertyNotify && ev.xproperty.atom == XA_WM_COMMAND ) ) {
                WindowMap::Iterator it = legacyWindows.find( ev.xany.window );
                if ( it != legacyWindows.end() && (*it).type != SM_WMCOMMAND ) {
                    awaiting_replies -= 1;
                    if ( (*it).type != SM_ERROR )
                        (*it).type = SM_WMCOMMAND;
                }
            }
        } else {
            /* Check timeout */
            int msecs = start.elapsed();
            if (msecs >= WM_SAVE_YOURSELF_TIMEOUT)
                break;
            /* Wait for more events */
            fd_set fds;
            FD_ZERO(&fds);
            int fd = ConnectionNumber(newdisplay);
            FD_SET(fd, &fds);
            struct timeval tmwait;
            tmwait.tv_sec = (WM_SAVE_YOURSELF_TIMEOUT - msecs) / 1000;
            tmwait.tv_usec = ((WM_SAVE_YOURSELF_TIMEOUT - msecs) % 1000) * 1000;
            ::select(fd+1, &fds, NULL, &fds, &tmwait);
        }
    }
    // Terminate work in new display
    XAllowEvents(newdisplay, ReplayPointer, CurrentTime);
    XAllowEvents(newdisplay, ReplayKeyboard, CurrentTime);
    XSync(newdisplay, False);
    XCloseDisplay(newdisplay);
    // Restore old error handler
    XSync(tqt_xdisplay(), False);
    XSetErrorHandler(oldHandler);
    for (WindowMap::Iterator it = legacyWindows.begin(); it != legacyWindows.end(); ++it) {
        if ( (*it).type != SM_ERROR) {
            WId w = it.key();
            (*it).wmCommand = windowWmCommand(w);
            (*it).wmClientMachine = windowWmClientMachine(w);
	}
    }
    kdDebug( 1218 ) << "Done saving " << legacyWindows.count() << " legacy session apps" << endl;
}