Пример #1
0
/** Set a client's sticky status. This will update transients. */
void SetClientSticky(ClientNode *np, char isSticky)
{

   ClientNode *tp;
   int x;
   char old;

   Assert(np);

   /* Get the old sticky status. */
   if(np->state.status & STAT_STICKY) {
      old = 1;
   } else {
      old = 0;
   }

   if(isSticky && !old) {

      /* Change from non-sticky to sticky. */

      for(x = 0; x < LAYER_COUNT; x++) {
         for(tp = nodes[x]; tp; tp = tp->next) {
            if(tp == np || tp->owner == np->window) {
               tp->state.status |= STAT_STICKY;
               SetCardinalAtom(tp->window, ATOM_NET_WM_DESKTOP, ~0UL);
               WriteState(tp);
            }
         }
      }

   } else if(!isSticky && old) {

      /* Change from sticky to non-sticky. */

      for(x = 0; x < LAYER_COUNT; x++) {
         for(tp = nodes[x]; tp; tp = tp->next) {
            if(tp == np || tp->owner == np->window) {
               tp->state.status &= ~STAT_STICKY;
               WriteState(tp);
            }
         }
      }

      /* Since this client is no longer sticky, we need to assign
       * a desktop. Here we use the current desktop.
       * Note that SetClientDesktop updates transients (which is good).
       */
      SetClientDesktop(np, currentDesktop);

   }

}
Пример #2
0
/*!
 *  This function saves the current window position and size using the base
 *  class persist method. Minimized and maximized state is also optionally
 *  preserved.
 *  @sa CResizableState::WriteState
 *  @note Window coordinates are in the form used by the system functions
 *  GetWindowPlacement and SetWindowPlacement.
 *
 *  @param pszName String that identifies stored settings
 *  @param bRectOnly Flag that specifies wether to ignore min/max state
 *
 *  @return Returns @a TRUE if successful, @a FALSE otherwise
 */
BOOL CResizableWndState::SaveWindowRect(LPCTSTR pszName, BOOL bRectOnly)
{
    CString data, id;
    WINDOWPLACEMENT wp;

    SecureZeroMemory(&wp, sizeof(WINDOWPLACEMENT));
    wp.length = sizeof(WINDOWPLACEMENT);
    if (!GetResizableWnd()->GetWindowPlacement(&wp))
        return FALSE;

    // use workspace coordinates
    RECT& rc = wp.rcNormalPosition;

    if (bRectOnly)  // save size/pos only (normal state)
    {
        data.Format(PLACEMENT_FMT, rc.left, rc.top,
            rc.right, rc.bottom, SW_SHOWNORMAL, 0, 0, 0);
    }
    else    // save also min/max state
    {
        data.Format(PLACEMENT_FMT, rc.left, rc.top,
            rc.right, rc.bottom, wp.showCmd, wp.flags,
            wp.ptMinPosition.x, wp.ptMinPosition.y);
    }

    id = CString(pszName) + PLACEMENT_ENT;
    return WriteState(id, data);
}
Пример #3
0
/*---------------------------------------------------------------------*/
BOOL ArchiveClose(H_ARCHIVE harchive)
{
    NODE *node;
    STREAM *stream;

    if (!ValidateHandle(harchive))
        return (FALSE);

    _archive[harchive].last_error = ARC_NO_ERROR;
    _archive_error = ARC_NO_ERROR;

    ArchiveLog(ARC_LOG_VERBOSE, "Close archive: %s", _archive[harchive].path);

    /* Close all open event files on archive... */
    if ((node = FirstNode(&_archive[harchive].streams))) {
        do {
            stream = (STREAM *) node->data;
            if (_archive[harchive].access == ARC_WRITE)
                CloseEventFileAndRename(harchive, stream);
            else
                CloseEventFile(stream);
        } while ((node = NextNode(node)) != NULL);
    }

    /* If open for write... */
    if (_archive[harchive].access == ARC_WRITE) {
        MUTEX_LOCK(&_archive[harchive].purge.mutex);
        if(_archive[harchive].purge.active ) {
            _archive[harchive].purge.stop = TRUE;
            MUTEX_UNLOCK(&_archive[harchive].purge.mutex);
            ArchiveLog(ARC_LOG_VERBOSE, "Stopping purge thread");
            SEM_POST(&_archive[harchive].purge.semaphore);
            THREAD_JOIN(&_archive[harchive].purge.thread_id);
        }
        else 
            MUTEX_UNLOCK(&_archive[harchive].purge.mutex);

        /* Mark as closed and write state to disk */
        _archive[harchive].state.write = FALSE;
        if (!WriteState(harchive))
            return (FALSE);
    }

    /* Close the state file */
    if (!FileClose(_archive[harchive].file)) {
        _archive[harchive].last_error = ARC_FILE_IO_ERROR;
        return (FALSE);
    }

    _n_archives--;

    /* Clear state */
    MUTEX_DESTROY(&_archive[harchive].mutex);
    DestroyList(&_archive[harchive].streams);
    DestroyPurge(&_archive[harchive].purge);

    InitArchive(harchive);

    return (TRUE);
}
Пример #4
0
/** Set a client's state to withdrawn. */
void SetClientWithdrawn(ClientNode *np)
{

   Assert(np);

   if(activeClient == np) {
      activeClient = NULL;
      np->state.status &= ~STAT_ACTIVE;
      FocusNextStacked(np);
   }

   if(np->state.status & STAT_MAPPED) {
      UnmapClient(np);
      if(np->parent != None) {
         JXUnmapWindow(display, np->parent);
      }
   } else if(np->state.status & STAT_SHADED) {
      if(!(np->state.status & STAT_MINIMIZED)) {
         if(np->parent != None) {
            JXUnmapWindow(display, np->parent);
         }
      }
   }

   np->state.status &= ~STAT_SHADED;
   np->state.status &= ~STAT_MINIMIZED;
   np->state.status &= ~STAT_SDESKTOP;

   WriteState(np);
   RequireTaskUpdate();
   RequirePagerUpdate();

}
Пример #5
0
/** Handle an unmap notify event. */
void HandleUnmapNotify(const XUnmapEvent *event) {

   ClientNode *np;
   XEvent e;

   Assert(event);

   np = FindClientByWindow(event->window);
   if(np && np->window == event->window) {

      if(JXCheckTypedWindowEvent(display, np->window, DestroyNotify, &e)) {
         HandleDestroyNotify(&e.xdestroywindow);
         return;
      }

      if(np->controller) {
         (np->controller)(1);
      }

      if(np->state.status & STAT_MAPPED) {

         np->state.status &= ~STAT_MAPPED;
         JXUnmapWindow(display, np->parent);

         WriteState(np);
         UpdateTaskBar();
         UpdatePager();

      }

   }

}
/*
** A "local" function of KeepState().  Enters #name# marked with #seqNo# into
** the state file (global) #journalPath#.  Used to keep a log of all writes
** performed by the memory.  Returns 1 if successful, else 0.
*/
static int
EnterInJournal(const char *name,
               double seqNo) {

  char journalRec[MAX_RECORD_SIZE];
  double now;

  memset(journalRec, 0, sizeof(journalRec));
  now = CurrentTime();

  if(sprintf(journalRec,"%10.0f %64s", seqNo, name) < 2) {
    FAIL1("EnterInJournal: write failed, errno %d\n", errno);
  }

  if(!WriteState(journalPath,
                 journalFileSize,
                 KEEP_A_LONG_TIME,
                 now,
                 journalRec,
                 strlen(journalRec))) {
    FAIL("EnterInJournal: write state failed\n");
  }

  return(1);

}
Пример #7
0
/** Minimize all transients as well as the specified client. */
void MinimizeTransients(ClientNode *np, char lower)
{

   ClientNode *tp;
   int x;

   Assert(np);

   /* Unmap the window and update its state. */
   if(np->state.status & (STAT_MAPPED | STAT_SHADED)) {
      UnmapClient(np);
      if(np->parent != None) {
         JXUnmapWindow(display, np->parent);
      }
   }
   np->state.status |= STAT_MINIMIZED;

   /* Minimize transient windows. */
   for(x = 0; x < LAYER_COUNT; x++) {
      tp = nodes[x];
      while(tp) {
         ClientNode *next = tp->next;
         if(tp->owner == np->window
            && (tp->state.status & (STAT_MAPPED | STAT_SHADED))
            && !(tp->state.status & STAT_MINIMIZED)) {
            MinimizeTransients(tp, lower);
         }
         tp = next;
      }
   }

   /* Focus the next window. */
   if(np->state.status & STAT_ACTIVE) {
      FocusNextStacked(np);
   }

   if(lower) {
      /* Move this client to the end of the layer list. */
      if(nodeTail[np->state.layer] != np) {
         if(np->prev) {
            np->prev->next = np->next;
         } else {
            nodes[np->state.layer] = np->next;
         }
         np->next->prev = np->prev;
         tp = nodeTail[np->state.layer];
         nodeTail[np->state.layer] = np;
         tp->next = np;
         np->prev = tp;
         np->next = NULL;
      }
   }

   WriteState(np);

}
Пример #8
0
/** Set the client layer. This will affect transients. */
void SetClientLayer(ClientNode *np, unsigned int layer)
{

   ClientNode *tp, *next;

   Assert(np);
   Assert(layer <= LAST_LAYER);

   if(np->state.layer != layer) {
      int x;

      /* Loop through all clients so we get transients. */
      for(x = FIRST_LAYER; x <= LAST_LAYER; x++) {
         tp = nodes[x];
         while(tp) {
            next = tp->next;
            if(tp == np || tp->owner == np->window) {

               /* Remove from the old node list */
               if(next) {
                  next->prev = tp->prev;
               } else {
                  nodeTail[tp->state.layer] = tp->prev;
               }
               if(tp->prev) {
                  tp->prev->next = next;
               } else {
                  nodes[tp->state.layer] = next;
               }

               /* Insert into the new node list */
               tp->prev = NULL;
               tp->next = nodes[layer];
               if(nodes[layer]) {
                  nodes[layer]->prev = tp;
               } else {
                  nodeTail[layer] = tp;
               }
               nodes[layer] = tp;

               /* Set the new layer */
               tp->state.layer = layer;
               WriteState(tp);

            }
            tp = next;
         }
      }

      RequireRestack();

   }

}
Пример #9
0
bool WorldSimulation::WriteState(string& s) const
{
  File f;
  if(!f.OpenData()) return false;
  if(!WriteState(f)) return false;
  const char* buf = (const char*)f.GetDataBuffer();
  //HACK for File internal buffer length bug returning buffer capacity rather
  //than size
  //int len = f.Length();
  int len = f.Position();
  s.resize(len);
  for(int i=0;i<len;i++) s[i] = buf[i];
  return true;
}
Пример #10
0
/*---------------------------------------------------------------------*/
BOOL OpenStateForWrite(H_ARCHIVE harchive)
{

    _archive[harchive].last_error = ARC_NO_ERROR;
    _archive_error = ARC_NO_ERROR;

    /* Create filespec for state file and open for read */
    sprintf(_archive[harchive].filespec, "%s%c%s", _archive[harchive].path,
        PATH_DELIMITER, STATE_FILENAME);
    if ((_archive[harchive].file = FileOpenForRead(_archive[harchive].filespec)) == VOID_H_FILE) {
        ArchiveLog(ARC_LOG_ERRORS, "OpenStateForWrite: Error opening state file: %s", _archive[harchive].filespec);
        _archive[harchive].last_error = ARC_FILE_IO_ERROR;
        return (FALSE);
    }
    /* Read the current state */
    if (!ReadState(harchive))
        return (FALSE);
    if (_archive[harchive].state.write) {
        ArchiveLog(ARC_LOG_ERRORS, "OpenStateForWrite: Archive is open for write by another process: %s", _archive[harchive].path);
        _archive[harchive].last_error = ARC_PERMISSION_DENIED;
        return (FALSE);
    }
    if (!FileClose(_archive[harchive].file)) {
        _archive[harchive].last_error = ARC_FILE_IO_ERROR;
        return (FALSE);
    }

    /* Reopen for write */
    if ((_archive[harchive].file = FileOpenForWrite(_archive[harchive].filespec)) == VOID_H_FILE) {
        ArchiveLog(ARC_LOG_ERRORS, "OpenStateForWrite: Error opening state file: %s", _archive[harchive].filespec);
        _archive[harchive].last_error = ARC_FILE_IO_ERROR;
        return (FALSE);
    }
    /* Mark as open for write */
    _archive[harchive].state.write = TRUE;
    /* Archive is open for read-write access */
    _archive[harchive].access = ARC_WRITE;
    /* Start the update timer */
    Timer48Start(&_archive[harchive].update, 0);
    if (!WriteState(harchive))
        return (FALSE);

    /* Start the update timer */
    Timer48Start(&_archive[harchive].update, UPDATE_INTERVAL);

    ArchiveLog(ARC_LOG_MAXIMUM, "State file opened for write: %s", _archive[harchive].filespec);

    return (TRUE);
}
Пример #11
0
void BodyParticleSystem::RunSimulation()
{
	Initialize();
	InitializeOpenCL();
	PutParticles(config.particle_count, hposold, hvelold);

	const std::string& configFilename = config.getConfigParser().getFilename();
	const std::string& pathPrefix = configFilename.substr(0, configFilename.find_last_of('.'));

    if (mkdir(pathPrefix.c_str(), 0755) == -1) {
	    std::cout << "Could not create directory '" << pathPrefix << "', exiting." << std::endl;
        exit(EXIT_FAILURE);
    }
    
    std::cout.precision(8);
	std::cout << std::fixed;
    
	time_t c0, c1;
	time(&c0);
	int it = 0;
	WriteState(pathPrefix, it); // write initial state
	for(it = 1; it <= config.step_count; ++it) // main propagation loop
	{
		PropagateStep();
		if ((it) % config.output_step_count == 0)
		{
			WriteState(pathPrefix, it);
			// output current statistics
			auto avg_s = std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(stats.average());
			std::cout << "Average OpenCL kernel runtime per iteration: " << avg_s.count() << " s" << std::endl;
		}
	}
	// NOTE: no final write, to have only equidistant simulation time intervalls between output values
	time(&c1);
	fprintf(stderr, "Simulation for %d particles over %d steps took %.0f s\n", config.particle_count, config.step_count, difftime(c1, c0));
}
Пример #12
0
/** Shade a client. */
void ShadeClient(ClientNode *np)
{

   Assert(np);

   if((np->state.status & (STAT_SHADED | STAT_FULLSCREEN)) ||
      !(np->state.border & BORDER_SHADE)) {
      return;
   }

   UnmapClient(np);
   np->state.status |= STAT_SHADED;

   WriteState(np);
   ResetBorder(np);
   RequirePagerUpdate();

}
Пример #13
0
/** Restore a window with its transients (helper method). */
void RestoreTransients(ClientNode *np, char raise)
{

   ClientNode *tp;
   int x;

   Assert(np);

   /* Make sure this window is on the current desktop. */
   SetClientDesktop(np, currentDesktop);

   /* Restore this window. */
   if(!(np->state.status & STAT_MAPPED)) {
      if(np->state.status & STAT_SHADED) {
         if(np->parent != None) {
            JXMapWindow(display, np->parent);
         }
      } else {
         JXMapWindow(display, np->window);
         if(np->parent != None) {
            JXMapWindow(display, np->parent);
         }
         np->state.status |= STAT_MAPPED;
      }
   }
   np->state.status &= ~STAT_MINIMIZED;
   np->state.status &= ~STAT_SDESKTOP;

   /* Restore transient windows. */
   for(x = 0; x < LAYER_COUNT; x++) {
      for(tp = nodes[x]; tp; tp = tp->next) {
         if(tp->owner == np->window && (tp->state.status & STAT_MINIMIZED)) {
            RestoreTransients(tp, raise);
         }
      }
   }

   if(raise) {
      FocusClient(np);
      RaiseClient(np);
   }
   WriteState(np);

}
Пример #14
0
/** Handle an unmap notify event. */
void HandleUnmapNotify(const XUnmapEvent *event)
{
   ClientNode *np;
   XEvent e;

   Assert(event);

   if(event->window != event->event) {
      /* Allow ICCCM synthetic UnmapNotify events through. */
      if (event->event != rootWindow || !event->send_event) {
         return;
      }
   }

   np = FindClientByWindow(event->window);
   if(np) {

      /* Grab the server to prevent the client from destroying the
       * window after we check for a DestroyNotify. */
      GrabServer();

      if(np->controller) {
         (np->controller)(1);
      }

      if(JXCheckTypedWindowEvent(display, np->window, DestroyNotify, &e)) {
         UpdateTime(&e);
         RemoveClient(np);
      } else if((np->state.status & STAT_MAPPED) || event->send_event) {
         if(!(np->state.status & STAT_HIDDEN)) {
            np->state.status &= ~STAT_MAPPED;
            JXUngrabButton(display, AnyButton, AnyModifier, np->window);
            GravitateClient(np, 1);
            JXReparentWindow(display, np->window, rootWindow, np->x, np->y);
            WriteState(np);
            JXRemoveFromSaveSet(display, np->window);
            RemoveClient(np);
         }
      }
      UngrabServer();

   }
}
Пример #15
0
/** Maximize a client window. */
void MaximizeClient(ClientNode *np, MaxFlags flags)
{

    /* Return if we don't have a client. */
    if(np == NULL) {
        return;
    }

   /* Don't allow maximization of full-screen clients. */
   if(np->state.status & STAT_FULLSCREEN) {
      return;
   }
   if(!(np->state.border & BORDER_MAX)) {
      return;
   }

   if(np->state.status & STAT_SHADED) {
      UnshadeClient(np);
   }

   RaiseClient(np);
   FocusClient(np);
   if(np->state.maxFlags) {
      /* Undo existing maximization. */
      np->x = np->oldx;
      np->y = np->oldy;
      np->width = np->oldWidth;
      np->height = np->oldHeight;
      np->state.maxFlags = MAX_NONE;
   }
   if(flags != MAX_NONE) {
      /* Maximize if requested. */
      PlaceMaximizedClient(np, flags);
   }

   WriteState(np);
   ResetBorder(np);
   DrawBorder(np);
   SendConfigureEvent(np);
   RequirePagerUpdate();

}
Пример #16
0
/** Handle a map request. */
void HandleMapRequest(const XMapEvent *event)
{
   ClientNode *np;
   Assert(event);
   if(CheckSwallowMap(event->window)) {
      return;
   }
   np = FindClientByWindow(event->window);
   if(!np) {
      GrabServer();
      np = AddClientWindow(event->window, 0, 1);
      if(np) {
         if(!(np->state.status & STAT_NOFOCUS)) {
            FocusClient(np);
         }
      } else {
         JXMapWindow(display, event->window);
      }
      UngrabServer();
   } else {
      if(!(np->state.status & STAT_MAPPED)) {
         UpdateState(np);
         np->state.status |= STAT_MAPPED;
         XMapWindow(display, np->window);
         if(np->parent != None) {
            XMapWindow(display, np->parent);
         }
         if(!(np->state.status & STAT_STICKY)) {
            np->state.desktop = currentDesktop;
         }
         if(!(np->state.status & STAT_NOFOCUS)) {
            FocusClient(np);
            RaiseClient(np);
         }
         WriteState(np);
         RequireTaskUpdate();
         RequirePagerUpdate();
      }
   }
   RequireRestack();
}
Пример #17
0
/*!
 *  This function saves the current property sheet active page using the base
 *  class persist method.
 *  @sa CResizableState::WriteState
 *
 *  @param pszName String that identifies stored settings
 *
 *  @return Returns @a TRUE if successful, @a FALSE otherwise
 */
BOOL CResizableSheetState::SavePage(LPCTSTR pszName)
{
    // saves active page index, or the initial page if problems
    // cannot use GetActivePage, because it always fails

    CPropertySheet* pSheet = DYNAMIC_DOWNCAST(CPropertySheet, GetResizableWnd());
    if (pSheet == NULL)
        return FALSE;

    int page = pSheet->m_psh.nStartPage;
    CTabCtrl *pTab = pSheet->GetTabControl();
    if (pTab != NULL)
        page = pTab->GetCurSel();
    if (page < 0)
        page = pSheet->m_psh.nStartPage;

    CString data, id;
    _itot(page, data.GetBuffer(10), 10);
    id = CString(pszName) + ACTIVEPAGE_ENT;
    return WriteState(id, data);
}
Пример #18
0
/** Unshade a client. */
void UnshadeClient(ClientNode *np)
{

   Assert(np);

   if(!(np->state.status & STAT_SHADED)) {
      return;
   }

   if(!(np->state.status & (STAT_MINIMIZED | STAT_SDESKTOP))) {
      JXMapWindow(display, np->window);
      np->state.status |= STAT_MAPPED;
   }
   np->state.status &= ~STAT_SHADED;

   WriteState(np);
   ResetBorder(np);
   RefocusClient();
   RequirePagerUpdate();

}
Пример #19
0
/*---------------------------------------------------------------------*/
BOOL ArchiveSync(H_ARCHIVE harchive)
{
    FILE_STAT stat;

    if (!ValidateHandle(harchive))
        return (FALSE);

    _archive[harchive].last_error = ARC_NO_ERROR;
    _archive_error = ARC_NO_ERROR;

    /* If we're open for write and the update timer has expired... */
    if (_archive[harchive].access == ARC_WRITE) {
        if (_archive[harchive].dirty) {
            if (!Timer48Expired(&_archive[harchive].update))
                return (TRUE);
            ArchiveLog(ARC_LOG_MAXIMUM, "Synchronize state file for write");
            if (!WriteState(harchive))
                return (FALSE);
            _archive[harchive].dirty = FALSE;
        }
        /* Restart the update timer */
        Timer48Restart(&_archive[harchive].update);
    }
    /* If we're open for read... */
    else if (_archive[harchive].access == ARC_READ) {
        /* If the state file has changed since we last looked... */
        if (!GetFileStat(_archive[harchive].filespec, &stat))
            return (FALSE);
        if (memcmp(&_archive[harchive].stat, &stat, sizeof(FILE_STAT)) != 0) {
            ArchiveLog(ARC_LOG_VERBOSE, "State file has changed, synchronizing");
            if (!ReadState(harchive))
                return (FALSE);
        }
    }
    else
        return (FALSE);

    return (TRUE);
}
Пример #20
0
/** Handle a _NET_MOVERESIZE_WINDOW request. */
void HandleNetMoveResize(const XClientMessageEvent *event, ClientNode *np) {

   long flags, gravity;
   long x, y;
   long width, height;
   int deltax, deltay;
   int north, south, east, west;

   Assert(event);
   Assert(np);

   gravity = event->data.l[0] & 0xFF;
   flags = event->data.l[0] >> 8;

   x = np->x;
   y = np->y;
   width = np->width;
   height = np->height;

   if(flags & (1 << 0)) {
      x = event->data.l[1];
   }
   if(flags & (1 << 1)) {
      y = event->data.l[2];
   }
   if(flags & (1 << 2)) {
      width = event->data.l[3];
   }
   if(flags & (1 << 3)) {
      height = event->data.l[4];
   }

   if(gravity == 0) {
      gravity = np->gravity;
   }

   GetBorderSize(np, &north, &south, &east, &west);
   GetGravityDelta(np, &deltax, &deltay);

   x -= deltax;
   y -= deltay;

   np->x = x;
   np->y = y;
   np->width = width;
   np->height = height;

   if(np->state.status & STAT_FULLSCREEN) {
      Warning("Fullscreen state will be shaped!");
   }

   /** Reset shaped bound */
   ResetRoundedRectWindow(np->parent);
   ShapeRoundedRectWindow(np->parent, 
      np->width + east + west,
      np->height + north + south);
   JXMoveResizeWindow(display, np->parent,
      np->x - west, np->y - north,
      np->width + east + west,
      np->height + north + south);
   JXMoveResizeWindow(display, np->window, west, north,
      np->width, np->height);

   WriteState(np);
   SendConfigureEvent(np);

}
Пример #21
0
/** Handle a property notify event. */
char HandlePropertyNotify(const XPropertyEvent *event)
{
   ClientNode *np = FindClientByWindow(event->window);
   if(np) {
      char changed = 0;
      switch(event->atom) {
      case XA_WM_NAME:
         ReadWMName(np);
         changed = 1;
         break;
      case XA_WM_NORMAL_HINTS:
         ReadWMNormalHints(np);
         if(ConstrainSize(np)) {
            ResetBorder(np);
         }
         changed = 1;
         break;
      case XA_WM_HINTS:
         if(np->state.status & STAT_URGENT) {
            UnregisterCallback(SignalUrgent, np);
         }
         ReadWMHints(np->window, &np->state, 1);
         if(np->state.status & STAT_URGENT) {
            RegisterCallback(URGENCY_DELAY, SignalUrgent, np);
         }
         WriteState(np);
         break;
      case XA_WM_TRANSIENT_FOR:
         JXGetTransientForHint(display, np->window, &np->owner);
         break;
      case XA_WM_ICON_NAME:
      case XA_WM_CLIENT_MACHINE:
         break;
      default:
         if(event->atom == atoms[ATOM_WM_COLORMAP_WINDOWS]) {
            ReadWMColormaps(np);
            UpdateClientColormap(np);
         } else if(event->atom == atoms[ATOM_WM_PROTOCOLS]) {
            ReadWMProtocols(np->window, &np->state);
         } else if(event->atom == atoms[ATOM_NET_WM_ICON]) {
            LoadIcon(np);
            changed = 1;
         } else if(event->atom == atoms[ATOM_NET_WM_NAME]) {
            ReadWMName(np);
            changed = 1;
         } else if(event->atom == atoms[ATOM_NET_WM_STRUT_PARTIAL]) {
            ReadClientStrut(np);
         } else if(event->atom == atoms[ATOM_NET_WM_STRUT]) {
            ReadClientStrut(np);
         } else if(event->atom == atoms[ATOM_MOTIF_WM_HINTS]) {
            UpdateState(np);
            WriteState(np);
            ResetBorder(np);
            changed = 1;
         } else if(event->atom == atoms[ATOM_NET_WM_WINDOW_OPACITY]) {
            ReadWMOpacity(np->window, &np->state.opacity);
            if(np->parent != None) {
               SetOpacity(np, np->state.opacity, 1);
            }
         }
         break;
      }

      if(changed) {
         DrawBorder(np);
         RequireTaskUpdate();
         RequirePagerUpdate();
      }
      if(np->state.status & STAT_WMDIALOG) {
         return 0;
      } else {
         return 1;
      }
   }

   return 1;
}
Пример #22
0
/** Add a window to management. */
ClientNode *AddClientWindow(Window w, char alreadyMapped, char notOwner)
{

   XWindowAttributes attr;
   ClientNode *np;

   Assert(w != None);

   /* Get window attributes. */
   if(JXGetWindowAttributes(display, w, &attr) == 0) {
      return NULL;
   }

   /* Determine if we should care about this window. */
   if(attr.override_redirect == True) {
      return NULL;
   }
   if(attr.class == InputOnly) {
      return NULL;
   }

   /* Prepare a client node for this window. */
   np = Allocate(sizeof(ClientNode));
   memset(np, 0, sizeof(ClientNode));

   np->window = w;
   np->owner = None;
   np->state.desktop = currentDesktop;

   np->x = attr.x;
   np->y = attr.y;
   np->width = attr.width;
   np->height = attr.height;
   np->cmap = attr.colormap;
   np->state.status = STAT_NONE;
   np->state.maxFlags = MAX_NONE;
   np->state.layer = LAYER_NORMAL;
   np->state.defaultLayer = LAYER_NORMAL;

   np->state.border = BORDER_DEFAULT;
   np->borderAction = BA_NONE;

   ReadClientInfo(np, alreadyMapped);

   if(!notOwner) {
      np->state.border = BORDER_OUTLINE | BORDER_TITLE | BORDER_MOVE;
      np->state.status |= STAT_WMDIALOG | STAT_STICKY;
      np->state.layer = LAYER_ABOVE;
      np->state.defaultLayer = LAYER_ABOVE;
   }

   ApplyGroups(np);
   if(np->icon == NULL) {
      LoadIcon(np);
   }

   /* We now know the layer, so insert */
   np->prev = NULL;
   np->next = nodes[np->state.layer];
   if(np->next) {
      np->next->prev = np;
   } else {
      nodeTail[np->state.layer] = np;
   }
   nodes[np->state.layer] = np;

   SetDefaultCursor(np->window);
   ReparentClient(np, notOwner);
   PlaceClient(np, alreadyMapped);

   if(!((np->state.status & STAT_FULLSCREEN) || np->state.maxFlags)) {
      int north, south, east, west;
      GetBorderSize(&np->state, &north, &south, &east, &west);
      if(np->parent != None) {
         JXMoveResizeWindow(display, np->parent, np->x - west, np->y - north,
                            np->width + east + west,
                            np->height + north + south);
         JXMoveResizeWindow(display, np->window, west, north,
                            np->width, np->height);
      } else {
         JXMoveResizeWindow(display, np->window, np->x, np->y,
                            np->width, np->height);
      }
   }

   /* If one of these fails we are SOL, so who cares. */
   XSaveContext(display, np->window, clientContext, (void*)np);
   if(np->parent != None) {
      XSaveContext(display, np->parent, frameContext, (void*)np);
   }

   if(np->state.status & STAT_MAPPED) {
      JXMapWindow(display, np->window);
      if(np->parent != None) {
         JXMapWindow(display, np->parent);
      }
   }

   clientCount += 1;

   if(!alreadyMapped) {
      RaiseClient(np);
   }

   if(np->state.status & STAT_OPACITY) {
      SetOpacity(np, np->state.opacity, 1);
   } else {
      SetOpacity(np, settings.inactiveClientOpacity, 1);
   }
   if(np->state.status & STAT_STICKY) {
      SetCardinalAtom(np->window, ATOM_NET_WM_DESKTOP, ~0UL);
   } else {
      SetCardinalAtom(np->window, ATOM_NET_WM_DESKTOP, np->state.desktop);
   }

   /* Shade the client if requested. */
   if(np->state.status & STAT_SHADED) {
      np->state.status &= ~STAT_SHADED;
      ShadeClient(np);
   }

   /* Minimize the client if requested. */
   if(np->state.status & STAT_MINIMIZED) {
      np->state.status &= ~STAT_MINIMIZED;
      MinimizeClient(np, 0);
   }

   /* Maximize the client if requested. */
   if(np->state.maxFlags) {
      const MaxFlags flags = np->state.maxFlags;
      np->state.maxFlags = MAX_NONE;
      MaximizeClient(np, flags);
   }

   if(np->state.status & STAT_URGENT) {
      RegisterCallback(URGENCY_DELAY, SignalUrgent, np);
   }

   /* Update task bars. */
   AddClientToTaskBar(np);

   /* Make sure we're still in sync */
   WriteState(np);
   SendConfigureEvent(np);

   /* Hide the client if we're not on the right desktop. */
   if(np->state.desktop != currentDesktop
      && !(np->state.status & STAT_STICKY)) {
      HideClient(np);
   }

   ReadClientStrut(np);

   /* Focus transients if their parent has focus. */
   if(np->owner != None) {
      if(activeClient && np->owner == activeClient->window) {
         FocusClient(np);
      }
   }

   /* Make the client fullscreen if requested. */
   if(np->state.status & STAT_FULLSCREEN) {
      np->state.status &= ~STAT_FULLSCREEN;
      SetClientFullScreen(np, 1);
   }
   ResetBorder(np);

   return np;

}
Пример #23
0
/** Handle a _NET_WM_STATE request. */
void HandleNetWMState(const XClientMessageEvent *event, ClientNode *np)
{

   unsigned int x;
   MaxFlags maxFlags;
   char actionStick;
   char actionShade;
   char actionFullScreen;
   char actionMinimize;
   char actionNolist;
   char actionNopager;
   char actionBelow;
   char actionAbove;

   /* Up to two actions to be applied together. */
   maxFlags = MAX_NONE;
   actionStick = 0;
   actionShade = 0;
   actionFullScreen = 0;
   actionMinimize = 0;
   actionNolist = 0;
   actionNopager = 0;
   actionBelow = 0;
   actionAbove = 0;

   for(x = 1; x <= 2; x++) {
      if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_STICKY]) {
         actionStick = 1;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_MAXIMIZED_VERT]) {
         maxFlags |= MAX_VERT;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_MAXIMIZED_HORZ]) {
         maxFlags |= MAX_HORIZ;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_SHADED]) {
         actionShade = 1;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_FULLSCREEN]) {
         actionFullScreen = 1;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_HIDDEN]) {
         actionMinimize = 1;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_SKIP_TASKBAR]) {
         actionNolist = 1;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_SKIP_PAGER]) {
         actionNopager = 1;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_BELOW]) {
         actionBelow = 1;
      } else if(event->data.l[x]
         == (long)atoms[ATOM_NET_WM_STATE_ABOVE]) {
         actionAbove = 1;
      }
   }

   switch(event->data.l[0]) {
   case 0: /* Remove */
      if(actionStick) {
         SetClientSticky(np, 0);
      }
      if(maxFlags != MAX_NONE && np->state.maxFlags) {
         MaximizeClient(np, np->state.maxFlags & ~maxFlags);
      }
      if(actionShade) {
         UnshadeClient(np);
      }
      if(actionFullScreen) {
         SetClientFullScreen(np, 0);
      }
      if(actionMinimize) {
         RestoreClient(np, 0);
      }
      if(actionNolist) {
         np->state.status &= ~STAT_NOLIST;
         RequireTaskUpdate();
      }
      if(actionNopager) {
         np->state.status &= ~STAT_NOPAGER;
         RequirePagerUpdate();
      }
      if(actionBelow && np->state.layer == LAYER_BELOW) {
         SetClientLayer(np, np->state.defaultLayer);
      }
      if(actionAbove && np->state.layer == LAYER_ABOVE) {
         SetClientLayer(np, np->state.defaultLayer);
      }
      break;
   case 1: /* Add */
      if(actionStick) {
         SetClientSticky(np, 1);
      }
      if(maxFlags != MAX_NONE) {
         MaximizeClient(np, np->state.maxFlags | maxFlags);
      }
      if(actionShade) {
         ShadeClient(np);
      }
      if(actionFullScreen) {
         SetClientFullScreen(np, 1);
      }
      if(actionMinimize) {
         MinimizeClient(np, 1);
      }
      if(actionNolist) {
         np->state.status |= STAT_NOLIST;
         RequireTaskUpdate();
      }
      if(actionNopager) {
         np->state.status |= STAT_NOPAGER;
         RequirePagerUpdate();
      }
      if(actionBelow) {
         SetClientLayer(np, LAYER_BELOW);
      }
      if(actionAbove) {
         SetClientLayer(np, LAYER_ABOVE);
      }
      break;
   case 2: /* Toggle */
      if(actionStick) {
         if(np->state.status & STAT_STICKY) {
            SetClientSticky(np, 0);
         } else {
            SetClientSticky(np, 1);
         }
      }
      if(maxFlags) {
         MaximizeClient(np, np->state.maxFlags ^ maxFlags);
      }
      if(actionShade) {
         if(np->state.status & STAT_SHADED) {
            UnshadeClient(np);
         } else {
            ShadeClient(np);
         }
      }
      if(actionFullScreen) {
         if(np->state.status & STAT_FULLSCREEN) {
            SetClientFullScreen(np, 0);
         } else {
            SetClientFullScreen(np, 1);
         }
      }
      if(actionBelow) {
         if(np->state.layer == LAYER_BELOW) {
            SetClientLayer(np, np->state.defaultLayer);
         } else {
            SetClientLayer(np, LAYER_BELOW);
         }
      }
      if(actionAbove) {
         if(np->state.layer == LAYER_ABOVE) {
            SetClientLayer(np, np->state.defaultLayer);
         } else {
            SetClientLayer(np, LAYER_ABOVE);
         }
      }
      /* Note that we don't handle toggling of hidden per EWMH
       * recommendations. */
      if(actionNolist) {
         np->state.status ^= STAT_NOLIST;
         RequireTaskUpdate();
      }
      if(actionNopager) {
         np->state.status ^= STAT_NOPAGER;
         RequirePagerUpdate();
      }
      break;
   default:
      Debug("bad _NET_WM_STATE action: %ld", event->data.l[0]);
      break;
   }

   /* Update _NET_WM_STATE if needed.
    * The state update is handled elsewhere for the other actions.
    */
   if(actionNolist | actionNopager | actionAbove | actionBelow) {
      WriteState(np);
   }

}
/*
** A "local" function of ProcessRequest() .  Stores #data# in #directory# with
** the attributes indicated by #s#.  Fails if the record size and count in #s#
** yield more than #max_size# total bytes.  Returns 1 if successful, else 0.
*/
static int
KeepState(const struct loglocation* logLoc,
          const struct state *s,
          const char *data,
          size_t max_size) {

  const char *curr;
  int i;
  size_t recordSize;

  if(s->rec_count > fileSize) {
    FAIL("KeepState: rec count too big\n");
  }

  if(s->rec_size > MAX_RECORD_SIZE) {
    WARN("KeepState: state record too big.\n");
    recordSize = MAX_RECORD_SIZE;
  }
  else {
    recordSize = (size_t)s->rec_size;
  }

  if(s->rec_count * recordSize > max_size) {
    FAIL1("KeepState: too much data %d\n", s->rec_count * recordSize);
  }

#ifdef WITH_NETLOGGER
  if (logLoc->loc_type==MEMORY_LOG_NETLOGGER)
  {
          for(curr = data, i = 0; i < s->rec_count; curr += recordSize, i++) {
                  if(!WriteStateNL(logLoc->path,
                          s->id,
                          fileSize,
                          s->time_out,
                          s->seq_no,
                          curr,
                          recordSize) ||
                          !EnterInJournal(s->id, s->seq_no)) {
                          if(errno == EMFILE) {
                                  CheckConnections();
                          }
                          FAIL("KeepState: write failed\n");
                  }
          }
          return (1);
  }
#endif /* WITH_NETLOGGER */

  for(curr = data, i = 0; i < s->rec_count; curr += recordSize, i++) {
    if(!WriteState(FileOfState(logLoc->path, s->id),
                   fileSize,
                   s->time_out,
                   s->seq_no,
                   curr,
                   recordSize) ||
       !EnterInJournal(s->id, s->seq_no)) {
      if(errno == EMFILE) {
        CheckConnections();
      }
      FAIL("KeepState: write failed\n");
    }
  }

  return(1);

}
Пример #25
0
COptionsDlg::~COptionsDlg()
{
	WriteState();
}
Пример #26
0
/** Set a client's full screen state. */
void SetClientFullScreen(ClientNode *np, char fullScreen)
{

   XEvent event;
   int north, south, east, west;
   BoundingBox box;
   const ScreenType *sp;

   Assert(np);

   /* Make sure there's something to do. */
   if(!fullScreen == !(np->state.status & STAT_FULLSCREEN)) {
      return;
   }
   if(!(np->state.border & BORDER_FULLSCREEN)) {
      return;
   }

   if(np->state.status & STAT_SHADED) {
      UnshadeClient(np);
   }

   if(fullScreen) {

      np->state.status |= STAT_FULLSCREEN;

      if(!(np->state.maxFlags)) {
         np->oldx = np->x;
         np->oldy = np->y;
         np->oldWidth = np->width;
         np->oldHeight = np->height;
      }

      sp = GetCurrentScreen(np->x, np->y);
      GetScreenBounds(sp, &box);

      GetBorderSize(&np->state, &north, &south, &east, &west);
      box.x += west;
      box.y += north;
      box.width -= east + west;
      box.height -= north + south;

      np->x = box.x;
      np->y = box.y;
      np->width = box.width;
      np->height = box.height;
      ResetBorder(np);

   } else {

      np->state.status &= ~STAT_FULLSCREEN;

      np->x = np->oldx;
      np->y = np->oldy;
      np->width = np->oldWidth;   
      np->height = np->oldHeight;
      ConstrainSize(np);
      ConstrainPosition(np);

      if(np->state.maxFlags != MAX_NONE) {
         PlaceMaximizedClient(np, np->state.maxFlags);
      }

      ResetBorder(np);

      event.type = MapRequest;
      event.xmaprequest.send_event = True;
      event.xmaprequest.display = display;
      event.xmaprequest.parent = np->parent;
      event.xmaprequest.window = np->window;
      JXSendEvent(display, rootWindow, False,
                  SubstructureRedirectMask, &event);

   }

   WriteState(np);
   SendConfigureEvent(np);
   RequireRestack();

}
Пример #27
0
/** Resize a client window (mouse initiated). */
void ResizeClient(ClientNode *np, BorderActionType action,
                  int startx, int starty) {

   XEvent event;
   int oldx, oldy;
   int oldw, oldh;
   int gwidth, gheight;
   int lastgwidth, lastgheight;
   int delta;
   int north, south, east, west;
   int ratio, minr, maxr;

   Assert(np);

   if(!(np->state.border & BORDER_RESIZE)) {
      return;
   }

   if(JUNLIKELY(!GrabMouseForResize(action))) {
      Debug("ResizeClient: could not grab mouse");
      return;
   }

   if(np->state.status & STAT_SHADED) {
      action &= ~(BA_RESIZE_N | BA_RESIZE_S);
   }

   np->controller = ResizeController;
   shouldStopResize = 0;

   oldx = np->x;
   oldy = np->y;
   oldw = np->width;
   oldh = np->height;

   gwidth = (np->width - np->baseWidth) / np->xinc;
   gheight = (np->height - np->baseHeight) / np->yinc;

   GetBorderSize(np, &north, &south, &east, &west);

   startx += np->x - west;
   starty += np->y - north;

   CreateResizeWindow(np);
   UpdateResizeWindow(np, gwidth, gheight);

   if(!(GetMouseMask() & (Button1Mask | Button3Mask))) {
      StopResize(np);
      return;
   }

   for(;;) {

      WaitForEvent(&event);

      if(shouldStopResize) {
         np->controller = NULL;
         return;
      }

      switch(event.type) {
      case ButtonRelease:
         if(   event.xbutton.button == Button1
            || event.xbutton.button == Button3) {
            StopResize(np);
            return;
         }
         break;
      case MotionNotify:

         SetMousePosition(event.xmotion.x_root, event.xmotion.y_root);
         DiscardMotionEvents(&event, np->window);

         if(action & BA_RESIZE_N) {
            delta = (event.xmotion.y - starty) / np->yinc;
            delta *= np->yinc;
            if(oldh - delta >= np->minHeight
               && (oldh - delta <= np->maxHeight || delta > 0)) {
               np->height = oldh - delta;
               np->y = oldy + delta;
            }
            if(!(action & (BA_RESIZE_E | BA_RESIZE_W))) {
               FixWidth(np);
            }
         }
         if(action & BA_RESIZE_S) {
            delta = (event.xmotion.y - starty) / np->yinc;
            delta *= np->yinc;
            np->height = oldh + delta;
            np->height = Max(np->height, np->minHeight);
            np->height = Min(np->height, np->maxHeight);
            if(!(action & (BA_RESIZE_E | BA_RESIZE_W))) {
               FixWidth(np);
            }
         }
         if(action & BA_RESIZE_E) {
            delta = (event.xmotion.x - startx) / np->xinc;
            delta *= np->xinc;
            np->width = oldw + delta;
            np->width = Max(np->width, np->minWidth);
            np->width = Min(np->width, np->maxWidth);
            if(!(action & (BA_RESIZE_N | BA_RESIZE_S))) {
               FixHeight(np);
            }
         }
         if(action & BA_RESIZE_W) {
            delta = (event.xmotion.x - startx) / np->xinc;
            delta *= np->xinc;
            if(oldw - delta >= np->minWidth
               && (oldw - delta <= np->maxWidth || delta > 0)) {
               np->width = oldw - delta;
               np->x = oldx + delta;
            }
            if(!(action & (BA_RESIZE_N | BA_RESIZE_S))) {
               FixHeight(np);
            }
         }

         if(np->sizeFlags & PAspect) {
            if((action & (BA_RESIZE_N | BA_RESIZE_S)) &&
               (action & (BA_RESIZE_E | BA_RESIZE_W))) {

               /* Fixed point with a 16-bit fraction. */
               ratio = (np->width << 16) / np->height;

               minr = (np->aspect.minx << 16) / np->aspect.miny;
               if(ratio < minr) {
                  delta = np->width;
                  np->width = (np->height * minr) >> 16;
                  if(action & BA_RESIZE_W) {
                     np->x -= np->width - delta;
                  }
               }

               maxr = (np->aspect.maxx << 16) / np->aspect.maxy;
               if(ratio > maxr) {
                  delta = np->height;
                  np->height = (np->width << 16) / maxr;
                  if(action & BA_RESIZE_N) {
                     np->y -= np->height - delta;
                  }
               }

            }
         }

         lastgwidth = gwidth;
         lastgheight = gheight;

         gwidth = (np->width - np->baseWidth) / np->xinc;
         gheight = (np->height - np->baseHeight) / np->yinc;

         if(lastgheight != gheight || lastgwidth != gwidth) {

            if(np->state.status & (STAT_HMAX | STAT_VMAX)) {
               np->state.status &= ~(STAT_HMAX | STAT_VMAX);
               WriteState(np);
               SendConfigureEvent(np);
            }

            UpdateResizeWindow(np, gwidth, gheight);

            if(resizeMode == RESIZE_OUTLINE) {
               ClearOutline();
               if(np->state.status & STAT_SHADED) {
                  DrawOutline(np->x - west, np->y - north,
                     np->width + west + east, north + south);
               } else {
                  DrawOutline(np->x - west, np->y - north,
                     np->width + west + east,
                     np->height + north + south);
               }
            } else {
               ResetRoundedRectWindow(np->parent);
               if(np->state.status & STAT_SHADED) {
                  ShapeRoundedRectWindow(np->parent, 
                     np->width + east + west,
                     north + south);
                  JXMoveResizeWindow(display, np->parent,
                     np->x - west, np->y - north,
                     np->width + west + east, north + south);
               } else {
                  ShapeRoundedRectWindow(np->parent, 
                     np->width + east + west,
                     np->height + north + south);
                  JXMoveResizeWindow(display, np->parent,
                     np->x - west, np->y - north,
                     np->width + west + east,
                     np->height + north + south);
               }
               JXMoveResizeWindow(display, np->window, west,
                  north, np->width, np->height);
               SendConfigureEvent(np);
            }

            UpdatePager();

         }

         break;
      default:
         break;
      }