text:
#include "mitkSetRegionTool.h"

#include "mitkToolManager.h"
#include "mitkOverwriteSliceImageFilter.h"

#include "ipSegmentation.h"

#include "mitkBaseRenderer.h"
#include "mitkImageDataItem.h"
#include "mitkLegacyAdaptors.h"

#include "mitkOverwriteDirectedPlaneImageFilter.h"

mitk::SetRegionTool::SetRegionTool(int paintingPixelValue)
:FeedbackContourTool("PressMoveReleaseWithCTRLInversion"),
 m_PaintingPixelValue(paintingPixelValue),
 m_FillContour(false),
 m_StatusFillWholeSlice(false)
{
}

mitk::SetRegionTool::~SetRegionTool()
{
}

void mitk::SetRegionTool::ConnectActionsAndFunctions()
{
  CONNECT_FUNCTION( "PrimaryButtonPressed", OnMousePressed);
  CONNECT_FUNCTION( "Release", OnMouseReleased);
  CONNECT_FUNCTION( "InvertLogic", OnInvertLogic);
}

void mitk::SetRegionTool::Activated()
{
  Superclass::Activated();
}

void mitk::SetRegionTool::Deactivated()
{
  Superclass::Deactivated();
}

bool mitk::SetRegionTool::OnMousePressed ( StateMachineAction*, InteractionEvent* interactionEvent )
{
  if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
      return false;

  mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
  //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
  if (!positionEvent) return false;

  m_LastEventSender = positionEvent->GetSender();
  m_LastEventSlice = m_LastEventSender->GetSlice();
  int timeStep = positionEvent->GetSender()->GetTimeStep();

  if ( FeedbackContourTool::CanHandleEvent(interactionEvent) < 1.0 ) return false;

  // 1. Get the working image
  Image::Pointer workingSlice   = FeedbackContourTool::GetAffectedWorkingSlice( positionEvent );
  if ( workingSlice.IsNull() ) return false; // can't do anything without the segmentation

  // if click was outside the image, don't continue
  const BaseGeometry* sliceGeometry = workingSlice->GetGeometry();
  itk::Index<2> projectedPointIn2D;
  sliceGeometry->WorldToIndex( positionEvent->GetPositionInWorld(), projectedPointIn2D );
  if ( !sliceGeometry->IsIndexInside( projectedPointIn2D ) )
  {
    MITK_ERROR << "point apparently not inside segmentation slice" << std::endl;
    return false; // can't use that as a seed point
  }

    // Convert to ipMITKSegmentationTYPE (because ipMITKSegmentationGetContour8N relys on that data type)
    itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage;
    CastToItkImage( workingSlice, correctPixelTypeImage );
    assert (correctPixelTypeImage.IsNotNull() );

  // possible bug in CastToItkImage ?
  // direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in
  // mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479:
  // virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0' failed
  // solution here: we overwrite it with an unity matrix
  itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection;
  imageDirection.SetIdentity();
  correctPixelTypeImage->SetDirection(imageDirection);

    Image::Pointer temporarySlice = Image::New();
  //  temporarySlice = ImportItkImage( correctPixelTypeImage );
    CastToMitkImage( correctPixelTypeImage, temporarySlice );

  // check index positions
  mitkIpPicDescriptor* originalPicSlice = mitkIpPicNew();
  CastToIpPicDescriptor( temporarySlice, originalPicSlice );

  int m_SeedPointMemoryOffset = projectedPointIn2D[1] * originalPicSlice->n[0] + projectedPointIn2D[0];

  if ( m_SeedPointMemoryOffset >= static_cast<int>( originalPicSlice->n[0] * originalPicSlice->n[1] ) ||
       m_SeedPointMemoryOffset < 0 )
  {
    MITK_ERROR << "Memory offset calculation if mitk::SetRegionTool has some serious flaw! Aborting.." << std::endl;
    return false;
  }

  // 2. Determine the contour that surronds the selected "piece of the image"

  // find a contour seed point
  unsigned int oneContourOffset = static_cast<unsigned int>( m_SeedPointMemoryOffset ); // safe because of earlier check if m_SeedPointMemoryOffset < 0

  /**
    * The logic of finding a starting point for the contour is the following:
    *
    *  - If the initial seed point is 0, we are either inside a hole or outside of every segmentation.
    *    We move to the right until we hit a 1, which must be part of a contour.
    *
    *  - If the initial seed point is 1, then ...
    *    we now do the same (running to the right) until we hit a 1
    *
    *  In both cases the found contour point is used to extract a contour and
    *  then a test is applied to find out if the initial seed point is contained
    *  in the contour. If this is the case, filling should be applied, otherwise
    *  nothing is done.
    */
  unsigned int size = originalPicSlice->n[0] * originalPicSlice->n[1];
/*
  unsigned int rowSize = originalPicSlice->n[0];
*/
  ipMITKSegmentationTYPE* data = static_cast<ipMITKSegmentationTYPE*>(originalPicSlice->data);

  if ( data[oneContourOffset] == 0 ) // initial seed 0
  {
    for ( ; oneContourOffset < size; ++oneContourOffset )
    {
      if ( data[oneContourOffset] > 0 ) break;
    }
  }
  else if ( data[oneContourOffset] == 1 ) // initial seed 1
  {
    unsigned int lastValidPixel = size-1; // initialization, will be changed lateron
    bool inSeg = true;    // inside segmentation?
    for ( ; oneContourOffset < size; ++oneContourOffset )
    {
      if ( ( data[oneContourOffset] == 0 ) && inSeg ) // pixel 0 and inside-flag set: this happens at the first pixel outside a filled region
      {
        inSeg = false;
        lastValidPixel = oneContourOffset - 1; // store the last pixel position inside a filled region
        break;
      }
      else // pixel 1, inside-flag doesn't matter: this happens while we are inside a filled region
      {
        inSeg = true; // first iteration lands here
      }

    }
    oneContourOffset = lastValidPixel;
  }
  else
  {
    MITK_ERROR << "Fill/Erase was never intended to work with other than binary images." << std::endl;
    m_FillContour = false;
    return false;
  }

  if (oneContourOffset == size) // nothing found until end of slice
  {
    m_FillContour = false;
    return false;
  }

  int numberOfContourPoints( 0 );
  int newBufferSize( 0 );
  //MITK_INFO << "getting contour from offset " << oneContourOffset << " ("<<oneContourOffset%originalPicSlice->n[0]<<","<<oneContourOffset/originalPicSlice->n[0]<<")"<<std::endl;
  float* contourPoints = ipMITKSegmentationGetContour8N( originalPicSlice, oneContourOffset, numberOfContourPoints, newBufferSize ); // memory allocated with malloc

  //MITK_INFO << "contourPoints " << contourPoints << " (N="<<numberOfContourPoints<<")"<<std::endl;
  assert(contourPoints == NULL || numberOfContourPoints > 0);

  bool cursorInsideContour = ipMITKSegmentationIsInsideContour( contourPoints, numberOfContourPoints, projectedPointIn2D[0], projectedPointIn2D[1]);

  // decide if contour should be filled or not
  m_FillContour = cursorInsideContour;

  if (m_FillContour)
  {
    // copy point from float* to mitk::Contour
    ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New();
    contourInImageIndexCoordinates->Expand(timeStep + 1);
    contourInImageIndexCoordinates->SetClosed(true, timeStep);
    Point3D newPoint;
    for (int index = 0; index < numberOfContourPoints; ++index)
    {
      newPoint[0] = contourPoints[ 2 * index + 0 ] - 0.5;
      newPoint[1] = contourPoints[ 2 * index + 1] - 0.5;
      newPoint[2] = 0;

      contourInImageIndexCoordinates->AddVertex(newPoint, timeStep);
    }

    m_SegmentationContourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( workingSlice->GetGeometry(), contourInImageIndexCoordinates, true ); // true, correct the result from ipMITKSegmentationGetContour8N

    // 3. Show the contour
    FeedbackContourTool::SetFeedbackContour( *m_SegmentationContourInWorldCoordinates );

    FeedbackContourTool::SetFeedbackContourVisible(true);
    mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
  }

  // always generate a second contour, containing the whole image (used when CTRL is pressed)
  {
    // copy point from float* to mitk::Contour
    ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New();
    contourInImageIndexCoordinates->Expand(timeStep + 1);
    contourInImageIndexCoordinates->SetClosed(true, timeStep);
    Point3D newPoint;
    newPoint[0] = 0; newPoint[1] = 0; newPoint[2] = 0.0;
    contourInImageIndexCoordinates->AddVertex( newPoint, timeStep );
    newPoint[0] = originalPicSlice->n[0]; newPoint[1] = 0; newPoint[2] = 0.0;
    contourInImageIndexCoordinates->AddVertex( newPoint, timeStep );
    newPoint[0] = originalPicSlice->n[0]; newPoint[1] = originalPicSlice->n[1]; newPoint[2] = 0.0;
    contourInImageIndexCoordinates->AddVertex( newPoint, timeStep );
    newPoint[0] = 0; newPoint[1] = originalPicSlice->n[1]; newPoint[2] = 0.0;
    contourInImageIndexCoordinates->AddVertex( newPoint, timeStep );

    m_WholeImageContourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( workingSlice->GetGeometry(), contourInImageIndexCoordinates, true ); // true, correct the result from ipMITKSegmentationGetContour8N

    // 3. Show the contour
    FeedbackContourTool::SetFeedbackContour( *m_SegmentationContourInWorldCoordinates );

    FeedbackContourTool::SetFeedbackContourVisible(true);
    mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
  }

  free(contourPoints);

  return true;
}

bool mitk::SetRegionTool::OnMouseReleased( StateMachineAction*, InteractionEvent* interactionEvent )
{
  if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
      return false;

  // 1. Hide the feedback contour, find out which slice the user clicked, find out which slice of the toolmanager's working image corresponds to that
  FeedbackContourTool::SetFeedbackContourVisible(false);

  mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
  //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
  if (!positionEvent) return false;

  assert( positionEvent->GetSender()->GetRenderWindow() );
  mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());

  int timeStep = positionEvent->GetSender()->GetTimeStep();

  if (!m_FillContour && !m_StatusFillWholeSlice) return true;

  if ( FeedbackContourTool::CanHandleEvent(interactionEvent) < 1.0 ) return false;

  DataNode* workingNode( m_ToolManager->GetWorkingData(0) );
  if (!workingNode) return false;

  Image* image = dynamic_cast<Image*>(workingNode->GetData());
  const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) );
  if ( !image || !planeGeometry ) return false;

  Image::Pointer slice = FeedbackContourTool::GetAffectedImageSliceAs2DImage( positionEvent, image );

  if ( slice.IsNull() )
  {
      MITK_ERROR << "Unable to extract slice." << std::endl;
      return false;
  }

  ContourModel* feedbackContour( FeedbackContourTool::GetFeedbackContour() );
  ContourModel::Pointer projectedContour = FeedbackContourTool::ProjectContourTo2DSlice( slice, feedbackContour, false, false ); // false: don't add 0.5 (done by FillContourInSlice)
  // false: don't constrain the contour to the image's inside
  if (projectedContour.IsNull()) return false;

  FeedbackContourTool::FillContourInSlice( projectedContour, timeStep, slice, m_PaintingPixelValue );

  this->WriteBackSegmentationResult(positionEvent, slice);

  m_WholeImageContourInWorldCoordinates = NULL;
  m_SegmentationContourInWorldCoordinates = NULL;

  return true;
}

/**
  Called when the CTRL key is pressed. Will change the painting pixel value from 0 to 1 or from 1 to 0.
*/
bool mitk::SetRegionTool::OnInvertLogic( StateMachineAction*, InteractionEvent* interactionEvent )
{
  if ( FeedbackContourTool::CanHandleEvent(interactionEvent) < 1.0 ) return false;

  mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
  //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
  if (!positionEvent) return false;

  if (m_StatusFillWholeSlice)
  {
    // use contour extracted from image data
    if (m_SegmentationContourInWorldCoordinates.IsNotNull())
      FeedbackContourTool::SetFeedbackContour( *m_SegmentationContourInWorldCoordinates );
    mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
  }
  else
  {
    // use some artificial contour
    if (m_WholeImageContourInWorldCoordinates.IsNotNull())
      FeedbackContourTool::SetFeedbackContour( *m_WholeImageContourInWorldCoordinates );
    mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
  }

  m_StatusFillWholeSlice = !m_StatusFillWholeSlice;

  return true;
}


text:
#include "modules/audio_processing/aec3/suppression_gain_limiter.h"

#include <math.h>
#include <algorithm>

#include "modules/audio_processing/aec3/aec3_common.h"

namespace webrtc {
namespace {

// Computes the gain rampup factor to use.
float ComputeGainRampupIncrease(
    const EchoCanceller3Config::EchoRemovalControl::GainRampup& rampup_config) {
  return powf(1.f / rampup_config.first_non_zero_gain,
              1.f / rampup_config.non_zero_gain_blocks);
}

}  // namespace

SuppressionGainUpperLimiter::SuppressionGainUpperLimiter(
    const EchoCanceller3Config& config)
    : rampup_config_(config.echo_removal_control.gain_rampup),
      gain_rampup_increase_(ComputeGainRampupIncrease(rampup_config_)) {
  Reset();
}

void SuppressionGainUpperLimiter::Reset() {
  recent_reset_ = true;
}

void SuppressionGainUpperLimiter::Update(bool render_activity,
                                         bool transparent_mode) {
  if (transparent_mode) {
    active_render_seen_ = true;
    call_startup_phase_ = false;
    recent_reset_ = false;
    suppressor_gain_limit_ = 1.f;
    return;
  }

  if (recent_reset_ && !call_startup_phase_) {
    // Only enforce 250 ms full suppression after in-call resets,
    constexpr int kMuteFramesAfterReset = kNumBlocksPerSecond / 4;
    realignment_counter_ = kMuteFramesAfterReset;
  } else if (!active_render_seen_ && render_activity) {
    // Enforce a tailormade suppression limiting during call startup.
    active_render_seen_ = true;
    realignment_counter_ = rampup_config_.full_gain_blocks;
  } else if (realignment_counter_ > 0) {
    if (--realignment_counter_ == 0) {
      call_startup_phase_ = false;
    }
  }
  recent_reset_ = false;

  // Do not enforce any gain limit on the suppressor.
  if (!IsActive()) {
    suppressor_gain_limit_ = 1.f;
    return;
  }

  // Enforce full suppression.
  if (realignment_counter_ > rampup_config_.non_zero_gain_blocks ||
      (!call_startup_phase_ && realignment_counter_ > 0)) {
    suppressor_gain_limit_ = rampup_config_.initial_gain;
    return;
  }

  // Start increasing the gain limit.
  if (realignment_counter_ == rampup_config_.non_zero_gain_blocks) {
    suppressor_gain_limit_ = rampup_config_.first_non_zero_gain;
    return;
  }

  // Increase the gain limit until it reaches 1.f.
  RTC_DCHECK_LT(0.f, suppressor_gain_limit_);
  suppressor_gain_limit_ =
      std::min(1.f, suppressor_gain_limit_ * gain_rampup_increase_);
  RTC_DCHECK_GE(1.f, suppressor_gain_limit_);
}

}  // namespace webrtc

redpajama_set_name: RedPajamaGithub


text:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <translate
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="500"
        android:propertyName="x"
        android:valueFrom="0"
        android:valueTo="1000"
        android:valueType="floatType" />
</set>


text:
namespace UGC{
class UGGroup;
class GRAPHICS3D_API UGDrawable
{
public:
	typedef UGArray<UGGroup*> ParentList;
	UGDrawable();
	virtual ~UGDrawable();
public:
	class UGDrawCallback
	{
		virtual void Draw(UGDrawable*) const {}
	};
	virtual void SetDrawCallback(UGDrawCallback* pDrawCallback){};
	virtual UGDrawCallback* GetDrawCallback(){return NULL;};

	class UGUpdateCallback
	{
		virtual void Update(UGDrawable*)const{};
	};
	virtual void SetUpdateCallback(UGUpdateCallback* pUpdateCallback){};
	virtual UGUpdateCallback* GetUpdateCallback(){return NULL;};

	class UGCullCallback
	{
		virtual void Cull(UGDrawable*)const{};
	};
	virtual void SetCullCallback(UGCullCallback* pCullCallback){};
	virtual UGCullCallback* GetCullCallback(){return NULL;};

	inline const ParentList& GetParents()const;
	inline ParentList& GetParents();
	inline UGGroup* GetParent(unsigned int i);
	inline unsigned int GetNumParents() const;

	UGMaterial* GetOrCreateMaterial();
	UGMaterial* GetMaterial();
	void ComputeBounds();

	virtual void Draw(UGGraphics3D* pGraphics3D) = 0;

protected:
	UGMaterial* m_pMaterial;
	ParentList m_pParents;
	UGBoundSphere m_BoundSphere;
	UGbool m_bBoundsDirty;
	UGDrawCallback* m_pDrawCallback;
	UGUpdateCallback* m_pUpdataCallback;
	UGCullCallback* m_pCullCallback;
};
}

#endif // !defined(UGDRAWABLE_H)


text:
package yundun

import (
	. "aliyun-openapi-go-sdk/core"
)

type GetDdosConfigOptionsRequest struct {
	RpcRequest
}

func (r *GetDdosConfigOptionsRequest) Init() {
	r.RpcRequest.Init()
	r.SetVersion(Version)
	r.SetAction("GetDdosConfigOptions")
	r.SetProduct(Product)
}

type GetDdosConfigOptionsResponse struct {
	QpsOptions1 struct {
		value []string `xml:"value" json:"value"`
	} `xml:"QpsOptions1" json:"QpsOptions1"`
	QpsOptions2 struct {
		value []string `xml:"value" json:"value"`
	} `xml:"QpsOptions2" json:"QpsOptions2"`
	RequestThresholdOptions1 struct {
		RequestThresholdOption []struct {
			Bps int `xml:"Bps" json:"Bps"`
			Pps int `xml:"Pps" json:"Pps"`
		} `xml:"RequestThresholdOption" json:"RequestThresholdOption"`
	} `xml:"RequestThresholdOptions1" json:"RequestThresholdOptions1"`
	RequestThresholdOptions2 struct {
		RequestThresholdOption []struct {
			Bps int `xml:"Bps" json:"Bps"`
			Pps int `xml:"Pps" json:"Pps"`
		} `xml:"RequestThresholdOption" json:"RequestThresholdOption"`
	} `xml:"RequestThresholdOptions2" json:"RequestThresholdOptions2"`
	ConnectionThresholdOptions struct {
		ConnectionThresholdOption []struct {
			Sipconn int `xml:"Sipconn" json:"Sipconn"`
			Sipnew  int `xml:"Sipnew" json:"Sipnew"`
		} `xml:"ConnectionThresholdOption" json:"ConnectionThresholdOption"`
	} `xml:"ConnectionThresholdOptions" json:"ConnectionThresholdOptions"`
}

func GetDdosConfigOptions(req *GetDdosConfigOptionsRequest, accessId, accessSecret string) (*GetDdosConfigOptionsResponse, error) {
	var pResponse GetDdosConfigOptionsResponse
	body, err := ApiHttpRequest(accessId, accessSecret, req)
	if err != nil {
		return nil, err
	}
	ApiUnmarshalResponse(req.GetFormat(), body, &pResponse)
	return &pResponse, err
}


text:
package org.elasticsearch.index.translog;

import org.apache.lucene.store.AlreadyClosedException;
import org.elasticsearch.common.io.Channels;
import org.elasticsearch.core.internal.io.IOUtils;
import org.elasticsearch.index.seqno.SequenceNumbers;

import java.io.Closeable;
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.atomic.AtomicBoolean;

import static org.elasticsearch.index.translog.Translog.getCommitCheckpointFileName;

/**
 * an immutable translog filereader
 */
public class TranslogReader extends BaseTranslogReader implements Closeable {
    protected final long length;
    private final int totalOperations;
    private final Checkpoint checkpoint;
    protected final AtomicBoolean closed = new AtomicBoolean(false);

    /**
     * Create a translog writer against the specified translog file channel.
     *
     * @param checkpoint the translog checkpoint
     * @param channel    the translog file channel to open a translog reader against
     * @param path       the path to the translog
     * @param header     the header of the translog file
     */
    TranslogReader(final Checkpoint checkpoint, final FileChannel channel, final Path path, final TranslogHeader header) {
        super(checkpoint.generation, channel, path, header);
        this.length = checkpoint.offset;
        this.totalOperations = checkpoint.numOps;
        this.checkpoint = checkpoint;
    }

    /**
     * Given a file channel, opens a {@link TranslogReader}, taking care of checking and validating the file header.
     *
     * @param channel the translog file channel
     * @param path the path to the translog
     * @param checkpoint the translog checkpoint
     * @param translogUUID the tranlog UUID
     * @return a new TranslogReader
     * @throws IOException if any of the file operations resulted in an I/O exception
     */
    public static TranslogReader open(
            final FileChannel channel, final Path path, final Checkpoint checkpoint, final String translogUUID) throws IOException {
        final TranslogHeader header = TranslogHeader.read(translogUUID, path, channel);
        return new TranslogReader(checkpoint, channel, path, header);
    }

    /**
     * Closes current reader and creates new one with new checkoint and same file channel
     */
    TranslogReader closeIntoTrimmedReader(long aboveSeqNo, ChannelFactory channelFactory) throws IOException {
        if (closed.compareAndSet(false, true)) {
            Closeable toCloseOnFailure = channel;
            final TranslogReader newReader;
            try {
                if (aboveSeqNo < checkpoint.trimmedAboveSeqNo
                    || aboveSeqNo < checkpoint.maxSeqNo && checkpoint.trimmedAboveSeqNo == SequenceNumbers.UNASSIGNED_SEQ_NO) {
                    final Path checkpointFile = path.getParent().resolve(getCommitCheckpointFileName(checkpoint.generation));
                    final Checkpoint newCheckpoint = new Checkpoint(checkpoint.offset, checkpoint.numOps,
                        checkpoint.generation, checkpoint.minSeqNo, checkpoint.maxSeqNo,
                        checkpoint.globalCheckpoint, checkpoint.minTranslogGeneration, aboveSeqNo);
                    Checkpoint.write(channelFactory, checkpointFile, newCheckpoint, StandardOpenOption.WRITE);

                    IOUtils.fsync(checkpointFile, false);
                    IOUtils.fsync(checkpointFile.getParent(), true);

                    newReader = new TranslogReader(newCheckpoint, channel, path, header);
                } else {
                    newReader = new TranslogReader(checkpoint, channel, path, header);
                }
                toCloseOnFailure = null;
                return newReader;
            } finally {
                IOUtils.close(toCloseOnFailure);
            }
        } else {
            throw new AlreadyClosedException(toString() + " is already closed");
        }
    }

    public long sizeInBytes() {
        return length;
    }

    public int totalOperations() {
        return totalOperations;
    }

    @Override
    final Checkpoint getCheckpoint() {
        return checkpoint;
    }

    /**
     * reads an operation at the given position into the given buffer.
     */
    protected void readBytes(ByteBuffer buffer, long position) throws IOException {
        if (position >= length) {
            throw new EOFException("read requested past EOF. pos [" + position + "] end: [" + length + "]");
        }
        if (position < getFirstOperationOffset()) {
            throw new IOException("read requested before position of first ops. pos [" + position + "] first op on: [" + getFirstOperationOffset() + "]");
        }
        Channels.readFromFileChannelWithEofException(channel, position, buffer);
    }

    @Override
    public final void close() throws IOException {
        if (closed.compareAndSet(false, true)) {
            channel.close();
        }
    }

    protected final boolean isClosed() {
        return closed.get();
    }

    protected void ensureOpen() {
        if (isClosed()) {
            throw new AlreadyClosedException(toString() + " is already closed");
        }
    }
}


text:
module FrontendTool
  module ApplicationHelper
    def component(name, props)
      render partial: "frontend_tool/components/#{name}", locals: props
    end
  end
end


text:
     Open Issues

<bs-progress *ngIf="isLoading" class="striped warning" [value]="progress"></bs-progress>

        Open issues on https://github.com/dart-lang/angular

    Id
    Title
    Author
    Action

    <template ngFor let-issue [ngForOf]="issues">

            {{issue.id}}

                <issue-title [issue]="issue"></issue-title>

            {{issue.author}}

                <bs-toggle-button
                        class="btn btn-primary"
                        [ngModel]="showDescriptionFor == issue"
                        (ngModelChange)="toggleDescription(issue)">
                    {{showDescriptionFor == issue ? 'Hide' : 'More'}}
                </bs-toggle-button>

                No content
                <issue-description *ngIf="issue.description.isNotEmpty" [issue]="issue">
                </issue-description>

    </template>


text:
var pandora    = require('pandora')
var arithmetic = pandora(require('./arithmetic'))
var relational = pandora(require('./relational'))

module.exports = pandora.merge(arithmetic, relational)


text:
class RemoveTweetLengthConstraint < ActiveRecord::Migration
  def change
    change_column :lessons, :tweet_message, :string, limit: nil
  end
end


text:
package me.adaptive.arp.api;

import java.io.Serializable;

/**
   Enumeration INetworkReachabilityCallbackWarning
*/
public enum INetworkReachabilityCallbackWarning implements Serializable {

     IncorrectScheme,
     NotSecure,
     NotTrusted,
     Redirected,
     NotRegisteredService,
     Unknown;

     /**
        Java serialization support.
        @since 2.2.13
     */
     private static final long serialVersionUID = 100556806L;

}
/**
------------------------------------| Engineered with ♥ in Barcelona, Catalonia |--------------------------------------
*/


text:
package leap.orm.event.reflect;

import leap.lang.reflect.ReflectMethod;
import leap.orm.event.PostUpdateListener;
import leap.orm.event.PreUpdateListener;
import leap.orm.event.UpdateEntityEvent;

public class ReflectUpdateEntityListener extends ReflectEntityListenerBase<UpdateEntityEvent> implements PreUpdateListener,PostUpdateListener {

    public ReflectUpdateEntityListener(Object inst, ReflectMethod m) {
        super(inst, m);
    }

    @Override
    public void postUpdateEntity(UpdateEntityEvent e) {
        func.accept(e);
    }

    @Override
    public void preUpdateEntity(UpdateEntityEvent e) {
        func.accept(e);
    }

}


text:
'use strict';
/**
 * Loading Directive
 * @see http://tobiasahlin.com/spinkit/
 */
angular
    .module('rdash')
    .directive('rdLoading', function(){
    	var directive = {
        restrict: 'AE',
        template: '

'
    };
    return directive;
    });


text:
using System.Collections.Generic;
using System.Linq;
using DotVVM.Framework.ViewModel;

namespace DotvvmWeb.Views.Docs.Controls.businesspack.ListView.sample5
{
    public class ViewModel : DotvvmViewModelBase
    {
        public string Summary { get; set; }

        public List<City> Cities { get; set; } = new List<City> {
            new City { Id = 1, Name = "Prague", Country = "Czech Republic" },
            new City { Id = 2, Name = "Bratislava", Country = "Slovakia" }
        };

        public List<int> SelectedCityIds { get; set; } = new List<int>();

        public void SelectionChanged()
        {
            Summary = string.Join(", ", SelectedCityIds.Select(c => c.ToString()));
        }
    }
}


text:
package rpc

import (
	"github.com/golang/glog"
	"github.com/nebulaim/telegramd/baselib/grpc_util"
	"github.com/nebulaim/telegramd/baselib/logger"
	"github.com/nebulaim/telegramd/proto/mtproto"
	"golang.org/x/net/context"
	"time"
)

// account.getTmpPassword#4a82327e password_hash:bytes period:int = account.TmpPassword;
func (s *AccountServiceImpl) AccountGetTmpPassword(ctx context.Context, request *mtproto.TLAccountGetTmpPassword) (*mtproto.Account_TmpPassword, error) {
	md := grpc_util.RpcMetadataFromIncoming(ctx)
	glog.Infof("AccountGetTmpPassword - metadata: %s, request: %s", logger.JsonDebugData(md), logger.JsonDebugData(request))

	// TODO(@benqi): Check password_hash invalid, android source code
	// byte[] hash = new byte[currentPassword.current_salt.length * 2 + passwordBytes.length];
	// System.arraycopy(currentPassword.current_salt, 0, hash, 0, currentPassword.current_salt.length);
	// System.arraycopy(passwordBytes, 0, hash, currentPassword.current_salt.length, passwordBytes.length);
	// System.arraycopy(currentPassword.current_salt, 0, hash, hash.length - currentPassword.current_salt.length, currentPassword.current_salt.length);

	// account.tmpPassword#db64fd34 tmp_password:bytes valid_until:int = account.TmpPassword;
	tmpPassword := mtproto.NewTLAccountTmpPassword()
	tmpPassword.SetTmpPassword([]byte("01234567899876543210"))
	tmpPassword.SetValidUntil(int32(time.Now().Unix()) + request.Period)

	glog.Infof("AccountServiceImpl - reply: %s", logger.JsonDebugData(tmpPassword))
	return tmpPassword.To_Account_TmpPassword(), nil
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StatsHelix.Charizard
{
    [Serializable]
    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
    public sealed class ControllerAttribute : Attribute
    {
        /// <summary>
        /// The prefix this controller is mapped to.
        /// Defaults to $"{ClassNameWithoutController}/".
        /// Note that this must not include the leading slash.
        /// </summary>
        public string Prefix { get; set; } = null;

        /// <summary>
        /// The regex that parses additional querystring parameters
        /// from the URL path.
        /// Defaults to null which means that no such regex will be used.
        /// Note that regexes are fast but still orders of magnitude slower
        /// than not using regexes. ;)
        /// </summary>
        public string PathParamsPattern { get; set; } = null;
    }
}


text:
'use strict';

exports.__esModule = true;
exports['default'] = zipAll;

var _zipSupport = require('./zip-support');

function zipAll(project) {
    return this.lift(new _zipSupport.ZipOperator(project));
}

//# sourceMappingURL=zipAll.js.map
module.exports = exports['default'];
//# sourceMappingURL=zipAll.js.map


text:
using System;
using NDatabase;
using NDatabase.Api;
using NDatabase.Oid;
using NDatabase.Tool.Wrappers;
using NUnit.Framework;
using Test.NDatabase.Tool;

namespace Test.NDatabase.Odb.Test.Oid
{
    [TestFixture]
    public class TestOid : ODBTest
    {
        [Test]
        public virtual void TestAndy1()
        {
            DeleteBase("test-oid");

            var odb = Open("test-oid");
            var b1 = new B("b");
            var a1 = new A("a", b1);
            odb.Store(a1);
            var oida = odb.GetObjectId(a1);
            var oidb = odb.GetObjectId(b1);
            odb.Close();
            odb = Open("test-oid");
            var a2 = (A) odb.GetObjectFromId(oida);
            var b2 = (B) odb.GetObjectFromId(oidb);
            odb.Close();
            AssertNotNull(a2);
            AssertNotNull(b2);
            AssertNotNull(a2.GetB());
        }

        [Test]
        public virtual void TestAndy2()
        {
            DeleteBase("test-oid");

            // LogUtil.allOn(true);
            var odb = Open("test-oid");
            var b1 = new B("b");
            var a1 = new A("a", b1);
            odb.Store(a1);
            var oida = (odb.GetObjectId(a1)).ObjectId;
            var oidb = (odb.GetObjectId(b1)).ObjectId;
            odb.Close();
            odb = Open("test-oid");
            var a2 = (A) odb.GetObjectFromId(new ObjectOID(oida));
            var b2 = (B) odb.GetObjectFromId(new ObjectOID(oidb));
            odb.Close();
            AssertNotNull(a2);
            AssertNotNull(b2);
            AssertNotNull(a2.GetB());
        }

        [Test]
        public virtual void TestAndy3()
        {
            DeleteBase("test-oid");

            var odb = Open("test-oid");
            try
            {
                var a2 = (A) odb.GetObjectFromId(new ObjectOID(34));
                Fail("Should have thrown Exception");
            }
            catch (Exception)
            {
            }
        }

        [Test]
        public virtual void TestEquals()
        {
            var oid1 = OIDFactory.BuildObjectOID(1);
            var oid2 = OIDFactory.BuildObjectOID(1);
            AssertEquals(oid1, oid2);
        }

        [Test]
        public virtual void TestOIdInMap()
        {
            var oid1 = OIDFactory.BuildObjectOID(1);
            var oid2 = OIDFactory.BuildObjectOID(1);
            var map = new OdbHashMap<OID, string>();
            map.Add(oid1, "oid1");
            AssertNotNull(map[oid2]);
        }

        /// <summary>
        ///   Performance test.
        /// </summary>
        /// <remarks>
        ///   Performance test. Using ID or long in hash map
        /// </remarks>
        [Test]
        public virtual void TestPerformanceOid()
        {
            var size = 300000;
            var oidMap = new OdbHashMap<OID, string>();

            // OID
            var timeOidMapCreation = new StopWatch();
            timeOidMapCreation.Start();
            // Creates a hashmap with 100000 Longs
            for (var i = 0; i < size; i++)
                oidMap.Add(OIDFactory.BuildObjectOID(i), i.ToString());
            timeOidMapCreation.End();
            var timeOidMapGet = new StopWatch();
            timeOidMapGet.Start();
            // get all map elements
            for (var i = 0; i < size; i++)
                AssertNotNull(oidMap[OIDFactory.BuildObjectOID(i)]);
            timeOidMapGet.End();
            Println(size + " objects : OID Map creation=" + timeOidMapCreation.GetDurationInMiliseconds() + " - get=" +
                    timeOidMapGet.GetDurationInMiliseconds());
        }

        // ok must enter the catch block
    }
}


text:
char *pem_encode(const unsigned char *, size_t, size_t *);
int x509_dump(const unsigned char *, size_t, int);

#endif


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Laurus.ProdTest.Core.Tests
{
    public class CommandTest : ITestStep
    {
        int ITestStep.Order { get; set; }

        string ITestStep.Name { get { return "Command"; } }

        TestStepResult ITestStep.Execute(Connection conn)
        {
            return default(TestStepResult);
        }

        TestStepResult ITestStep.Execute(ref ConnectionInfo connectionInfo)
        {
            throw new NotImplementedException();
        }
    }
}


text:
#include <windows.h>
#include <commctrl.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <memory.h>
#include <stdarg.h>

#include "iup.h"
#include "iupcbs.h"

#include "iup_object.h"
#include "iup_attrib.h"
#include "iup_str.h"
#include "iup_drv.h"
#include "iup_drvfont.h"
#include "iup_stdcontrols.h"
#include "iup_tabs.h"
#include "iup_image.h"
#include "iup_array.h"
#include "iup_assert.h"
#include "iup_draw.h"
#include "iup_childtree.h"

#include "iupwin_drv.h"
#include "iupwin_handle.h"
#include "iupwin_draw.h"
#include "iupwin_info.h"
#include "iupwin_str.h"

#ifndef WS_EX_COMPOSITED
#define WS_EX_COMPOSITED        0x02000000L
#endif

#define ITABS_CLOSE_SIZE 12

static void winTabsInitializeCloseImage(void)
{
  Ihandle *image_close;
  COLORREF bgcolor;

  unsigned char img_close[ITABS_CLOSE_SIZE * ITABS_CLOSE_SIZE] =
  {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0,
    0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0,
    0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0,
    0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0,
    0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0,
    0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0,
    0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  };

  image_close = IupImage(ITABS_CLOSE_SIZE, ITABS_CLOSE_SIZE, img_close);
  IupSetAttribute(image_close, "0", "BGCOLOR");
  IupSetAttribute(image_close, "1", "0 0 0");
  IupSetHandle("IMGCLOSE", image_close);

  image_close = IupImage(ITABS_CLOSE_SIZE, ITABS_CLOSE_SIZE, img_close);
  IupSetAttribute(image_close, "0", "BGCOLOR");
  bgcolor = GetSysColor(COLOR_HIGHLIGHT);
  IupSetRGB(image_close, "1", GetRValue(bgcolor), GetGValue(bgcolor), GetBValue(bgcolor));
  IupSetHandle("IMGCLOSEHIGH", image_close);
}

static void winTabsInitVisibleArray(Iarray* visible_array, int count)
{
  int old_count = iupArrayCount(visible_array);
  if (old_count != count)
  {
    iupArrayRemove(visible_array, 0, old_count);
    iupArrayAdd(visible_array, count);
  }

  /* all visible by default */
  {
    int pos;
    int* visible_array_array_data = (int*)iupArrayGetData(visible_array);
    for (pos = 0; pos < count; pos++)
      visible_array_array_data[pos] = 1;
  }
}

static Iarray* winTabsGetVisibleArray(Ihandle* ih)
{
  Iarray* visible_array = (Iarray*)iupAttribGet(ih, "_IUPWIN_VISIBLEARRAY");

  if (!visible_array)
  {
    int count = IupGetChildCount(ih);

    /* create the array if does not exist */
    visible_array = iupArrayCreate(50, sizeof(int));
    iupAttribSet(ih, "_IUPWIN_VISIBLEARRAY", (char*)visible_array);

    winTabsInitVisibleArray(visible_array, count);
  }

  return visible_array;
}

/* #define PRINT_VISIBLE_ARRAY 1 */
#if PRINT_VISIBLE_ARRAY
/* For debugging  */
static void winTabsPrintVisibleArray(Ihandle* ih)
{
  Iarray* visible_array = winTabsGetVisibleArray(ih);
  int i, count = iupArrayCount(visible_array);
  int* visible_array_array_data = (int*)iupArrayGetData(visible_array);

  for (i = 0; i < count; i++)
    printf("%d=%d ", i, visible_array_array_data[i]);

  printf("\n");
}
#endif

static int winTabsHasInVisible(Iarray* visible_array)
{
  int i;
  int count = iupArrayCount(visible_array);
  int* visible_array_array_data = (int*)iupArrayGetData(visible_array);

  for (i = 0; i < count; i++)
  {
    if (visible_array_array_data[i] == 0)
      return 1;
  }

  return 0;
}

static void winTabsSetVisibleArrayItem(Ihandle* ih, int pos, int visible)
{
  /* if set to visible and all are visible, just return */
  if (visible && !ih->data->has_invisible)
    return;
  else
  {
    Iarray* visible_array = winTabsGetVisibleArray(ih);
    int* visible_array_array_data = (int*)iupArrayGetData(visible_array);

    /* first invisible init array */
    if (!visible && !ih->data->has_invisible)
    {
      int count = IupGetChildCount(ih);
      winTabsInitVisibleArray(visible_array, count);
    }

    visible_array_array_data[pos] = visible;

    if (!visible)
      ih->data->has_invisible = 1;
    else
      ih->data->has_invisible = winTabsHasInVisible(visible_array);
  }
}

static void winTabsInsertVisibleArrayItem(Ihandle* ih, int pos)
{
  if (ih->data->has_invisible)
  {
    Iarray* visible_array = winTabsGetVisibleArray(ih);
    iupArrayInsert(visible_array, pos, 1);
    winTabsSetVisibleArrayItem(ih, pos, 1);
  }
}

static void winTabsDeleteVisibleArrayItem(Ihandle* ih, int pos)
{
  if (ih->data->has_invisible)
  {
    Iarray* visible_array = winTabsGetVisibleArray(ih);
    iupArrayRemove(visible_array, pos, 1);
    ih->data->has_invisible = winTabsHasInVisible(visible_array);
  }
}

static int winTabsIsTabVisible(Ihandle* ih, int pos)
{
  if (ih->data->has_invisible)
  {
    Iarray* visible_array = winTabsGetVisibleArray(ih);
    int* visible_array_array_data = (int*)iupArrayGetData(visible_array);
    return visible_array_array_data[pos];
  }
  else
    return 1;
}

static int winTabsGetInsertPos(Ihandle* ih, int pos)
{
  if (ih->data->has_invisible)
  {
    Iarray* visible_array = winTabsGetVisibleArray(ih);
    int* visible_array_array_data = (int*)iupArrayGetData(visible_array);
    int i, p;

    for (i = 0, p = 0; i < pos; i++)
    {
      if (visible_array_array_data[i] != 0)
        p++;
    }

    return p;
  }
  else
    return pos;
}

static int winTabsPosFixToWin(Ihandle* ih, int pos)
{
  if (ih->data->has_invisible)
  {
    Iarray* visible_array = winTabsGetVisibleArray(ih);
    int* visible_array_array_data = (int*)iupArrayGetData(visible_array);
    int i, p;

    if (!visible_array_array_data[pos])
      return -1;

    for (i = 0, p = 0; i<pos; i++)
    {
      if (visible_array_array_data[i] != 0)
        p++;
    }

    return p;
  }
  else
    return pos;
}

static int winTabsPosFixFromWin(Ihandle* ih, int p)
{
  if (ih->data->has_invisible)
  {
    Iarray* visible_array = winTabsGetVisibleArray(ih);
    int* visible_array_array_data = (int*)iupArrayGetData(visible_array);
    int pos, pp, count = iupArrayCount(visible_array);

    for (pos = 0, pp = -1; pos<count; pos++)
    {
      if (visible_array_array_data[pos] != 0)
        pp++;

      if (pp == p)
        return pos;
    }

    iupERROR("IupTabs Error. Invalid internal visible state.");
    return 0;  /* INTERNAL ERROR: must always be found */
  }
  else
    return p;
}

static int winTabsGetPageWindowPos(Ihandle* ih, HWND tab_container)
{
  TCITEM tie;
  int p, num_tabs;

  num_tabs = (int)SendMessage(ih->handle, TCM_GETITEMCOUNT, 0, 0);
  tie.mask = TCIF_PARAM;

  for (p = 0; p<num_tabs; p++)
  {
    SendMessage(ih->handle, TCM_GETITEM, p, (LPARAM)&tie);
    if (tab_container == (HWND)tie.lParam)
      return p;
  }

  return -1;
}

int iupdrvTabsExtraDecor(Ihandle* ih)
{
  (void)ih;
  return 0;
}

int iupdrvTabsGetLineCountAttrib(Ihandle* ih)
{
  return (int)SendMessage(ih->handle, TCM_GETROWCOUNT, 0, 0);
}

static HWND winTabsGetPageWindow(Ihandle* ih, int pos)
{
  int p = winTabsPosFixToWin(ih, pos);
  if (p >= 0)
  {
    TCITEM tie;
    tie.mask = TCIF_PARAM;
    SendMessage(ih->handle, TCM_GETITEM, p, (LPARAM)&tie);
    return (HWND)tie.lParam;
  }
  else
    return NULL;  /* invisible */
}

void iupdrvTabsSetCurrentTab(Ihandle* ih, int pos)
{
  int p = winTabsPosFixToWin(ih, pos);
  if (p >= 0)
  {
    int prev_pos = iupdrvTabsGetCurrentTab(ih);
    HWND tab_container = winTabsGetPageWindow(ih, prev_pos);
    if (tab_container)
      ShowWindow(tab_container, SW_HIDE);

    SendMessage(ih->handle, TCM_SETCURSEL, p, 0);

    tab_container = winTabsGetPageWindow(ih, pos);
    if (tab_container)
      ShowWindow(tab_container, SW_SHOW);
  }
}

int iupdrvTabsGetCurrentTab(Ihandle* ih)
{
  return winTabsPosFixFromWin(ih, (int)SendMessage(ih->handle, TCM_GETCURSEL, 0, 0));
}

static int winTabsGetImageIndex(Ihandle* ih, const char* name)
{
  HIMAGELIST image_list;
  int count, i, bpp, ret;
  int width, height;
  Iarray* bmp_array;
  HBITMAP *bmp_array_data, hMask=NULL;
  HBITMAP bmp = iupImageGetImage(name, ih, 0);
  if (!bmp)
    return -1;

  /* the array is used to avoid adding the same bitmap twice */
  bmp_array = (Iarray*)iupAttribGet(ih, "_IUPWIN_BMPARRAY");
  if (!bmp_array)
  {
    /* create the array if does not exist */
    bmp_array = iupArrayCreate(50, sizeof(HBITMAP));
    iupAttribSet(ih, "_IUPWIN_BMPARRAY", (char*)bmp_array);
  }

  bmp_array_data = iupArrayGetData(bmp_array);

  /* must use this info, since image can be a driver image loaded from resources */
  iupdrvImageGetInfo(bmp, &width, &height, &bpp);

  image_list = (HIMAGELIST)SendMessage(ih->handle, TCM_GETIMAGELIST, 0, 0);
  if (!image_list)
  {
    UINT flags = ILC_COLOR32 | (bpp == 8 ? ILC_MASK : 0);

    /* create the image list if does not exist */
    image_list = ImageList_Create(width, height, flags, 0, 50);
    SendMessage(ih->handle, TCM_SETIMAGELIST, 0, (LPARAM)image_list);
  }

  /* check if that bitmap is already added to the list,
     but we can not compare with the actual bitmap at the list since it is a copy */
  count = ImageList_GetImageCount(image_list);
  for (i=0; i<count; i++)
  {
    if (bmp_array_data[i] == bmp)
      return i;
  }

  if (bpp == 8)
  {
    Ihandle* image = IupGetHandle(name);
    if (image)
    {
      iupAttribSet(image, "_IUPIMG_NO_INVERT", "1");
      hMask = iupdrvImageCreateMask(image);
      iupAttribSet(image, "_IUPIMG_NO_INVERT", NULL);
    }
  }

  bmp_array_data = iupArrayInc(bmp_array);
  bmp_array_data[i] = bmp;
  ret = ImageList_Add(image_list, bmp, hMask);  /* the bmp is duplicated at the list */
  DeleteObject(hMask);
  return ret;
}

static void winTabSetPageWindowPos(HWND tab_container, RECT *rect)
{
  SetWindowPos(tab_container, NULL,
                rect->left, rect->top,
                rect->right - rect->left, rect->bottom - rect->top,
                SWP_NOACTIVATE|SWP_NOZORDER);
}

static void winTabsPlacePageWindows(Ihandle* ih, RECT* rect)
{
  Ihandle* child;

  for (child = ih->firstchild; child; child = child->brother)
  {
    HWND tab_container = (HWND)iupAttribGet(child, "_IUPTAB_CONTAINER");
    winTabSetPageWindowPos(tab_container, rect);
  }
}

static int winTabsUsingXPStyles(Ihandle* ih)
{
  return iupwin_comctl32ver6 && ih->data->type == ITABS_TOP && !(ih->data->show_close);
}

static void winTabsDrawPageBackground(Ihandle* ih, HDC hDC, RECT* rect)
{
  unsigned char r=0, g=0, b=0;
  char* color = iupAttribGetInheritNativeParent(ih, "BGCOLOR");
  if (!color) color = iupAttribGetInheritNativeParent(ih, "BACKGROUND");
  if (!color) color = iupAttribGet(ih, "BACKGROUND");
  if (!color) color = IupGetGlobal("DLGBGCOLOR");
  iupStrToRGB(color, &r, &g, &b);
  SetDCBrushColor(hDC, RGB(r,g,b));
  FillRect(hDC, rect, (HBRUSH)GetStockObject(DC_BRUSH));
}

static LRESULT CALLBACK winTabsPageWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
  switch (msg)
  {
  case WM_ERASEBKGND:
    {
      RECT rect;
      HDC hDC = (HDC)wp;
      Ihandle* ih = iupwinHandleGet(hWnd);
      GetClientRect(ih->handle, &rect);
      winTabsDrawPageBackground(ih, hDC, &rect);

      /* return non zero value */
      return 1;
    }
  case WM_COMMAND:
  case WM_CTLCOLORSCROLLBAR:
  case WM_CTLCOLORBTN:
  case WM_CTLCOLOREDIT:
  case WM_CTLCOLORLISTBOX:
  case WM_CTLCOLORSTATIC:
  case WM_DRAWITEM:
  case WM_HSCROLL:
  case WM_NOTIFY:
  case WM_VSCROLL:
    /* Forward the container messages to its parent. */
    return SendMessage(GetParent(hWnd), msg, wp, lp);
  }

  return DefWindowProc(hWnd, msg, wp, lp);
}

static HWND winTabsCreatePageWindow(Ihandle* ih)
{
  HWND hWnd;
  DWORD dwStyle = WS_CHILD|WS_CLIPSIBLINGS,
      dwExStyle = 0;

  iupwinGetNativeParentStyle(ih, &dwExStyle, &dwStyle);

  hWnd = iupwinCreateWindowEx(ih->handle, TEXT("IupTabsPage"), dwExStyle, dwStyle, 0, NULL);

  iupwinHandleAdd(ih, hWnd);

  return hWnd;
}

static void winTabsInsertItem(Ihandle* ih, Ihandle* child, int pos, HWND tab_container)
{
  TCITEM tie;
  char *tabtitle, *tabimage;
  int old_rowcount, old_num_tabs, p;
  RECT rect;

  tabtitle = iupAttribGet(child, "TABTITLE");
  if (!tabtitle)
  {
    tabtitle = iupAttribGetId(ih, "TABTITLE", pos);
    if (tabtitle)
      iupAttribSetStr(child, "TABTITLE", tabtitle);
  }
  tabimage = iupAttribGet(child, "TABIMAGE");
  if (!tabimage)
  {
    tabimage = iupAttribGetId(ih, "TABIMAGE", pos);
    if (tabimage)
      iupAttribSetStr(child, "TABIMAGE", tabimage);
  }
  if (!tabtitle && !tabimage)
    tabtitle = "     ";

  old_num_tabs = (int)SendMessage(ih->handle, TCM_GETITEMCOUNT, 0, 0);
  old_rowcount = (int)SendMessage(ih->handle, TCM_GETROWCOUNT, 0, 0);

  tie.mask = TCIF_PARAM;

  if (tabtitle)
  {
    tie.mask |= TCIF_TEXT;
    tie.pszText = iupwinStrToSystem(tabtitle);
    tie.cchTextMax = lstrlen(tie.pszText);

    iupwinSetMnemonicTitle(ih, pos, tabtitle);
  }

  if (tabimage)
  {
    tie.mask |= TCIF_IMAGE;
    tie.iImage = winTabsGetImageIndex(ih, tabimage);
  }

  p = winTabsGetInsertPos(ih, pos);

  /* create tabs and label them */
  tie.lParam = (LPARAM)tab_container;
  SendMessage(ih->handle, TCM_INSERTITEM, p, (LPARAM)&tie);

  /* Calculate the display rectangle, assuming the
  tab control is the size of the client area. */
  GetClientRect(ih->handle, &rect);
  SendMessage(ih->handle, TCM_ADJUSTRECT, FALSE, (LPARAM)&rect);

  winTabSetPageWindowPos(tab_container, &rect);

  if (ih->data->is_multiline)
  {
    if (ih->data->type == ITABS_LEFT || ih->data->type == ITABS_RIGHT)
    {
      int rowcount = (int)SendMessage(ih->handle, TCM_GETROWCOUNT, 0, 0);
      if (rowcount != old_rowcount)
        winTabsPlacePageWindows(ih, &rect);
    }

    iupdrvRedrawNow(ih);
  }

  /* the first page of an empty tabs must be shown (set as current) */
  if (old_num_tabs == 0)
  {
    ShowWindow(tab_container, SW_SHOW);
    SendMessage(ih->handle, TCM_SETCURSEL, 0, 0);
  }

#if PRINT_VISIBLE_ARRAY
  winTabsPrintVisibleArray(ih);
#endif
}

static void winTabsDeleteItem(Ihandle* ih, int p, HWND tab_container)
{
  /* Make sure tab container is hidden */
  ShowWindow(tab_container, SW_HIDE);

  SendMessage(ih->handle, TCM_DELETEITEM, p, 0);

#if PRINT_VISIBLE_ARRAY
  winTabsPrintVisibleArray(ih);
#endif
}

/* ------------------------------------------------------------------------- */
/* winTabs - Sets and Gets Attrib                                           */
/* ------------------------------------------------------------------------- */

static int winTabsSetPaddingAttrib(Ihandle* ih, const char* value)
{
  iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x');

  if (ih->handle)
  {
    int extra_h = (ih->data->show_close)? ITABS_CLOSE_SIZE: 0;
    SendMessage(ih->handle, TCM_SETPADDING, 0, MAKELPARAM(ih->data->horiz_padding + extra_h, ih->data->vert_padding));
    return 0;
  }
  else
    return 1; /* store until not mapped, when mapped will be set again */
}

static int winTabsSetMultilineAttrib(Ihandle* ih, const char* value)
{
  if (ih->handle) /* allow to set only before mapping */
    return 0;

  if (iupStrBoolean(value))
    ih->data->is_multiline = 1;
  else
  {
    if (ih->data->type == ITABS_BOTTOM || ih->data->type == ITABS_TOP)
      ih->data->is_multiline = 0;
    else
      ih->data->is_multiline = 1;   /* always true if left/right */
  }

  return 0;
}

static char* winTabsGetMultilineAttrib(Ihandle* ih)
{
  return iupStrReturnBoolean (ih->data->is_multiline);
}

static int winTabsSetTabTypeAttrib(Ihandle* ih, const char* value)
{
  if (ih->handle) /* allow to set only before mapping */
    return 0;

  if(iupStrEqualNoCase(value, "BOTTOM"))
  {
    ih->data->type = ITABS_BOTTOM;
    ih->data->orientation = ITABS_HORIZONTAL;  /* TABTYPE controls TABORIENTATION in Windows */
  }
  else if(iupStrEqualNoCase(value, "LEFT"))
  {
    ih->data->type = ITABS_LEFT;
    ih->data->orientation = ITABS_VERTICAL;  /* TABTYPE controls TABORIENTATION in Windows */
    ih->data->is_multiline = 1; /* VERTICAL works only with MULTILINE */
  }
  else if(iupStrEqualNoCase(value, "RIGHT"))
  {
    ih->data->type = ITABS_RIGHT;
    ih->data->orientation = ITABS_VERTICAL;  /* TABTYPE controls TABORIENTATION in Windows */
    ih->data->is_multiline = 1; /* VERTICAL works only with MULTILINE */
  }
  else /* "TOP" */
  {
    ih->data->type = ITABS_TOP;
    ih->data->orientation = ITABS_HORIZONTAL;  /* TABTYPE controls TABORIENTATION in Windows */
  }

  return 0;
}

static int winTabsSetTabTitleAttrib(Ihandle* ih, int pos, const char* value)
{
  Ihandle* child = IupGetChild(ih, pos);
  if (child)
    iupAttribSetStr(child, "TABTITLE", value);

  if (value)
  {
    int p = winTabsPosFixToWin(ih, pos);
    if (p >= 0)
    {
      TCITEM tie;

      tie.mask = TCIF_TEXT;
      tie.pszText = iupwinStrToSystem(value);
      tie.cchTextMax = lstrlen(tie.pszText);

      iupwinSetMnemonicTitle(ih, pos, value);

      SendMessage(ih->handle, TCM_SETITEM, p, (LPARAM)&tie);
    }
  }

  return 0;
}

static int winTabsSetTabImageAttrib(Ihandle* ih, int pos, const char* value)
{
  int p;
  Ihandle* child = IupGetChild(ih, pos);
  if (child)
    iupAttribSetStr(child, "TABIMAGE", value);

  p = winTabsPosFixToWin(ih, pos);
  if (p >= 0)
  {
    TCITEM tie;

    tie.mask = TCIF_IMAGE;
    if (value)
      tie.iImage = winTabsGetImageIndex(ih, value);
    else
      tie.iImage = -1;

    SendMessage(ih->handle, TCM_SETITEM, p, (LPARAM)&tie);
  }

  return 1;
}

static int winTabsSetTabVisibleAttrib(Ihandle* ih, int pos, const char* value)
{
  Ihandle* child = IupGetChild(ih, pos);
  if (child)
  {
    int p = winTabsPosFixToWin(ih, pos);
    if (iupStrBoolean(value))
    {
      if (p < 0)  /* is invisible */
      {
        HWND tab_container = (HWND)iupAttribGet(child, "_IUPTAB_CONTAINER");

        winTabsSetVisibleArrayItem(ih, pos, 1);  /* to visible */

        winTabsInsertItem(ih, child, pos, tab_container);
      }
    }
    else
    {
      if (p >= 0)  /* is visible */
      {
        HWND tab_container = (HWND)iupAttribGet(child, "_IUPTAB_CONTAINER");

        iupTabsCheckCurrentTab(ih, pos, 0);
        winTabsSetVisibleArrayItem(ih, pos, 0);  /* to invisible */

        winTabsDeleteItem(ih, p, tab_container);
      }
    }
  }
  return 0;
}

int iupdrvTabsIsTabVisible(Ihandle* child, int pos)
{
  Ihandle* ih = child->parent;
  return winTabsIsTabVisible(ih, pos);
}

static char* winTabsGetBgColorAttrib(Ihandle* ih)
{
  /* the most important use of this is to provide
     the correct background for images */
  if (iupwin_comctl32ver6)
  {
    COLORREF cr;
    if (iupwinDrawGetThemeTabsBgColor(ih->handle, &cr))
      return iupStrReturnStrf("%d %d %d", (int)GetRValue(cr), (int)GetGValue(cr), (int)GetBValue(cr));
  }

  return IupGetGlobal("DLGBGCOLOR");
}

static int winTabsSetBgColorAttrib(Ihandle *ih, const char *value)
{
  (void)value;
  iupdrvPostRedraw(ih);
  return 1;
}

static int winTabsIsInsideCloseButton(Ihandle* ih, int p)
{
  RECT rect;
  POINT pt;
  int border = 4, start, end;

  GetCursorPos(&pt);
  ScreenToClient(ih->handle, &pt);

  /* Get tab rectangle and define start/end positions of the image */
  SendMessage(ih->handle, TCM_GETITEMRECT, (WPARAM)p, (LPARAM)&rect);

  if(ih->data->type == ITABS_BOTTOM || ih->data->type == ITABS_TOP)
  {
    end = rect.right - border;
    start = end - ITABS_CLOSE_SIZE;
    if (pt.x >= start && pt.x <= end)
    {
      start = ((rect.bottom - rect.top) - ITABS_CLOSE_SIZE) / 2 + rect.top;
      end = start + ITABS_CLOSE_SIZE;
      if (pt.y >= start && pt.y <= end)
        return 1;
    }
  }
  else if(ih->data->type == ITABS_LEFT)
  {
    start = rect.top + border;
    end = start + ITABS_CLOSE_SIZE;
    if (pt.y >= start && pt.y <= end)
    {
      start = ((rect.right - rect.left) - ITABS_CLOSE_SIZE) / 2 + rect.left;
      end = start + ITABS_CLOSE_SIZE;
      if (pt.x >= start && pt.x <= end)
        return 1;
    }
  }
  else  /* ITABS_RIGHT */
  {
    end = rect.bottom - border;
    start = end - ITABS_CLOSE_SIZE;
    if (pt.y >= start && pt.y <= end)
    {
      start = ((rect.right - rect.left) - ITABS_CLOSE_SIZE) / 2 + rect.left;
      end = start + ITABS_CLOSE_SIZE;
      if (pt.x >= start && pt.x <= end)
        return 1;
    }
  }

  return 0;
}

static int winTabsCtlColor(Ihandle* ih, HDC hdc, LRESULT *result)
{
  /* works only when NOT winTabsUsingXPStyles */
  COLORREF bgcolor;
  if (iupwinGetParentBgColor(ih, &bgcolor))
  {
    SetDCBrushColor(hdc, bgcolor);
    *result = (LRESULT)GetStockObject(DC_BRUSH);
    return 1;
  }
  return 0;
}

static int winTabsWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
{
  (void)result;

  if (msg_info->code == TCN_SELCHANGING)
  {
    IFnnn cb = (IFnnn)IupGetCallback(ih, "TABCHANGE_CB");
    int prev_pos = iupdrvTabsGetCurrentTab(ih);
    iupAttribSetInt(ih, "_IUPTABS_PREV_CHILD_POS", prev_pos);

    /* save the previous handle if callback exists */
    if (cb)
    {
      Ihandle* prev_child = IupGetChild(ih, prev_pos);
      iupAttribSet(ih, "_IUPTABS_PREV_CHILD", (char*)prev_child);
    }

    return 0;
  }

  if (msg_info->code == TCN_SELCHANGE)
  {
    IFnnn cb = (IFnnn)IupGetCallback(ih, "TABCHANGE_CB");
    int pos = iupdrvTabsGetCurrentTab(ih);
    int prev_pos = iupAttribGetInt(ih, "_IUPTABS_PREV_CHILD_POS");
    HWND tab_container = winTabsGetPageWindow(ih, pos);
    if (tab_container)
      ShowWindow(tab_container, SW_SHOW);
    tab_container = winTabsGetPageWindow(ih, prev_pos);
    if (tab_container)
      ShowWindow(tab_container, SW_HIDE);

    if (cb)
    {
      Ihandle* child = IupGetChild(ih, pos);
      Ihandle* prev_child = (Ihandle*)iupAttribGet(ih, "_IUPTABS_PREV_CHILD");
      iupAttribSet(ih, "_IUPTABS_PREV_CHILD", NULL);

      /* avoid duplicate calls when a Tab is inside another Tab. */
      if (prev_child)
        cb(ih, child, prev_child);
    }
    else
    {
      IFnii cb2 = (IFnii)IupGetCallback(ih, "TABCHANGEPOS_CB");
      if (cb2)
        cb2(ih, pos, prev_pos);
    }

    return 0;
  }

  if (msg_info->code == NM_RCLICK)
  {
    IFni cb = (IFni)IupGetCallback(ih, "RIGHTCLICK_CB");
    if (cb)
    {
      TCHITTESTINFO ht;
      int p;

      GetCursorPos(&ht.pt);
      ScreenToClient(ih->handle, &ht.pt);

      p = (int)SendMessage(ih->handle, TCM_HITTEST, 0, (LPARAM)&ht);
      if (p >= 0)
      {
        int pos = winTabsPosFixFromWin(ih, p);
        cb(ih, pos);
      }
    }

    return 0;
  }

  return 0; /* result not used */
}

static int winTabsMsgProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result)
{
  switch (msg)
  {
  case WM_SIZE:
  {
    RECT rect;
    WNDPROC oldProc = (WNDPROC)IupGetCallback(ih, "_IUPWIN_OLDWNDPROC_CB");
    CallWindowProc(oldProc, ih->handle, msg, wp, lp);

    SetRect(&rect, 0, 0, LOWORD(lp), HIWORD(lp));
    SendMessage(ih->handle, TCM_ADJUSTRECT, FALSE, (LPARAM)&rect);

    winTabsPlacePageWindows(ih, &rect);

    *result = 0;
    return 1;
  }
  case WM_MOUSELEAVE:
    if (ih->data->show_close)
    {
      int high_p = iupAttribGetInt(ih, "_IUPTABS_CLOSEHIGH");
      if (high_p != -1)
      {
        iupAttribSetInt(ih, "_IUPTABS_CLOSEHIGH", -1);
        iupdrvRedrawNow(ih);
      }
    }
    break;
  case WM_MOUSEMOVE:
    if (ih->data->show_close)
    {
      TCHITTESTINFO ht;
      int p, high_p, press_p;

      ht.pt.x = (int)(short)LOWORD(lp);
      ht.pt.y = (int)(short)HIWORD(lp);
      p = (int)SendMessage(ih->handle, TCM_HITTEST, 0, (LPARAM)&ht);

      high_p = iupAttribGetInt(ih, "_IUPTABS_CLOSEHIGH");
      if (winTabsIsInsideCloseButton(ih, p))
      {
        if (high_p != p)
        {
          /* must be called so WM_MOUSELEAVE will be called */
          iupwinTrackMouseLeave(ih);

          iupAttribSetInt(ih, "_IUPTABS_CLOSEHIGH", p);
          iupdrvRedrawNow(ih);
        }
      }
      else
      {
        if (high_p != -1)
        {
          iupAttribSetInt(ih, "_IUPTABS_CLOSEHIGH", -1);
          iupdrvRedrawNow(ih);
        }
      }

      press_p = iupAttribGetInt(ih, "_IUPTABS_CLOSEPRESS");
      if (press_p != -1 && !winTabsIsInsideCloseButton(ih, press_p))
      {
        iupAttribSetInt(ih, "_IUPTABS_CLOSEPRESS", -1);
        iupdrvRedrawNow(ih);
      }
    }
    break;
  case WM_LBUTTONDOWN:
    if (ih->data->show_close)
    {
      TCHITTESTINFO ht;
      int p;

      ht.pt.x = (int)(short)LOWORD(lp);
      ht.pt.y = (int)(short)HIWORD(lp);
      p = (int)SendMessage(ih->handle, TCM_HITTEST, 0, (LPARAM)&ht);

      if (p >= 0 && winTabsIsInsideCloseButton(ih, p))
      {
        iupAttribSetInt(ih, "_IUPTABS_CLOSEPRESS", p);  /* used for press feedback */
        iupdrvRedrawNow(ih);

        *result = 0;
        return 1;
      }
      else
        iupAttribSetInt(ih, "_IUPTABS_CLOSEPRESS", -1);
    }
    break;
  case WM_LBUTTONUP:
    if (ih->data->show_close)
    {
      int press_p = iupAttribGetInt(ih, "_IUPTABS_CLOSEPRESS");
      if (press_p != -1)
      {
        if (winTabsIsInsideCloseButton(ih, press_p))
        {
          int pos = winTabsPosFixFromWin(ih, press_p);
          Ihandle *child = IupGetChild(ih, pos);
          HWND tab_container = (HWND)iupAttribGet(child, "_IUPTAB_CONTAINER");

          iupAttribSetInt(ih, "_IUPTABS_CLOSEPRESS", -1);

          if (tab_container)
          {
            int ret = IUP_DEFAULT;
            IFni cb = (IFni)IupGetCallback(ih, "TABCLOSE_CB");
            if (cb)
              ret = cb(ih, pos);

            if (ret == IUP_CONTINUE) /* destroy tab and children */
            {
              IupDestroy(child);
              IupRefreshChildren(ih);
            }
            else if (ret == IUP_DEFAULT) /* hide tab and children */
            {
              iupTabsCheckCurrentTab(ih, pos, 0);
              winTabsSetVisibleArrayItem(ih, pos, 0);  /* to invisible */
              winTabsDeleteItem(ih, press_p, tab_container);
            }
            else if (ret == IUP_IGNORE)
            {
              *result = 0;
              return 1;
            }
          }
        }

        iupdrvRedrawNow(ih);
      }
    }
    break;
  }

  return iupwinBaseContainerMsgProc(ih, msg, wp, lp, result);
}

static void winTabsDrawRotateText(HDC hDC, char* text, int x, int y, HFONT hFont, COLORREF fgcolor, int align)
{
  COLORREF oldcolor;
  HFONT hOldFont;

  LOGFONT lf;
  GetObject(hFont, sizeof(LOGFONT), &lf);  /* get current font */
  if (align)   /* bottom to top */
  {
    lf.lfEscapement = 900;  /* rotate 90 degrees CCW */
    lf.lfOrientation = 900;
  }
  else         /* top to bottom */
  {
    lf.lfEscapement = -900;  /* rotate 90 degrees CW */
    lf.lfOrientation = -900;
  }
  hFont = CreateFontIndirect(&lf);  /* set font in order to rotate text */

  hOldFont = (HFONT)SelectObject(hDC, hFont);

  SetTextAlign(hDC, align ? TA_TOP | TA_LEFT : TA_BOTTOM | TA_LEFT);
  SetBkMode(hDC, TRANSPARENT);
  oldcolor = SetTextColor(hDC, fgcolor);

  {
    int len = (int)strlen(text);
    TCHAR* str = iupwinStrToSystemLen(text, &len);
    TextOut(hDC, x, y, str, len);
  }

  SelectObject(hDC, hOldFont);
  SetTextColor(hDC, oldcolor);
  SetBkMode(hDC, OPAQUE);

  DeleteObject(hFont);
}

static void winTabsDrawTab(Ihandle* ih, HDC hDC, int p, int width, int height, COLORREF fgcolor)
{
  HBITMAP hBitmapClose, hCloseMask = NULL;
  HFONT hFont = (HFONT)iupwinGetHFontAttrib(ih);
	TCHAR title[256] = TEXT("");
	TCITEM tci;
  HIMAGELIST image_list = (HIMAGELIST)SendMessage(ih->handle, TCM_GETIMAGELIST, 0, 0);
  int imgW = 0, imgH = 0, txtW = 0, txtH = 0,
    bpp, style = 0, x = 0, y = 0, border = 4;
  char *str = NULL, *value = NULL;
  int high_p, press_p;

  tci.mask = TCIF_TEXT | TCIF_IMAGE;
	tci.pszText = title;
	tci.cchTextMax = 255;
  SendMessage(ih->handle, TCM_GETITEM, (WPARAM)p, (LPARAM)(&tci));

  if (title[0])
  {
    value = iupwinStrFromSystem(title);
    str = iupStrProcessMnemonic(value, NULL, 0);   /* remove & */
    iupdrvFontGetMultiLineStringSize(ih, str, &txtW, &txtH);
  }

  if (tci.iImage != -1)
  {
    IMAGEINFO pImgInfo;
    ImageList_GetImageInfo(image_list, tci.iImage, &pImgInfo);
    imgW = pImgInfo.rcImage.right - pImgInfo.rcImage.left;
    imgH = pImgInfo.rcImage.bottom - pImgInfo.rcImage.top;
  }

  /* Create the close button image */
  high_p = iupAttribGetInt(ih, "_IUPTABS_CLOSEHIGH");
  if (high_p == p)
    hBitmapClose = iupImageGetImage("IMGCLOSEHIGH", ih, 0);
  else
    hBitmapClose = iupImageGetImage("IMGCLOSE", ih, 0);
  if (!hBitmapClose)
  {
    if (str && str != value) free(str);
    return;
  }

  iupdrvImageGetInfo(hBitmapClose, NULL, NULL, &bpp);
  if (bpp == 8)
    hCloseMask = iupdrvImageCreateMask(IupGetHandle("IMGCLOSE"));

  /* Draw image tab, title tab and close image */
  if (ih->data->type == ITABS_BOTTOM || ih->data->type == ITABS_TOP)
  {
    x = border;

    if (tci.iImage != -1)
    {
      y = (height - imgH) / 2;
      ImageList_Draw(image_list, tci.iImage, hDC, x, y, ILD_NORMAL);
      x += imgW + border;
    }

    if (title[0])
    {
      y = (height - txtH) / 2;
      iupwinDrawText(hDC, str, x, y, txtW, txtH, hFont, fgcolor, style);
    }

    x = width - border - ITABS_CLOSE_SIZE;
    y = (height - ITABS_CLOSE_SIZE) / 2;
  }
  else if(ih->data->type == ITABS_LEFT)
  {
    y = height;

    if (tci.iImage != -1)
    {
      x = (width - imgW) / 2;
      y -= border + imgH;
      ImageList_Draw(image_list, tci.iImage, hDC, x, y, ILD_NORMAL);  /* Tab image is already rotated into the list! */
    }

    if (title[0])
    {
      x = (width - txtH) / 2;  /* text is rotated switch W/H */
      y -= border;
      winTabsDrawRotateText(hDC, str, x, y, hFont, fgcolor, 1);
    }

    x = (width - ITABS_CLOSE_SIZE) / 2;
    y = border;
  }
  else  /* ITABS_RIGHT */
  {
    y = border;

    if (tci.iImage != -1)
    {
      x = (width - imgW) / 2;
      ImageList_Draw(image_list, tci.iImage, hDC, x, y, ILD_NORMAL);  /* Tab image is already rotated into the list! */
      y += imgH + border;
    }

    if (title[0])
    {
      x = (width - txtH) / 2;  /* text is rotated switch W/H */
      winTabsDrawRotateText(hDC, str, x, y, hFont, fgcolor, 0);
    }

    x = (width - ITABS_CLOSE_SIZE) / 2;
    y = height - border - ITABS_CLOSE_SIZE;
  }

  press_p = iupAttribGetInt(ih, "_IUPTABS_CLOSEPRESS");
  if (press_p == p)
  {
    x++;
    y++;
  }

  iupwinDrawBitmap(hDC, hBitmapClose, hCloseMask, x, y, ITABS_CLOSE_SIZE, ITABS_CLOSE_SIZE, bpp);

  if (hCloseMask)
    DeleteObject(hCloseMask);

  if (str && str != value) free(str);
}

static void winTabsDrawItem(Ihandle* ih, DRAWITEMSTRUCT *drawitem)
{
  HDC hDC;
  iupwinBitmapDC bmpDC;
  RECT rect;
  int x, y, width, height, p;
  COLORREF fgcolor;
  COLORREF bgcolor;

  /* If there are no tab items, skip this message */
  if (drawitem->itemID == -1)
    return;

  p = drawitem->itemID;

  x = drawitem->rcItem.left;
  y = drawitem->rcItem.top;
  width = drawitem->rcItem.right - drawitem->rcItem.left;
  height = drawitem->rcItem.bottom - drawitem->rcItem.top;

  hDC = iupwinDrawCreateBitmapDC(&bmpDC, drawitem->hDC, x, y, width, height);

  if (iupwinGetParentBgColor(ih, &bgcolor))
  {
    SetDCBrushColor(hDC, bgcolor);
    SetRect(&rect, 0, 0, width, height);
    FillRect(hDC, &rect, (HBRUSH)GetStockObject(DC_BRUSH));
  }

  if (drawitem->itemState & ODS_DISABLED)
    fgcolor = GetSysColor(COLOR_GRAYTEXT);
  else
  {
    if (!iupwinGetColorRef(ih, "FGCOLOR", &fgcolor))
      fgcolor = GetSysColor(COLOR_WINDOWTEXT);
  }

  winTabsDrawTab(ih, hDC, p, width, height, fgcolor);

  /* If the item has the focus, draw the focus rectangle */
  if (drawitem->itemState & ODS_FOCUS)
    iupdrvDrawFocusRect(ih, hDC, 0, 0, width, height);

  iupwinDrawDestroyBitmapDC(&bmpDC);
}

/* ------------------------------------------------------------------------- */
/* winTabs - Methods and Init Class                                          */
/* ------------------------------------------------------------------------- */

static void winTabsChildAddedMethod(Ihandle* ih, Ihandle* child)
{
  if (IupGetName(child) == NULL)
    iupAttribSetHandleName(child);

  if (ih->handle)
  {
    int pos = IupGetChildPos(ih, child);

    HWND tab_container = winTabsCreatePageWindow(ih);

    iupAttribSet(child, "_IUPTAB_CONTAINER", (char*)tab_container);

    winTabsInsertVisibleArrayItem(ih, pos);  /* add to the array and set to visible */

    winTabsInsertItem(ih, child, pos, tab_container);
  }
}

static void winTabsChildRemovedMethod(Ihandle* ih, Ihandle* child, int pos)
{
  if (ih->handle)
  {
    HWND tab_container = (HWND)iupAttribGet(child, "_IUPTAB_CONTAINER");
    if (tab_container)
    {
      int p = winTabsGetPageWindowPos(ih, tab_container);

      iupTabsCheckCurrentTab(ih, pos, 1);
      winTabsDeleteVisibleArrayItem(ih, pos);
      if (p != -1) winTabsDeleteItem(ih, p, tab_container);

      iupwinHandleRemove(tab_container);
      DestroyWindow(tab_container);
      iupAttribSet(child, "_IUPTAB_CONTAINER", NULL);
    }
  }
}

static int winTabsMapMethod(Ihandle* ih)
{
  DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | TCS_HOTTRACK | WS_TABSTOP,
      dwExStyle = 0;

  if (!ih->parent)
    return IUP_ERROR;

  if (ih->data->type == ITABS_BOTTOM)
    dwStyle |= TCS_BOTTOM;
  else if (ih->data->type == ITABS_RIGHT)
    dwStyle |= TCS_VERTICAL|TCS_RIGHT;
  else if (ih->data->type == ITABS_LEFT)
    dwStyle |= TCS_VERTICAL;

  if (ih->data->is_multiline)
    dwStyle |= TCS_MULTILINE;

  if (ih->data->show_close)
    dwStyle |= TCS_OWNERDRAWFIXED;

  iupwinGetNativeParentStyle(ih, &dwExStyle, &dwStyle);

  if (dwExStyle & WS_EX_COMPOSITED && !ih->data->is_multiline && iupwinIsVistaOrNew())
  {
    /* workaround for composite bug in Vista */
    ih->data->is_multiline = 1;
    dwStyle |= TCS_MULTILINE;
  }

  if (!iupwinCreateWindow(ih, WC_TABCONTROL, dwExStyle, dwStyle, NULL))
    return IUP_ERROR;

  /* replace the WinProc to handle other messages */
  IupSetCallback(ih, "_IUPWIN_CTRLMSGPROC_CB", (Icallback)winTabsMsgProc);

  /* Process WM_NOTIFY */
  IupSetCallback(ih, "_IUPWIN_NOTIFY_CB", (Icallback)winTabsWmNotify);

  /* Process background color */
  IupSetCallback(ih, "_IUPWIN_CTLCOLOR_CB", (Icallback)winTabsCtlColor);

  if (ih->data->show_close)
  {
    /* change tab width to draw an close image */
    SendMessage(ih->handle, TCM_SETPADDING, 0, MAKELPARAM(ITABS_CLOSE_SIZE, 0));

    iupAttribSetInt(ih, "_IUPTABS_CLOSEHIGH", -1);
    iupAttribSetInt(ih, "_IUPTABS_CLOSEPRESS", -1);

    /* owner draw tab image + tab title + close image */
    IupSetCallback(ih, "_IUPWIN_DRAWITEM_CB", (Icallback)winTabsDrawItem);
  }

  if (iupwin_comctl32ver6 && (ih->data->type != ITABS_TOP || ih->data->show_close))
  {
    /* XP Styles support only TABTYPE=TOP,
       show_close ownerdraw will work only with classic style */
    iupwinDrawRemoveTheme(ih->handle);
  }

  /* Change children background */
  if (winTabsUsingXPStyles(ih))
  {
    char* color = iupAttribGetInheritNativeParent(ih, "BGCOLOR");
    if (!color)
      color = iupAttribGetInheritNativeParent(ih, "BACKGROUND");
    if (!color)
    {
      COLORREF cr;
      if (iupwinDrawGetThemeTabsBgColor(ih->handle, &cr))
        iupAttribSetStrf(ih, "BACKGROUND", "%d %d %d", (int)GetRValue(cr), (int)GetGValue(cr), (int)GetBValue(cr));
    }
  }

  /* Create pages and tabs */
  if (ih->firstchild)
  {
    Ihandle* child;
    for (child = ih->firstchild; child; child = child->brother)
      winTabsChildAddedMethod(ih, child);
  }

  return IUP_NOERROR;
}

static void winTabsUnMapMethod(Ihandle* ih)
{
  Iarray* iarray;

  HIMAGELIST image_list = (HIMAGELIST)SendMessage(ih->handle, TCM_GETIMAGELIST, 0, 0);
  if (image_list)
    ImageList_Destroy(image_list);

  iarray = (Iarray*)iupAttribGet(ih, "_IUPWIN_BMPARRAY");
  if (iarray)
  {
    iupAttribSet(ih, "_IUPWIN_BMPARRAY", NULL);
    iupArrayDestroy(iarray);
  }

  iarray = (Iarray*)iupAttribGet(ih, "_IUPWIN_VISIBLEARRAY");
  if (iarray)
  {
    iupAttribSet(ih, "_IUPWIN_VISIBLEARRAY", NULL);
    iupArrayDestroy(iarray);
  }

  iupdrvBaseUnMapMethod(ih);
}

static void winTabsRegisterClass(void)
{
  WNDCLASS wndclass;
  ZeroMemory(&wndclass, sizeof(WNDCLASS));

  wndclass.hInstance      = iupwin_hinstance;
  wndclass.lpszClassName  = TEXT("IupTabsPage");
  wndclass.lpfnWndProc    = (WNDPROC)winTabsPageWndProc;
  wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  wndclass.style          = CS_PARENTDC;
  wndclass.hbrBackground  = NULL;  /* remove the background to optimize redraw */

  RegisterClass(&wndclass);
}

void iupdrvTabsInitClass(Iclass* ic)
{
  if (!iupwinClassExist(TEXT("IupTabsPage")))
    winTabsRegisterClass();

  /* Driver Dependent Class functions */
  ic->Map = winTabsMapMethod;
  ic->UnMap = winTabsUnMapMethod;
  ic->ChildAdded     = winTabsChildAddedMethod;
  ic->ChildRemoved   = winTabsChildRemovedMethod;

  /* Driver Dependent Attribute functions */

  iupClassRegisterCallback(ic, "TABCLOSE_CB", "i");

  /* Visual */
  iupClassRegisterAttribute(ic, "BGCOLOR", winTabsGetBgColorAttrib, winTabsSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_NO_SAVE|IUPAF_DEFAULT);

  /* Special */
  iupClassRegisterAttribute(ic, "FGCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "DLGFGCOLOR", IUPAF_NOT_MAPPED);

  /* IupTabs only */
  iupClassRegisterAttribute(ic, "TABTYPE", iupTabsGetTabTypeAttrib, winTabsSetTabTypeAttrib, IUPAF_SAMEASSYSTEM, "TOP", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "TABORIENTATION", iupTabsGetTabOrientationAttrib, NULL, IUPAF_SAMEASSYSTEM, "HORIZONTAL", IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);  /* can not be set, depends on TABTYPE in Windows */
  iupClassRegisterAttribute(ic, "MULTILINE", winTabsGetMultilineAttrib, winTabsSetMultilineAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
  iupClassRegisterAttributeId(ic, "TABTITLE", iupTabsGetTitleAttrib, winTabsSetTabTitleAttrib, IUPAF_NO_DEFAULTVALUE | IUPAF_NO_INHERIT);
  iupClassRegisterAttributeId(ic, "TABIMAGE", NULL, winTabsSetTabImageAttrib, IUPAF_IHANDLENAME|IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
  iupClassRegisterAttributeId(ic, "TABVISIBLE", iupTabsGetTabVisibleAttrib, winTabsSetTabVisibleAttrib, IUPAF_NO_DEFAULTVALUE | IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "PADDING", iupTabsGetPaddingAttrib, winTabsSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);

  /* necessary because transparent background does not work when not using visual styles */
  if (!iupwin_comctl32ver6)  /* Used by iupdrvImageCreateImage */
    iupClassRegisterAttribute(ic, "FLAT_ALPHA", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);

  /* Default node images */
  if (!IupGetHandle("IMGCLOSE"))
    winTabsInitializeCloseImage();
}