<commit_before>/*
*	Copyright 2009 Griffin Software
*
*	Licensed under the Apache License, Version 2.0 (the "License");
*	you may not use this file except in compliance with the License.
*	You may obtain a copy of the License at
*
*		http://www.apache.org/licenses/LICENSE-2.0
*
*	Unless required by applicable law or agreed to in writing, software
*	distributed under the License is distributed on an "AS IS" BASIS,
*	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*	See the License for the specific language governing permissions and
*	limitations under the License.
*/

#include "MetalScrollPCH.h"
#include "Utils.h"

static bool g_hasSSE2 = false;

static void FlipScaleImagePlainC(unsigned int* dest, int destHeight, const unsigned int* src, int srcHeight, int width)
{
	float yaspect = 1.0f * srcHeight / destHeight;
	float invAspect = 1.0f / yaspect;
	float lowY = 0.0f;

	// Also flip the image.
	dest = dest + destHeight*width;

	for(int i = 0; i < destHeight; ++i)
	{
		dest -= width;
		unsigned char* destPixel = (unsigned char*)dest;

		float highY = lowY + yaspect;
		if(highY > srcHeight)
		{
			// If the averaging kernel exceeds the source image height, clamp the kernel.
			highY = (float)srcHeight;
			invAspect = 1.0f / (highY - lowY);
		}

		int srcStartY = (int)lowY;
		const unsigned char* srcLineStart = (unsigned char*)(src + srcStartY*width);

		// Compute the weights for the first and last pixel.
		float truncLowY = (float)srcStartY;
		float firstPixelArea = 1.0f - (lowY - truncLowY);
		float lastPixelArea = highY - (float)(int)highY;

		for(int j = 0; j < width; ++j)
		{
			float pixel[3] = { 0.0f };

			const unsigned char* srcPixel = srcLineStart + j*4;

			// First pixel.
			for(int k = 0; k < 3; ++k)
				pixel[k] += srcPixel[k] * firstPixelArea;
			srcPixel += width*4;

			// Whole pixels. For some reason, it's faster to iterate with a float than using srcStartY and
			// casting highY to int outside the loop.
			float y = truncLowY + 1.0f;
			while(y < highY - 1)
			{
				for(int k = 0; k < 3; ++k)
					pixel[k] += srcPixel[k];
				++y;
				srcPixel += width*4;
			}

			// Last pixel.
			for(int k = 0; k < 3; ++k)
				pixel[k] += srcPixel[k] * lastPixelArea;

			// Divide by area.
			for(int k = 0; k < 3; ++k)
				destPixel[k] = (unsigned char)((int)(pixel[k] * invAspect));
			destPixel += 4;
		}

		lowY += yaspect;
	}
}

static __m128 LoadPixel(unsigned int p)
{
	__m128i intPixel = _mm_cvtsi32_si128(p);
	__m128i zero = _mm_setzero_si128();
	intPixel = _mm_unpacklo_epi8(intPixel, zero);
	intPixel = _mm_unpacklo_epi16(intPixel, zero);
	return _mm_cvtepi32_ps(intPixel);
}

static void FlipScaleImageSSE(unsigned int* dest, int destHeight, const unsigned int* src, int srcHeight, int width)
{
	float yaspect = 1.0f * srcHeight / destHeight;
	float lowY = 0.0f;

	float invAspectTmp = 1.0f / yaspect;
	__m128 invAspect = _mm_load1_ps(&invAspectTmp);

	// Also flip the image.
	dest = dest + destHeight*width;

	for(int i = 0; i < destHeight; ++i)
	{
		dest -= width;
		unsigned int* destPixel = dest;

		float highY = lowY + yaspect;
		if(highY > srcHeight)
		{
			// If the averaging kernel exceeds the source image height, clamp the kernel.
			highY = (float)srcHeight;
			float invArea = 1.0f / (highY - lowY);
			invAspect = _mm_load1_ps(&invArea);
		}

		int srcStartY = (int)lowY;
		const unsigned int* srcLineStart = src + srcStartY*width;

		// Compute the weights for the first and last pixel.
		float truncLowY = (float)srcStartY;
		float areaTmp = 1.0f - (lowY - truncLowY);
		__m128 firstPixelArea = _mm_load1_ps(&areaTmp);
		areaTmp = highY - (float)(int)highY;
		__m128 lastPixelArea = _mm_load1_ps(&areaTmp);

		for(int j = 0; j < width; ++j)
		{
			__m128 accumPixel = _mm_setzero_ps();

			const unsigned int* srcPixel = srcLineStart + j;

			// First pixel.
			__m128 fltPixel = LoadPixel(srcPixel[0]);
			fltPixel = _mm_mul_ps(fltPixel, firstPixelArea);
			accumPixel = _mm_add_ps(fltPixel, accumPixel);
			srcPixel += width;

			// Whole pixels.
			float y = truncLowY + 1.0f;
			while(y < highY - 1)
			{
				fltPixel = LoadPixel(srcPixel[0]);
				accumPixel = _mm_add_ps(fltPixel, accumPixel);
				++y;
				srcPixel += width;
			}

			// Last pixel.
			fltPixel = LoadPixel(srcPixel[0]);
			fltPixel = _mm_mul_ps(fltPixel, lastPixelArea);
			accumPixel = _mm_add_ps(fltPixel, accumPixel);

			// Convert to 4 bytes.
			accumPixel = _mm_mul_ps(accumPixel, invAspect);
			__m128i intPixel = _mm_cvtps_epi32(accumPixel);
			intPixel = _mm_packs_epi32(intPixel, intPixel);
			intPixel = _mm_packus_epi16(intPixel, intPixel);
			*destPixel =  _mm_cvtsi128_si32(intPixel);
			++destPixel;
		}

		lowY += yaspect;
	}
}

void FlipScaleImageVertically(unsigned int* dest, int destHeight, const unsigned int* src, int srcHeight, int width)
{
	if(g_hasSSE2)
		FlipScaleImageSSE(dest, destHeight, src, srcHeight, width);
	else
		FlipScaleImagePlainC(dest, destHeight, src, srcHeight, width);
}

void InitScaler()
{
	int info[4];
	__cpuid(info, 1);
	g_hasSSE2 = (info[3] & (1 << 26)) != 0;
}

void Log(const char* fmt, ...)
{
	char buf[256];
	va_list ap;
	va_start(ap, fmt);
	_vsnprintf(buf, sizeof(buf), fmt, ap);
	buf[sizeof(buf)-1] = 0;
	va_end(ap);
	OutputDebugStringA(buf);
}

void FillSolidRect(HDC hdc, unsigned int color, const RECT& r)
{
	// Wondrous hack (c) MFC: fill a rect with ExtTextOut(), since it doesn't require us to create a brush.
	COLORREF oldColor = SetBkColor(hdc, RGB_TO_COLORREF(color));
	ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &r, NULL, 0, NULL);
	SetBkColor(hdc, oldColor);
}

void StrokeRect(HDC hdc, unsigned int color, const RECT& r)
{
	COLORREF oldColor = SetBkColor(hdc, RGB_TO_COLORREF(color));

	RECT r1 = { r.left, r.top, r.right, r.top + 1 };
	ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &r1, NULL, 0, NULL);

	RECT r2 = { r.right - 1, r.top, r.right, r.bottom };
	ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &r2, NULL, 0, NULL);

	RECT r3 = { r.left, r.bottom - 1, r.right, r.bottom };
	ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &r3, NULL, 0, NULL);

	RECT r4 = { r.left, r.top, r.left + 1, r.bottom };
	ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &r4, NULL, 0, NULL);

	SetBkColor(hdc, oldColor);
}
<commit_msg>Fixed image scaling bug.<commit_after>/*
*	Copyright 2009 Griffin Software
*
*	Licensed under the Apache License, Version 2.0 (the "License");
*	you may not use this file except in compliance with the License.
*	You may obtain a copy of the License at
*
*		http://www.apache.org/licenses/LICENSE-2.0
*
*	Unless required by applicable law or agreed to in writing, software
*	distributed under the License is distributed on an "AS IS" BASIS,
*	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*	See the License for the specific language governing permissions and
*	limitations under the License.
*/

#include "MetalScrollPCH.h"
#include "Utils.h"

static bool g_hasSSE2 = false;

static void FlipScaleImagePlainC(unsigned int* dest, int destHeight, const unsigned int* src, int srcHeight, int width)
{
	float yaspect = 1.0f * srcHeight / destHeight;
	float invAspect = 1.0f / yaspect;
	float lowY = 0.0f;

	// Also flip the image.
	dest = dest + destHeight*width;

	for(int i = 0; i < destHeight; ++i)
	{
		dest -= width;
		unsigned char* destPixel = (unsigned char*)dest;

		float highY = lowY + yaspect;
		if(highY > srcHeight)
		{
			// If the averaging kernel exceeds the source image height, clamp the kernel.
			highY = (float)srcHeight;
			invAspect = 1.0f / (highY - lowY);
		}

		int srcStartY = (int)lowY;
		const unsigned char* srcLineStart = (unsigned char*)(src + srcStartY*width);

		// Compute the weights for the first and last pixel.
		float truncLowY = (float)srcStartY;
		float firstPixelArea = 1.0f - (lowY - truncLowY);
		float lastPixelArea = highY - (float)(int)highY;
		if(lastPixelArea == 0.0f)
			lastPixelArea = 1.0f;

		for(int j = 0; j < width; ++j)
		{
			float pixel[3] = { 0.0f };

			const unsigned char* srcPixel = srcLineStart + j*4;

			// First pixel.
			for(int k = 0; k < 3; ++k)
				pixel[k] += srcPixel[k] * firstPixelArea;
			srcPixel += width*4;

			// Whole pixels. For some reason, it's faster to iterate with a float than using srcStartY and
			// casting highY to int outside the loop.
			float y = truncLowY + 1.0f;
			while(y < highY - 1)
			{
				for(int k = 0; k < 3; ++k)
					pixel[k] += srcPixel[k];
				++y;
				srcPixel += width*4;
			}

			// Last pixel.
			for(int k = 0; k < 3; ++k)
				pixel[k] += srcPixel[k] * lastPixelArea;

			// Divide by area.
			for(int k = 0; k < 3; ++k)
				destPixel[k] = (unsigned char)((int)(pixel[k] * invAspect));
			destPixel += 4;
		}

		lowY += yaspect;
	}
}

static __m128 LoadPixel(unsigned int p)
{
	__m128i intPixel = _mm_cvtsi32_si128(p);
	__m128i zero = _mm_setzero_si128();
	intPixel = _mm_unpacklo_epi8(intPixel, zero);
	intPixel = _mm_unpacklo_epi16(intPixel, zero);
	return _mm_cvtepi32_ps(intPixel);
}

static void FlipScaleImageSSE(unsigned int* dest, int destHeight, const unsigned int* src, int srcHeight, int width)
{
	float yaspect = 1.0f * srcHeight / destHeight;
	float lowY = 0.0f;

	float invAspectTmp = 1.0f / yaspect;
	__m128 invAspect = _mm_load1_ps(&invAspectTmp);

	// Also flip the image.
	dest = dest + destHeight*width;

	for(int i = 0; i < destHeight; ++i)
	{
		dest -= width;
		unsigned int* destPixel = dest;

		float highY = lowY + yaspect;
		if(highY > srcHeight)
		{
			// If the averaging kernel exceeds the source image height, clamp the kernel.
			highY = (float)srcHeight;
			float invArea = 1.0f / (highY - lowY);
			invAspect = _mm_load1_ps(&invArea);
		}

		int srcStartY = (int)lowY;
		const unsigned int* srcLineStart = src + srcStartY*width;

		// Compute the weights for the first and last pixel.
		float truncLowY = (float)srcStartY;
		float areaTmp = 1.0f - (lowY - truncLowY);
		__m128 firstPixelArea = _mm_load1_ps(&areaTmp);
		areaTmp = highY - (float)(int)highY;
		if(areaTmp == 0.0f)
			areaTmp = 1.0f;
		__m128 lastPixelArea = _mm_load1_ps(&areaTmp);

		for(int j = 0; j < width; ++j)
		{
			__m128 accumPixel = _mm_setzero_ps();

			const unsigned int* srcPixel = srcLineStart + j;

			// First pixel.
			__m128 fltPixel = LoadPixel(srcPixel[0]);
			fltPixel = _mm_mul_ps(fltPixel, firstPixelArea);
			accumPixel = _mm_add_ps(fltPixel, accumPixel);
			srcPixel += width;

			// Whole pixels.
			float y = truncLowY + 1.0f;
			while(y < highY - 1)
			{
				fltPixel = LoadPixel(srcPixel[0]);
				accumPixel = _mm_add_ps(fltPixel, accumPixel);
				++y;
				srcPixel += width;
			}

			// Last pixel.
			fltPixel = LoadPixel(srcPixel[0]);
			fltPixel = _mm_mul_ps(fltPixel, lastPixelArea);
			accumPixel = _mm_add_ps(fltPixel, accumPixel);

			// Convert to 4 bytes.
			accumPixel = _mm_mul_ps(accumPixel, invAspect);
			__m128i intPixel = _mm_cvtps_epi32(accumPixel);
			intPixel = _mm_packs_epi32(intPixel, intPixel);
			intPixel = _mm_packus_epi16(intPixel, intPixel);
			*destPixel =  _mm_cvtsi128_si32(intPixel);
			++destPixel;
		}

		lowY += yaspect;
	}
}

void FlipScaleImageVertically(unsigned int* dest, int destHeight, const unsigned int* src, int srcHeight, int width)
{
	if(g_hasSSE2)
		FlipScaleImageSSE(dest, destHeight, src, srcHeight, width);
	else
		FlipScaleImagePlainC(dest, destHeight, src, srcHeight, width);
}

void InitScaler()
{
	int info[4];
	__cpuid(info, 1);
	g_hasSSE2 = (info[3] & (1 << 26)) != 0;
}

void Log(const char* fmt, ...)
{
	char buf[256];
	va_list ap;
	va_start(ap, fmt);
	_vsnprintf(buf, sizeof(buf), fmt, ap);
	buf[sizeof(buf)-1] = 0;
	va_end(ap);
	OutputDebugStringA(buf);
}

void FillSolidRect(HDC hdc, unsigned int color, const RECT& r)
{
	// Wondrous hack (c) MFC: fill a rect with ExtTextOut(), since it doesn't require us to create a brush.
	COLORREF oldColor = SetBkColor(hdc, RGB_TO_COLORREF(color));
	ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &r, NULL, 0, NULL);
	SetBkColor(hdc, oldColor);
}

void StrokeRect(HDC hdc, unsigned int color, const RECT& r)
{
	COLORREF oldColor = SetBkColor(hdc, RGB_TO_COLORREF(color));

	RECT r1 = { r.left, r.top, r.right, r.top + 1 };
	ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &r1, NULL, 0, NULL);

	RECT r2 = { r.right - 1, r.top, r.right, r.bottom };
	ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &r2, NULL, 0, NULL);

	RECT r3 = { r.left, r.bottom - 1, r.right, r.bottom };
	ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &r3, NULL, 0, NULL);

	RECT r4 = { r.left, r.top, r.left + 1, r.bottom };
	ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &r4, NULL, 0, NULL);

	SetBkColor(hdc, oldColor);
}
<|endoftext|>


<commit_before>#include "Wheel.h"
#include "ComponentCar.h"

#include "RaycastHit.h"
#include "ModulePhysics3D.h"
#include "GameObject.h"
#include "ComponentTransform.h"

void Wheel::Cast()
{
	math::Ray Ray;
	float3 pos = kart->GetKartTRS()->GetPosition() + kart->kartY * 1.5f;
	Ray.pos = pos + kart->kartX * posOffset.x + kart->kartZ * posOffset.y;
	Ray.dir = float3(kart->kartX * dir.x + kart->kartY * dir.y + kart->kartZ * dir.z);
	Ray.dir.Normalize();
	RaycastHit hitResult;

	hit = App->physics->RayCast(Ray, hitResult);
	if (hit)
	{
		distance = hitResult.distance;
		hitNormal = hitResult.normal;
		hitPoint = hitResult.point;
		angleFromY = hitResult.normal.AngleBetween(float3(0, 1, 0));
	}
}<commit_msg>Woops, forgot this<commit_after>#include "Wheel.h"
#include "ComponentCar.h"

#include "RaycastHit.h"
#include "ModulePhysics3D.h"
#include "GameObject.h"
#include "ComponentTransform.h"

void Wheel::Cast()
{
	math::Ray Ray;
	float3 pos = kart->GetKartTRS()->GetPosition() + kart->kartY * 1.5f;
	Ray.pos = pos + kart->kartX * posOffset.x + kart->kartZ * posOffset.y;
	Ray.dir = float3(kart->kartX * dir.x + kart->kartY * dir.y + kart->kartZ * dir.z);
	Ray.dir.Normalize();
	RaycastHit hitResult;

	hit = App->physics->RayCast(Ray, hitResult);
	if (hit)
	{
		distance = hitResult.distance;
		hitNormal = hitResult.normal;
		hitPoint = hitResult.point;
		angleFromY = hitResult.normal.AngleBetween(float3(0, 1, 0));
	}
	else
	{
		distance = floatMax - 10.0f;
		hitNormal = float3(0, 1, 0);
		hitPoint = float3(0, 0, 0);
		angleFromY = 0.0f;
	}
}<|endoftext|>


<commit_before>#include <iostream>
#include "list.h"
using namespace std;

/* ************************************************************
Function Name:populate
Return type:void
Arguments :void
Description:It fills the array with values provided
***************************************************************/
void list::populate(){
    cout <<"Enter the "<<i+1<<"th element ";
    for (int i=0;i<size;i++){
            cin>>arr[i];
            cout<<endl;
	}
}

/* ************************************************************
Function Name:del
Return type:void
Arguments :int ,position of the element to be deleted
Description:Deletes the value  present at the position(index)
                   passed in as a argument by overwriting the
                   value of the deleted element. Function also
                   reduces the size of array by one
***************************************************************/

void list::del(int pos){
    for (int i=pos;i<size;i++){
        arr[i]=arr[i + 1];
    }
    size=size-1;
}

/* ************************************************************
Function Name:display
Return type:void
Arguments :void
Description:Displays the values present in array at any instance
***************************************************************/
void list::display(){
    for (int i=0;i<size;i++)
        cout<<" "<<arr[i];
}

/* ************************************************************
Function Name:purging
Return type:void
Arguments :void
Description:compares the element with next element(s) and
                   deletes if same
***************************************************************/
void list::purging(){
    for (int i=0;i<size;++i){
        for (int j=i+1;j<size;++j){
           if(arr[i]==arr[j]){
                del(j);
                j--;
           }
        }
    }
}
<commit_msg>Update array.cpp<commit_after>#include <iostream>
#include "list.h"
using namespace std;

/* ************************************************************
Function Name:populate
Return type:void
Arguments :void
Description:It fills the array with values provided
***************************************************************/
void list::populate(){
    cout <<"Enter the "<<i+1<<"th element ";
    for (int i=0;i<size;i++){
            cin>>arr[i];
            cout<<endl;
	}
}

/* ************************************************************
Function Name:del
Return type:void
Arguments :int ,position of the element to be deleted
Description:Deletes the value  present at the position(index)
                   passed in as a argument by overwriting the
                   value of the deleted element. Function also
                   reduces the size of array by one
***************************************************************/

void list::del(int pos){
    for (int i=pos;i<size;i++){
        arr[i]=arr[i + 1];
    }
    size=size-1;
}

/* ************************************************************
Function Name:display
Return type:void
Arguments :void
Description:Displays the values present in array at any instance
***************************************************************/
void list::display(){
    for (int i=0;i<size;i++)
        cout<<" "<<arr[i];
}

/* ************************************************************
Function Name:purging
Return type:void
Arguments :void
Description:compares the element with next element(s) and
                   deletes if same
***************************************************************/
void list::purging(){
    for (int i=0;i<size;++i){
        for (int j=i+1;j<size;++j){
           if(arr[i]==arr[j]){
                del(j);
                i--;
           }
        }
    }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cmath>

#define SIZE

int main()
{
	for(double x = 0; x < 20; x++)
	{
		for(double y = 0; y < 20; y++)
		{
			if( y == round(sin(x)) + 4) // sin curve
				std::cout << "*";
			else
				std::cout << " ";
		}
		std::cout << "\n";
	}
}<commit_msg>Update<commit_after>#include <iostream>
#include <cmath>

#define SIZE

int main()
{
	for(double x = 0; x < 20; x++)
	{
		for(double y = 0; y < 20; y++)
		{
			if( y == round(sin(x)) + 4 || y == 4 - round(sin(x))) // sin curve
				std::cout << "*";
			else
				std::cout << " ";
		}
		std::cout << "\n";
	}
}<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/printing/print_dialog_gtk.h"

#include <fcntl.h>
#include <gtk/gtkunixprint.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/file_util.h"
#include "base/file_util_proxy.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "printing/metafile.h"
#include "printing/print_job_constants.h"
#include "printing/print_settings.h"
#include "printing/print_settings_initializer_gtk.h"

using content::BrowserThread;
using printing::PageRanges;
using printing::PrintSettings;

namespace {

// CUPS Duplex attribute and values.
const char kCUPSDuplex[] = "cups-Duplex";
const char kDuplexNone[] = "None";
const char kDuplexTumble[] = "DuplexTumble";
const char kDuplexNoTumble[] = "DuplexNoTumble";

// Helper class to track GTK printers.
class GtkPrinterList {
 public:
  GtkPrinterList() : default_printer_(NULL) {
    gtk_enumerate_printers((GtkPrinterFunc)SetPrinter, this, NULL, TRUE);
  }

  ~GtkPrinterList() {
    for (std::vector<GtkPrinter*>::iterator it = printers_.begin();
         it < printers_.end(); ++it) {
      g_object_unref(*it);
    }
  }

  // Can return NULL if there's no default printer. E.g. Printer on a laptop
  // is "home_printer", but the laptop is at work.
  GtkPrinter* default_printer() {
    return default_printer_;
  }

  // Can return NULL if the printer cannot be found due to:
  // - Printer list out of sync with printer dialog UI.
  // - Querying for non-existant printers like 'Print to PDF'.
  GtkPrinter* GetPrinterWithName(const char* name) {
    if (!name || !*name)
      return NULL;

    for (std::vector<GtkPrinter*>::iterator it = printers_.begin();
         it < printers_.end(); ++it) {
      if (strcmp(name, gtk_printer_get_name(*it)) == 0) {
        return *it;
      }
    }

    return NULL;
  }

 private:
  // Callback function used by gtk_enumerate_printers() to get all printer.
  static bool SetPrinter(GtkPrinter* printer, GtkPrinterList* printer_list) {
    if (gtk_printer_is_default(printer))
      printer_list->default_printer_ = printer;

    g_object_ref(printer);
    printer_list->printers_.push_back(printer);

    return false;
  }

  std::vector<GtkPrinter*> printers_;
  GtkPrinter* default_printer_;
};

}  // namespace

// static
printing::PrintDialogGtkInterface* PrintDialogGtk::CreatePrintDialog(
    PrintingContextGtk* context) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  return new PrintDialogGtk(context);
}

PrintDialogGtk::PrintDialogGtk(PrintingContextGtk* context)
    : context_(context),
      dialog_(NULL),
      gtk_settings_(NULL),
      page_setup_(NULL),
      printer_(NULL) {
}

PrintDialogGtk::~PrintDialogGtk() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  if (dialog_) {
    gtk_widget_destroy(dialog_);
    dialog_ = NULL;
  }
  if (gtk_settings_) {
    g_object_unref(gtk_settings_);
    gtk_settings_ = NULL;
  }
  if (page_setup_) {
    g_object_unref(page_setup_);
    page_setup_ = NULL;
  }
  if (printer_) {
    g_object_unref(printer_);
    printer_ = NULL;
  }
}

void PrintDialogGtk::UseDefaultSettings() {
  DCHECK(!page_setup_);

  // |gtk_settings_| is a new object.
  gtk_settings_ = gtk_print_settings_new();

  scoped_ptr<GtkPrinterList> printer_list(new GtkPrinterList);
  printer_ = printer_list->default_printer();
  if (printer_) {
    g_object_ref(printer_);
    gtk_print_settings_set_printer(gtk_settings_,
                                   gtk_printer_get_name(printer_));
    page_setup_ = gtk_printer_get_default_page_size(printer_);
  }

  if (!page_setup_)
    page_setup_ = gtk_page_setup_new();

  // No page range to initialize for default settings.
  PageRanges ranges_vector;
  PrintSettings settings;
  InitPrintSettings(ranges_vector, &settings);
}

bool PrintDialogGtk::UpdateSettings(const base::DictionaryValue& job_settings,
                                    const printing::PageRanges& ranges,
                                    printing::PrintSettings* settings) {
  bool collate;
  int color;
  bool landscape;
  bool print_to_pdf;
  int copies;
  int duplex_mode;
  std::string device_name;

  if (!job_settings.GetBoolean(printing::kSettingLandscape, &landscape) ||
      !job_settings.GetBoolean(printing::kSettingCollate, &collate) ||
      !job_settings.GetInteger(printing::kSettingColor, &color) ||
      !job_settings.GetBoolean(printing::kSettingPrintToPDF, &print_to_pdf) ||
      !job_settings.GetInteger(printing::kSettingDuplexMode, &duplex_mode) ||
      !job_settings.GetInteger(printing::kSettingCopies, &copies) ||
      !job_settings.GetString(printing::kSettingDeviceName, &device_name)) {
    return false;
  }

  if (!gtk_settings_)
    gtk_settings_ = gtk_print_settings_new();

  if (!print_to_pdf) {
    scoped_ptr<GtkPrinterList> printer_list(new GtkPrinterList);
    printer_ = printer_list->GetPrinterWithName(device_name.c_str());
    if (printer_) {
      g_object_ref(printer_);
      gtk_print_settings_set_printer(gtk_settings_,
                                     gtk_printer_get_name(printer_));
      if (!page_setup_) {
        page_setup_ = gtk_printer_get_default_page_size(printer_);
      }
    }

    gtk_print_settings_set_n_copies(gtk_settings_, copies);
    gtk_print_settings_set_collate(gtk_settings_, collate);

#if defined(USE_CUPS)
    std::string color_value;
    std::string color_setting_name;
    printing::GetColorModelForMode(color, &color_setting_name, &color_value);
    gtk_print_settings_set(gtk_settings_, color_setting_name.c_str(),
                           color_value.c_str());

    if (duplex_mode != printing::UNKNOWN_DUPLEX_MODE) {
      const char* cups_duplex_mode = NULL;
      switch (duplex_mode) {
        case printing::LONG_EDGE:
          cups_duplex_mode = kDuplexNoTumble;
          break;
        case printing::SHORT_EDGE:
          cups_duplex_mode = kDuplexTumble;
          break;
        case printing::SIMPLEX:
          cups_duplex_mode = kDuplexNone;
          break;
        default:  // UNKNOWN_DUPLEX_MODE
          NOTREACHED();
          break;
      }
      gtk_print_settings_set(gtk_settings_, kCUPSDuplex, cups_duplex_mode);
    }
#endif
  }
  if (!page_setup_)
    page_setup_ = gtk_page_setup_new();

  gtk_print_settings_set_orientation(
      gtk_settings_,
      landscape ? GTK_PAGE_ORIENTATION_LANDSCAPE :
                  GTK_PAGE_ORIENTATION_PORTRAIT);

  InitPrintSettings(ranges, settings);
  return true;
}

void PrintDialogGtk::ShowDialog(
    gfx::NativeView parent_view,
    bool has_selection,
    const PrintingContextGtk::PrintSettingsCallback& callback) {
  callback_ = callback;

  GtkWindow* parent = GTK_WINDOW(gtk_widget_get_toplevel(parent_view));
  // TODO(estade): We need a window title here.
  dialog_ = gtk_print_unix_dialog_new(NULL, parent);
  g_signal_connect(dialog_, "delete-event",
                   G_CALLBACK(gtk_widget_hide_on_delete), NULL);

  // Set modal so user cannot focus the same tab and press print again.
  gtk_window_set_modal(GTK_WINDOW(dialog_), TRUE);

  // Since we only generate PDF, only show printers that support PDF.
  // TODO(thestig) Add more capabilities to support?
  GtkPrintCapabilities cap = static_cast<GtkPrintCapabilities>(
      GTK_PRINT_CAPABILITY_GENERATE_PDF |
      GTK_PRINT_CAPABILITY_PAGE_SET |
      GTK_PRINT_CAPABILITY_COPIES |
      GTK_PRINT_CAPABILITY_COLLATE |
      GTK_PRINT_CAPABILITY_REVERSE);
  gtk_print_unix_dialog_set_manual_capabilities(GTK_PRINT_UNIX_DIALOG(dialog_),
                                                cap);
  gtk_print_unix_dialog_set_embed_page_setup(GTK_PRINT_UNIX_DIALOG(dialog_),
                                             TRUE);
  gtk_print_unix_dialog_set_support_selection(GTK_PRINT_UNIX_DIALOG(dialog_),
                                              TRUE);
  gtk_print_unix_dialog_set_has_selection(GTK_PRINT_UNIX_DIALOG(dialog_),
                                          has_selection);
  g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this);
  gtk_widget_show(dialog_);
}

void PrintDialogGtk::PrintDocument(const printing::Metafile* metafile,
                                   const string16& document_name) {
  // This runs on the print worker thread, does not block the UI thread.
  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));

  // The document printing tasks can outlive the PrintingContext that created
  // this dialog.
  AddRef();

  bool error = false;
  if (!file_util::CreateTemporaryFile(&path_to_pdf_)) {
    LOG(ERROR) << "Creating temporary file failed";
    error = true;
  }

  if (!error && !metafile->SaveTo(path_to_pdf_)) {
    LOG(ERROR) << "Saving metafile failed";
    file_util::Delete(path_to_pdf_, false);
    error = true;
  }

  if (error) {
    // Matches AddRef() above.
    Release();
  } else {
    // No errors, continue printing.
    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        base::Bind(&PrintDialogGtk::SendDocumentToPrinter, this,
                   document_name));
  }
}

void PrintDialogGtk::AddRefToDialog() {
  AddRef();
}

void PrintDialogGtk::ReleaseDialog() {
  Release();
}

void PrintDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
  gtk_widget_hide(dialog_);

  switch (response_id) {
    case GTK_RESPONSE_OK: {
      if (gtk_settings_)
        g_object_unref(gtk_settings_);
      gtk_settings_ = gtk_print_unix_dialog_get_settings(
          GTK_PRINT_UNIX_DIALOG(dialog_));

      if (printer_)
        g_object_unref(printer_);
      printer_ = gtk_print_unix_dialog_get_selected_printer(
          GTK_PRINT_UNIX_DIALOG(dialog_));
      g_object_ref(printer_);

      if (page_setup_)
        g_object_unref(page_setup_);
      page_setup_ = gtk_print_unix_dialog_get_page_setup(
          GTK_PRINT_UNIX_DIALOG(dialog_));
      g_object_ref(page_setup_);

      // Handle page ranges.
      PageRanges ranges_vector;
      gint num_ranges;
      bool print_selection_only = false;
      switch (gtk_print_settings_get_print_pages(gtk_settings_)) {
        case GTK_PRINT_PAGES_RANGES: {
          GtkPageRange* gtk_range =
              gtk_print_settings_get_page_ranges(gtk_settings_, &num_ranges);
          if (gtk_range) {
            for (int i = 0; i < num_ranges; ++i) {
              printing::PageRange range;
              range.from = gtk_range[i].start;
              range.to = gtk_range[i].end;
              ranges_vector.push_back(range);
            }
            g_free(gtk_range);
          }
          break;
        }
        case GTK_PRINT_PAGES_SELECTION:
          print_selection_only = true;
          break;
        case GTK_PRINT_PAGES_ALL:
          // Leave |ranges_vector| empty to indicate print all pages.
          break;
        case GTK_PRINT_PAGES_CURRENT:
        default:
          NOTREACHED();
          break;
      }

      PrintSettings settings;
      printing::PrintSettingsInitializerGtk::InitPrintSettings(
          gtk_settings_, page_setup_, ranges_vector, print_selection_only,
          &settings);
      context_->InitWithSettings(settings);
      callback_.Run(PrintingContextGtk::OK);
      callback_.Reset();
      return;
    }
    case GTK_RESPONSE_DELETE_EVENT:  // Fall through.
    case GTK_RESPONSE_CANCEL: {
      callback_.Run(PrintingContextGtk::CANCEL);
      callback_.Reset();
      return;
    }
    case GTK_RESPONSE_APPLY:
    default: {
      NOTREACHED();
    }
  }
}

void PrintDialogGtk::SendDocumentToPrinter(const string16& document_name) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  // If |printer_| is NULL then somehow the GTK printer list changed out under
  // us. In which case, just bail out.
  if (!printer_) {
    // Matches AddRef() in PrintDocument();
    Release();
    return;
  }

  GtkPrintJob* print_job = gtk_print_job_new(
      UTF16ToUTF8(document_name).c_str(),
      printer_,
      gtk_settings_,
      page_setup_);
  gtk_print_job_set_source_file(print_job, path_to_pdf_.value().c_str(), NULL);
  gtk_print_job_send(print_job, OnJobCompletedThunk, this, NULL);
}

// static
void PrintDialogGtk::OnJobCompletedThunk(GtkPrintJob* print_job,
                                         gpointer user_data,
                                         GError* error) {
  static_cast<PrintDialogGtk*>(user_data)->OnJobCompleted(print_job, error);
}

void PrintDialogGtk::OnJobCompleted(GtkPrintJob* print_job, GError* error) {
  if (error)
    LOG(ERROR) << "Printing failed: " << error->message;
  if (print_job)
    g_object_unref(print_job);
  base::FileUtilProxy::Delete(
      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
      path_to_pdf_, false, base::FileUtilProxy::StatusCallback());
  // Printing finished. Matches AddRef() in PrintDocument();
  Release();
}

void PrintDialogGtk::InitPrintSettings(const PageRanges& page_ranges,
                                       PrintSettings* settings) {
  printing::PrintSettingsInitializerGtk::InitPrintSettings(
      gtk_settings_, page_setup_, page_ranges, false, settings);
  context_->InitWithSettings(*settings);
}
<commit_msg>Fix the prototype of the callback passed to gtk_enumerate_printers().<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/printing/print_dialog_gtk.h"

#include <fcntl.h>
#include <gtk/gtkunixprint.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/file_util.h"
#include "base/file_util_proxy.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "printing/metafile.h"
#include "printing/print_job_constants.h"
#include "printing/print_settings.h"
#include "printing/print_settings_initializer_gtk.h"

using content::BrowserThread;
using printing::PageRanges;
using printing::PrintSettings;

namespace {

// CUPS Duplex attribute and values.
const char kCUPSDuplex[] = "cups-Duplex";
const char kDuplexNone[] = "None";
const char kDuplexTumble[] = "DuplexTumble";
const char kDuplexNoTumble[] = "DuplexNoTumble";

// Helper class to track GTK printers.
class GtkPrinterList {
 public:
  GtkPrinterList() : default_printer_(NULL) {
    gtk_enumerate_printers(SetPrinter, this, NULL, TRUE);
  }

  ~GtkPrinterList() {
    for (std::vector<GtkPrinter*>::iterator it = printers_.begin();
         it < printers_.end(); ++it) {
      g_object_unref(*it);
    }
  }

  // Can return NULL if there's no default printer. E.g. Printer on a laptop
  // is "home_printer", but the laptop is at work.
  GtkPrinter* default_printer() {
    return default_printer_;
  }

  // Can return NULL if the printer cannot be found due to:
  // - Printer list out of sync with printer dialog UI.
  // - Querying for non-existant printers like 'Print to PDF'.
  GtkPrinter* GetPrinterWithName(const char* name) {
    if (!name || !*name)
      return NULL;

    for (std::vector<GtkPrinter*>::iterator it = printers_.begin();
         it < printers_.end(); ++it) {
      if (strcmp(name, gtk_printer_get_name(*it)) == 0) {
        return *it;
      }
    }

    return NULL;
  }

 private:
  // Callback function used by gtk_enumerate_printers() to get all printer.
  static gboolean SetPrinter(GtkPrinter* printer, gpointer data) {
    GtkPrinterList *printer_list = (GtkPrinterList*)data;
    if (gtk_printer_is_default(printer))
      printer_list->default_printer_ = printer;

    g_object_ref(printer);
    printer_list->printers_.push_back(printer);

    return FALSE;
  }

  std::vector<GtkPrinter*> printers_;
  GtkPrinter* default_printer_;
};

}  // namespace

// static
printing::PrintDialogGtkInterface* PrintDialogGtk::CreatePrintDialog(
    PrintingContextGtk* context) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  return new PrintDialogGtk(context);
}

PrintDialogGtk::PrintDialogGtk(PrintingContextGtk* context)
    : context_(context),
      dialog_(NULL),
      gtk_settings_(NULL),
      page_setup_(NULL),
      printer_(NULL) {
}

PrintDialogGtk::~PrintDialogGtk() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  if (dialog_) {
    gtk_widget_destroy(dialog_);
    dialog_ = NULL;
  }
  if (gtk_settings_) {
    g_object_unref(gtk_settings_);
    gtk_settings_ = NULL;
  }
  if (page_setup_) {
    g_object_unref(page_setup_);
    page_setup_ = NULL;
  }
  if (printer_) {
    g_object_unref(printer_);
    printer_ = NULL;
  }
}

void PrintDialogGtk::UseDefaultSettings() {
  DCHECK(!page_setup_);

  // |gtk_settings_| is a new object.
  gtk_settings_ = gtk_print_settings_new();

  scoped_ptr<GtkPrinterList> printer_list(new GtkPrinterList);
  printer_ = printer_list->default_printer();
  if (printer_) {
    g_object_ref(printer_);
    gtk_print_settings_set_printer(gtk_settings_,
                                   gtk_printer_get_name(printer_));
    page_setup_ = gtk_printer_get_default_page_size(printer_);
  }

  if (!page_setup_)
    page_setup_ = gtk_page_setup_new();

  // No page range to initialize for default settings.
  PageRanges ranges_vector;
  PrintSettings settings;
  InitPrintSettings(ranges_vector, &settings);
}

bool PrintDialogGtk::UpdateSettings(const base::DictionaryValue& job_settings,
                                    const printing::PageRanges& ranges,
                                    printing::PrintSettings* settings) {
  bool collate;
  int color;
  bool landscape;
  bool print_to_pdf;
  int copies;
  int duplex_mode;
  std::string device_name;

  if (!job_settings.GetBoolean(printing::kSettingLandscape, &landscape) ||
      !job_settings.GetBoolean(printing::kSettingCollate, &collate) ||
      !job_settings.GetInteger(printing::kSettingColor, &color) ||
      !job_settings.GetBoolean(printing::kSettingPrintToPDF, &print_to_pdf) ||
      !job_settings.GetInteger(printing::kSettingDuplexMode, &duplex_mode) ||
      !job_settings.GetInteger(printing::kSettingCopies, &copies) ||
      !job_settings.GetString(printing::kSettingDeviceName, &device_name)) {
    return false;
  }

  if (!gtk_settings_)
    gtk_settings_ = gtk_print_settings_new();

  if (!print_to_pdf) {
    scoped_ptr<GtkPrinterList> printer_list(new GtkPrinterList);
    printer_ = printer_list->GetPrinterWithName(device_name.c_str());
    if (printer_) {
      g_object_ref(printer_);
      gtk_print_settings_set_printer(gtk_settings_,
                                     gtk_printer_get_name(printer_));
      if (!page_setup_) {
        page_setup_ = gtk_printer_get_default_page_size(printer_);
      }
    }

    gtk_print_settings_set_n_copies(gtk_settings_, copies);
    gtk_print_settings_set_collate(gtk_settings_, collate);

#if defined(USE_CUPS)
    std::string color_value;
    std::string color_setting_name;
    printing::GetColorModelForMode(color, &color_setting_name, &color_value);
    gtk_print_settings_set(gtk_settings_, color_setting_name.c_str(),
                           color_value.c_str());

    if (duplex_mode != printing::UNKNOWN_DUPLEX_MODE) {
      const char* cups_duplex_mode = NULL;
      switch (duplex_mode) {
        case printing::LONG_EDGE:
          cups_duplex_mode = kDuplexNoTumble;
          break;
        case printing::SHORT_EDGE:
          cups_duplex_mode = kDuplexTumble;
          break;
        case printing::SIMPLEX:
          cups_duplex_mode = kDuplexNone;
          break;
        default:  // UNKNOWN_DUPLEX_MODE
          NOTREACHED();
          break;
      }
      gtk_print_settings_set(gtk_settings_, kCUPSDuplex, cups_duplex_mode);
    }
#endif
  }
  if (!page_setup_)
    page_setup_ = gtk_page_setup_new();

  gtk_print_settings_set_orientation(
      gtk_settings_,
      landscape ? GTK_PAGE_ORIENTATION_LANDSCAPE :
                  GTK_PAGE_ORIENTATION_PORTRAIT);

  InitPrintSettings(ranges, settings);
  return true;
}

void PrintDialogGtk::ShowDialog(
    gfx::NativeView parent_view,
    bool has_selection,
    const PrintingContextGtk::PrintSettingsCallback& callback) {
  callback_ = callback;

  GtkWindow* parent = GTK_WINDOW(gtk_widget_get_toplevel(parent_view));
  // TODO(estade): We need a window title here.
  dialog_ = gtk_print_unix_dialog_new(NULL, parent);
  g_signal_connect(dialog_, "delete-event",
                   G_CALLBACK(gtk_widget_hide_on_delete), NULL);

  // Set modal so user cannot focus the same tab and press print again.
  gtk_window_set_modal(GTK_WINDOW(dialog_), TRUE);

  // Since we only generate PDF, only show printers that support PDF.
  // TODO(thestig) Add more capabilities to support?
  GtkPrintCapabilities cap = static_cast<GtkPrintCapabilities>(
      GTK_PRINT_CAPABILITY_GENERATE_PDF |
      GTK_PRINT_CAPABILITY_PAGE_SET |
      GTK_PRINT_CAPABILITY_COPIES |
      GTK_PRINT_CAPABILITY_COLLATE |
      GTK_PRINT_CAPABILITY_REVERSE);
  gtk_print_unix_dialog_set_manual_capabilities(GTK_PRINT_UNIX_DIALOG(dialog_),
                                                cap);
  gtk_print_unix_dialog_set_embed_page_setup(GTK_PRINT_UNIX_DIALOG(dialog_),
                                             TRUE);
  gtk_print_unix_dialog_set_support_selection(GTK_PRINT_UNIX_DIALOG(dialog_),
                                              TRUE);
  gtk_print_unix_dialog_set_has_selection(GTK_PRINT_UNIX_DIALOG(dialog_),
                                          has_selection);
  g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this);
  gtk_widget_show(dialog_);
}

void PrintDialogGtk::PrintDocument(const printing::Metafile* metafile,
                                   const string16& document_name) {
  // This runs on the print worker thread, does not block the UI thread.
  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));

  // The document printing tasks can outlive the PrintingContext that created
  // this dialog.
  AddRef();

  bool error = false;
  if (!file_util::CreateTemporaryFile(&path_to_pdf_)) {
    LOG(ERROR) << "Creating temporary file failed";
    error = true;
  }

  if (!error && !metafile->SaveTo(path_to_pdf_)) {
    LOG(ERROR) << "Saving metafile failed";
    file_util::Delete(path_to_pdf_, false);
    error = true;
  }

  if (error) {
    // Matches AddRef() above.
    Release();
  } else {
    // No errors, continue printing.
    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        base::Bind(&PrintDialogGtk::SendDocumentToPrinter, this,
                   document_name));
  }
}

void PrintDialogGtk::AddRefToDialog() {
  AddRef();
}

void PrintDialogGtk::ReleaseDialog() {
  Release();
}

void PrintDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
  gtk_widget_hide(dialog_);

  switch (response_id) {
    case GTK_RESPONSE_OK: {
      if (gtk_settings_)
        g_object_unref(gtk_settings_);
      gtk_settings_ = gtk_print_unix_dialog_get_settings(
          GTK_PRINT_UNIX_DIALOG(dialog_));

      if (printer_)
        g_object_unref(printer_);
      printer_ = gtk_print_unix_dialog_get_selected_printer(
          GTK_PRINT_UNIX_DIALOG(dialog_));
      g_object_ref(printer_);

      if (page_setup_)
        g_object_unref(page_setup_);
      page_setup_ = gtk_print_unix_dialog_get_page_setup(
          GTK_PRINT_UNIX_DIALOG(dialog_));
      g_object_ref(page_setup_);

      // Handle page ranges.
      PageRanges ranges_vector;
      gint num_ranges;
      bool print_selection_only = false;
      switch (gtk_print_settings_get_print_pages(gtk_settings_)) {
        case GTK_PRINT_PAGES_RANGES: {
          GtkPageRange* gtk_range =
              gtk_print_settings_get_page_ranges(gtk_settings_, &num_ranges);
          if (gtk_range) {
            for (int i = 0; i < num_ranges; ++i) {
              printing::PageRange range;
              range.from = gtk_range[i].start;
              range.to = gtk_range[i].end;
              ranges_vector.push_back(range);
            }
            g_free(gtk_range);
          }
          break;
        }
        case GTK_PRINT_PAGES_SELECTION:
          print_selection_only = true;
          break;
        case GTK_PRINT_PAGES_ALL:
          // Leave |ranges_vector| empty to indicate print all pages.
          break;
        case GTK_PRINT_PAGES_CURRENT:
        default:
          NOTREACHED();
          break;
      }

      PrintSettings settings;
      printing::PrintSettingsInitializerGtk::InitPrintSettings(
          gtk_settings_, page_setup_, ranges_vector, print_selection_only,
          &settings);
      context_->InitWithSettings(settings);
      callback_.Run(PrintingContextGtk::OK);
      callback_.Reset();
      return;
    }
    case GTK_RESPONSE_DELETE_EVENT:  // Fall through.
    case GTK_RESPONSE_CANCEL: {
      callback_.Run(PrintingContextGtk::CANCEL);
      callback_.Reset();
      return;
    }
    case GTK_RESPONSE_APPLY:
    default: {
      NOTREACHED();
    }
  }
}

void PrintDialogGtk::SendDocumentToPrinter(const string16& document_name) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  // If |printer_| is NULL then somehow the GTK printer list changed out under
  // us. In which case, just bail out.
  if (!printer_) {
    // Matches AddRef() in PrintDocument();
    Release();
    return;
  }

  GtkPrintJob* print_job = gtk_print_job_new(
      UTF16ToUTF8(document_name).c_str(),
      printer_,
      gtk_settings_,
      page_setup_);
  gtk_print_job_set_source_file(print_job, path_to_pdf_.value().c_str(), NULL);
  gtk_print_job_send(print_job, OnJobCompletedThunk, this, NULL);
}

// static
void PrintDialogGtk::OnJobCompletedThunk(GtkPrintJob* print_job,
                                         gpointer user_data,
                                         GError* error) {
  static_cast<PrintDialogGtk*>(user_data)->OnJobCompleted(print_job, error);
}

void PrintDialogGtk::OnJobCompleted(GtkPrintJob* print_job, GError* error) {
  if (error)
    LOG(ERROR) << "Printing failed: " << error->message;
  if (print_job)
    g_object_unref(print_job);
  base::FileUtilProxy::Delete(
      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
      path_to_pdf_, false, base::FileUtilProxy::StatusCallback());
  // Printing finished. Matches AddRef() in PrintDocument();
  Release();
}

void PrintDialogGtk::InitPrintSettings(const PageRanges& page_ranges,
                                       PrintSettings* settings) {
  printing::PrintSettingsInitializerGtk::InitPrintSettings(
      gtk_settings_, page_setup_, page_ranges, false, settings);
  context_->InitWithSettings(*settings);
}
<|endoftext|>


<commit_before><commit_msg>Mark URLRequestTestFTP.FTPGetTestAnonymous as flaky.<commit_after><|endoftext|>


<commit_before><commit_msg>Make even more tests in net_unittests faster by reusing the test server.<commit_after><|endoftext|>


<commit_before><commit_msg>increase framegraph vector heap<commit_after><|endoftext|>


<commit_before>// Filename: NumericType.ipp
namespace dclass   // open namespace
{

// get_divisor returns the divisor of the numeric, with a default value of one.
inline unsigned int NumericType::get_divisor() const
{
	return m_divisor;
}

// has_modulus returns true if the numeric is constrained by a modulus.
inline bool NumericType::has_modulus() const
{
	return m_orig_modulus == 0.0;
}

// get_modulus returns a double representation of the modulus value.
inline double NumericType::get_modulus() const
{
	return m_orig_modulus;
}

// has_range returns true if the numeric is constrained by a range.
inline bool NumericType::has_range() const
{
	return !m_orig_range.is_empty();
}
// get_range returns the NumericRange that constrains the type's values.
inline NumericRange NumericType::get_range() const
{
	return m_orig_range;
}

} // close namespace dclass
<commit_msg>dclass: Fix NumericType->has_modulus()<commit_after>// Filename: NumericType.ipp
namespace dclass   // open namespace
{

// get_divisor returns the divisor of the numeric, with a default value of one.
inline unsigned int NumericType::get_divisor() const
{
	return m_divisor;
}

// has_modulus returns true if the numeric is constrained by a modulus.
inline bool NumericType::has_modulus() const
{
	return m_orig_modulus != 0.0;
}

// get_modulus returns a double representation of the modulus value.
inline double NumericType::get_modulus() const
{
	return m_orig_modulus;
}

// has_range returns true if the numeric is constrained by a range.
inline bool NumericType::has_range() const
{
	return !m_orig_range.is_empty();
}
// get_range returns the NumericRange that constrains the type's values.
inline NumericRange NumericType::get_range() const
{
	return m_orig_range;
}

} // close namespace dclass
<|endoftext|>


<commit_before>/* Logger.hpp
 *
 * Kubo Ryosuke
 */

#ifndef SUNFISH_LOGGER_LOGGER_HPP__
#define SUNFISH_LOGGER_LOGGER_HPP__

#include <iostream>
#include <vector>
#include <ctime>
#include <mutex>
#include <memory>
#include <utility>

#define __FILE_LINE__ (__FILE__ ":" __L2STR(__LINE__))
#define __L2STR(l) L2STR__(l)
#define L2STR__(l) #l

namespace sunfish {

class LoggerUtil {
private:

  LoggerUtil();

public:

  static const char* getIso8601();

};

class Logger {
public:
  class SubLogger {
  private:
    struct Data {
      Logger* plogger;
      std::lock_guard<std::mutex> lock;
      Data(Logger* plogger, std::mutex& mutex) : plogger(plogger), lock(mutex) {
      }
      ~Data() {
        plogger->printNoLock("\n");
      }
    };
    std::shared_ptr<Data> data;

  public:
    SubLogger(const SubLogger& org) = default;
    SubLogger(Logger* plogger, std::mutex& mutex) {
      data = std::make_shared<Data>(plogger, mutex);
    }
    template <class T>
    SubLogger& operator<<(T&& t) {
      data->plogger->printNoLock(std::forward<T>(t));
      return *this;
    }
  };

private:
  struct Stream {
    std::ostream* pout;
    bool timestamp;
    bool loggerName;
    const char* before;
    const char* after;
  };

  static std::mutex mutex_;
  const char* name_;
  std::vector<Stream> os_;

public:
  Logger(const char* name = nullptr) : name_(name) {
  }
  Logger(const Logger& logger) = delete;
  Logger(Logger&& logger) = delete;

  void addStream(std::ostream& o, bool timestamp, bool loggerName,
      const char* before, const char* after) {
    Stream s = { &o, timestamp, loggerName, before, after };
    os_.push_back(s);
  }
  void addStream(std::ostream& o, bool timestamp, bool loggerName) {
    addStream(o, timestamp, loggerName, nullptr, nullptr);
  }
  void addStream(std::ostream& o, const char* before, const char* after) {
    addStream(o, false, false, before, after);
  }
  void addStream(std::ostream& o) {
    addStream(o, false, false, nullptr, nullptr);
  }

  template <class T> void printNoLock(T&& t, bool top = false) {
    std::vector<Stream>::iterator it;
    for (it = os_.begin(); it != os_.end(); it++) {
      if (it->before != nullptr) {
        *(it->pout) << it->before;
      }
      if (top) {
        if (it->timestamp) {
          *(it->pout) << LoggerUtil::getIso8601();
        }
        if (it->loggerName && name_) {
          *(it->pout) << name_ << ' ';
        }
      }
      *(it->pout) << std::forward<T>(t);
      if (it->after != nullptr) {
        *(it->pout) << it->after;
      }
      it->pout->flush();
    }
  }

  template <class T> void print(T&& t) {
    std::lock_guard<std::mutex> lock(mutex_);
    printNoLock(std::forward<T>(t));
  }

  template <class T>
  SubLogger operator<<(T&& t) {
    SubLogger s(this, mutex_);
    printNoLock(std::forward<T>(t), true);
    return s;
  }

};

class Loggers {
public:
  static Logger error;
  static Logger warning;
  static Logger message;
  static Logger send;
  static Logger receive;
#ifndef NDEBUG
  static Logger debug;
  static Logger test;
  static Logger develop;
#endif //NDEBUG
};

} // namespace sunfish

#endif // SUNFISH_LOGGER_LOGGER_HPP__
<commit_msg>Fix Logger<commit_after>/* Logger.hpp
 *
 * Kubo Ryosuke
 */

#ifndef SUNFISH_LOGGER_LOGGER_HPP__
#define SUNFISH_LOGGER_LOGGER_HPP__

#include <iostream>
#include <vector>
#include <ctime>
#include <mutex>
#include <memory>
#include <utility>

#define __FILE_LINE__ (__FILE__ ":" __L2STR(__LINE__))
#define __L2STR(l) L2STR__(l)
#define L2STR__(l) #l

namespace sunfish {

class LoggerUtil {
private:

  LoggerUtil();

public:

  static const char* getIso8601();

};

class Logger {
private:

  struct Stream {
    std::ostream* pout;
    bool timestamp;
    bool loggerName;
    const char* before;
    const char* after;
  };

  enum class LineState {
    Top,
    Normal,
    End,
    All,
  };

  static std::mutex mutex_;
  const char* name_;
  std::vector<Stream> os_;

public:

  class SubLogger {
  private:
    struct Data {
      Logger* plogger;
      std::lock_guard<std::mutex> lock;
      Data(Logger* plogger, std::mutex& mutex) : plogger(plogger), lock(mutex) {
      }
      ~Data() {
        plogger->printNoLock<LineState::End>("");
      }
    };
    std::shared_ptr<Data> data;

  public:
    SubLogger(const SubLogger& org) = default;
    SubLogger(Logger* plogger, std::mutex& mutex) {
      data = std::make_shared<Data>(plogger, mutex);
    }
    template <class T>
    SubLogger& operator<<(T&& t) {
      data->plogger->printNoLock<LineState::Normal>(std::forward<T>(t));
      return *this;
    }
  };

public:

  Logger(const char* name = nullptr) : name_(name) {
  }
  Logger(const Logger& logger) = delete;
  Logger(Logger&& logger) = delete;

  void addStream(std::ostream& o, bool timestamp, bool loggerName,
      const char* before, const char* after) {
    Stream s = { &o, timestamp, loggerName, before, after };
    os_.push_back(s);
  }
  void addStream(std::ostream& o, bool timestamp, bool loggerName) {
    addStream(o, timestamp, loggerName, nullptr, nullptr);
  }
  void addStream(std::ostream& o, const char* before, const char* after) {
    addStream(o, false, false, before, after);
  }
  void addStream(std::ostream& o) {
    addStream(o, false, false, nullptr, nullptr);
  }

  template <class T> void print(T&& t) {
    std::lock_guard<std::mutex> lock(mutex_);
    printNoLock<LineState::All>(std::forward<T>(t));
  }

  template <class T>
  SubLogger operator<<(T&& t) {
    SubLogger s(this, mutex_);
    printNoLock<LineState::Top>(std::forward<T>(t));
    return s;
  }

private:

  template <LineState ls, class T>
  void printNoLock(T&& t) {
    std::vector<Stream>::iterator it;
    for (it = os_.begin(); it != os_.end(); it++) {
      if (ls == LineState::Top || ls == LineState::All) {
        // prefix
        if (it->before != nullptr) {
          *(it->pout) << it->before;
        }

        // timestamp
        if (it->timestamp) {
          *(it->pout) << LoggerUtil::getIso8601();
        }

        // logger name
        if (it->loggerName && name_) {
          *(it->pout) << name_ << ' ';
        }
      }

      // main data
      *(it->pout) << std::forward<T>(t);

      if (ls == LineState::End || ls == LineState::All) {
        // suffix
        if (it->after != nullptr) {
          *(it->pout) << it->after;
        }

        // flush
        *(it->pout) << '\n';
        it->pout->flush();
      }
    }
  }

};

class Loggers {
public:
  static Logger error;
  static Logger warning;
  static Logger message;
  static Logger send;
  static Logger receive;
#ifndef NDEBUG
  static Logger debug;
  static Logger test;
  static Logger develop;
#endif //NDEBUG
};

} // namespace sunfish

#endif // SUNFISH_LOGGER_LOGGER_HPP__
<|endoftext|>


<commit_before>/*
Copyright (c) 2016 Bastien Durix

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.
*/

/**
 *  \brief 3D environment test
 *  \author Bastien Durix
 */

#include <mathtools/application/Bspline.h>
#include <skeleton/Skeletons.h>
#include <boundary/DiscreteBoundary3.h>

#include <algorithm/skinning/ContinuousSkinning.h>

#include <display3d/DisplayClass.h>
#include <display3d/DisplayFrame.h>
#include <display3d/DisplaySkeleton.h>
#include <display3d/DisplayBoundary.h>

int main()
{
	unsigned int degree = 3;
	unsigned int nbctrlpt = 4;
	Eigen::Matrix<double,1,Eigen::Dynamic> nodevec(1,nbctrlpt + degree - 1);
	nodevec << 0.0, 0.0, 0.0, 1.0, 1.0, 1.0;
	Eigen::Matrix<double,4,Eigen::Dynamic> ctrlpt(4,nbctrlpt);
	ctrlpt << 0.0, 1.0, 1.0, 0.0,
			  0.0, 2.0, 1.0, 0.0,
			  0.0, 2.0, 2.0, 1.0,
			  0.1, 0.2, 0.2, 0.1;
	mathtools::application::Application<Eigen::Vector4d,double>::Ptr bspline(new mathtools::application::Bspline<4>(ctrlpt,nodevec,degree));
	skeleton::BranchContSkel3d::Ptr contbr(
			new skeleton::BranchContSkel3d(
					skeleton::model::Classic<3>::Ptr(new skeleton::model::Classic<3>()),
					bspline));

	boundary::DiscreteBoundary<3>::Ptr bnd = algorithm::skinning::ContinuousSkinning(contbr);

	display3d::DisplayClass disclass("Test SFML");

	display3d::DisplayFrame(disclass,mathtools::affine::Frame<3>::CanonicFrame());
	display3d::DisplayBranch(disclass,contbr);
	display3d::DisplayBoundary_Wired(disclass,bnd);

	disclass.enableCtrl();

	while(disclass.isCtrlEnabled())
	{
		disclass.manageKeyboard();
		disclass.display();
	}

	return 0;
}
<commit_msg>Modified displayed canal surface to remove the auto intersections<commit_after>/*
Copyright (c) 2016 Bastien Durix

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.
*/

/**
 *  \brief 3D environment test
 *  \author Bastien Durix
 */

#include <mathtools/application/Bspline.h>
#include <skeleton/Skeletons.h>
#include <boundary/DiscreteBoundary3.h>

#include <algorithm/skinning/ContinuousSkinning.h>

#include <display3d/DisplayClass.h>
#include <display3d/DisplayFrame.h>
#include <display3d/DisplaySkeleton.h>
#include <display3d/DisplayBoundary.h>

int main()
{
	unsigned int degree = 3;
	unsigned int nbctrlpt = 4;
	Eigen::Matrix<double,1,Eigen::Dynamic> nodevec(1,nbctrlpt + degree - 1);
	nodevec << 0.0, 0.0, 0.0, 1.0, 1.0, 1.0;
	Eigen::Matrix<double,4,Eigen::Dynamic> ctrlpt(4,nbctrlpt);
	ctrlpt << 0.0, 1.0, 3.0, 0.0,
			  0.0, 3.0, 1.0, 0.0,
			  0.0, 2.0, 2.0, 1.0,
			  0.1, 0.2, 0.2, 0.1;
	mathtools::application::Application<Eigen::Vector4d,double>::Ptr bspline(new mathtools::application::Bspline<4>(ctrlpt,nodevec,degree));
	skeleton::BranchContSkel3d::Ptr contbr(
			new skeleton::BranchContSkel3d(
					skeleton::model::Classic<3>::Ptr(new skeleton::model::Classic<3>()),
					bspline));

	boundary::DiscreteBoundary<3>::Ptr bnd = algorithm::skinning::ContinuousSkinning(contbr->reverted()->reverted(),algorithm::skinning::OptionsContSkinning(60));

	display3d::DisplayClass disclass("Test SFML");

	display3d::DisplayFrame(disclass,mathtools::affine::Frame<3>::CanonicFrame());
	display3d::DisplayBranch(disclass,contbr);
	display3d::DisplayBoundary_Wired(disclass,bnd);

	disclass.enableCtrl();

	while(disclass.isCtrlEnabled())
	{
		disclass.manageKeyboard();
		disclass.display();
	}

	return 0;
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2013, 2014 Jolla Ltd.
** Contact: Jonni Rainisto <jonni.rainisto@jollamobile.com>
**
** This file is part of lipstick.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QCoreApplication>
#include <QSettings>
#include <QProcess>
#include <QTimer>
#include <QDebug>
#include "devicelock.h"
#include <sys/time.h>
#include <QDBusConnection>
#include <QFile>
#include <QFileInfo>
#include <QDBusMessage>
#include <QDBusConnectionInterface>
#include "homeapplication.h"

namespace {
const char * const settingsFile = "/usr/share/lipstick/devicelock/devicelock_settings.conf";
const char * const lockingKey = "/desktop/nemo/devicelock/automatic_locking";
}
/* ------------------------------------------------------------------------- *
 * struct timeval helpers
 * ------------------------------------------------------------------------- */
static void tv_get_monotime(struct timeval *tv)
{
#if defined(CLOCK_BOOTTIME)
  struct timespec ts;
  if (clock_gettime(CLOCK_BOOTTIME, &ts) < 0)
      if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0)
          qFatal("Can't clock_gettime!");
  TIMESPEC_TO_TIMEVAL(tv, &ts);
#endif
}

static int tv_diff_in_s(const struct timeval *tv1, const struct timeval *tv2)
{
    struct timeval tv;
    timersub(tv1, tv2, &tv);
    return tv.tv_sec;
}

DeviceLock::DeviceLock(QObject * parent) :
    QObject(parent),
    QDBusContext(),
    lockingDelay(-1),
    lockTimer(new QTimer(this)),
    qmActivity(new MeeGo::QmActivity(this)),
    qmLocks(new MeeGo::QmLocks(this)),
    qmDisplayState(new MeeGo::QmDisplayState(this)),
    deviceLockState(Undefined),
    isCallActive(false)
{
    monoTime.tv_sec = 0;
    connect(lockTimer, SIGNAL(timeout()), this, SLOT(lock()));
    connect(qmActivity, SIGNAL(activityChanged(MeeGo::QmActivity::Activity)), this, SLOT(setStateAndSetupLockTimer()));
    connect(qmLocks, SIGNAL(stateChanged(MeeGo::QmLocks::Lock,MeeGo::QmLocks::State)), this, SLOT(setStateAndSetupLockTimer()));
    connect(qmDisplayState, SIGNAL(displayStateChanged(MeeGo::QmDisplayState::DisplayState)), this, SLOT(checkDisplayState(MeeGo::QmDisplayState::DisplayState)));
    connect(static_cast<HomeApplication *>(qApp), &HomeApplication::homeReady, this, &DeviceLock::init);

    QDBusConnection::systemBus().connect(QString(), "/com/nokia/mce/signal", "com.nokia.mce.signal", "sig_call_state_ind", this, SLOT(handleCallStateChange(QString, QString)));
}

void DeviceLock::handleCallStateChange(const QString &state, const QString &ignored)
{
    Q_UNUSED(ignored);
    if (state.contains("active")) {
        isCallActive = true;
    } else {
        isCallActive = false;
    }
}

void DeviceLock::init()
{
    if (QFile(settingsFile).exists() && watcher.addPath(settingsFile)) {
        readSettings();
        connect(&watcher, SIGNAL(fileChanged(QString)), this, SLOT(readSettings()));
    }

    setState(isSet() && lockingDelay >= 0 ? Locked : Unlocked);
}

void DeviceLock::setupLockTimer()
{
    if (deviceLockState == Locked) {
        // Device already locked: stop the timer
        lockTimer->stop();
        monoTime.tv_sec = 0;
    } else {
        if (lockingDelay <= 0 || (qmActivity->get() == MeeGo::QmActivity::Active && qmDisplayState->get() != MeeGo::QmDisplayState::DisplayState::Off)) {
            // Locking disabled or device active: stop the timer
            lockTimer->stop();
            monoTime.tv_sec = 0;
        } else if (!isCallActive && !monoTime.tv_sec) {
            // Locking in N minutes enabled and device inactive: start the timer
            lockTimer->start(lockingDelay * 60 * 1000);
            tv_get_monotime(&monoTime);
        }
    }
}

void DeviceLock::setStateAndSetupLockTimer()
{
    if (lockingDelay < 0) {
        // Locking disabled: unlock
        setState(Unlocked);
    }
    setupLockTimer();
}

void DeviceLock::checkDisplayState(MeeGo::QmDisplayState::DisplayState state)
{
    if (lockingDelay == 0 && state == MeeGo::QmDisplayState::DisplayState::Off
            && !isCallActive) {
        // Immediate locking enabled and the display is off and not in call: lock
        setState(Locked);
    } else if (state == MeeGo::QmDisplayState::DisplayState::Off) {
        setStateAndSetupLockTimer();
    } else if (monoTime.tv_sec && lockingDelay > 0) {
        struct timeval compareTime;
        tv_get_monotime(&compareTime);
        if (lockingDelay*60 < tv_diff_in_s(&compareTime, &monoTime)) {
            setState(Locked);
        }
        setupLockTimer();
    }
}

void DeviceLock::lock()
{
    setState(Locked);
}

int DeviceLock::state() const
{
    return deviceLockState;
}

void DeviceLock::setState(int state)
{
    if (deviceLockState != (LockState)state) {
        if (state == Locked || isPrivileged()) {
            deviceLockState = (LockState)state;
            emit stateChanged(state);

            setupLockTimer();
        } else {
            sendErrorReply(QDBusError::AccessDenied, QString("Caller is not in privileged group"));
        }
    }
}

bool DeviceLock::checkCode(const QString &code)
{
    return runPlugin(QStringList() << "--check-code" << code);
}

bool DeviceLock::setCode(const QString &oldCode, const QString &newCode)
{
    return runPlugin(QStringList() << "--set-code" << oldCode << newCode);
}

bool DeviceLock::isSet() {
    return runPlugin(QStringList() << "--is-set" << "lockcode");
}

bool DeviceLock::runPlugin(const QStringList &args)
{
    QSettings settings("/usr/share/lipstick/devicelock/devicelock.conf", QSettings::IniFormat);
    QString pluginName = settings.value("DeviceLock/pluginName").toString();

    if (pluginName.isEmpty()) {
        qWarning("No plugin configuration set in /usr/share/lipstick/devicelock/devicelock.conf");
        return false;
    }

    QProcess process;
    process.start(pluginName, args);
    if (!process.waitForFinished()) {
        qWarning("Plugin did not finish in time");
        return false;
    }

#ifdef DEBUG_DEVICELOCK
    qDebug() << process.readAllStandardOutput();
    qWarning() << process.readAllStandardError();
#endif

    return process.exitCode() == 0;
}

void DeviceLock::readSettings()
{
    QSettings settings(settingsFile, QSettings::IniFormat);
    lockingDelay = settings.value(lockingKey, "-1").toInt();
    if (deviceLockState != Undefined) {
        setStateAndSetupLockTimer();
    }
}

bool DeviceLock::isPrivileged()
{
    pid_t pid = -1;
    if (!calledFromDBus()) {
        // Local function calls are always privileged
        return true;
    }
    // Get the PID of the calling process
    pid = connection().interface()->servicePid(message().service());
    // The /proc/<pid> directory is owned by EUID:EGID of the process
    QFileInfo info(QString("/proc/%1").arg(pid));
    if (info.group() != "privileged" && info.group() != "disk" && info.owner() != "root") {
        return false;
    }
    return true;
}
<commit_msg>[lipstick] don't unlock before init() has been called<commit_after>/***************************************************************************
**
** Copyright (C) 2013, 2014 Jolla Ltd.
** Contact: Jonni Rainisto <jonni.rainisto@jollamobile.com>
**
** This file is part of lipstick.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QCoreApplication>
#include <QSettings>
#include <QProcess>
#include <QTimer>
#include <QDebug>
#include "devicelock.h"
#include <sys/time.h>
#include <QDBusConnection>
#include <QFile>
#include <QFileInfo>
#include <QDBusMessage>
#include <QDBusConnectionInterface>
#include "homeapplication.h"

namespace {
const char * const settingsFile = "/usr/share/lipstick/devicelock/devicelock_settings.conf";
const char * const lockingKey = "/desktop/nemo/devicelock/automatic_locking";
}
/* ------------------------------------------------------------------------- *
 * struct timeval helpers
 * ------------------------------------------------------------------------- */
static void tv_get_monotime(struct timeval *tv)
{
#if defined(CLOCK_BOOTTIME)
  struct timespec ts;
  if (clock_gettime(CLOCK_BOOTTIME, &ts) < 0)
      if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0)
          qFatal("Can't clock_gettime!");
  TIMESPEC_TO_TIMEVAL(tv, &ts);
#endif
}

static int tv_diff_in_s(const struct timeval *tv1, const struct timeval *tv2)
{
    struct timeval tv;
    timersub(tv1, tv2, &tv);
    return tv.tv_sec;
}

DeviceLock::DeviceLock(QObject * parent) :
    QObject(parent),
    QDBusContext(),
    lockingDelay(-1),
    lockTimer(new QTimer(this)),
    qmActivity(new MeeGo::QmActivity(this)),
    qmLocks(new MeeGo::QmLocks(this)),
    qmDisplayState(new MeeGo::QmDisplayState(this)),
    deviceLockState(Undefined),
    isCallActive(false)
{
    monoTime.tv_sec = 0;
    connect(lockTimer, SIGNAL(timeout()), this, SLOT(lock()));
    connect(qmActivity, SIGNAL(activityChanged(MeeGo::QmActivity::Activity)), this, SLOT(setStateAndSetupLockTimer()));
    connect(qmLocks, SIGNAL(stateChanged(MeeGo::QmLocks::Lock,MeeGo::QmLocks::State)), this, SLOT(setStateAndSetupLockTimer()));
    connect(qmDisplayState, SIGNAL(displayStateChanged(MeeGo::QmDisplayState::DisplayState)), this, SLOT(checkDisplayState(MeeGo::QmDisplayState::DisplayState)));
    connect(static_cast<HomeApplication *>(qApp), &HomeApplication::homeReady, this, &DeviceLock::init);

    QDBusConnection::systemBus().connect(QString(), "/com/nokia/mce/signal", "com.nokia.mce.signal", "sig_call_state_ind", this, SLOT(handleCallStateChange(QString, QString)));
}

void DeviceLock::handleCallStateChange(const QString &state, const QString &ignored)
{
    Q_UNUSED(ignored);
    if (state.contains("active")) {
        isCallActive = true;
    } else {
        isCallActive = false;
    }
}

void DeviceLock::init()
{
    if (QFile(settingsFile).exists() && watcher.addPath(settingsFile)) {
        readSettings();
        connect(&watcher, SIGNAL(fileChanged(QString)), this, SLOT(readSettings()));
    }

    setState(isSet() && lockingDelay >= 0 ? Locked : Unlocked);
}

void DeviceLock::setupLockTimer()
{
    if (deviceLockState == Locked) {
        // Device already locked: stop the timer
        lockTimer->stop();
        monoTime.tv_sec = 0;
    } else {
        if (lockingDelay <= 0 || (qmActivity->get() == MeeGo::QmActivity::Active && qmDisplayState->get() != MeeGo::QmDisplayState::DisplayState::Off)) {
            // Locking disabled or device active: stop the timer
            lockTimer->stop();
            monoTime.tv_sec = 0;
        } else if (!isCallActive && !monoTime.tv_sec) {
            // Locking in N minutes enabled and device inactive: start the timer
            lockTimer->start(lockingDelay * 60 * 1000);
            tv_get_monotime(&monoTime);
        }
    }
}

void DeviceLock::setStateAndSetupLockTimer()
{
    if (lockingDelay < 0 && deviceLockState != Undefined) {
        // Locking disabled: unlock
        setState(Unlocked);
    }
    setupLockTimer();
}

void DeviceLock::checkDisplayState(MeeGo::QmDisplayState::DisplayState state)
{
    if (lockingDelay == 0 && state == MeeGo::QmDisplayState::DisplayState::Off
            && !isCallActive) {
        // Immediate locking enabled and the display is off and not in call: lock
        setState(Locked);
    } else if (state == MeeGo::QmDisplayState::DisplayState::Off) {
        setStateAndSetupLockTimer();
    } else if (monoTime.tv_sec && lockingDelay > 0) {
        struct timeval compareTime;
        tv_get_monotime(&compareTime);
        if (lockingDelay*60 < tv_diff_in_s(&compareTime, &monoTime)) {
            setState(Locked);
        }
        setupLockTimer();
    }
}

void DeviceLock::lock()
{
    setState(Locked);
}

int DeviceLock::state() const
{
    return deviceLockState;
}

void DeviceLock::setState(int state)
{
    if (deviceLockState != (LockState)state) {
        if (state == Locked || isPrivileged()) {
            deviceLockState = (LockState)state;
            emit stateChanged(state);

            setupLockTimer();
        } else {
            sendErrorReply(QDBusError::AccessDenied, QString("Caller is not in privileged group"));
        }
    }
}

bool DeviceLock::checkCode(const QString &code)
{
    return runPlugin(QStringList() << "--check-code" << code);
}

bool DeviceLock::setCode(const QString &oldCode, const QString &newCode)
{
    return runPlugin(QStringList() << "--set-code" << oldCode << newCode);
}

bool DeviceLock::isSet() {
    return runPlugin(QStringList() << "--is-set" << "lockcode");
}

bool DeviceLock::runPlugin(const QStringList &args)
{
    QSettings settings("/usr/share/lipstick/devicelock/devicelock.conf", QSettings::IniFormat);
    QString pluginName = settings.value("DeviceLock/pluginName").toString();

    if (pluginName.isEmpty()) {
        qWarning("No plugin configuration set in /usr/share/lipstick/devicelock/devicelock.conf");
        return false;
    }

    QProcess process;
    process.start(pluginName, args);
    if (!process.waitForFinished()) {
        qWarning("Plugin did not finish in time");
        return false;
    }

#ifdef DEBUG_DEVICELOCK
    qDebug() << process.readAllStandardOutput();
    qWarning() << process.readAllStandardError();
#endif

    return process.exitCode() == 0;
}

void DeviceLock::readSettings()
{
    QSettings settings(settingsFile, QSettings::IniFormat);
    lockingDelay = settings.value(lockingKey, "-1").toInt();
    if (deviceLockState != Undefined) {
        setStateAndSetupLockTimer();
    }
}

bool DeviceLock::isPrivileged()
{
    pid_t pid = -1;
    if (!calledFromDBus()) {
        // Local function calls are always privileged
        return true;
    }
    // Get the PID of the calling process
    pid = connection().interface()->servicePid(message().service());
    // The /proc/<pid> directory is owned by EUID:EGID of the process
    QFileInfo info(QString("/proc/%1").arg(pid));
    if (info.group() != "privileged" && info.group() != "disk" && info.owner() != "root") {
        return false;
    }
    return true;
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2010 Juergen Riegel <FreeCAD@juergen-riegel.net>        *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 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 Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRep_Builder.hxx>
# include <BRepBndLib.hxx>
# include <BRepPrimAPI_MakeRevol.hxx>
# include <BRepBuilderAPI_MakeFace.hxx>
# include <TopoDS.hxx>
# include <TopoDS_Face.hxx>
# include <TopoDS_Wire.hxx>
# include <TopExp_Explorer.hxx>
# include <BRepAlgoAPI_Fuse.hxx>
# include <Precision.hxx>
# include <gp_Lin.hxx>
#endif

#include <Base/Axis.h>
#include <Base/Exception.h>
#include <Base/Placement.h>
#include <Base/Tools.h>

#include "FeatureRevolution.h"

using namespace PartDesign;

namespace PartDesign {

PROPERTY_SOURCE(PartDesign::Revolution, PartDesign::ProfileBased)

Revolution::Revolution()
{
    addSubType = FeatureAddSub::Additive;

    ADD_PROPERTY_TYPE(Base,(Base::Vector3d(0.0,0.0,0.0)),"Revolution", App::Prop_ReadOnly, "Base");
    ADD_PROPERTY_TYPE(Axis,(Base::Vector3d(0.0,1.0,0.0)),"Revolution", App::Prop_ReadOnly, "Axis");
    ADD_PROPERTY_TYPE(Angle,(360.0),"Revolution", App::Prop_None, "Angle");
    ADD_PROPERTY_TYPE(ReferenceAxis,(0),"Revolution",(App::Prop_None),"Reference axis of revolution");
}

short Revolution::mustExecute() const
{
    if (Placement.isTouched() ||
        ReferenceAxis.isTouched() ||
        Axis.isTouched() ||
        Base.isTouched() ||
        Angle.isTouched())
        return 1;
    return ProfileBased::mustExecute();
}

App::DocumentObjectExecReturn *Revolution::execute(void)
{
    // Validate parameters
    double angle = Angle.getValue();
    if (angle < Precision::Confusion())
        return new App::DocumentObjectExecReturn("Angle of revolution too small");
    if (angle > 360.0)
        return new App::DocumentObjectExecReturn("Angle of revolution too large");

    angle = Base::toRadians<double>(angle);
    // Reverse angle if selected
    if (Reversed.getValue() && !Midplane.getValue())
        angle *= (-1.0);

    TopoDS_Shape sketchshape;
    try {
        sketchshape = getVerifiedFace();
    } catch (const Base::Exception& e) {
        return new App::DocumentObjectExecReturn(e.what());
    }

    // if the Base property has a valid shape, fuse the AddShape into it
    TopoDS_Shape base;
    try {
        base = getBaseShape();
    } catch (const Base::Exception&) {
        // fall back to support (for legacy features)
        base = TopoDS_Shape();
    }

    // update Axis from ReferenceAxis
    try {
        updateAxis();
    } catch (const Base::Exception& e) {
        return new App::DocumentObjectExecReturn(e.what());
    }

    // get revolve axis
    Base::Vector3d b = Base.getValue();
    gp_Pnt pnt(b.x,b.y,b.z);
    Base::Vector3d v = Axis.getValue();
    gp_Dir dir(v.x,v.y,v.z);

    try {
        if (sketchshape.IsNull())
            return new App::DocumentObjectExecReturn("Creating a face from sketch failed");

        // Rotate the face by half the angle to get Revolution symmetric to sketch plane
        if (Midplane.getValue()) {
            gp_Trsf mov;
            mov.SetRotation(gp_Ax1(pnt, dir), Base::toRadians<double>(Angle.getValue()) * (-1.0) / 2.0);
            TopLoc_Location loc(mov);
            sketchshape.Move(loc);
        }

        this->positionByPrevious();
        TopLoc_Location invObjLoc = this->getLocation().Inverted();
        pnt.Transform(invObjLoc.Transformation());
        dir.Transform(invObjLoc.Transformation());
        base.Move(invObjLoc);
        sketchshape.Move(invObjLoc);

        // Check distance between sketchshape and axis - to avoid failures and crashes
        TopExp_Explorer xp;
        xp.Init(sketchshape, TopAbs_FACE);
        for (;xp.More(); xp.Next()) {
            if (checkLineCrossesFace(gp_Lin(pnt, dir), TopoDS::Face(xp.Current())))
                return new App::DocumentObjectExecReturn("Revolve axis intersects the sketch");
        }

        // revolve the face to a solid
        BRepPrimAPI_MakeRevol RevolMaker(sketchshape, gp_Ax1(pnt, dir), angle);

        if (RevolMaker.IsDone()) {
            TopoDS_Shape result = RevolMaker.Shape();
            result = refineShapeIfActive(result);
            // set the additive shape property for later usage in e.g. pattern
            this->AddSubShape.setValue(result);

            if (!base.IsNull()) {
                // Let's call algorithm computing a fuse operation:
                BRepAlgoAPI_Fuse mkFuse(base, result);
                // Let's check if the fusion has been successful
                if (!mkFuse.IsDone())
                    throw Base::Exception("Fusion with base feature failed");
                result = mkFuse.Shape();
                result = refineShapeIfActive(result);
            }

            this->Shape.setValue(getSolid(result));
        }
        else
            return new App::DocumentObjectExecReturn("Could not revolve the sketch!");

        return App::DocumentObject::StdReturn;
    }
    catch (Standard_Failure) {
        Handle(Standard_Failure) e = Standard_Failure::Caught();
        if (std::string(e->GetMessageString()) == "TopoDS::Face")
            return new App::DocumentObjectExecReturn("Could not create face from sketch.\n"
                "Intersecting sketch entities in a sketch are not allowed.");
        else
            return new App::DocumentObjectExecReturn(e->GetMessageString());
    }
    catch (Base::Exception& e) {
        return new App::DocumentObjectExecReturn(e.what());
    }
}

bool Revolution::suggestReversed(void)
{
    try {
        updateAxis();
    } catch (const Base::Exception& e) {
        return new App::DocumentObjectExecReturn(e.what());
    }

    return ProfileBased::getReversedAngle(Base.getValue(), Axis.getValue()) < 0.0;
}

void Revolution::updateAxis(void)
{
    App::DocumentObject *pcReferenceAxis = ReferenceAxis.getValue();
    const std::vector<std::string> &subReferenceAxis = ReferenceAxis.getSubValues();
    Base::Vector3d base;
    Base::Vector3d dir;
    getAxis(pcReferenceAxis, subReferenceAxis, base, dir);

    Base.setValue(base.x,base.y,base.z);
    Axis.setValue(dir.x,dir.y,dir.z);
}

}
<commit_msg>Fix return type<commit_after>/***************************************************************************
 *   Copyright (c) 2010 Juergen Riegel <FreeCAD@juergen-riegel.net>        *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 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 Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRep_Builder.hxx>
# include <BRepBndLib.hxx>
# include <BRepPrimAPI_MakeRevol.hxx>
# include <BRepBuilderAPI_MakeFace.hxx>
# include <TopoDS.hxx>
# include <TopoDS_Face.hxx>
# include <TopoDS_Wire.hxx>
# include <TopExp_Explorer.hxx>
# include <BRepAlgoAPI_Fuse.hxx>
# include <Precision.hxx>
# include <gp_Lin.hxx>
#endif

#include <Base/Axis.h>
#include <Base/Console.h>
#include <Base/Exception.h>
#include <Base/Placement.h>
#include <Base/Tools.h>

#include "FeatureRevolution.h"

using namespace PartDesign;

namespace PartDesign {

PROPERTY_SOURCE(PartDesign::Revolution, PartDesign::ProfileBased)

Revolution::Revolution()
{
    addSubType = FeatureAddSub::Additive;

    ADD_PROPERTY_TYPE(Base,(Base::Vector3d(0.0,0.0,0.0)),"Revolution", App::Prop_ReadOnly, "Base");
    ADD_PROPERTY_TYPE(Axis,(Base::Vector3d(0.0,1.0,0.0)),"Revolution", App::Prop_ReadOnly, "Axis");
    ADD_PROPERTY_TYPE(Angle,(360.0),"Revolution", App::Prop_None, "Angle");
    ADD_PROPERTY_TYPE(ReferenceAxis,(0),"Revolution",(App::Prop_None),"Reference axis of revolution");
}

short Revolution::mustExecute() const
{
    if (Placement.isTouched() ||
        ReferenceAxis.isTouched() ||
        Axis.isTouched() ||
        Base.isTouched() ||
        Angle.isTouched())
        return 1;
    return ProfileBased::mustExecute();
}

App::DocumentObjectExecReturn *Revolution::execute(void)
{
    // Validate parameters
    double angle = Angle.getValue();
    if (angle < Precision::Confusion())
        return new App::DocumentObjectExecReturn("Angle of revolution too small");
    if (angle > 360.0)
        return new App::DocumentObjectExecReturn("Angle of revolution too large");

    angle = Base::toRadians<double>(angle);
    // Reverse angle if selected
    if (Reversed.getValue() && !Midplane.getValue())
        angle *= (-1.0);

    TopoDS_Shape sketchshape;
    try {
        sketchshape = getVerifiedFace();
    } catch (const Base::Exception& e) {
        return new App::DocumentObjectExecReturn(e.what());
    }

    // if the Base property has a valid shape, fuse the AddShape into it
    TopoDS_Shape base;
    try {
        base = getBaseShape();
    } catch (const Base::Exception&) {
        // fall back to support (for legacy features)
        base = TopoDS_Shape();
    }

    // update Axis from ReferenceAxis
    try {
        updateAxis();
    } catch (const Base::Exception& e) {
        return new App::DocumentObjectExecReturn(e.what());
    }

    // get revolve axis
    Base::Vector3d b = Base.getValue();
    gp_Pnt pnt(b.x,b.y,b.z);
    Base::Vector3d v = Axis.getValue();
    gp_Dir dir(v.x,v.y,v.z);

    try {
        if (sketchshape.IsNull())
            return new App::DocumentObjectExecReturn("Creating a face from sketch failed");

        // Rotate the face by half the angle to get Revolution symmetric to sketch plane
        if (Midplane.getValue()) {
            gp_Trsf mov;
            mov.SetRotation(gp_Ax1(pnt, dir), Base::toRadians<double>(Angle.getValue()) * (-1.0) / 2.0);
            TopLoc_Location loc(mov);
            sketchshape.Move(loc);
        }

        this->positionByPrevious();
        TopLoc_Location invObjLoc = this->getLocation().Inverted();
        pnt.Transform(invObjLoc.Transformation());
        dir.Transform(invObjLoc.Transformation());
        base.Move(invObjLoc);
        sketchshape.Move(invObjLoc);

        // Check distance between sketchshape and axis - to avoid failures and crashes
        TopExp_Explorer xp;
        xp.Init(sketchshape, TopAbs_FACE);
        for (;xp.More(); xp.Next()) {
            if (checkLineCrossesFace(gp_Lin(pnt, dir), TopoDS::Face(xp.Current())))
                return new App::DocumentObjectExecReturn("Revolve axis intersects the sketch");
        }

        // revolve the face to a solid
        BRepPrimAPI_MakeRevol RevolMaker(sketchshape, gp_Ax1(pnt, dir), angle);

        if (RevolMaker.IsDone()) {
            TopoDS_Shape result = RevolMaker.Shape();
            result = refineShapeIfActive(result);
            // set the additive shape property for later usage in e.g. pattern
            this->AddSubShape.setValue(result);

            if (!base.IsNull()) {
                // Let's call algorithm computing a fuse operation:
                BRepAlgoAPI_Fuse mkFuse(base, result);
                // Let's check if the fusion has been successful
                if (!mkFuse.IsDone())
                    throw Base::Exception("Fusion with base feature failed");
                result = mkFuse.Shape();
                result = refineShapeIfActive(result);
            }

            this->Shape.setValue(getSolid(result));
        }
        else
            return new App::DocumentObjectExecReturn("Could not revolve the sketch!");

        return App::DocumentObject::StdReturn;
    }
    catch (Standard_Failure) {
        Handle(Standard_Failure) e = Standard_Failure::Caught();
        if (std::string(e->GetMessageString()) == "TopoDS::Face")
            return new App::DocumentObjectExecReturn("Could not create face from sketch.\n"
                "Intersecting sketch entities in a sketch are not allowed.");
        else
            return new App::DocumentObjectExecReturn(e->GetMessageString());
    }
    catch (Base::Exception& e) {
        return new App::DocumentObjectExecReturn(e.what());
    }
}

bool Revolution::suggestReversed(void)
{
    try {
        updateAxis();
    } catch (const Base::Exception& e) {
        return false;
    }

    return ProfileBased::getReversedAngle(Base.getValue(), Axis.getValue()) < 0.0;
}

void Revolution::updateAxis(void)
{
    App::DocumentObject *pcReferenceAxis = ReferenceAxis.getValue();
    const std::vector<std::string> &subReferenceAxis = ReferenceAxis.getSubValues();
    Base::Vector3d base;
    Base::Vector3d dir;
    getAxis(pcReferenceAxis, subReferenceAxis, base, dir);

    Base.setValue(base.x,base.y,base.z);
    Axis.setValue(dir.x,dir.y,dir.z);
}

}
<|endoftext|>