<commit_before>#include "audio_draw.h"
#include "audio_nodes.h"
#include "recorder_node.h"

#include <cinder/audio/Utilities.h>
#include <cinder/audio/MonitorNode.h>
#include <cinder/Font.h>
#include <cinder/gl/gl.h>
#include <cinder/gl/TextureFont.h>
#include <cinder/app/App.h>
#include <cinder/Area.h>

#include "Resources.h"

namespace cieq
{

Plot::Plot()
	: mDrawBounds(true)
	, mBoundsColor(0.5f, 0.5f, 0.5f, 1)
{}

void Plot::draw()
{
	drawLocal();

	if (mDrawBounds)
	{
		drawBounds();
	}

	if (mDrawLabels)
	{
		drawLabels();
	}
}

void Plot::drawBounds()
{
	ci::gl::color(mBoundsColor);
	ci::gl::drawStrokedRect(mBounds);
}

void Plot::drawLabels()
{
	ci::gl::color(0, 0.9f, 0.9f);

	// draw x-axis label
	ci::gl::drawStringCentered(mHorzText, ci::Vec2f(mBounds.x1 + mBounds.getWidth() / 2.0f, mBounds.y2 + mLabelFont.getSize()), ci::ColorA::white(), mLabelFont);

	// draw plot title
	ci::gl::drawStringCentered(mPlotTitle, ci::Vec2f(mBounds.x1 + mBounds.getWidth() / 2.0f, mBounds.y1 - mLabelFont.getSize() * 2.0f), ci::ColorA::white(), mLabelFont);

	// draw y-axis label
	ci::gl::pushModelView();
	ci::gl::translate(mBounds.x1 - mLabelFont.getSize() * 2.0f, mBounds.y1 + mBounds.getHeight() / 2.0f);
	ci::gl::rotate(-90.0f);
	ci::gl::drawStringCentered(mVertText, ci::Vec2f::zero(), ci::ColorA::white(), mLabelFont);
	ci::gl::popModelView();
}

void Plot::onHorzAxisTextChange()
{
	mHorzText = mHorzTitle + " (" + mHorzUnit +")";
}

void Plot::onVertAxisTextChange()
{
	mVertText = mVertTitle + " (" + mVertUnit + ")";
}

void Plot::setup()
{
	mLabelFont = ci::Font(ci::app::loadResource(LABEL_FONT), 16);
}

SpectrumPlot::SpectrumPlot(AudioNodes& nodes)
	: mScaleDecibels( true )
	, mAudioNodes(nodes)
{
	setPlotTitle("FFT Analysis of input data");
	setHorzAxisTitle("Frequency").setHorzAxisUnit("Hz");
	setVertAxisTitle("Magnitude").setVertAxisUnit("Db");
}

// original draw function is from Cinder examples _audio/common
void SpectrumPlot::drawLocal()
{
	auto spectrum = mAudioNodes.getMonitorSpectralNode()->getMagSpectrum();

	if (spectrum.empty())
		return;

	ci::ColorA bottomColor(0, 0, 0.7f, 1);

	float width = mBounds.getWidth();
	float height = mBounds.getHeight();
	std::size_t numBins = spectrum.size();
	float padding = 0;
	float binWidth = ( width - padding * ( numBins - 1 ) ) / (float)numBins;

	std::size_t numVerts = spectrum.size() * 2 + 2;
	if( mVerts.size() < numVerts ) {
		mVerts.resize( numVerts );
		mColors.resize( numVerts );
	}

	std::size_t currVertex = 0;
	ci::Rectf bin(mBounds.x1, mBounds.y1, mBounds.x1 + binWidth, mBounds.y2);
	for( std::size_t i = 0; i < numBins; i++ ) {
		float m = spectrum[i];
		if( mScaleDecibels )
			m = ci::audio::linearToDecibel(m) / 100;

		bin.y1 = bin.y2 - m * height;

		mVerts[currVertex] = bin.getLowerLeft();
		mColors[currVertex] = bottomColor;
		mVerts[currVertex + 1] = bin.getUpperLeft();
		mColors[currVertex + 1] = ci::ColorA( 0, m, 0.7f, 1 );

		bin += ci::Vec2f(binWidth + padding, 0);
		currVertex += 2;
	}

	mVerts[currVertex] = bin.getLowerLeft();
	mColors[currVertex] = bottomColor;
	mVerts[currVertex + 1] = bin.getUpperLeft();
	mColors[currVertex + 1] = mColors[currVertex - 1];

	ci::gl::color(0, 0.9f, 0);

	glEnableClientState( GL_VERTEX_ARRAY );
	glEnableClientState( GL_COLOR_ARRAY );
	glVertexPointer( 2, GL_FLOAT, 0, mVerts.data() );
	glColorPointer( 4, GL_FLOAT, 0, mColors.data() );  // note: on OpenGL ES v1.1, the 'size' param to glColorPointer can only be 4
	glDrawArrays( GL_TRIANGLE_STRIP, 0, (GLsizei)mVerts.size() );
	glDisableClientState( GL_VERTEX_ARRAY );
	glDisableClientState( GL_COLOR_ARRAY );
}

void SpectrumPlot::enableDecibelsScale(bool on /*= true*/)
{
	mScaleDecibels = on;
}

WaveformPlot::WaveformPlot(AudioNodes& nodes)
	: mGraphColor(0, 0.9f, 0, 1)
	, mAudioNodes(nodes)
{
	setPlotTitle("RAW input data");
	setHorzAxisTitle("Time").setHorzAxisUnit("s");
	setVertAxisTitle("Amplitude").setVertAxisUnit("...");
}

void WaveformPlot::setGraphColor(const ci::ColorA& color)
{
	mGraphColor = color;
}

// original draw function is from Cinder examples _audio/common
void WaveformPlot::drawLocal()
{
	auto buffer = mAudioNodes.getMonitorNode()->getBuffer();

	ci::gl::color(mGraphColor);

	const float waveHeight = mBounds.getHeight() / (float)buffer.getNumChannels();
	const float xScale = mBounds.getWidth() / (float)buffer.getNumFrames();

	float yOffset = mBounds.y1;
	for (std::size_t ch = 0; ch < buffer.getNumChannels(); ch++) {
		ci::PolyLine2f waveform;
		const float *channel = buffer.getChannel(ch);
		float x = mBounds.x1;
		for (std::size_t i = 0; i < buffer.getNumFrames(); i++) {
			x += xScale;
			float y = (1 - (channel[i] * 0.5f + 0.5f)) * waveHeight + yOffset;
			waveform.push_back(ci::Vec2f(x, y));
		}

		if (!waveform.getPoints().empty())
			ci::gl::draw(waveform);

		yOffset += waveHeight;
	}
}

SpectrogramPlot::SpectrogramPlot(AudioNodes& nodes)
	: mAudioNodes(nodes)
	, mTexH(0)
	, mTexW(0)
	, mFrameCounter(0)
	, mActiveSurface(0)
	, mBackBufferSurface(1)
{
	setPlotTitle("Spectrogram");
	setHorzAxisTitle("Frequency").setHorzAxisUnit("Hz");
	setVertAxisTitle("Time").setVertAxisUnit("s");
}

void SpectrogramPlot::drawLocal()
{
	auto spectrum = mAudioNodes.getMonitorSpectralNode()->getMagSpectrum();

	if (spectrum.empty())
		return;

	auto surface_iter = mSpectrals[mActiveSurface].getIter();
	while (surface_iter.line())
	{
		if (surface_iter.mY != mFrameCounter) continue;
		while (surface_iter.pixel())
		{
			auto m = ci::audio::linearToDecibel(spectrum[surface_iter.mX]) / 100;
			surface_iter.r() = m;
			surface_iter.g() = m;
			surface_iter.b() = 1.0f - m;
		}
	}

	//mFrameCounter++;

	const auto height_offset = (mFrameCounter)* (mBounds.getHeight() / mTexH);
	const auto available_height = mBounds.getHeight() - height_offset;

	ci::gl::draw(mSpectrals[mActiveSurface], mBounds);
	ci::Area requested_area(0, mFrameCounter, mTexW, mTexH);
	ci::Rectf requested_rect(mBounds.x1, mBounds.y1 + height_offset, mBounds.x2, mBounds.y2);
	ci::gl::draw(mTexCache, requested_area, requested_rect);

	mFrameCounter++;

	if (mFrameCounter >= mTexH)
	{
		mFrameCounter = 0;
		std::swap(mActiveSurface, mBackBufferSurface);
		mTexCache.update(mSpectrals[mBackBufferSurface]);
	}
}

void SpectrogramPlot::setup()
{
	Plot::setup();
	mTexW = mAudioNodes.getMonitorSpectralNode()->getNumBins();
	//swap out the texture every 3 seconds
	mTexH = static_cast<std::size_t>(ci::app::getFrameRate() * 3.0f);

	mSpectrals[0] = ci::Surface32f(mTexW, mTexH, false);
	mSpectrals[1] = ci::Surface32f(mTexW, mTexH, false);

	mTexCache = ci::gl::Texture(mSpectrals.back());
}

ContiguousWaveformPlot::ContiguousWaveformPlot(AudioNodes& nodes)
	: mGraphColor(0, 0.9f, 0, 1)
	, mAudioNodes(nodes)
	, mSampleToSkip(0)
{
	setPlotTitle("Recorded input data");
	setHorzAxisTitle("Time").setHorzAxisUnit("s");
	setVertAxisTitle("Sample").setVertAxisUnit("units");
}

void ContiguousWaveformPlot::setGraphColor(const ci::ColorA& color)
{
	mGraphColor = color;
}

void ContiguousWaveformPlot::drawLocal()
{
	auto points = mAudioNodes.getBufferRecorderNode()->getRecordedCopy();

	ci::gl::color(mGraphColor);

	const float waveHeight = mBounds.getHeight() / (float)points->getNumChannels();
	const float xScale = 1.0f;

	float yOffset = mBounds.y1;
	for (std::size_t ch = 0; ch < points->getNumChannels(); ch++)
	{
		const float *channel = points->getChannel(ch);
		for (std::size_t i = 0; i < mAudioNodes.getBufferRecorderNode()->getWritePosition(); i += mSampleToSkip)
		{
			if (mGraphs[ch].size() <= i / mSampleToSkip)
			{
				float x = mBounds.x1 + mGraphs[ch].getPoints().size();
				float y = (1 - (channel[i] * 0.5f + 0.5f));

				for (std::size_t j = i; i > mSampleToSkip && j > i - mSampleToSkip; --j)
				{
					y = (y + (1 - (channel[j] * 0.5f + 0.5f))) / 2.0f;
				}

				y *= waveHeight;
				if (ci::math<float>::abs(y) > waveHeight) y = 0; //fix me
				y += yOffset;

				mGraphs[ch].push_back(ci::Vec2f(x, y));
			}
		}

		if (!mGraphs[ch].getPoints().empty())
			ci::gl::draw(mGraphs[ch]);

		yOffset += waveHeight;
	}
}

void ContiguousWaveformPlot::setup()
{
	Plot::setup();
	auto recorder = mAudioNodes.getBufferRecorderNode();
	mGraphs.resize(mAudioNodes.getBufferRecorderNode()->getNumChannels());
	mSampleToSkip = static_cast<std::size_t>(recorder->getNumFrames() / mBounds.getWidth());
}

} //!namespace cieq<commit_msg>Changed contiguous audio draw logic for a better estimate of the actual signal<commit_after>#include "audio_draw.h"
#include "audio_nodes.h"
#include "recorder_node.h"

#include <cinder/audio/Utilities.h>
#include <cinder/audio/MonitorNode.h>
#include <cinder/Font.h>
#include <cinder/gl/gl.h>
#include <cinder/gl/TextureFont.h>
#include <cinder/app/App.h>
#include <cinder/Area.h>

#include "Resources.h"

namespace cieq
{

Plot::Plot()
	: mDrawBounds(true)
	, mBoundsColor(0.5f, 0.5f, 0.5f, 1)
{}

void Plot::draw()
{
	drawLocal();

	if (mDrawBounds)
	{
		drawBounds();
	}

	if (mDrawLabels)
	{
		drawLabels();
	}
}

void Plot::drawBounds()
{
	ci::gl::color(mBoundsColor);
	ci::gl::drawStrokedRect(mBounds);
}

void Plot::drawLabels()
{
	ci::gl::color(0, 0.9f, 0.9f);

	// draw x-axis label
	ci::gl::drawStringCentered(mHorzText, ci::Vec2f(mBounds.x1 + mBounds.getWidth() / 2.0f, mBounds.y2 + mLabelFont.getSize()), ci::ColorA::white(), mLabelFont);

	// draw plot title
	ci::gl::drawStringCentered(mPlotTitle, ci::Vec2f(mBounds.x1 + mBounds.getWidth() / 2.0f, mBounds.y1 - mLabelFont.getSize() * 2.0f), ci::ColorA::white(), mLabelFont);

	// draw y-axis label
	ci::gl::pushModelView();
	ci::gl::translate(mBounds.x1 - mLabelFont.getSize() * 2.0f, mBounds.y1 + mBounds.getHeight() / 2.0f);
	ci::gl::rotate(-90.0f);
	ci::gl::drawStringCentered(mVertText, ci::Vec2f::zero(), ci::ColorA::white(), mLabelFont);
	ci::gl::popModelView();
}

void Plot::onHorzAxisTextChange()
{
	mHorzText = mHorzTitle + " (" + mHorzUnit +")";
}

void Plot::onVertAxisTextChange()
{
	mVertText = mVertTitle + " (" + mVertUnit + ")";
}

void Plot::setup()
{
	mLabelFont = ci::Font(ci::app::loadResource(LABEL_FONT), 16);
}

SpectrumPlot::SpectrumPlot(AudioNodes& nodes)
	: mScaleDecibels( true )
	, mAudioNodes(nodes)
{
	setPlotTitle("FFT Analysis of input data");
	setHorzAxisTitle("Frequency").setHorzAxisUnit("Hz");
	setVertAxisTitle("Magnitude").setVertAxisUnit("Db");
}

// original draw function is from Cinder examples _audio/common
void SpectrumPlot::drawLocal()
{
	auto spectrum = mAudioNodes.getMonitorSpectralNode()->getMagSpectrum();

	if (spectrum.empty())
		return;

	ci::ColorA bottomColor(0, 0, 0.7f, 1);

	float width = mBounds.getWidth();
	float height = mBounds.getHeight();
	std::size_t numBins = spectrum.size();
	float padding = 0;
	float binWidth = ( width - padding * ( numBins - 1 ) ) / (float)numBins;

	std::size_t numVerts = spectrum.size() * 2 + 2;
	if( mVerts.size() < numVerts ) {
		mVerts.resize( numVerts );
		mColors.resize( numVerts );
	}

	std::size_t currVertex = 0;
	ci::Rectf bin(mBounds.x1, mBounds.y1, mBounds.x1 + binWidth, mBounds.y2);
	for( std::size_t i = 0; i < numBins; i++ ) {
		float m = spectrum[i];
		if( mScaleDecibels )
			m = ci::audio::linearToDecibel(m) / 100;

		bin.y1 = bin.y2 - m * height;

		mVerts[currVertex] = bin.getLowerLeft();
		mColors[currVertex] = bottomColor;
		mVerts[currVertex + 1] = bin.getUpperLeft();
		mColors[currVertex + 1] = ci::ColorA( 0, m, 0.7f, 1 );

		bin += ci::Vec2f(binWidth + padding, 0);
		currVertex += 2;
	}

	mVerts[currVertex] = bin.getLowerLeft();
	mColors[currVertex] = bottomColor;
	mVerts[currVertex + 1] = bin.getUpperLeft();
	mColors[currVertex + 1] = mColors[currVertex - 1];

	ci::gl::color(0, 0.9f, 0);

	glEnableClientState( GL_VERTEX_ARRAY );
	glEnableClientState( GL_COLOR_ARRAY );
	glVertexPointer( 2, GL_FLOAT, 0, mVerts.data() );
	glColorPointer( 4, GL_FLOAT, 0, mColors.data() );  // note: on OpenGL ES v1.1, the 'size' param to glColorPointer can only be 4
	glDrawArrays( GL_TRIANGLE_STRIP, 0, (GLsizei)mVerts.size() );
	glDisableClientState( GL_VERTEX_ARRAY );
	glDisableClientState( GL_COLOR_ARRAY );
}

void SpectrumPlot::enableDecibelsScale(bool on /*= true*/)
{
	mScaleDecibels = on;
}

WaveformPlot::WaveformPlot(AudioNodes& nodes)
	: mGraphColor(0, 0.9f, 0, 1)
	, mAudioNodes(nodes)
{
	setPlotTitle("RAW input data");
	setHorzAxisTitle("Time").setHorzAxisUnit("s");
	setVertAxisTitle("Amplitude").setVertAxisUnit("...");
}

void WaveformPlot::setGraphColor(const ci::ColorA& color)
{
	mGraphColor = color;
}

// original draw function is from Cinder examples _audio/common
void WaveformPlot::drawLocal()
{
	auto buffer = mAudioNodes.getMonitorNode()->getBuffer();

	ci::gl::color(mGraphColor);

	const float waveHeight = mBounds.getHeight() / (float)buffer.getNumChannels();
	const float xScale = mBounds.getWidth() / (float)buffer.getNumFrames();

	float yOffset = mBounds.y1;
	for (std::size_t ch = 0; ch < buffer.getNumChannels(); ch++) {
		ci::PolyLine2f waveform;
		const float *channel = buffer.getChannel(ch);
		float x = mBounds.x1;
		for (std::size_t i = 0; i < buffer.getNumFrames(); i++) {
			x += xScale;
			float y = (1 - (channel[i] * 0.5f + 0.5f)) * waveHeight + yOffset;
			waveform.push_back(ci::Vec2f(x, y));
		}

		if (!waveform.getPoints().empty())
			ci::gl::draw(waveform);

		yOffset += waveHeight;
	}
}

SpectrogramPlot::SpectrogramPlot(AudioNodes& nodes)
	: mAudioNodes(nodes)
	, mTexH(0)
	, mTexW(0)
	, mFrameCounter(0)
	, mActiveSurface(0)
	, mBackBufferSurface(1)
{
	setPlotTitle("Spectrogram");
	setHorzAxisTitle("Frequency").setHorzAxisUnit("Hz");
	setVertAxisTitle("Time").setVertAxisUnit("s");
}

void SpectrogramPlot::drawLocal()
{
	auto spectrum = mAudioNodes.getMonitorSpectralNode()->getMagSpectrum();

	if (spectrum.empty())
		return;

	auto surface_iter = mSpectrals[mActiveSurface].getIter();
	while (surface_iter.line())
	{
		if (surface_iter.mY != mFrameCounter) continue;
		while (surface_iter.pixel())
		{
			auto m = ci::audio::linearToDecibel(spectrum[surface_iter.mX]) / 100;
			surface_iter.r() = m;
			surface_iter.g() = m;
			surface_iter.b() = 1.0f - m;
		}
	}

	//mFrameCounter++;

	const auto height_offset = (mFrameCounter)* (mBounds.getHeight() / mTexH);
	const auto available_height = mBounds.getHeight() - height_offset;

	ci::gl::draw(mSpectrals[mActiveSurface], mBounds);
	ci::Area requested_area(0, mFrameCounter, mTexW, mTexH);
	ci::Rectf requested_rect(mBounds.x1, mBounds.y1 + height_offset, mBounds.x2, mBounds.y2);
	ci::gl::draw(mTexCache, requested_area, requested_rect);

	mFrameCounter++;

	if (mFrameCounter >= mTexH)
	{
		mFrameCounter = 0;
		std::swap(mActiveSurface, mBackBufferSurface);
		mTexCache.update(mSpectrals[mBackBufferSurface]);
	}
}

void SpectrogramPlot::setup()
{
	Plot::setup();
	mTexW = mAudioNodes.getMonitorSpectralNode()->getNumBins();
	//swap out the texture every 3 seconds
	mTexH = static_cast<std::size_t>(ci::app::getFrameRate() * 3.0f);

	mSpectrals[0] = ci::Surface32f(mTexW, mTexH, false);
	mSpectrals[1] = ci::Surface32f(mTexW, mTexH, false);

	mTexCache = ci::gl::Texture(mSpectrals.back());
}

ContiguousWaveformPlot::ContiguousWaveformPlot(AudioNodes& nodes)
	: mGraphColor(0, 0.9f, 0, 1)
	, mAudioNodes(nodes)
	, mSampleToSkip(0)
{
	setPlotTitle("Recorded input data");
	setHorzAxisTitle("Time").setHorzAxisUnit("s");
	setVertAxisTitle("Sample").setVertAxisUnit("units");
}

void ContiguousWaveformPlot::setGraphColor(const ci::ColorA& color)
{
	mGraphColor = color;
}

void ContiguousWaveformPlot::drawLocal()
{
	auto points = mAudioNodes.getBufferRecorderNode()->getRecordedCopy();

	ci::gl::color(mGraphColor);

	const float waveHeight = mBounds.getHeight() / (float)points->getNumChannels();
	const float xScale = 1.0f;

	float yOffset = mBounds.y1 + 0.25f * mBounds.getHeight();
	for (std::size_t ch = 0; ch < points->getNumChannels(); ch++)
	{
		const float *channel = points->getChannel(ch);
		for (std::size_t i = 0; i < mAudioNodes.getBufferRecorderNode()->getWritePosition(); i += mSampleToSkip)
		{
			if (mGraphs[ch].size() <= i / mSampleToSkip)
			{
				float x = mBounds.x1 + mGraphs[ch].getPoints().size();

				float y_min = 0.0f;
				float y_max = 0.0f;

				for (std::size_t j = i; i > mSampleToSkip && j > i - mSampleToSkip; --j)
				{
					const auto current_y = channel[j] * 0.5f;
					y_min = ci::math<float>::min(y_min, current_y);
					y_max = ci::math<float>::max(y_max, current_y);
				}

				y_min *= waveHeight;
				y_max *= waveHeight;

				// handle abnormal noise
				if (ci::math<float>::abs(y_max) > waveHeight) y_max = 0;
				if (ci::math<float>::abs(y_min) > waveHeight) y_min = 0;

				y_min += yOffset;
				y_max += yOffset;

				mGraphs[ch].push_back(ci::Vec2f(x - 0.01f, y_min));
				mGraphs[ch].push_back(ci::Vec2f(x + 0.01f, y_max));
			}
		}

		if (!mGraphs[ch].getPoints().empty())
			ci::gl::draw(mGraphs[ch]);

		yOffset += waveHeight;
	}
}

void ContiguousWaveformPlot::setup()
{
	Plot::setup();
	auto recorder = mAudioNodes.getBufferRecorderNode();
	mGraphs.resize(mAudioNodes.getBufferRecorderNode()->getNumChannels());
	mSampleToSkip = static_cast<std::size_t>(recorder->getNumFrames() / mBounds.getWidth());
}

} //!namespace cieq<|endoftext|>


<commit_before>#include "config.h"

#ifdef CONFIG_TASKBAR

#include "ylib.h"
#include "aworkspaces.h"
#include "wmtaskbar.h"
#include "prefs.h"
#include "wmmgr.h"
#include "wmapp.h"
#include "wmframe.h"
#include "yrect.h"
#include "yicon.h"
#include "wmwinlist.h"
#include "wpixmaps.h"
#include "intl.h"

YColor * WorkspaceButton::normalButtonBg(NULL);
YColor * WorkspaceButton::normalButtonFg(NULL);

YColor * WorkspaceButton::activeButtonBg(NULL);
YColor * WorkspaceButton::activeButtonFg(NULL);

ref<YFont> WorkspaceButton::normalButtonFont;
ref<YFont> WorkspaceButton::activeButtonFont;

static ref<YResourcePaths> getResourcePaths() {
    return YResourcePaths::subdirs("workspace", false);
}

WorkspaceButton::WorkspaceButton(long ws, YWindow *parent): ObjectButton(parent, (YAction *)0)
{
    fWorkspace = ws;
    //setDND(true);
}

void WorkspaceButton::handleClick(const XButtonEvent &up, int /*count*/) {
    switch (up.button) {
#ifdef CONFIG_WINLIST
        case 2:
            if (windowList)
                windowList->showFocused(-1, -1);
            break;
#endif
#ifdef CONFIG_WINMENU
        case 3:
            manager->popupWindowListMenu(this, up.x_root, up.y_root);
            break;
#endif
        case 4:
            manager->switchToPrevWorkspace(false);
            break;
        case 5:
            manager->switchToNextWorkspace(false);
            break;
    }
}

void WorkspaceButton::handleDNDEnter() {
    if (fRaiseTimer == 0)
        fRaiseTimer = new YTimer(autoRaiseDelay);
    if (fRaiseTimer) {
        fRaiseTimer->setTimerListener(this);
        fRaiseTimer->startTimer();
    }
    repaint();
}

void WorkspaceButton::handleDNDLeave() {
    if (fRaiseTimer && fRaiseTimer->getTimerListener() == this) {
        fRaiseTimer->stopTimer();
        fRaiseTimer->setTimerListener(0);
    }
    repaint();
}

bool WorkspaceButton::handleTimer(YTimer *t) {
    if (t == fRaiseTimer) {
        manager->activateWorkspace(fWorkspace);
    }
    return false;
}

void WorkspaceButton::actionPerformed(YAction */*action*/, unsigned int modifiers) {
    if (modifiers & ShiftMask) {
        manager->switchToWorkspace(fWorkspace, true);
    } else if (modifiers & xapp->AltMask) {
        if (manager->getFocus())
            manager->getFocus()->wmOccupyWorkspace(fWorkspace);
    } else {
        manager->activateWorkspace(fWorkspace);
        return;
    }
}

WorkspacesPane::WorkspacesPane(YWindow *parent): YWindow(parent) {
    long w;

    fWorkspaceButtonCount = workspaceCount;

    if (fWorkspaceButtonCount > 0)
        fWorkspaceButton = new WorkspaceButton *[fWorkspaceButtonCount];
    else
        fWorkspaceButton = 0;

    if (fWorkspaceButton) {
        ref<YResourcePaths> paths = getResourcePaths();

        int ht = smallIconSize + 8;
        int leftX = 0;

        for (w = 0; w < fWorkspaceButtonCount; w++) {
            WorkspaceButton *wk = new WorkspaceButton(w, this);
            if (wk) {
                if (pagerShowPreview) {
                    wk->setSize((int) round((double)
                                (ht * desktop->width() / desktop->height())), ht);
                } else {
                    ref<YImage> image
                        (paths->loadImage("workspace/", workspaceNames[w]));
                    if (image != null)
                        wk->setImage(image);
                    else
                        wk->setText(workspaceNames[w]);
                }
#if 0
                ref<YImage> image
                    (paths->loadImage("workspace/", workspaceNames[w]));

                if (image != null)
                    wk->setImage(image);
                else
                    wk->setText(workspaceNames[w]);
#endif

/// TODO "why my_basename here?"
                char * wn(newstr(my_basename(workspaceNames[w])));
                char * ext(strrchr(wn, '.'));
                if (ext) *ext = '\0';

                wk->setToolTip(ustring(_("Workspace: ")).append(wn));
                delete[] wn;

                //if ((int)wk->height() + 1 > ht) ht = wk->height() + 1;
            }
            fWorkspaceButton[w] = wk;
        }

        for (w = 0; w < fWorkspaceButtonCount; w++) {
            YButton *wk = fWorkspaceButton[w];
            //leftX += 2;
            if (wk) {
                wk->setGeometry(YRect(leftX, 0, wk->width(), ht));
                wk->show();
                leftX += wk->width();
            }
        }
        setSize(leftX, ht);
    }
}

WorkspacesPane::~WorkspacesPane() {
    if (fWorkspaceButton) {
        for (long w = 0; w < fWorkspaceButtonCount; w++)
            delete fWorkspaceButton[w];
        delete [] fWorkspaceButton;
    }
}

void WorkspacesPane::repositionButtons() {
    MSG(("WorkspacesPane::repositionButtons()"));
    int ht = height();
    int leftX = 0;
    for (long w = 0; w < fWorkspaceButtonCount; w++) {
        YButton *wk = fWorkspaceButton[w];
        //leftX += 2;
        if (wk) {
            wk->setGeometry(YRect(leftX, 0, wk->width(), ht));
            wk->show(); // no effect if already shown
            leftX += wk->width();
        }
    }
    setSize(leftX, ht);
}

void WorkspacesPane::relabelButtons() {
    if (pagerShowPreview)
        return;

    ref<YResourcePaths> paths = getResourcePaths();

    for (long w = 0; w < fWorkspaceButtonCount; w++) {
        YButton *wk = fWorkspaceButton[w];
        if (wk) {
            ref<YImage> image
                (paths->loadImage("workspace/",workspaceNames[w]));
            if (image != null)
                wk->setImage(image);
            else
                wk->setText(workspaceNames[w]);

            char * wn(newstr(my_basename(workspaceNames[w])));
            char * ext(strrchr(wn, '.'));
            if (ext) *ext = '\0';

            wk->setToolTip(ustring(_("Workspace: ")).append(wn));
            delete[] wn;
        }
    }

    repositionButtons();
}

void WorkspacesPane::configure(const YRect &r) {
    YWindow::configure(r);

    int ht = height();
    int leftX = 0;
    for (int w = 0; w < fWorkspaceButtonCount; w++) {
        YButton *wk = fWorkspaceButton[w];
        //leftX += 2;
        if (wk) {
            wk->setGeometry(YRect(leftX, 0, wk->width(), ht));
            leftX += wk->width();
        }
    }
}

void WorkspacesPane::updateButtons() {
    MSG(("WorkspacesPane::udpateButtons(): updating %ld -> %ld",
         fWorkspaceButtonCount,workspaceCount));
    long fOldWorkspaceButtonCount = fWorkspaceButtonCount;
    fWorkspaceButtonCount = workspaceCount;
    if (fWorkspaceButtonCount != fOldWorkspaceButtonCount) {
        WorkspaceButton **fOldWorkspaceButton = fWorkspaceButton;
        fWorkspaceButton = new WorkspaceButton *[fWorkspaceButtonCount];
        if (fWorkspaceButtonCount > fOldWorkspaceButtonCount) {
            for (long w = 0; w < fOldWorkspaceButtonCount; w++)
                fWorkspaceButton[w] = fOldWorkspaceButton[w];
            int ht = smallIconSize + 8;
            MSG(("WorkspacesPane::updateButtons(): adding new buttons"));
            ref<YResourcePaths> paths = getResourcePaths();
            for (long w = fOldWorkspaceButtonCount; w < fWorkspaceButtonCount; w++) {
                WorkspaceButton *wk = new WorkspaceButton(w, this);
                if (wk) {
                    if (pagerShowPreview) {
                        wk->setSize((int) round((double)
                                    (ht * desktop->width() / desktop->height())), ht);
                    } else {
                        ref<YImage> image
                            (paths->loadImage("workspace/", workspaceNames[w]));
                        if (image != null)
                            wk->setImage(image);
                        else
                            wk->setText(workspaceNames[w]);
                    }

                    char * wn(newstr(my_basename(workspaceNames[w])));
                    char * ext(strrchr(wn, '.'));
                    if (ext) *ext = '\0';

                    wk->setToolTip(ustring(_("Workspace: ")).append(wn));
                }
                fWorkspaceButton[w] = wk;
            }
        } else
        if (fWorkspaceButtonCount < fOldWorkspaceButtonCount) {
            for (long w = 0; w < fWorkspaceButtonCount; w++)
                fWorkspaceButton[w] = fOldWorkspaceButton[w];
            MSG(("WorkspacesPane::updateButtons(): removing buttons"));
            for (long w = fWorkspaceButtonCount; w < fOldWorkspaceButtonCount; w++) {
                MSG(("WorkspacePane::updateButtons(): removing button for workspace %ld",w));
                delete fOldWorkspaceButton[w];
                MSG(("WorkspacePane::updateButtons(): removed  button for workspace %ld",w));
            }
        }
        if (fOldWorkspaceButton != 0)
            delete[] fOldWorkspaceButton;
        repositionButtons();
    }
}

WorkspaceButton *WorkspacesPane::workspaceButton(long n) {
    return (fWorkspaceButton ? fWorkspaceButton[n] : NULL);
}

ref<YFont> WorkspaceButton::getFont() {
    return isPressed()
        ? (*activeWorkspaceFontName || *activeWorkspaceFontNameXft)
        ? activeButtonFont != null
        ? activeButtonFont
        : activeButtonFont = YFont::getFont(XFA(activeWorkspaceFontName))
        : YButton::getFont()
        : (*normalWorkspaceFontName || *normalWorkspaceFontNameXft)
        ? normalButtonFont != null
        ? normalButtonFont
        : normalButtonFont = YFont::getFont(XFA(normalWorkspaceFontName))
        : YButton::getFont();
}

YColor * WorkspaceButton::getColor() {
    return isPressed()
        ? *clrWorkspaceActiveButtonText
        ? activeButtonFg
        ? activeButtonFg
        : activeButtonFg = new YColor(clrWorkspaceActiveButtonText)
        : YButton::getColor()
        : *clrWorkspaceNormalButtonText
        ? normalButtonFg
        ? normalButtonFg
        : normalButtonFg = new YColor(clrWorkspaceNormalButtonText)
        : YButton::getColor();
}

YSurface WorkspaceButton::getSurface() {
    if (activeButtonBg == 0)
        activeButtonBg =
            new YColor(*clrWorkspaceActiveButton
                       ? clrWorkspaceActiveButton : clrActiveButton);
    if (normalButtonBg == 0)
        normalButtonBg =
            new YColor(*clrWorkspaceNormalButton
                       ? clrWorkspaceNormalButton : clrNormalButton);

#ifdef CONFIG_GRADIENTS
    return (isPressed() ? YSurface(activeButtonBg,
                                   workspacebuttonactivePixmap,
                                   workspacebuttonactivePixbuf)
            : YSurface(normalButtonBg,
                       workspacebuttonPixmap,
                       workspacebuttonPixbuf));
#else
    return (isPressed() ? YSurface(activeButtonBg, workspacebuttonactivePixmap)
            : YSurface(normalButtonBg, workspacebuttonPixmap));
#endif
}

void WorkspacesPane::repaint() {
    if (!pagerShowPreview) return;

    for (int w = 0; w < fWorkspaceButtonCount; w++) {
        fWorkspaceButton[w]->repaint();
    }
}

void WorkspaceButton::paint(Graphics &g, const YRect &/*r*/) {
    if (!pagerShowPreview) {
        YButton::paint(g, YRect(0,0,0,0));
        return;
    }

    int x(0), y(0), w(width()), h(height());

    if (w > 1 && h > 1) {
        YSurface surface(getSurface());
        g.setColor(surface.color);
        g.drawSurface(surface, x, y, w, h);

        if (pagerShowBorders) {
            x += 1; y += 1; w -= 2; h -= 2;
        }

        int wx, wy, ww, wh;
        double sf = (double) desktop->width() / w;

        ref<YIcon> icon;
        YColor *colors[] = {
            surface.color,
            surface.color->brighter(),
            surface.color->darker(),
            getColor(),
            NULL, // getColor()->brighter(),
            getColor()->darker()
        };

        for (YFrameWindow *yfw = manager->bottomLayer(WinLayerBelow);
                yfw && yfw->getActiveLayer() <= WinLayerDock;
                yfw = yfw->prevLayer()) {
            if (yfw->isHidden() ||
                    !yfw->visibleOn(fWorkspace) ||
                    (yfw->frameOptions() & YFrameWindow::foIgnoreWinList))
                continue;
            wx = (int) round(yfw->x() / sf) + x;
            wy = (int) round(yfw->y() / sf) + y;
            ww = (int) round(yfw->width() / sf);
            wh = (int) round(yfw->height()  / sf);
            if (ww < 1 || wh < 1)
                continue;
            if (yfw->isMaximizedVert()) { // !!! hack
                wy = y; wh = h;
            }
            if (yfw->isMinimized()) {
                if (!pagerShowMinimized)
                    continue;
                g.setColor(colors[2]);
            } else {
                if (ww > 2 && wh > 2) {
                    if (yfw->focused())
                        g.setColor(colors[1]);
                    else
                        g.setColor(colors[2]);
                    g.fillRect(wx+1, wy+1, ww-2, wh-2);

#ifndef LITE
                    if (pagerShowWindowIcons && ww > smallIconSize+1 &&
                            wh > smallIconSize+1 && (icon = yfw->clientIcon()) != null &&
                            icon->small() != null) {
                        g.drawImage(icon->small(),
                                    wx + (ww-smallIconSize)/2,
                                    wy + (wh-smallIconSize)/2);
                    }
#endif
                }
                g.setColor(colors[5]);
            }
            if (ww == 1 && wh == 1)
                g.drawPoint(wx, wy);
            else
                g.drawRect(wx, wy, ww-1, wh-1);
        }

        if (pagerShowBorders) {
            g.setColor(surface.color);
            g.draw3DRect(x-1, y-1, w+1, h+1, !isPressed());
        }

        if (pagerShowNumbers) {
            ref<YFont> font = getFont();

            char label[9];
            sprintf(label, "%ld", (long) (fWorkspace+1) % 100);

            wx = (w - font->textWidth(label)) / 2 + x;
            wy = (h - font->height()) / 2 + font->ascent() + y;

            g.setFont(font);
            g.setColor(colors[0]);
            g.drawChars(label, 0, strlen(label), wx+1, wy+1);
            g.setColor(colors[3]);
            g.drawChars(label, 0, strlen(label), wx, wy);
        }
    }
}

#endif
<commit_msg>free workspace data when done.<commit_after>#include "config.h"

#ifdef CONFIG_TASKBAR

#include "ylib.h"
#include "aworkspaces.h"
#include "wmtaskbar.h"
#include "prefs.h"
#include "wmmgr.h"
#include "wmapp.h"
#include "wmframe.h"
#include "yrect.h"
#include "yicon.h"
#include "wmwinlist.h"
#include "wpixmaps.h"
#include "intl.h"

YColor * WorkspaceButton::normalButtonBg(NULL);
YColor * WorkspaceButton::normalButtonFg(NULL);

YColor * WorkspaceButton::activeButtonBg(NULL);
YColor * WorkspaceButton::activeButtonFg(NULL);

ref<YFont> WorkspaceButton::normalButtonFont;
ref<YFont> WorkspaceButton::activeButtonFont;

static ref<YResourcePaths> getResourcePaths() {
    return YResourcePaths::subdirs("workspace", false);
}

WorkspaceButton::WorkspaceButton(long ws, YWindow *parent): ObjectButton(parent, (YAction *)0)
{
    fWorkspace = ws;
    //setDND(true);
}

void WorkspaceButton::handleClick(const XButtonEvent &up, int /*count*/) {
    switch (up.button) {
#ifdef CONFIG_WINLIST
        case 2:
            if (windowList)
                windowList->showFocused(-1, -1);
            break;
#endif
#ifdef CONFIG_WINMENU
        case 3:
            manager->popupWindowListMenu(this, up.x_root, up.y_root);
            break;
#endif
        case 4:
            manager->switchToPrevWorkspace(false);
            break;
        case 5:
            manager->switchToNextWorkspace(false);
            break;
    }
}

void WorkspaceButton::handleDNDEnter() {
    if (fRaiseTimer == 0)
        fRaiseTimer = new YTimer(autoRaiseDelay);
    if (fRaiseTimer) {
        fRaiseTimer->setTimerListener(this);
        fRaiseTimer->startTimer();
    }
    repaint();
}

void WorkspaceButton::handleDNDLeave() {
    if (fRaiseTimer && fRaiseTimer->getTimerListener() == this) {
        fRaiseTimer->stopTimer();
        fRaiseTimer->setTimerListener(0);
    }
    repaint();
}

bool WorkspaceButton::handleTimer(YTimer *t) {
    if (t == fRaiseTimer) {
        manager->activateWorkspace(fWorkspace);
    }
    return false;
}

void WorkspaceButton::actionPerformed(YAction */*action*/, unsigned int modifiers) {
    if (modifiers & ShiftMask) {
        manager->switchToWorkspace(fWorkspace, true);
    } else if (modifiers & xapp->AltMask) {
        if (manager->getFocus())
            manager->getFocus()->wmOccupyWorkspace(fWorkspace);
    } else {
        manager->activateWorkspace(fWorkspace);
        return;
    }
}

WorkspacesPane::WorkspacesPane(YWindow *parent): YWindow(parent) {
    long w;

    fWorkspaceButtonCount = workspaceCount;

    if (fWorkspaceButtonCount > 0)
        fWorkspaceButton = new WorkspaceButton *[fWorkspaceButtonCount];
    else
        fWorkspaceButton = 0;

    if (fWorkspaceButton) {
        ref<YResourcePaths> paths = getResourcePaths();

        int ht = smallIconSize + 8;
        int leftX = 0;

        for (w = 0; w < fWorkspaceButtonCount; w++) {
            WorkspaceButton *wk = new WorkspaceButton(w, this);
            if (wk) {
                if (pagerShowPreview) {
                    wk->setSize((int) round((double)
                                (ht * desktop->width() / desktop->height())), ht);
                } else {
                    ref<YImage> image
                        (paths->loadImage("workspace/", workspaceNames[w]));
                    if (image != null)
                        wk->setImage(image);
                    else
                        wk->setText(workspaceNames[w]);
                }
#if 0
                ref<YImage> image
                    (paths->loadImage("workspace/", workspaceNames[w]));

                if (image != null)
                    wk->setImage(image);
                else
                    wk->setText(workspaceNames[w]);
#endif

/// TODO "why my_basename here?"
                char * wn(newstr(my_basename(workspaceNames[w])));
                char * ext(strrchr(wn, '.'));
                if (ext) *ext = '\0';

                wk->setToolTip(ustring(_("Workspace: ")).append(wn));
                delete[] wn;

                //if ((int)wk->height() + 1 > ht) ht = wk->height() + 1;
            }
            fWorkspaceButton[w] = wk;
        }

        for (w = 0; w < fWorkspaceButtonCount; w++) {
            YButton *wk = fWorkspaceButton[w];
            //leftX += 2;
            if (wk) {
                wk->setGeometry(YRect(leftX, 0, wk->width(), ht));
                wk->show();
                leftX += wk->width();
            }
        }
        setSize(leftX, ht);
    }
}

WorkspacesPane::~WorkspacesPane() {
    if (fWorkspaceButton) {
        for (long w = 0; w < fWorkspaceButtonCount; w++)
            delete fWorkspaceButton[w];
        delete [] fWorkspaceButton;
    }
    for (int i = workspaceCount; --i >= 0; --workspaceCount) {
        delete[] workspaceNames[i]; workspaceNames[i] = 0;
        delete workspaceActionActivate[i]; workspaceActionActivate[i] = 0;
        delete workspaceActionMoveTo[i]; workspaceActionMoveTo[i] = 0;
    }
}

void WorkspacesPane::repositionButtons() {
    MSG(("WorkspacesPane::repositionButtons()"));
    int ht = height();
    int leftX = 0;
    for (long w = 0; w < fWorkspaceButtonCount; w++) {
        YButton *wk = fWorkspaceButton[w];
        //leftX += 2;
        if (wk) {
            wk->setGeometry(YRect(leftX, 0, wk->width(), ht));
            wk->show(); // no effect if already shown
            leftX += wk->width();
        }
    }
    setSize(leftX, ht);
}

void WorkspacesPane::relabelButtons() {
    if (pagerShowPreview)
        return;

    ref<YResourcePaths> paths = getResourcePaths();

    for (long w = 0; w < fWorkspaceButtonCount; w++) {
        YButton *wk = fWorkspaceButton[w];
        if (wk) {
            ref<YImage> image
                (paths->loadImage("workspace/",workspaceNames[w]));
            if (image != null)
                wk->setImage(image);
            else
                wk->setText(workspaceNames[w]);

            char * wn(newstr(my_basename(workspaceNames[w])));
            char * ext(strrchr(wn, '.'));
            if (ext) *ext = '\0';

            wk->setToolTip(ustring(_("Workspace: ")).append(wn));
            delete[] wn;
        }
    }

    repositionButtons();
}

void WorkspacesPane::configure(const YRect &r) {
    YWindow::configure(r);

    int ht = height();
    int leftX = 0;
    for (int w = 0; w < fWorkspaceButtonCount; w++) {
        YButton *wk = fWorkspaceButton[w];
        //leftX += 2;
        if (wk) {
            wk->setGeometry(YRect(leftX, 0, wk->width(), ht));
            leftX += wk->width();
        }
    }
}

void WorkspacesPane::updateButtons() {
    MSG(("WorkspacesPane::udpateButtons(): updating %ld -> %ld",
         fWorkspaceButtonCount,workspaceCount));
    long fOldWorkspaceButtonCount = fWorkspaceButtonCount;
    fWorkspaceButtonCount = workspaceCount;
    if (fWorkspaceButtonCount != fOldWorkspaceButtonCount) {
        WorkspaceButton **fOldWorkspaceButton = fWorkspaceButton;
        fWorkspaceButton = new WorkspaceButton *[fWorkspaceButtonCount];
        if (fWorkspaceButtonCount > fOldWorkspaceButtonCount) {
            for (long w = 0; w < fOldWorkspaceButtonCount; w++)
                fWorkspaceButton[w] = fOldWorkspaceButton[w];
            int ht = smallIconSize + 8;
            MSG(("WorkspacesPane::updateButtons(): adding new buttons"));
            ref<YResourcePaths> paths = getResourcePaths();
            for (long w = fOldWorkspaceButtonCount; w < fWorkspaceButtonCount; w++) {
                WorkspaceButton *wk = new WorkspaceButton(w, this);
                if (wk) {
                    if (pagerShowPreview) {
                        wk->setSize((int) round((double)
                                    (ht * desktop->width() / desktop->height())), ht);
                    } else {
                        ref<YImage> image
                            (paths->loadImage("workspace/", workspaceNames[w]));
                        if (image != null)
                            wk->setImage(image);
                        else
                            wk->setText(workspaceNames[w]);
                    }

                    char * wn(newstr(my_basename(workspaceNames[w])));
                    char * ext(strrchr(wn, '.'));
                    if (ext) *ext = '\0';

                    wk->setToolTip(ustring(_("Workspace: ")).append(wn));
                }
                fWorkspaceButton[w] = wk;
            }
        } else
        if (fWorkspaceButtonCount < fOldWorkspaceButtonCount) {
            for (long w = 0; w < fWorkspaceButtonCount; w++)
                fWorkspaceButton[w] = fOldWorkspaceButton[w];
            MSG(("WorkspacesPane::updateButtons(): removing buttons"));
            for (long w = fWorkspaceButtonCount; w < fOldWorkspaceButtonCount; w++) {
                MSG(("WorkspacePane::updateButtons(): removing button for workspace %ld",w));
                delete fOldWorkspaceButton[w];
                MSG(("WorkspacePane::updateButtons(): removed  button for workspace %ld",w));
            }
        }
        if (fOldWorkspaceButton != 0)
            delete[] fOldWorkspaceButton;
        repositionButtons();
    }
}

WorkspaceButton *WorkspacesPane::workspaceButton(long n) {
    return (fWorkspaceButton ? fWorkspaceButton[n] : NULL);
}

ref<YFont> WorkspaceButton::getFont() {
    return isPressed()
        ? (*activeWorkspaceFontName || *activeWorkspaceFontNameXft)
        ? activeButtonFont != null
        ? activeButtonFont
        : activeButtonFont = YFont::getFont(XFA(activeWorkspaceFontName))
        : YButton::getFont()
        : (*normalWorkspaceFontName || *normalWorkspaceFontNameXft)
        ? normalButtonFont != null
        ? normalButtonFont
        : normalButtonFont = YFont::getFont(XFA(normalWorkspaceFontName))
        : YButton::getFont();
}

YColor * WorkspaceButton::getColor() {
    return isPressed()
        ? *clrWorkspaceActiveButtonText
        ? activeButtonFg
        ? activeButtonFg
        : activeButtonFg = new YColor(clrWorkspaceActiveButtonText)
        : YButton::getColor()
        : *clrWorkspaceNormalButtonText
        ? normalButtonFg
        ? normalButtonFg
        : normalButtonFg = new YColor(clrWorkspaceNormalButtonText)
        : YButton::getColor();
}

YSurface WorkspaceButton::getSurface() {
    if (activeButtonBg == 0)
        activeButtonBg =
            new YColor(*clrWorkspaceActiveButton
                       ? clrWorkspaceActiveButton : clrActiveButton);
    if (normalButtonBg == 0)
        normalButtonBg =
            new YColor(*clrWorkspaceNormalButton
                       ? clrWorkspaceNormalButton : clrNormalButton);

#ifdef CONFIG_GRADIENTS
    return (isPressed() ? YSurface(activeButtonBg,
                                   workspacebuttonactivePixmap,
                                   workspacebuttonactivePixbuf)
            : YSurface(normalButtonBg,
                       workspacebuttonPixmap,
                       workspacebuttonPixbuf));
#else
    return (isPressed() ? YSurface(activeButtonBg, workspacebuttonactivePixmap)
            : YSurface(normalButtonBg, workspacebuttonPixmap));
#endif
}

void WorkspacesPane::repaint() {
    if (!pagerShowPreview) return;

    for (int w = 0; w < fWorkspaceButtonCount; w++) {
        fWorkspaceButton[w]->repaint();
    }
}

void WorkspaceButton::paint(Graphics &g, const YRect &/*r*/) {
    if (!pagerShowPreview) {
        YButton::paint(g, YRect(0,0,0,0));
        return;
    }

    int x(0), y(0), w(width()), h(height());

    if (w > 1 && h > 1) {
        YSurface surface(getSurface());
        g.setColor(surface.color);
        g.drawSurface(surface, x, y, w, h);

        if (pagerShowBorders) {
            x += 1; y += 1; w -= 2; h -= 2;
        }

        int wx, wy, ww, wh;
        double sf = (double) desktop->width() / w;

        ref<YIcon> icon;
        YColor *colors[] = {
            surface.color,
            surface.color->brighter(),
            surface.color->darker(),
            getColor(),
            NULL, // getColor()->brighter(),
            getColor()->darker()
        };

        for (YFrameWindow *yfw = manager->bottomLayer(WinLayerBelow);
                yfw && yfw->getActiveLayer() <= WinLayerDock;
                yfw = yfw->prevLayer()) {
            if (yfw->isHidden() ||
                    !yfw->visibleOn(fWorkspace) ||
                    (yfw->frameOptions() & YFrameWindow::foIgnoreWinList))
                continue;
            wx = (int) round(yfw->x() / sf) + x;
            wy = (int) round(yfw->y() / sf) + y;
            ww = (int) round(yfw->width() / sf);
            wh = (int) round(yfw->height()  / sf);
            if (ww < 1 || wh < 1)
                continue;
            if (yfw->isMaximizedVert()) { // !!! hack
                wy = y; wh = h;
            }
            if (yfw->isMinimized()) {
                if (!pagerShowMinimized)
                    continue;
                g.setColor(colors[2]);
            } else {
                if (ww > 2 && wh > 2) {
                    if (yfw->focused())
                        g.setColor(colors[1]);
                    else
                        g.setColor(colors[2]);
                    g.fillRect(wx+1, wy+1, ww-2, wh-2);

#ifndef LITE
                    if (pagerShowWindowIcons && ww > smallIconSize+1 &&
                            wh > smallIconSize+1 && (icon = yfw->clientIcon()) != null &&
                            icon->small() != null) {
                        g.drawImage(icon->small(),
                                    wx + (ww-smallIconSize)/2,
                                    wy + (wh-smallIconSize)/2);
                    }
#endif
                }
                g.setColor(colors[5]);
            }
            if (ww == 1 && wh == 1)
                g.drawPoint(wx, wy);
            else
                g.drawRect(wx, wy, ww-1, wh-1);
        }

        if (pagerShowBorders) {
            g.setColor(surface.color);
            g.draw3DRect(x-1, y-1, w+1, h+1, !isPressed());
        }

        if (pagerShowNumbers) {
            ref<YFont> font = getFont();

            char label[9];
            sprintf(label, "%ld", (long) (fWorkspace+1) % 100);

            wx = (w - font->textWidth(label)) / 2 + x;
            wy = (h - font->height()) / 2 + font->ascent() + y;

            g.setFont(font);
            g.setColor(colors[0]);
            g.drawChars(label, 0, strlen(label), wx+1, wy+1);
            g.setColor(colors[3]);
            g.drawChars(label, 0, strlen(label), wx, wy);
        }
    }
}

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: unocpres.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 06:48:53 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SD_UNOCPRES_HXX
#define _SD_UNOCPRES_HXX

#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XINDEXCONTAINER_HPP_
#include <com/sun/star/container/XIndexContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMED_HPP_
#include <com/sun/star/container/XNamed.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
#include <com/sun/star/lang/XUnoTunnel.hpp>
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

#include <cppuhelper/implbase5.hxx>
#include <unotools/servicehelper.hxx>

///////////////////////////////////////////////////////////////////////////////

class SdXImpressDocument;
class SdView;
class SdDrawViewShell;
class SdCustomShow;

class SdXCustomPresentation :   public ::cppu::WeakImplHelper5< ::com::sun::star::container::XIndexContainer,
                                                                ::com::sun::star::container::XNamed,
                                                                ::com::sun::star::lang::XUnoTunnel,
                                                                ::com::sun::star::lang::XComponent,
                                                                ::com::sun::star::lang::XServiceInfo >
{
private:
    SdCustomShow*       mpSdCustomShow;
    SdXImpressDocument* mpModel;

    // for xComponent
    ::osl::Mutex aDisposeContainerMutex;
    ::cppu::OInterfaceContainerHelper aDisposeListeners;
    BOOL bDisposing;

public:
    SdXCustomPresentation() throw();
    SdXCustomPresentation( SdCustomShow* mpSdCustomShow, SdXImpressDocument* pMyModel) throw();
    virtual ~SdXCustomPresentation() throw();

    // internal
    void Invalidate() { mpSdCustomShow = NULL; }
    SdCustomShow* GetSdCustomShow() const throw() { return mpSdCustomShow; }
    void SetSdCustomShow( SdCustomShow* pShow ) throw() { mpSdCustomShow = pShow; }
    SdXImpressDocument* GetModel() const throw() { return mpModel; }

    // uno helper
    UNO3_GETIMPLEMENTATION_DECL(SdXCustomPresentation)

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    // XIndexContainer
    virtual void SAL_CALL insertByIndex( sal_Int32 Index, const ::com::sun::star::uno::Any& Element ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeByIndex( sal_Int32 Index ) throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XIndexReplace
    virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const ::com::sun::star::uno::Any& Element ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XElementAccess
    virtual ::com::sun::star::uno::Type SAL_CALL getElementType() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException);

    // XIndexAccess
    virtual sal_Int32 SAL_CALL getCount() throw(::com::sun::star::uno::RuntimeException) ;
    virtual ::com::sun::star::uno::Any SAL_CALL getByIndex( sal_Int32 Index ) throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XNamed
    virtual ::rtl::OUString SAL_CALL getName(  ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setName( const ::rtl::OUString& aName ) throw(::com::sun::star::uno::RuntimeException);

    // XComponent
    virtual void SAL_CALL dispose(  ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw(::com::sun::star::uno::RuntimeException);
};

// --------------------------------------------------------------------------

#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
#include <com/sun/star/container/XNameContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#endif

#include <cppuhelper/implbase3.hxx>

#include "unomodel.hxx"
#include "drawdoc.hxx"

class List;

class SdXCustomPresentationAccess : public ::cppu::WeakImplHelper3< ::com::sun::star::container::XNameContainer,
                                                                    ::com::sun::star::lang::XSingleServiceFactory,
                                                                    ::com::sun::star::lang::XServiceInfo >
{
private:
    SdXImpressDocument& mrModel;

    // intern
    inline List* GetCustomShowList() const throw();
    sal_Int32 getSdCustomShowIdx( const ::rtl::OUString& Name ) const throw();
    SdCustomShow * getSdCustomShow( const ::rtl::OUString& Name ) const throw();

public:
    SdXCustomPresentationAccess(SdXImpressDocument& rMyModel) throw();
    ~SdXCustomPresentationAccess() throw();

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    // XSingleServiceFactory
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstance(  ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithArguments( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);

    // XNameContainer
    virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeByName( const ::rtl::OUString& Name ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XNameReplace
    virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XNameAccess
    virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw(::com::sun::star::uno::RuntimeException);

    // XElementAccess
    virtual ::com::sun::star::uno::Type SAL_CALL getElementType() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException);
};

inline List * SdXCustomPresentationAccess::GetCustomShowList() const throw()
{
    if(mrModel.GetDoc())
        return mrModel.GetDoc()->GetCustomShowList(sal_False);
    else
        return NULL;
};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.3.624); FILE MERGED 2008/04/01 15:36:14 thb 1.3.624.3: #i85898# Stripping all external header guards 2008/04/01 12:39:26 thb 1.3.624.2: #i85898# Stripping all external header guards 2008/03/31 13:59:08 rt 1.3.624.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: unocpres.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _SD_UNOCPRES_HXX
#define _SD_UNOCPRES_HXX

#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/container/XIndexContainer.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <cppuhelper/interfacecontainer.h>
#include <osl/mutex.hxx>

#include <cppuhelper/implbase5.hxx>
#include <unotools/servicehelper.hxx>

///////////////////////////////////////////////////////////////////////////////

class SdXImpressDocument;
class SdView;
class SdDrawViewShell;
class SdCustomShow;

class SdXCustomPresentation :   public ::cppu::WeakImplHelper5< ::com::sun::star::container::XIndexContainer,
                                                                ::com::sun::star::container::XNamed,
                                                                ::com::sun::star::lang::XUnoTunnel,
                                                                ::com::sun::star::lang::XComponent,
                                                                ::com::sun::star::lang::XServiceInfo >
{
private:
    SdCustomShow*       mpSdCustomShow;
    SdXImpressDocument* mpModel;

    // for xComponent
    ::osl::Mutex aDisposeContainerMutex;
    ::cppu::OInterfaceContainerHelper aDisposeListeners;
    BOOL bDisposing;

public:
    SdXCustomPresentation() throw();
    SdXCustomPresentation( SdCustomShow* mpSdCustomShow, SdXImpressDocument* pMyModel) throw();
    virtual ~SdXCustomPresentation() throw();

    // internal
    void Invalidate() { mpSdCustomShow = NULL; }
    SdCustomShow* GetSdCustomShow() const throw() { return mpSdCustomShow; }
    void SetSdCustomShow( SdCustomShow* pShow ) throw() { mpSdCustomShow = pShow; }
    SdXImpressDocument* GetModel() const throw() { return mpModel; }

    // uno helper
    UNO3_GETIMPLEMENTATION_DECL(SdXCustomPresentation)

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    // XIndexContainer
    virtual void SAL_CALL insertByIndex( sal_Int32 Index, const ::com::sun::star::uno::Any& Element ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeByIndex( sal_Int32 Index ) throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XIndexReplace
    virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const ::com::sun::star::uno::Any& Element ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XElementAccess
    virtual ::com::sun::star::uno::Type SAL_CALL getElementType() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException);

    // XIndexAccess
    virtual sal_Int32 SAL_CALL getCount() throw(::com::sun::star::uno::RuntimeException) ;
    virtual ::com::sun::star::uno::Any SAL_CALL getByIndex( sal_Int32 Index ) throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XNamed
    virtual ::rtl::OUString SAL_CALL getName(  ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setName( const ::rtl::OUString& aName ) throw(::com::sun::star::uno::RuntimeException);

    // XComponent
    virtual void SAL_CALL dispose(  ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw(::com::sun::star::uno::RuntimeException);
};

// --------------------------------------------------------------------------
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>

#include <cppuhelper/implbase3.hxx>

#include "unomodel.hxx"
#include "drawdoc.hxx"

class List;

class SdXCustomPresentationAccess : public ::cppu::WeakImplHelper3< ::com::sun::star::container::XNameContainer,
                                                                    ::com::sun::star::lang::XSingleServiceFactory,
                                                                    ::com::sun::star::lang::XServiceInfo >
{
private:
    SdXImpressDocument& mrModel;

    // intern
    inline List* GetCustomShowList() const throw();
    sal_Int32 getSdCustomShowIdx( const ::rtl::OUString& Name ) const throw();
    SdCustomShow * getSdCustomShow( const ::rtl::OUString& Name ) const throw();

public:
    SdXCustomPresentationAccess(SdXImpressDocument& rMyModel) throw();
    ~SdXCustomPresentationAccess() throw();

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    // XSingleServiceFactory
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstance(  ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithArguments( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);

    // XNameContainer
    virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeByName( const ::rtl::OUString& Name ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XNameReplace
    virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XNameAccess
    virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw(::com::sun::star::uno::RuntimeException);

    // XElementAccess
    virtual ::com::sun::star::uno::Type SAL_CALL getElementType() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException);
};

inline List * SdXCustomPresentationAccess::GetCustomShowList() const throw()
{
    if(mrModel.GetDoc())
        return mrModel.GetDoc()->GetCustomShowList(sal_False);
    else
        return NULL;
};

#endif

<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Nathan Osman
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 **/

#include <QApplication>
#include <QDesktopWidget>
#include <QIcon>
#include <QPainter>
#include <QPixmap>
#include <QPoint>
#include <QRect>
#include <QScreen>
#include <QSvgRenderer>

#include "trayicon.h"

TrayIcon::TrayIcon()
{
    mTrayIcon.setContextMenu(&mMenu);
    mTrayIcon.setToolTip(tr("NitroShare"));
    mTrayIcon.show();

    // The following code has a single purpose - to determine the appropriate
    // size for the tray icon - this is done by determining the scaling factor
    // for the screen containing the tray icon and setting the size
    // accordingly - simply calling QIcon("[...].svg") doesn't work in KDE

    // Retrieve the geometry for the tray icon
    QRect rect = mTrayIcon.geometry();

    // Obtain the screen for the tray icon
    QScreen *screen = QApplication::screens().at(
        QApplication::desktop()->screenNumber(QPoint(rect.x(), rect.y()))
    );

    // Determine the dimension with the smallest size and scale it
    int minSize = qMin(rect.width(), rect.height());
    minSize = minSize ? minSize : 48;
    minSize *= screen->devicePixelRatio();

    // Create an empty pixmap with that size and make it transparent
    QPixmap pixmap(minSize, minSize);
    pixmap.fill(Qt::transparent);

    // Render the SVG (finally!)
    QSvgRenderer renderer(QString(":/img/tray.svg"));
    QPainter painter(&pixmap);
    renderer.render(&painter);

    // *Now* we can set the icon
    mTrayIcon.setIcon(QIcon(pixmap));
}

void TrayIcon::addAction(const QString &text, QObject *receiver, const char *member)
{
    mMenu.addAction(text, receiver, member);
}

void TrayIcon::addSeparator()
{
    mMenu.addSeparator();
}

void TrayIcon::showMessage(const QString &message)
{
    mTrayIcon.showMessage(tr("NitroShare Notification"), message);
}
<commit_msg>Attempt to fix tray icon on macOS (#111).<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Nathan Osman
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 **/

#include <QApplication>
#include <QDesktopWidget>
#include <QIcon>
#include <QPainter>
#include <QPixmap>
#include <QPoint>
#include <QRect>
#include <QScreen>
#include <QSvgRenderer>

#include "trayicon.h"

TrayIcon::TrayIcon()
{
    mTrayIcon.setContextMenu(&mMenu);
    mTrayIcon.setToolTip(tr("NitroShare"));
    mTrayIcon.show();

    // The following code has a single purpose - to determine the appropriate
    // size for the tray icon - this is done by determining the scaling factor
    // for the screen containing the tray icon and setting the size
    // accordingly - simply calling QIcon("[...].svg") doesn't work in KDE

    // Retrieve the geometry for the tray icon
    QRect rect = mTrayIcon.geometry();

    // Obtain the screen for the tray icon
    QScreen *screen = QApplication::screens().at(
        QApplication::desktop()->screenNumber(QPoint(rect.x(), rect.y()))
    );

    // Determine the dimension with the smallest size and scale it
    int minSize = qMin(rect.width(), rect.height());
    minSize = minSize ? minSize : 48;
    minSize *= screen->devicePixelRatio();

    // Create an empty pixmap with that size and make it transparent
    QPixmap pixmap(minSize, minSize);
    pixmap.fill(Qt::transparent);

    // Render the SVG (finally!)
    QSvgRenderer renderer(QString(":/img/tray.svg"));
    QPainter painter(&pixmap);
    renderer.render(&painter);

    // *Now* we can set the icon (and set it as a mask)
    QIcon icon(pixmap);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
    icon.setIsMask(true);
#endif
    mTrayIcon.setIcon(icon);
}

void TrayIcon::addAction(const QString &text, QObject *receiver, const char *member)
{
    mMenu.addAction(text, receiver, member);
}

void TrayIcon::addSeparator()
{
    mMenu.addSeparator();
}

void TrayIcon::showMessage(const QString &message)
{
    mTrayIcon.showMessage(tr("NitroShare Notification"), message);
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#include <mapnik/image_options.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/std_pair.hpp>

namespace mapnik { namespace detail {

namespace qi = boost::spirit::qi;

template <typename Iterator>
struct image_options_grammar
    : qi::grammar<Iterator, image_options_map(), boost::spirit::ascii::space_type>
{
    using pair_type = std::pair<std::string, boost::optional<std::string>>;
    image_options_grammar()
        : image_options_grammar::base_type(start)
    {
        qi::lit_type lit;
        qi::char_type char_;
        start = pair >> *(lit(':') >> pair)
            ;
        pair = key >> -('=' >> value)
            ;
        key = char_("a-zA-Z_") >> *char_("a-zA-Z_0-9\\.")
            ;
        value = +char_("a-zA-Z_0-9\\.")
            ;
    }

    qi::rule<Iterator, image_options_map(), boost::spirit::ascii::space_type> start;
    qi::rule<Iterator, pair_type(), boost::spirit::ascii::space_type> pair;
    qi::rule<Iterator, std::string(), boost::spirit::ascii::space_type> key, value;
};

} // ns detail

image_options_map parse_image_options(std::string const& str)
{
     auto const begin = str.begin();
     auto const end = str.end();
     boost::spirit::ascii::space_type space;
     mapnik::detail::image_options_grammar<std::string::const_iterator> g;
     image_options_map options;
     bool success = boost::spirit::qi::phrase_parse(begin, end, g, space, options);
     if (!success)
     {
         throw std::runtime_error("Can't parse image options: " + str);
     }
     return options;   // RVO
}

} // ns mapnik
<commit_msg>Also allow the possibility for negative values being passed to image option values<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#include <mapnik/image_options.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/std_pair.hpp>

namespace mapnik { namespace detail {

namespace qi = boost::spirit::qi;

template <typename Iterator>
struct image_options_grammar
    : qi::grammar<Iterator, image_options_map(), boost::spirit::ascii::space_type>
{
    using pair_type = std::pair<std::string, boost::optional<std::string>>;
    image_options_grammar()
        : image_options_grammar::base_type(start)
    {
        qi::lit_type lit;
        qi::char_type char_;
        start = pair >> *(lit(':') >> pair)
            ;
        pair = key >> -('=' >> value)
            ;
        key = char_("a-zA-Z_") >> *char_("a-zA-Z_0-9\\.\\-")
            ;
        value = +char_("a-zA-Z_0-9\\.\\-")
            ;
    }

    qi::rule<Iterator, image_options_map(), boost::spirit::ascii::space_type> start;
    qi::rule<Iterator, pair_type(), boost::spirit::ascii::space_type> pair;
    qi::rule<Iterator, std::string(), boost::spirit::ascii::space_type> key, value;
};

} // ns detail

image_options_map parse_image_options(std::string const& str)
{
     auto const begin = str.begin();
     auto const end = str.end();
     boost::spirit::ascii::space_type space;
     mapnik::detail::image_options_grammar<std::string::const_iterator> g;
     image_options_map options;
     bool success = boost::spirit::qi::phrase_parse(begin, end, g, space, options);
     if (!success)
     {
         throw std::runtime_error("Can't parse image options: " + str);
     }
     return options;   // RVO
}

} // ns mapnik
<|endoftext|>


<commit_before>/*
	Copyright (C) 2017 by Claude SIMON (http://zeusw.org/epeios/contact.html).

	This file is part of XDHq.

    XDHq is free software: you can redistribute it and/or modify it
    under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    XDHq is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with XDHq.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "xdhp.h"

#include "registry.h"
#include "treep.h"

#include "server.h"

#include "sclargmnt.h"

#include "csdmns.h"
#include "csdcmn.h"
#include "mtk.h"

using namespace xdhp;

namespace {

	class rComm_	// ...unication.
	{
	private:
		mtx::rHandler Read_, Write_;
		str::wString Language_;
		fdr::rRWDriver *Driver_;
	public:
		void reset( bso::sBool P = true )
		{
			if ( P ) {
				if ( Read_ != mtx::UndefinedHandler )
					mtx::Delete( Read_ );

				if ( Write_ != mtx::UndefinedHandler )
					mtx::Delete( Write_ );
			}

			tol::reset( P, Language_, Driver_ );
			Read_ = Write_ = mtx::UndefinedHandler;
		}
		qCDTOR( rComm_ );
		void Init( const str::dString &Language )
		{
			reset();

			Read_ = mtx::Create();
			Write_ = mtx::Create();

			mtx::Lock( Read_ );

			Language_.Init( Language );
			Driver_ = NULL;
		}
		qRODISCLOSEr( str::dString, Language );
		void Write( fdr::rRWDriver *Driver )	// If 'Driver' == NULL, it only waits for dismissal.
		{
			mtx::Lock( Write_ );

			if ( ( Driver_ != NULL ) && ( Driver != NULL ) )
				qRGnr();

			Driver_ = Driver;

			if ( Driver == NULL )
				mtx::Unlock( Write_ );
			else
				mtx::Unlock( Read_ );
		}
		fdr::rRWDriver *Read( void )
		{
			mtx::Lock( Read_ );

			if ( Driver_ == NULL )
				qRGnr();

			return Driver_;
		}
		void Dismiss( void )
		{
			mtx::Unlock( Write_ );
		}
	};

	class rConn_	// ...exion.
	{
	private:
		mtx::rHandler Read_, Write_;
		rComm_ *Comm_;
	public:
		void reset( bso::sBool P = true )
		{
			if ( P ) {
				if ( Read_ != mtx::UndefinedHandler )
					mtx::Delete( Read_ );

				if ( Write_ != mtx::UndefinedHandler )
					mtx::Delete( Write_ );
			}

			Read_ = Write_ = mtx::UndefinedHandler;
			Comm_ = NULL;
		}
		qCDTOR( rConn_ );
		void Init( void )
		{
			reset();

			Read_ = mtx::Create();
			Write_ = mtx::Create();

			mtx::Lock( Read_ );

			Comm_ = NULL;
		}
		void Write( rComm_ *Comm )
		{
			mtx::Lock( Write_ );

			if ( Comm_ != NULL )
				qRGnr();

			Comm_ = Comm;

			mtx::Unlock( Read_ );
		}
		rComm_ *Read( void )
		{
			rComm_ *Comm = NULL;

			mtx::Lock( Read_ );

			if ( Comm_ == NULL )
				qRGnr();

			Comm = Comm_;

			mtx::Unlock( Write_ );

			return Comm;
		}
	} Conn_;

	typedef csdmns::cProcessing cProcessing_;

	class sProcessing
	: public cProcessing_
	{
	protected:
		virtual void *CSDSCBPreProcess(
			fdr::rRWDriver *IODriver,
			const ntvstr::char__ *Origin ) override
		{
			rComm_ *Comm = NULL;
		qRH;
			flw::sDressedRWFlow<> Flow;
			str::wString Language;
		qRB;
			Flow.Init( *IODriver );
			Language.Init();
			server::Handshake( Flow, Language );

			Comm = new rComm_;

			if ( Comm == NULL )
				qRAlc();

			Comm->Init( Language );

			prtcl::PutAnswer( prtcl::aOK_1, Flow );
			Flow.Commit();

			Conn_.Write( Comm );
		qRR;
			if ( Comm != NULL )
				delete Comm;
		qRT;
		qRE;
			return Comm;
		}
		virtual csdscb::eAction CSDSCBProcess(
			fdr::rRWDriver *IODriver,
			void *UP ) override
		{
			if ( UP == NULL )
				qRGnr();

			rComm_ &Comm = *(rComm_ *)UP;

			Comm.Write( IODriver );

			Comm.Write( NULL );	// Wait for dismissal.

			return csdscb::aContinue;
		}
		virtual bso::sBool CSDSCBPostProcess( void *UP ) override
		{
			if ( UP == NULL )
				qRGnr();

			delete (rComm_ *)UP;

			return true;
		}
	public:
		void Init( void )
		{}
	} Processing_;

	csdmns::rServer Server_;

	void Process_( void * )
	{
		Server_.Process();
	}
}

SCLZND_F( xdhp::Listen )
{
qRH;
	str::wString Arguments;
qRB;
	Arguments.Init();
	Caller.Get( Arguments );

	sclargmnt::FillRegistry( Arguments, sclargmnt::faIsArgument, sclargmnt::uaReport );

	Processing_.Init();
	Conn_.Init();

	Server_.Init( sclmisc::MGetU16( registry::parameter::Service ), Processing_ );

	mtk::RawLaunch( Process_, NULL );
qRR;
qRT;
qRE;
}

namespace {
	namespace {
		typedef fdr::rRWDressedDriver rRWDriver_;

		class rDriver_
		: public rRWDriver_
		{
		private:
			qRMV( rComm_, C_, Comm_ );
			qRMV( fdr::rRWDriver, D_, Driver_ );
		protected:
			virtual fdr::sSize FDRRead(
				fdr::sSize Maximum,
				fdr::sByte *Buffer ) override
			{
				if ( Driver_ == NULL ) {
					Driver_ = C_().Read();
				}

				D_().ITake( tht::GetTID() );
				return D_().Read( Maximum, Buffer, fdr::bNonBlocking );
			}
			virtual void FDRDismiss( bso::sBool Unlock ) override
			{
				D_().Dismiss( Unlock );
			}
			virtual tht::sTID FDRITake( fdr::sTID Owner ) override
			{
				return D_().ITake( Owner );
			}
			virtual fdr::sSize FDRWrite(
				const fdr::sByte *Buffer,
				fdr::sSize Maximum ) override
			{
				if ( Driver_ == NULL ) {
					Driver_ = C_().Read();
				}

				D_().OTake( tht::GetTID() );
				return D_().Write( Buffer, Maximum );
			}
			virtual void FDRCommit( bso::sBool Unlock ) override
			{
				D_().Commit( Unlock );
				C_().Dismiss();
				Driver_ = NULL;
			}
			virtual tht::sTID FDROTake( tht::sTID Owner ) override
			{
				return D_().OTake( Owner );
			}
		public:
			void reset( bso::sBool P = true )
			{
				rRWDriver_::reset( P );

				tol::reset( P, Comm_, Driver_ );
			}
			qCVDTOR( rDriver_ );
			void Init( rComm_ *Comm )
			{
				rRWDriver_::Init( fdr::ts_Default );

				Driver_ = NULL;
				Comm_ = Comm;
			}
			const str::dString &Language( void ) const
			{
				return C_().Language();
			}
		};
	}
	struct rRack_ {
	private:
		rDriver_ Driver_;
	public:
		flw::sDressedRWFlow<> Flow;
		void reset( bso::sBool P = true )
		{
			tol::reset( P, Driver_, Flow );
		}
		qCDTOR( rRack_ );
		void Init( rComm_ *Comm )
		{
			Driver_.Init( Comm );
			Flow.Init( Driver_ );

		}
		const str::dString &Language( void ) const
		{
			return Driver_.Language();
		}
	};
}

SCLZND_F( xdhp::New )
{
qRH;
	rRack_ *Rack = NULL;
qRB;
	if ( (Rack = new rRack_) == NULL )
		qRAlc();

	Rack->Init( Conn_.Read() );

	Caller.SetReturnValue( (bso::sS64)Rack );
qRR;
	if ( Rack != NULL )
		delete Rack;
qRT;
qRE;
}

SCLZND_F( xdhp::Delete )
{
	bso::sS64 Long = 0;

	Caller.Get( Long );

	if ( Long == 0 )
		qRGnr();

	delete (rRack_ * )Long;
}

namespace {
	rRack_ &GetRack_( sclznd::sCaller &Caller )
	{
		bso::sS64 Long = 0;

		Caller.Get( Long );

		if ( Long == 0 )
			qRGnr();

		return *(rRack_ *)Long;
	}

	flw::sRWFlow &GetFlow_( sclznd::sCaller &Caller )
	{
		return GetRack_( Caller ).Flow;
	}
}

#define RACK	rRack_ &Rack = GetRack_( Caller )
#define FLOW	flw::sRWFlow &Flow = GetFlow_( Caller )

SCLZND_F( xdhp::GetAction )
{
qRH;
	str::wString Id, Action;
	str::wStrings Strings;
qRB;
	FLOW;

	tol::Init( Id, Action );
	server::GetAction( Flow, Id, Action );

	Strings.Init();

	Strings.Append( Id );
	Strings.Append( Action );

	Caller.SetReturnValue( Strings );
qRR;
qRT;
qRE;
}

SCLZND_F( xdhp::Alert )
{
qRH;
	str::wString Message;
qRB;
	FLOW;

	Message.Init();
	Caller.Get( Message );

	server::Alert( Message, Flow );
qRR;
qRT;
qRE;
}

SCLZND_F( xdhp::Confirm )
{
	bso::sBool Return = false;
qRH;
	str::wString Message, Response;
qRB;
	FLOW;

	Message.Init();
	Caller.Get( Message );

	Response.Init();
	server::Confirm( Message, Flow, Response );

	Caller.SetReturnValue( Response == "true" );
qRR;
qRT;
qRE;
}

namespace {
	void SetLayout_(
		const str::dString &Id,
		sclznd::sCaller &Caller,
		const str::dString &Language,
		flw::sRWFlow &Flow )
	{
	qRH;
		str::wString XML, XSLFilename;
	qRB;
		tol::Init( XML, XSLFilename );

		treep::GetXML( Caller, XML );
		Caller.Get( XSLFilename );

		server::layout::Set( Id, XML, XSLFilename, Language, Flow );
	qRR;
	qRT;
	qRE;
	}

	void SetLayout_(
		sclznd::sCaller &Caller,
		const str::dString &Language,
		flw::sRWFlow &Flow )
	{
	qRH;
		str::wString Id;
	qRB;
		tol::Init( Id );
		Caller.Get( Id );

		SetLayout_( Id, Caller, Language, Flow );
	qRR;
	qRT;
	qRE;
	}
}

SCLZND_F( xdhp::SetLayout )
{
	RACK;

	SetLayout_( Caller, Rack.Language(), Rack.Flow );
}

SCLZND_F( xdhp::GetContents )
{
qRH;
	str::wStrings Ids, Contents;
qRB;
	FLOW;

	Ids.Init();
	Caller.Get( Ids );

	Contents.Init();
	server::contents::Get( Ids, Flow, Contents );

	Caller.SetReturnValue( Contents );
qRR;
qRT;
qRE;
}

SCLZND_F( xdhp::SetContents )
{
qRH;
	str::wStrings Ids, Contents;
qRB;
	FLOW;

	tol::Init( Ids, Contents );
	Caller.Get( Ids, Contents );

	server::contents::Set( Ids, Contents, Flow );
qRR;
qRT;
qRE;
}

SCLZND_F( xdhp::DressWidgets )
{
qRH;
	str::wString Id;
qRB;
	FLOW;

	tol::Init( Id );
	Caller.Get( Id );

	server::widgets::Dress( Id, Flow );
qRR;
qRT;
qRE;
}

namespace {
	void HandleClasses_(
		sclznd::sCaller &Caller,
		void( *Function )(
			const str::dStrings &Ids,
			const str::dStrings &Classes,
			flw::sRWFlow &Flow) )
	{
	qRH;
		str::wStrings Ids, Classes;
	qRB;
		FLOW;

		tol::Init( Ids, Classes );
		Caller.Get( Ids, Classes );

		Function( Ids, Classes, Flow );
	qRR;
	qRT;
	qRE;
	}
}

SCLZND_F( xdhp::AddClasses )
{
	HandleClasses_( Caller, server::classes::Add );
}

SCLZND_F( xdhp::RemoveClasses )
{
	HandleClasses_( Caller, server::classes::Remove );
}

SCLZND_F( xdhp::ToggleClasses )
{
	HandleClasses_( Caller, server::classes::Toggle );
}

namespace {
	void HandleElements_(
		sclznd::sCaller &Caller,
		void( *Function )(
			const str::dStrings &Ids,
			flw::sRWFlow &Flow) )
	{
	qRH;
		str::wStrings Ids;
	qRB;
		FLOW;

		tol::Init( Ids );
		Caller.Get( Ids );

		Function( Ids, Flow );
	qRR;
	qRT;
	qRE;
	}
}

SCLZND_F( xdhp::EnableElements )
{
	HandleElements_( Caller, server::elements::Enable );
}

SCLZND_F( xdhp::DisableElements )
{
	HandleElements_( Caller, server::elements::Disable );
}

namespace {
	void Get_(
		sclznd::sCaller &Caller,
		void( *Function )(
			const str::dString &Id,
			const str::dString &Name,
			flw::sRWFlow &Flow,
			str::dString &Value ) )
	{
	qRH;
		str::wString Id, Name, Value;
	qRB;
		FLOW;

		tol::Init( Id, Name );
		Caller.Get( Id, Name );

		tol::Init( Value );
		Function( Id, Name, Flow, Value );

		Caller.SetReturnValue( Value );
	qRR;
	qRT;
	qRE;
	}

	void Set_(
		sclznd::sCaller &Caller,
		void( *Function )(
			const str::dString &Id,
			const str::dString &Name,
			const str::dString &Value,
			flw::sRWFlow &Flow ) )
	{
	qRH;
		str::wString Id, Name, Value;
	qRB;
		FLOW;

		tol::Init( Id, Name, Value );
		Caller.Get( Id, Name, Value );

		Function( Id, Name, Value, Flow );
	qRR;
	qRT;
	qRE;
	}

}

SCLZND_F( xdhp::GetAttribute )
{
	Get_( Caller, server::attribute::Get );
}

SCLZND_F( xdhp::SetAttribute )
{
	Set_( Caller, server::attribute::Set );
}

SCLZND_F( xdhp::GetProperty )
{
	Get_( Caller, server::property::Get );
}

SCLZND_F( xdhp::SetProperty )
{
	Set_( Caller, server::property::Set );
}

<commit_msg>23/01/2018 11:42:03<commit_after>/*
	Copyright (C) 2017 by Claude SIMON (http://zeusw.org/epeios/contact.html).

	This file is part of XDHq.

    XDHq is free software: you can redistribute it and/or modify it
    under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    XDHq is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with XDHq.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "xdhp.h"

#include "registry.h"
#include "treep.h"

#include "proxy.h"

#include "sclargmnt.h"

#include "csdmns.h"
#include "csdcmn.h"
#include "mtk.h"

using namespace xdhp;

namespace {

	namespace {
		typedef proxy::rData rPData_;
	}

	class rData_
		: public rPData_
	{};

	proxy::rSharing<rData_> Sharing_;
	proxy::rProcessing<rData_> Processing_;
	csdmns::rServer Server_;

	void Process_( void * )
	{
		Server_.Process();
	}
}

SCLZND_F( xdhp::Listen )
{
qRH;
	str::wString Arguments;
qRB;
	Arguments.Init();
	Caller.Get( Arguments );

	sclargmnt::FillRegistry( Arguments, sclargmnt::faIsArgument, sclargmnt::uaReport );

	Sharing_.Init();
	Processing_.Init( Sharing_ );
	Server_.Init( sclmisc::MGetU16( registry::parameter::Service ), Processing_ );

	mtk::RawLaunch( Process_, NULL );
qRR;
qRT;
qRE;
}

namespace {
	namespace {
		typedef fdr::rRWDressedDriver rRWDriver_;

		class rDriver_
		: public rRWDriver_
		{
		private:
			qRMV( rComm_, C_, Comm_ );
			qRMV( fdr::rRWDriver, D_, Driver_ );
		protected:
			virtual fdr::sSize FDRRead(
				fdr::sSize Maximum,
				fdr::sByte *Buffer ) override
			{
				if ( Driver_ == NULL ) {
					Driver_ = C_().Read();
				}

				D_().ITake( tht::GetTID() );
				return D_().Read( Maximum, Buffer, fdr::bNonBlocking );
			}
			virtual void FDRDismiss( bso::sBool Unlock ) override
			{
				D_().Dismiss( Unlock );
			}
			virtual tht::sTID FDRITake( fdr::sTID Owner ) override
			{
				return D_().ITake( Owner );
			}
			virtual fdr::sSize FDRWrite(
				const fdr::sByte *Buffer,
				fdr::sSize Maximum ) override
			{
				if ( Driver_ == NULL ) {
					Driver_ = C_().Read();
				}

				D_().OTake( tht::GetTID() );
				return D_().Write( Buffer, Maximum );
			}
			virtual void FDRCommit( bso::sBool Unlock ) override
			{
				D_().Commit( Unlock );
				C_().Dismiss();
				Driver_ = NULL;
			}
			virtual tht::sTID FDROTake( tht::sTID Owner ) override
			{
				return D_().OTake( Owner );
			}
		public:
			void reset( bso::sBool P = true )
			{
				rRWDriver_::reset( P );

				tol::reset( P, Comm_, Driver_ );
			}
			qCVDTOR( rDriver_ );
			void Init( rComm_ *Comm )
			{
				rRWDriver_::Init( fdr::ts_Default );

				Driver_ = NULL;
				Comm_ = Comm;
			}
			const str::dString &Language( void ) const
			{
				return C_().Language();
			}
		};
	}
	struct rRack_ {
	private:
		rDriver_ Driver_;
	public:
		flw::sDressedRWFlow<> Flow;
		void reset( bso::sBool P = true )
		{
			tol::reset( P, Driver_, Flow );
		}
		qCDTOR( rRack_ );
		void Init( rComm_ *Comm )
		{
			Driver_.Init( Comm );
			Flow.Init( Driver_ );

		}
		const str::dString &Language( void ) const
		{
			return Driver_.Language();
		}
	};
}

SCLZND_F( xdhp::New )
{
qRH;
	rRack_ *Rack = NULL;
qRB;
	if ( (Rack = new rRack_) == NULL )
		qRAlc();

	Rack->Init( Conn_.Read() );

	Caller.SetReturnValue( (bso::sS64)Rack );
qRR;
	if ( Rack != NULL )
		delete Rack;
qRT;
qRE;
}

SCLZND_F( xdhp::Delete )
{
	bso::sS64 Long = 0;

	Caller.Get( Long );

	if ( Long == 0 )
		qRGnr();

	delete (rRack_ * )Long;
}

namespace {
	rRack_ &GetRack_( sclznd::sCaller &Caller )
	{
		bso::sS64 Long = 0;

		Caller.Get( Long );

		if ( Long == 0 )
			qRGnr();

		return *(rRack_ *)Long;
	}

	flw::sRWFlow &GetFlow_( sclznd::sCaller &Caller )
	{
		return GetRack_( Caller ).Flow;
	}
}

#define RACK	rRack_ &Rack = GetRack_( Caller )
#define FLOW	flw::sRWFlow &Flow = GetFlow_( Caller )

SCLZND_F( xdhp::GetAction )
{
qRH;
	str::wString Id, Action;
	str::wStrings Strings;
qRB;
	FLOW;

	tol::Init( Id, Action );
	server::GetAction( Flow, Id, Action );

	Strings.Init();

	Strings.Append( Id );
	Strings.Append( Action );

	Caller.SetReturnValue( Strings );
qRR;
qRT;
qRE;
}

SCLZND_F( xdhp::Alert )
{
qRH;
	str::wString Message;
qRB;
	FLOW;

	Message.Init();
	Caller.Get( Message );

	server::Alert( Message, Flow );
qRR;
qRT;
qRE;
}

SCLZND_F( xdhp::Confirm )
{
	bso::sBool Return = false;
qRH;
	str::wString Message, Response;
qRB;
	FLOW;

	Message.Init();
	Caller.Get( Message );

	Response.Init();
	server::Confirm( Message, Flow, Response );

	Caller.SetReturnValue( Response == "true" );
qRR;
qRT;
qRE;
}

namespace {
	void SetLayout_(
		const str::dString &Id,
		sclznd::sCaller &Caller,
		const str::dString &Language,
		flw::sRWFlow &Flow )
	{
	qRH;
		str::wString XML, XSLFilename;
	qRB;
		tol::Init( XML, XSLFilename );

		treep::GetXML( Caller, XML );
		Caller.Get( XSLFilename );

		server::layout::Set( Id, XML, XSLFilename, Language, Flow );
	qRR;
	qRT;
	qRE;
	}

	void SetLayout_(
		sclznd::sCaller &Caller,
		const str::dString &Language,
		flw::sRWFlow &Flow )
	{
	qRH;
		str::wString Id;
	qRB;
		tol::Init( Id );
		Caller.Get( Id );

		SetLayout_( Id, Caller, Language, Flow );
	qRR;
	qRT;
	qRE;
	}
}

SCLZND_F( xdhp::SetLayout )
{
	RACK;

	SetLayout_( Caller, Rack.Language(), Rack.Flow );
}

SCLZND_F( xdhp::GetContents )
{
qRH;
	str::wStrings Ids, Contents;
qRB;
	FLOW;

	Ids.Init();
	Caller.Get( Ids );

	Contents.Init();
	server::contents::Get( Ids, Flow, Contents );

	Caller.SetReturnValue( Contents );
qRR;
qRT;
qRE;
}

SCLZND_F( xdhp::SetContents )
{
qRH;
	str::wStrings Ids, Contents;
qRB;
	FLOW;

	tol::Init( Ids, Contents );
	Caller.Get( Ids, Contents );

	server::contents::Set( Ids, Contents, Flow );
qRR;
qRT;
qRE;
}

SCLZND_F( xdhp::DressWidgets )
{
qRH;
	str::wString Id;
qRB;
	FLOW;

	tol::Init( Id );
	Caller.Get( Id );

	server::widgets::Dress( Id, Flow );
qRR;
qRT;
qRE;
}

namespace {
	void HandleClasses_(
		sclznd::sCaller &Caller,
		void( *Function )(
			const str::dStrings &Ids,
			const str::dStrings &Classes,
			flw::sRWFlow &Flow) )
	{
	qRH;
		str::wStrings Ids, Classes;
	qRB;
		FLOW;

		tol::Init( Ids, Classes );
		Caller.Get( Ids, Classes );

		Function( Ids, Classes, Flow );
	qRR;
	qRT;
	qRE;
	}
}

SCLZND_F( xdhp::AddClasses )
{
	HandleClasses_( Caller, server::classes::Add );
}

SCLZND_F( xdhp::RemoveClasses )
{
	HandleClasses_( Caller, server::classes::Remove );
}

SCLZND_F( xdhp::ToggleClasses )
{
	HandleClasses_( Caller, server::classes::Toggle );
}

namespace {
	void HandleElements_(
		sclznd::sCaller &Caller,
		void( *Function )(
			const str::dStrings &Ids,
			flw::sRWFlow &Flow) )
	{
	qRH;
		str::wStrings Ids;
	qRB;
		FLOW;

		tol::Init( Ids );
		Caller.Get( Ids );

		Function( Ids, Flow );
	qRR;
	qRT;
	qRE;
	}
}

SCLZND_F( xdhp::EnableElements )
{
	HandleElements_( Caller, server::elements::Enable );
}

SCLZND_F( xdhp::DisableElements )
{
	HandleElements_( Caller, server::elements::Disable );
}

namespace {
	void Get_(
		sclznd::sCaller &Caller,
		void( *Function )(
			const str::dString &Id,
			const str::dString &Name,
			flw::sRWFlow &Flow,
			str::dString &Value ) )
	{
	qRH;
		str::wString Id, Name, Value;
	qRB;
		FLOW;

		tol::Init( Id, Name );
		Caller.Get( Id, Name );

		tol::Init( Value );
		Function( Id, Name, Flow, Value );

		Caller.SetReturnValue( Value );
	qRR;
	qRT;
	qRE;
	}

	void Set_(
		sclznd::sCaller &Caller,
		void( *Function )(
			const str::dString &Id,
			const str::dString &Name,
			const str::dString &Value,
			flw::sRWFlow &Flow ) )
	{
	qRH;
		str::wString Id, Name, Value;
	qRB;
		FLOW;

		tol::Init( Id, Name, Value );
		Caller.Get( Id, Name, Value );

		Function( Id, Name, Value, Flow );
	qRR;
	qRT;
	qRE;
	}

}

SCLZND_F( xdhp::GetAttribute )
{
	Get_( Caller, server::attribute::Get );
}

SCLZND_F( xdhp::SetAttribute )
{
	Set_( Caller, server::attribute::Set );
}

SCLZND_F( xdhp::GetProperty )
{
	Get_( Caller, server::property::Get );
}

SCLZND_F( xdhp::SetProperty )
{
	Set_( Caller, server::property::Set );
}

<|endoftext|>