<commit_before>// Copyright 2014-2015 Project Vogue. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <vector>

#include "base/logging.h"
#include "elang/lir/factory.h"
#include "elang/lir/instructions.h"
#include "elang/lir/instruction_visitor.h"
#include "elang/lir/literals.h"
#include "elang/lir/value.h"

#ifdef ELANG_TARGET_ARCH_X64
#include "elang/lir/instructions_x64.h"
#endif

namespace elang {
namespace lir {

base::StringPiece ToStringPiece(Opcode opcode) {
  static const char* const mnemonics[] = {
#define V(Name, mnemonic, ...) mnemonic,
      FOR_EACH_LIR_INSTRUCTION(V)
#undef V
          "Invalid",
  };
  return mnemonics[std::min(static_cast<size_t>(opcode),
                            arraysize(mnemonics) - 1)];
}

// Implement visitor pattern:
//  InstructionVIsitor::VisitXXX(XXXInstruction* instruction)
//  XXXInstruction::Accept(InstructionVisitor* visitor)
#define V(Name, ...)                                               \
  void InstructionVisitor::Visit##Name(Name##Instruction* instr) { \
    DoDefaultVisit(instr);                                         \
  }                                                                \
  void Name##Instruction::Accept(InstructionVisitor* visitor) {    \
    visitor->Visit##Name(this);                                    \
  }
FOR_EACH_LIR_INSTRUCTION(V)
#undef V

// Constructors
#define V(Name, ...) \
  Name##Instruction::Name##Instruction() {}
FOR_EACH_LIR_INSTRUCTION_0_0(V)
#undef V

#define V(Name, ...) \
  Name##Instruction::Name##Instruction(Value input) { InitInput(0, input); }
FOR_EACH_LIR_INSTRUCTION_0_1(V)
#undef V

#define V(Name, ...)                                              \
  Name##Instruction::Name##Instruction(Value left, Value right) { \
    InitInput(0, left);                                           \
    InitInput(1, right);                                          \
  }
FOR_EACH_LIR_INSTRUCTION_0_2(V)
#undef V

#define V(Name, ...)                                                \
  Name##Instruction::Name##Instruction(Value output, Value input) { \
    DCHECK(output.is_register());                                   \
    InitOutput(0, output);                                          \
    InitInput(0, input);                                            \
  }
FOR_EACH_LIR_INSTRUCTION_1_1(V)
#undef V

#define V(Name, ...)                                             \
  Name##Instruction::Name##Instruction(Value output, Value left, \
                                       Value right) {            \
    DCHECK(output.is_register());                                \
    InitOutput(0, output);                                       \
    InitInput(0, left);                                          \
    InitInput(1, right);                                         \
  }
FOR_EACH_LIR_INSTRUCTION_1_2(V)
#undef V

//////////////////////////////////////////////////////////////////////
//
// BasicBlockOperands::Iterator
//
BasicBlockOperands::Iterator::Iterator(const Iterator& other)
    : Iterator(other.pointer_) {
}

BasicBlockOperands::Iterator::Iterator(BasicBlock** pointer)
    : pointer_(pointer) {
}

BasicBlockOperands::Iterator::~Iterator() {
}

BasicBlockOperands::Iterator& BasicBlockOperands::Iterator::operator=(
    const Iterator& other) {
  pointer_ = other.pointer_;
  return *this;
}

BasicBlockOperands::Iterator& BasicBlockOperands::Iterator::operator++() {
  ++pointer_;
  return *this;
}

bool BasicBlockOperands::Iterator::operator==(const Iterator& other) const {
  return pointer_ == other.pointer_;
}

bool BasicBlockOperands::Iterator::operator!=(const Iterator& other) const {
  return !operator==(other);
}

//////////////////////////////////////////////////////////////////////
//
// BasicBlockOperands
//
BasicBlockOperands::BasicBlockOperands(const BasicBlockOperands& other)
    : BasicBlockOperands(other.start_, other.end_) {
}

BasicBlockOperands::BasicBlockOperands(BasicBlock** start, BasicBlock** end)
    : end_(end), start_(start) {
  DCHECK_LE(start_, end_);
}

BasicBlockOperands::BasicBlockOperands()
    : BasicBlockOperands(nullptr, nullptr) {
}

BasicBlockOperands::~BasicBlockOperands() {
}

BasicBlockOperands& BasicBlockOperands::operator=(
    const BasicBlockOperands& other) {
  end_ = other.end_;
  start_ = other.start_;
  return *this;
}

//////////////////////////////////////////////////////////////////////
//
// Instruction::Values
//
Instruction::Values::Values(const Values& other)
    : end_(other.end_), start_(other.start_) {
}

Instruction::Values::Values(Value* start, Value* end)
    : end_(end), start_(start) {
}

Instruction::Values::~Values() {
}

Instruction::Values& Instruction::Values::operator=(const Values& other) {
  end_ = other.end_;
  start_ = other.start_;
  return *this;
}

//////////////////////////////////////////////////////////////////////
//
// Instruction::Values::Iterator
//
Instruction::Values::Iterator::Iterator(const Iterator& other)
    : pointer_(other.pointer_) {
}

Instruction::Values::Iterator::Iterator(Value* pointer) : pointer_(pointer) {
}

Instruction::Values::Iterator::~Iterator() {
}

Instruction::Values::Iterator& Instruction::Values::Iterator::operator=(
    const Iterator& other) {
  pointer_ = other.pointer_;
  return *this;
}

bool Instruction::Values::Iterator::operator==(const Iterator& other) const {
  return pointer_ == other.pointer_;
}

bool Instruction::Values::Iterator::operator!=(const Iterator& other) const {
  return !operator==(other);
}

Instruction::Values::Iterator& Instruction::Values::Iterator::operator++() {
  ++pointer_;
  return *this;
}

//////////////////////////////////////////////////////////////////////
//
// Instruction
//
Instruction::Instruction() : basic_block_(nullptr), id_(0) {
}

BasicBlock* Instruction::block_operand(int index) const {
  auto const operands = block_operands();
  DCHECK_GE(index, 0);
  DCHECK_LT(index, operands.size());
  return operands.start_[index];
}

BasicBlockOperands Instruction::block_operands() const {
  return BasicBlockOperands();
}

Value Instruction::input(int index) const {
  DCHECK_GE(index, 0);
  DCHECK_LE(index, CountInputs());
  return InputValues()[index];
}

Instruction::Values Instruction::inputs() const {
  auto const start = InputValues();
  return Values(start, start + CountInputs());
}

base::StringPiece Instruction::mnemonic() const {
  return ToStringPiece(opcode());
}

Value Instruction::output(int index) const {
  DCHECK_GE(index, 0);
  DCHECK_LE(index, CountOutputs());
  return OutputValues()[index];
}

Instruction::Values Instruction::outputs() const {
  auto const start = OutputValues();
  return Values(start, start + CountOutputs());
}

void Instruction::InitInput(int index, Value new_input) {
  SetInput(index, new_input);
}

void Instruction::InitOutput(int index, Value new_output) {
  SetOutput(index, new_output);
}

void Instruction::SetBlockOperand(int index, BasicBlock* new_value) {
  auto const operands = block_operands();
  DCHECK_GE(index, 0);
  DCHECK_LT(index, operands.size());
  operands.start_[index] = new_value;
}

void Instruction::SetInput(int index, Value new_input) {
  DCHECK_GE(index, 0);
  DCHECK_LE(index, CountInputs());
  InputValues()[index] = new_input;
}

void Instruction::SetOutput(int index, Value new_output) {
  DCHECK_GE(index, 0);
  DCHECK_LE(index, CountOutputs());
  DCHECK(new_output.is_register());
  OutputValues()[index] = new_output;
}

bool Instruction::IsTerminator() const {
  return false;
}

// BranchInstruction
BranchInstruction::BranchInstruction(Value condition,
                                     BasicBlock* true_block,
                                     BasicBlock* false_block) {
  InitInput(0, condition);
  InitBlockOperand(0, true_block);
  InitBlockOperand(1, false_block);
}

// JumpInstruction
JumpInstruction::JumpInstruction(BasicBlock* target_block) {
  InitBlockOperand(0, target_block);
}

// PCopyInstruction
PCopyInstruction::PCopyInstruction(Zone* zone,
                                   const std::vector<Value>& outputs,
                                   const std::vector<Value>& inputs)
    : inputs_(zone, inputs), outputs_(zone, outputs) {
  DCHECK_EQ(inputs_.size(), outputs_.size());
#ifndef NDEBUG
  for (auto const output : outputs_)
    DCHECK(!output.is_read_only());
#endif
}

// PCopyInstruction Instruction operand protocol
int PCopyInstruction::CountInputs() const {
  return static_cast<int>(inputs_.size());
}

int PCopyInstruction::CountOutputs() const {
  return static_cast<int>(outputs_.size());
}

Value* PCopyInstruction::InputValues() const {
  return const_cast<PCopyInstruction*>(this)->inputs_.data();
}

Value* PCopyInstruction::OutputValues() const {
  return const_cast<PCopyInstruction*>(this)->outputs_.data();
}

// PhiInput
PhiInput::PhiInput(BasicBlock* basic_block, Value value)
    : basic_block_(basic_block), value_(value) {
}

// PhiInstruction
PhiInstruction::PhiInstruction(Value output) : output_(output) {
}

Value PhiInstruction::input_of(BasicBlock* basic_block) const {
  auto const phi_input = FindPhiInputFor(basic_block);
  DCHECK(phi_input);
  return phi_input->value();
}

int PhiInstruction::CountInputs() const {
  NOTREACHED();
  return 0;
}

int PhiInstruction::CountOutputs() const {
  return 1;
}

PhiInput* PhiInstruction::FindPhiInputFor(BasicBlock* block) const {
  for (auto phi_input : phi_inputs_) {
    if (phi_input->basic_block() == block)
      return phi_input;
  }
  return nullptr;
}

Value* PhiInstruction::InputValues() const {
  NOTREACHED();
  return nullptr;
}

Value* PhiInstruction::OutputValues() const {
  return &const_cast<PhiInstruction*>(this)->output_;
}

// PhiInstructionList
PhiInstructionList::PhiInstructionList(const InstructionList& list)
    : list_(&list) {
}

PhiInstructionList::Iterator PhiInstructionList::begin() const {
  return PhiInstructionList::Iterator(list_->begin());
}

PhiInstructionList::Iterator PhiInstructionList::end() const {
  return PhiInstructionList::Iterator(list_->end());
}

PhiInstructionList::Iterator::Iterator(
    const InstructionList::Iterator& iterator)
    : IteratorOnIterator(iterator) {
}

PhiInstruction* PhiInstructionList::Iterator::operator*() const {
  return (*iterator())->as<PhiInstruction>();
}

// RetInstruction
RetInstruction::RetInstruction(BasicBlock* exit_block) {
  DCHECK(exit_block->first_instruction()->is<ExitInstruction>());
  InitBlockOperand(0, exit_block);
}

}  // namespace lir
}  // namespace elang
<commit_msg>elang/lir: Use |Value::is_output()| instead of |Value::is_regiser()| to check output operand for supporting |Value::Kind::Condition|.<commit_after>// Copyright 2014-2015 Project Vogue. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <vector>

#include "base/logging.h"
#include "elang/lir/factory.h"
#include "elang/lir/instructions.h"
#include "elang/lir/instruction_visitor.h"
#include "elang/lir/literals.h"
#include "elang/lir/value.h"

#ifdef ELANG_TARGET_ARCH_X64
#include "elang/lir/instructions_x64.h"
#endif

namespace elang {
namespace lir {

base::StringPiece ToStringPiece(Opcode opcode) {
  static const char* const mnemonics[] = {
#define V(Name, mnemonic, ...) mnemonic,
      FOR_EACH_LIR_INSTRUCTION(V)
#undef V
          "Invalid",
  };
  return mnemonics[std::min(static_cast<size_t>(opcode),
                            arraysize(mnemonics) - 1)];
}

// Implement visitor pattern:
//  InstructionVIsitor::VisitXXX(XXXInstruction* instruction)
//  XXXInstruction::Accept(InstructionVisitor* visitor)
#define V(Name, ...)                                               \
  void InstructionVisitor::Visit##Name(Name##Instruction* instr) { \
    DoDefaultVisit(instr);                                         \
  }                                                                \
  void Name##Instruction::Accept(InstructionVisitor* visitor) {    \
    visitor->Visit##Name(this);                                    \
  }
FOR_EACH_LIR_INSTRUCTION(V)
#undef V

// Constructors
#define V(Name, ...) \
  Name##Instruction::Name##Instruction() {}
FOR_EACH_LIR_INSTRUCTION_0_0(V)
#undef V

#define V(Name, ...) \
  Name##Instruction::Name##Instruction(Value input) { InitInput(0, input); }
FOR_EACH_LIR_INSTRUCTION_0_1(V)
#undef V

#define V(Name, ...)                                              \
  Name##Instruction::Name##Instruction(Value left, Value right) { \
    InitInput(0, left);                                           \
    InitInput(1, right);                                          \
  }
FOR_EACH_LIR_INSTRUCTION_0_2(V)
#undef V

#define V(Name, ...)                                                \
  Name##Instruction::Name##Instruction(Value output, Value input) { \
    DCHECK(output.is_register());                                   \
    InitOutput(0, output);                                          \
    InitInput(0, input);                                            \
  }
FOR_EACH_LIR_INSTRUCTION_1_1(V)
#undef V

#define V(Name, ...)                                             \
  Name##Instruction::Name##Instruction(Value output, Value left, \
                                       Value right) {            \
    DCHECK(output.is_output());                                  \
    InitOutput(0, output);                                       \
    InitInput(0, left);                                          \
    InitInput(1, right);                                         \
  }
FOR_EACH_LIR_INSTRUCTION_1_2(V)
#undef V

//////////////////////////////////////////////////////////////////////
//
// BasicBlockOperands::Iterator
//
BasicBlockOperands::Iterator::Iterator(const Iterator& other)
    : Iterator(other.pointer_) {
}

BasicBlockOperands::Iterator::Iterator(BasicBlock** pointer)
    : pointer_(pointer) {
}

BasicBlockOperands::Iterator::~Iterator() {
}

BasicBlockOperands::Iterator& BasicBlockOperands::Iterator::operator=(
    const Iterator& other) {
  pointer_ = other.pointer_;
  return *this;
}

BasicBlockOperands::Iterator& BasicBlockOperands::Iterator::operator++() {
  ++pointer_;
  return *this;
}

bool BasicBlockOperands::Iterator::operator==(const Iterator& other) const {
  return pointer_ == other.pointer_;
}

bool BasicBlockOperands::Iterator::operator!=(const Iterator& other) const {
  return !operator==(other);
}

//////////////////////////////////////////////////////////////////////
//
// BasicBlockOperands
//
BasicBlockOperands::BasicBlockOperands(const BasicBlockOperands& other)
    : BasicBlockOperands(other.start_, other.end_) {
}

BasicBlockOperands::BasicBlockOperands(BasicBlock** start, BasicBlock** end)
    : end_(end), start_(start) {
  DCHECK_LE(start_, end_);
}

BasicBlockOperands::BasicBlockOperands()
    : BasicBlockOperands(nullptr, nullptr) {
}

BasicBlockOperands::~BasicBlockOperands() {
}

BasicBlockOperands& BasicBlockOperands::operator=(
    const BasicBlockOperands& other) {
  end_ = other.end_;
  start_ = other.start_;
  return *this;
}

//////////////////////////////////////////////////////////////////////
//
// Instruction::Values
//
Instruction::Values::Values(const Values& other)
    : end_(other.end_), start_(other.start_) {
}

Instruction::Values::Values(Value* start, Value* end)
    : end_(end), start_(start) {
}

Instruction::Values::~Values() {
}

Instruction::Values& Instruction::Values::operator=(const Values& other) {
  end_ = other.end_;
  start_ = other.start_;
  return *this;
}

//////////////////////////////////////////////////////////////////////
//
// Instruction::Values::Iterator
//
Instruction::Values::Iterator::Iterator(const Iterator& other)
    : pointer_(other.pointer_) {
}

Instruction::Values::Iterator::Iterator(Value* pointer) : pointer_(pointer) {
}

Instruction::Values::Iterator::~Iterator() {
}

Instruction::Values::Iterator& Instruction::Values::Iterator::operator=(
    const Iterator& other) {
  pointer_ = other.pointer_;
  return *this;
}

bool Instruction::Values::Iterator::operator==(const Iterator& other) const {
  return pointer_ == other.pointer_;
}

bool Instruction::Values::Iterator::operator!=(const Iterator& other) const {
  return !operator==(other);
}

Instruction::Values::Iterator& Instruction::Values::Iterator::operator++() {
  ++pointer_;
  return *this;
}

//////////////////////////////////////////////////////////////////////
//
// Instruction
//
Instruction::Instruction() : basic_block_(nullptr), id_(0) {
}

BasicBlock* Instruction::block_operand(int index) const {
  auto const operands = block_operands();
  DCHECK_GE(index, 0);
  DCHECK_LT(index, operands.size());
  return operands.start_[index];
}

BasicBlockOperands Instruction::block_operands() const {
  return BasicBlockOperands();
}

Value Instruction::input(int index) const {
  DCHECK_GE(index, 0);
  DCHECK_LE(index, CountInputs());
  return InputValues()[index];
}

Instruction::Values Instruction::inputs() const {
  auto const start = InputValues();
  return Values(start, start + CountInputs());
}

base::StringPiece Instruction::mnemonic() const {
  return ToStringPiece(opcode());
}

Value Instruction::output(int index) const {
  DCHECK_GE(index, 0);
  DCHECK_LE(index, CountOutputs());
  return OutputValues()[index];
}

Instruction::Values Instruction::outputs() const {
  auto const start = OutputValues();
  return Values(start, start + CountOutputs());
}

void Instruction::InitInput(int index, Value new_input) {
  SetInput(index, new_input);
}

void Instruction::InitOutput(int index, Value new_output) {
  SetOutput(index, new_output);
}

void Instruction::SetBlockOperand(int index, BasicBlock* new_value) {
  auto const operands = block_operands();
  DCHECK_GE(index, 0);
  DCHECK_LT(index, operands.size());
  operands.start_[index] = new_value;
}

void Instruction::SetInput(int index, Value new_input) {
  DCHECK_GE(index, 0);
  DCHECK_LE(index, CountInputs());
  InputValues()[index] = new_input;
}

void Instruction::SetOutput(int index, Value new_output) {
  DCHECK_GE(index, 0);
  DCHECK_LE(index, CountOutputs());
  DCHECK(new_output.is_output());
  OutputValues()[index] = new_output;
}

bool Instruction::IsTerminator() const {
  return false;
}

// BranchInstruction
BranchInstruction::BranchInstruction(Value condition,
                                     BasicBlock* true_block,
                                     BasicBlock* false_block) {
  InitInput(0, condition);
  InitBlockOperand(0, true_block);
  InitBlockOperand(1, false_block);
}

// JumpInstruction
JumpInstruction::JumpInstruction(BasicBlock* target_block) {
  InitBlockOperand(0, target_block);
}

// PCopyInstruction
PCopyInstruction::PCopyInstruction(Zone* zone,
                                   const std::vector<Value>& outputs,
                                   const std::vector<Value>& inputs)
    : inputs_(zone, inputs), outputs_(zone, outputs) {
  DCHECK_EQ(inputs_.size(), outputs_.size());
#ifndef NDEBUG
  for (auto const output : outputs_)
    DCHECK(!output.is_read_only());
#endif
}

// PCopyInstruction Instruction operand protocol
int PCopyInstruction::CountInputs() const {
  return static_cast<int>(inputs_.size());
}

int PCopyInstruction::CountOutputs() const {
  return static_cast<int>(outputs_.size());
}

Value* PCopyInstruction::InputValues() const {
  return const_cast<PCopyInstruction*>(this)->inputs_.data();
}

Value* PCopyInstruction::OutputValues() const {
  return const_cast<PCopyInstruction*>(this)->outputs_.data();
}

// PhiInput
PhiInput::PhiInput(BasicBlock* basic_block, Value value)
    : basic_block_(basic_block), value_(value) {
}

// PhiInstruction
PhiInstruction::PhiInstruction(Value output) : output_(output) {
}

Value PhiInstruction::input_of(BasicBlock* basic_block) const {
  auto const phi_input = FindPhiInputFor(basic_block);
  DCHECK(phi_input);
  return phi_input->value();
}

int PhiInstruction::CountInputs() const {
  NOTREACHED();
  return 0;
}

int PhiInstruction::CountOutputs() const {
  return 1;
}

PhiInput* PhiInstruction::FindPhiInputFor(BasicBlock* block) const {
  for (auto phi_input : phi_inputs_) {
    if (phi_input->basic_block() == block)
      return phi_input;
  }
  return nullptr;
}

Value* PhiInstruction::InputValues() const {
  NOTREACHED();
  return nullptr;
}

Value* PhiInstruction::OutputValues() const {
  return &const_cast<PhiInstruction*>(this)->output_;
}

// PhiInstructionList
PhiInstructionList::PhiInstructionList(const InstructionList& list)
    : list_(&list) {
}

PhiInstructionList::Iterator PhiInstructionList::begin() const {
  return PhiInstructionList::Iterator(list_->begin());
}

PhiInstructionList::Iterator PhiInstructionList::end() const {
  return PhiInstructionList::Iterator(list_->end());
}

PhiInstructionList::Iterator::Iterator(
    const InstructionList::Iterator& iterator)
    : IteratorOnIterator(iterator) {
}

PhiInstruction* PhiInstructionList::Iterator::operator*() const {
  return (*iterator())->as<PhiInstruction>();
}

// RetInstruction
RetInstruction::RetInstruction(BasicBlock* exit_block) {
  DCHECK(exit_block->first_instruction()->is<ExitInstruction>());
  InitBlockOperand(0, exit_block);
}

}  // namespace lir
}  // namespace elang
<|endoftext|>


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

#include <assert.h>
#include <stdlib.h>

#include <iostream>

#include "glproc.hpp"
#include "glws.hpp"
#include "ws.hpp"

namespace glws {

Display *display = NULL;
int screen = 0;

static void
describeEvent(const XEvent &event) {
    if (0) {
        switch (event.type) {
        case ConfigureNotify:
            std::cerr << "ConfigureNotify";
            break;
        case Expose:
            std::cerr << "Expose";
            break;
        case KeyPress:
            std::cerr << "KeyPress";
            break;
        case MapNotify:
            std::cerr << "MapNotify";
            break;
        case ReparentNotify:
            std::cerr << "ReparentNotify";
            break;
        default:
            std::cerr << "Event " << event.type;
        }
        std::cerr << " " << event.xany.window << "\n";
    }
}

static void
processEvent(XEvent &event) {
    describeEvent(event);

    switch (event.type) {
    case KeyPress:
        {
            char buffer[32];
            KeySym keysym;
            XLookupString(&event.xkey, buffer, sizeof buffer - 1, &keysym, NULL);
            if (keysym == XK_Escape) {
                exit(0);
            }
        }
        break;
    }
}

static int
errorHandler(Display *dpy, XErrorEvent *error)
{
    char buffer[512];
    XGetErrorText(dpy, error->error_code, buffer, sizeof buffer);
    std::cerr << "error: xlib: " << buffer;

    if (error->request_code < 128) {
        std::string request_code = std::to_string(error->request_code);
        XGetErrorDatabaseText(dpy, "XRequest", request_code.c_str(), "", buffer, sizeof buffer);
        std::cerr << " in " << buffer;
    }

    std::cerr << "\n";
    return 0;
}

static int (*oldErrorHandler)(Display *, XErrorEvent *) = NULL;

void
initX(void)
{
#ifndef NDEBUG
    _Xdebug = 1;
#endif

    XInitThreads();

    oldErrorHandler = XSetErrorHandler(errorHandler);

    display = XOpenDisplay(NULL);
    if (!display) {
        std::cerr << "error: unable to open display " << XDisplayName(NULL) << "\n";
        exit(1);
    }

    screen = DefaultScreen(display);
}

void
cleanupX(void)
{
    if (display) {
        XCloseDisplay(display);
        display = NULL;
    }

    XSetErrorHandler(oldErrorHandler);
    oldErrorHandler = NULL;
}

bool
processEvents(void)
{
    while (XPending(display) > 0) {
        XEvent event;
        XNextEvent(display, &event);
        processEvent(event);
    }
    return true;
}

static void
waitForEvent(Window window, int type)
{
    XEvent event;
    do {
        XWindowEvent(display, window, StructureNotifyMask | KeyPressMask, &event);
        processEvent(event);
    } while (event.type != type);
}

void
processKeys(Window window)
{
    XEvent event;
    while (XCheckWindowEvent(display, window, StructureNotifyMask | KeyPressMask, &event)) {
        processEvent(event);
    }
}

Window
createWindow(XVisualInfo *visinfo,
             const char *name,
             int width, int height)
{
    Window root = RootWindow(display, screen);

    /* window attributes */
    XSetWindowAttributes attr;
    attr.background_pixel = 0;
    attr.border_pixel = 0;
    attr.colormap = XCreateColormap(display, root, visinfo->visual, AllocNone);
    attr.event_mask = StructureNotifyMask | KeyPressMask;

    unsigned long mask;
    mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;

    int x = 0, y = 0;

    Window window = XCreateWindow(
        display, root,
        x, y, width, height,
        0,
        visinfo->depth,
        InputOutput,
        visinfo->visual,
        mask,
        &attr);

    XSizeHints sizehints;
    sizehints.x = x;
    sizehints.y = y;
    sizehints.width  = width;
    sizehints.height = height;
    sizehints.flags = USSize | USPosition;
    XSetNormalHints(display, window, &sizehints);

    XSetStandardProperties(
        display, window, name, name,
        None, (char **)NULL, 0, &sizehints);

    return window;
}

void
resizeWindow(Window window, int w, int h)
{
    // Tell the window manager to respect the requested size
    XSizeHints size_hints;
    size_hints.max_width  = size_hints.min_width  = w;
    size_hints.max_height = size_hints.min_height = h;
    size_hints.flags = PMinSize | PMaxSize;
    XSetWMNormalHints(display, window, &size_hints);

    XResizeWindow(display, window, w, h);

    waitForEvent(window, ConfigureNotify);
}

void
showWindow(Window window)
{
    // FIXME: This works for DRI drivers, but not NVIDIA proprietary drivers,
    // for which the only solution seems to be to use Pbuffers.
    if (true || !ws::headless) {
        XMapWindow(display, window);
        waitForEvent(window, MapNotify);
    }
}

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

#include <assert.h>
#include <stdlib.h>

#include <iostream>

#include "glproc.hpp"
#include "glws.hpp"
#include "ws.hpp"

namespace glws {

Display *display = NULL;
int screen = 0;

static void
describeEvent(const XEvent &event) {
    if (0) {
        switch (event.type) {
        case ConfigureNotify:
            std::cerr << "ConfigureNotify";
            break;
        case Expose:
            std::cerr << "Expose";
            break;
        case KeyPress:
            std::cerr << "KeyPress";
            break;
        case MapNotify:
            std::cerr << "MapNotify";
            break;
        case ReparentNotify:
            std::cerr << "ReparentNotify";
            break;
        default:
            std::cerr << "Event " << event.type;
        }
        std::cerr << " " << event.xany.window << "\n";
    }
}

static void
processEvent(XEvent &event) {
    describeEvent(event);

    switch (event.type) {
    case KeyPress:
        {
            char buffer[32];
            KeySym keysym;
            XLookupString(&event.xkey, buffer, sizeof buffer - 1, &keysym, NULL);
            if (keysym == XK_Escape) {
                exit(0);
            }
        }
        break;
    }
}

static int
errorHandler(Display *dpy, XErrorEvent *error)
{
    char buffer[512];
    XGetErrorText(dpy, error->error_code, buffer, sizeof buffer);
    std::cerr << "error: xlib: " << buffer;

    if (error->request_code < 128) {
        std::string request_code = std::to_string(error->request_code);
        XGetErrorDatabaseText(dpy, "XRequest", request_code.c_str(), "", buffer, sizeof buffer);
        std::cerr << " in " << buffer;
    }

    std::cerr << "\n";
    return 0;
}

static int (*oldErrorHandler)(Display *, XErrorEvent *) = NULL;

void
initX(void)
{
#ifndef NDEBUG
    _Xdebug = 1;
#endif

    XInitThreads();

    oldErrorHandler = XSetErrorHandler(errorHandler);

    display = XOpenDisplay(NULL);
    if (!display) {
        std::cerr << "error: unable to open display " << XDisplayName(NULL) << "\n";
        exit(1);
    }

    screen = DefaultScreen(display);
}

void
cleanupX(void)
{
    if (display) {
        XCloseDisplay(display);
        display = NULL;
    }

    XSetErrorHandler(oldErrorHandler);
    oldErrorHandler = NULL;
}

bool
processEvents(void)
{
    while (XPending(display) > 0) {
        XEvent event;
        XNextEvent(display, &event);
        processEvent(event);
    }
    return true;
}

static void
waitForEvent(Window window, int type)
{
    XEvent event;
    do {
        XWindowEvent(display, window, StructureNotifyMask | KeyPressMask, &event);
        processEvent(event);
    } while (event.type != type);
}

void
processKeys(Window window)
{
    XEvent event;
    while (XCheckWindowEvent(display, window, StructureNotifyMask | KeyPressMask, &event)) {
        processEvent(event);
    }
}

Window
createWindow(XVisualInfo *visinfo,
             const char *name,
             int width, int height)
{
    Window root = RootWindow(display, screen);

    /* window attributes */
    XSetWindowAttributes attr;
    attr.background_pixel = 0;
    attr.border_pixel = 0;
    attr.colormap = XCreateColormap(display, root, visinfo->visual, AllocNone);
    attr.event_mask = StructureNotifyMask | KeyPressMask;

    unsigned long mask;
    mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;

    int x = 0, y = 0;

    Window window = XCreateWindow(
        display, root,
        x, y, width, height,
        0,
        visinfo->depth,
        InputOutput,
        visinfo->visual,
        mask,
        &attr);

    XSizeHints sizehints;
    sizehints.x = x;
    sizehints.y = y;
    sizehints.width  = width;
    sizehints.height = height;
    sizehints.flags = USSize | USPosition;
    XSetNormalHints(display, window, &sizehints);

    XSetStandardProperties(
        display, window, name, name,
        None, (char **)NULL, 0, &sizehints);

    XSync(display, False);

    return window;
}

void
resizeWindow(Window window, int w, int h)
{
    // Tell the window manager to respect the requested size
    XSizeHints size_hints;
    size_hints.max_width  = size_hints.min_width  = w;
    size_hints.max_height = size_hints.min_height = h;
    size_hints.flags = PMinSize | PMaxSize;
    XSetWMNormalHints(display, window, &size_hints);

    XResizeWindow(display, window, w, h);

    waitForEvent(window, ConfigureNotify);
}

void
showWindow(Window window)
{
    // FIXME: This works for DRI drivers, but not NVIDIA proprietary drivers,
    // for which the only solution seems to be to use Pbuffers.
    if (true || !ws::headless) {
        XMapWindow(display, window);
        waitForEvent(window, MapNotify);
    }
}

} /* namespace glws */
<|endoftext|>


<commit_before>/*****************************************************************************
 * QMenuView
 ****************************************************************************
 * Copyright © 2011 VLC authors and VideoLAN
 * $Id$
 *
 * Authors: Jean-Baptiste Kempf <jb@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "qt4.hpp"
#include "util/qmenuview.hpp"

#include "components/playlist/vlc_model.hpp" /* data( IsCurrentRole ) */

#include <QFont>
#include <QVariant>
#include <assert.h>

/***
 * This is a simple view, like a QListView, but displayed as a QMenu
 * So far, this is quite limited.
 *
 * This is now linked to VLC's models. It should be splittable in the future.
 *
 * TODO: - limit the width of the entries
 *       - deal with a root item
 ***/

Q_DECLARE_METATYPE(QModelIndex); // So we can store it in a QVariant

QMenuView::QMenuView( QWidget * parent, int _iMaxVisibleCount )
          : QMenu( parent ), iMaxVisibleCount( _iMaxVisibleCount )
{
    m_model = NULL;

    /* Rebuild the Menu just before showing it */
    CONNECT( this, aboutToShow(), this, rebuild() );

    /* */
    CONNECT( this, triggered(QAction*), this, activate(QAction*) );
}

/* */
void QMenuView::rebuild()
{
    if( !m_model )
        return;

    /* Clear all Items */
    clear();

    /* Rebuild from root */
    build( QModelIndex() );

    if( isEmpty() )
        addAction( qtr( "Empty" ) )->setDisabled( true );
}

/* */
void QMenuView::build( const QModelIndex &parent )
{
    int i_count = iMaxVisibleCount == 0 ? m_model->rowCount( parent )
                                         : __MIN( iMaxVisibleCount, m_model->rowCount( parent ) );
    for( int i = 0; i < i_count; i++ )
    {
        QModelIndex idx = m_model->index(i, 0, parent);
        if( m_model->hasChildren( idx ) )
        {
            build( idx );
        }
        else
        {
            addAction( createActionFromIndex( idx ) );
        }
    }
}

/* Create individual actions */
QAction* QMenuView::createActionFromIndex( QModelIndex index )
{
    QIcon icon = qvariant_cast<QIcon>( index.data( Qt::DecorationRole ) );
    QAction * action = new QAction( icon, index.data().toString(), this );

    /* Display in bold the active element */
    if( index.data( VLCModel::IsCurrentRole ).toBool() )
    {
        QFont font; font.setBold ( true );
        action->setFont( font );
    }

    /* Some items could be hypothetically disabled */
    action->setEnabled( index.flags().testFlag( Qt::ItemIsEnabled ) );

    /* */
    QVariant variant; variant.setValue( index );
    action->setData( variant );

    return action;
}

/* QMenu action trigger */
void QMenuView::activate( QAction* action )
{
    assert( m_model );

    QVariant variant = action->data();
    if( variant.canConvert<QModelIndex>() )
    {
        emit activated( variant.value<QModelIndex>());
    }
}

<commit_msg>Qt: menus: do not store QModelIndex.<commit_after>/*****************************************************************************
 * QMenuView
 ****************************************************************************
 * Copyright © 2011 VLC authors and VideoLAN
 * $Id$
 *
 * Authors: Jean-Baptiste Kempf <jb@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "qt4.hpp"
#include "util/qmenuview.hpp"

#include "components/playlist/vlc_model.hpp" /* data( IsCurrentRole ) */

#include <QFont>
#include <QVariant>
#include <assert.h>

/***
 * This is a simple view, like a QListView, but displayed as a QMenu
 * So far, this is quite limited.
 *
 * This is now linked to VLC's models. It should be splittable in the future.
 *
 * TODO: - limit the width of the entries
 *       - deal with a root item
 ***/

Q_DECLARE_METATYPE(QPersistentModelIndex); // So we can store it in a QVariant

QMenuView::QMenuView( QWidget * parent, int _iMaxVisibleCount )
          : QMenu( parent ), iMaxVisibleCount( _iMaxVisibleCount )
{
    m_model = NULL;

    /* Rebuild the Menu just before showing it */
    CONNECT( this, aboutToShow(), this, rebuild() );

    /* */
    CONNECT( this, triggered(QAction*), this, activate(QAction*) );
}

/* */
void QMenuView::rebuild()
{
    if( !m_model )
        return;

    /* Clear all Items */
    clear();

    /* Rebuild from root */
    build( QModelIndex() );

    if( isEmpty() )
        addAction( qtr( "Empty" ) )->setDisabled( true );
}

/* */
void QMenuView::build( const QModelIndex &parent )
{
    int i_count = iMaxVisibleCount == 0 ? m_model->rowCount( parent )
                                         : __MIN( iMaxVisibleCount, m_model->rowCount( parent ) );
    for( int i = 0; i < i_count; i++ )
    {
        QModelIndex idx = m_model->index(i, 0, parent);
        if( m_model->hasChildren( idx ) )
        {
            build( idx );
        }
        else
        {
            addAction( createActionFromIndex( idx ) );
        }
    }
}

/* Create individual actions */
QAction* QMenuView::createActionFromIndex( QModelIndex index )
{
    QIcon icon = qvariant_cast<QIcon>( index.data( Qt::DecorationRole ) );
    QAction * action = new QAction( icon, index.data().toString(), this );

    /* Display in bold the active element */
    if( index.data( VLCModel::IsCurrentRole ).toBool() )
    {
        QFont font; font.setBold ( true );
        action->setFont( font );
    }

    /* Some items could be hypothetically disabled */
    action->setEnabled( index.flags().testFlag( Qt::ItemIsEnabled ) );

    /* */
    QVariant variant; variant.setValue( QPersistentModelIndex( index ) );
    action->setData( variant );

    return action;
}

/* QMenu action trigger */
void QMenuView::activate( QAction* action )
{
    assert( m_model );

    QVariant variant = action->data();
    if( variant.canConvert<QPersistentModelIndex>() )
    {
        emit activated( variant.value<QPersistentModelIndex>());
    }
}

<|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"
#ifndef DBACCESS_INDEXES_HXX_
#include "CIndexes.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
#include <com/sun/star/sdbc/XResultSet.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_INDEXTYPE_HPP_
#include <com/sun/star/sdbc/IndexType.hpp>
#endif
#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
#include "dbastrings.hrc"
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx>
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

using namespace connectivity;
using namespace connectivity::sdbcx;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace dbaccess;
using namespace cppu;

ObjectType OIndexes::createObject(const ::rtl::OUString& _rName)
{
    ObjectType xRet;
    if ( m_xIndexes.is() && m_xIndexes->hasByName(_rName) )
        xRet.set(m_xIndexes->getByName(_rName),UNO_QUERY);
    else
        xRet = OIndexesHelper::createObject(_rName);

    return xRet;
}
// -------------------------------------------------------------------------
Reference< XPropertySet > OIndexes::createDescriptor()
{
    Reference<XDataDescriptorFactory> xData( m_xIndexes,UNO_QUERY);
    if(xData.is())
        return xData->createDataDescriptor();
    else
        return OIndexesHelper::createDescriptor();
}
// -------------------------------------------------------------------------
// XAppend
ObjectType OIndexes::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
{
    Reference<XAppend> xData( m_xIndexes,UNO_QUERY);
    if ( !xData.is() )
        return OIndexesHelper::appendObject( _rForName, descriptor );

    xData->appendByDescriptor(descriptor);
    return createObject( _rForName );
}
// -------------------------------------------------------------------------
// XDrop
void OIndexes::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName)
{
    if ( m_xIndexes.is() )
    {
        Reference<XDrop> xData( m_xIndexes,UNO_QUERY);
        if ( xData.is() )
            xData->dropByName(_sElementName);
    }
    else
        OIndexesHelper::dropObject(_nPos,_sElementName);
}
// -------------------------------------------------------------------------
void SAL_CALL OIndexes::disposing(void)
{
    if ( m_xIndexes.is() )
        clear_NoDispose();
    else
        OIndexesHelper::disposing();
}
// -----------------------------------------------------------------------------

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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"
#ifndef DBACCESS_INDEXES_HXX_
#include "CIndexes.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
#include <com/sun/star/sdbc/XResultSet.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_INDEXTYPE_HPP_
#include <com/sun/star/sdbc/IndexType.hpp>
#endif
#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
#include "dbastrings.hrc"
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx>
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

using namespace connectivity;
using namespace connectivity::sdbcx;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace dbaccess;
using namespace cppu;

ObjectType OIndexes::createObject(const ::rtl::OUString& _rName)
{
    ObjectType xRet;
    if ( m_xIndexes.is() && m_xIndexes->hasByName(_rName) )
        xRet.set(m_xIndexes->getByName(_rName),UNO_QUERY);
    else
        xRet = OIndexesHelper::createObject(_rName);

    return xRet;
}
// -------------------------------------------------------------------------
Reference< XPropertySet > OIndexes::createDescriptor()
{
    Reference<XDataDescriptorFactory> xData( m_xIndexes,UNO_QUERY);
    if(xData.is())
        return xData->createDataDescriptor();
    else
        return OIndexesHelper::createDescriptor();
}
// -------------------------------------------------------------------------
// XAppend
ObjectType OIndexes::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
{
    Reference<XAppend> xData( m_xIndexes,UNO_QUERY);
    if ( !xData.is() )
        return OIndexesHelper::appendObject( _rForName, descriptor );

    xData->appendByDescriptor(descriptor);
    return createObject( _rForName );
}
// -------------------------------------------------------------------------
// XDrop
void OIndexes::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName)
{
    if ( m_xIndexes.is() )
    {
        Reference<XDrop> xData( m_xIndexes,UNO_QUERY);
        if ( xData.is() )
            xData->dropByName(_sElementName);
    }
    else
        OIndexesHelper::dropObject(_nPos,_sElementName);
}
// -------------------------------------------------------------------------
void SAL_CALL OIndexes::disposing(void)
{
    if ( m_xIndexes.is() )
        clear_NoDispose();
    else
        OIndexesHelper::disposing();
}
// -----------------------------------------------------------------------------

<|endoftext|>


<commit_before>#include "models/api/javascript-api.h"
#include <QJSEngine>
#include <QJSValueIterator>
#include "functions.h"
#include "logger.h"
#include "mixed-settings.h"
#include "models/page.h"
#include "models/pool.h"
#include "models/site.h"
#include "tags/tag-database.h"

QStringList jsToStringList(const QJSValue &val)
{
	QStringList ret;

	QJSValueIterator it(val);
	while (it.hasNext())
	{
		it.next();
		ret.append(it.value().toString());
	}

	return ret;
}

QString normalize(QString key)
{
	key = key.toLower();
	key[0] = key[0].toUpper();
	return key;
}

JavascriptApi::JavascriptApi(const QMap<QString, QString> &data, const QJSValue &source, const QString &key)
	: Api(normalize(key), data), m_source(source), m_key(key)
{}

void JavascriptApi::fillUrlObject(const QJSValue &result, Site *site, PageUrl &ret) const
{
	// Script errors and exceptions
	if (result.isError())
	{
		QString err = QString("Uncaught exception at line %1: %2").arg(result.property("lineNumber").toInt()).arg(result.toString());
		ret.error = err;
		log(err, Logger::Error);
		return;
	}

	// Parse result
	QString url;
	if (result.isObject())
	{
		if (result.hasProperty("error"))
		{
			ret.error = result.property("error").toString();
			return;
		}

		url = result.property("url").toString();
	}
	else
	{ url = result.toString(); }

	// Site-ize url
	if (site != Q_NULLPTR)
	{
		url = site->fixLoginUrl(url);
		url = site->fixUrl(url).toString();
	}

	ret.url = url;
}

PageUrl JavascriptApi::pageUrl(const QString &search, int page, int limit, int lastPage, int lastPageMinId, int lastPageMaxId, Site *site) const
{
	PageUrl ret;

	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue urlFunction = api.property("search").property("url");
	if (urlFunction.isUndefined())
	{
		ret.error = "This API does not support search";
		return ret;
	}

	QJSValue query = m_source.engine()->newObject();
	query.setProperty("search", search);
	query.setProperty("page", page);

	QJSValue opts = m_source.engine()->newObject();
	opts.setProperty("limit", limit);
	QJSValue auth = m_source.engine()->newObject();
	MixedSettings *settings = site->settings();
	settings->beginGroup("auth");
	for (const QString &key : settings->childKeys())
	{
		QString value = settings->value(key).toString();
		if (key == "pseudo" && !auth.hasProperty("login"))
		{ auth.setProperty("login", value); }
		if (key == "password" && !auth.hasProperty("password_hash"))
		{ auth.setProperty("password_hash", value); }
		auth.setProperty(key, value);
	}
	settings->endGroup();
	opts.setProperty("auth", auth);

	QJSValue previous = QJSValue(QJSValue::UndefinedValue);
	if (lastPage > 0)
	{
		previous = m_source.engine()->newObject();
		previous.setProperty("page", lastPage);
		previous.setProperty("minId", lastPageMinId);
		previous.setProperty("maxId", lastPageMaxId);
	}

	QJSValue result = urlFunction.call(QList<QJSValue>() << query << opts << previous);
	fillUrlObject(result, site, ret);

	return ret;
}

QList<Tag> JavascriptApi::makeTags(const QJSValue &tags, Site *site) const
{
	QList<Tag> ret;
	QMap<int, TagType> tagTypes = site->tagDatabase()->tagTypes();

	QJSValueIterator it(tags);
	while (it.hasNext())
	{
		it.next();

		QJSValue tag = it.value();
		if (tag.isString())
		{
			ret.append(Tag(tag.toString()));
			continue;
		}
		else if (!tag.isObject())
		{ continue; }

		int id = tag.hasProperty("id") ? tag.property("id").toInt() : 0;
		QString text = tag.property("name").toString();
		int count = tag.hasProperty("count") ? tag.property("count").toInt() : 0;

		QString type;
		int typeId;
		if (tag.hasProperty("type"))
		{
			if (tag.property("type").isNumber())
			{ typeId = tag.property("type").toInt(); }
			else
			{ type = tag.property("type").toString(); }
		}
		if (tag.hasProperty("typeId"))
		{ typeId = tag.property("typeId").toInt(); }

		TagType tagType = !type.isEmpty() ? TagType(type) : (tagTypes.contains(typeId) ? tagTypes[typeId] : TagType("unknown"));
		ret.append(Tag(id, text, tagType, count));
	}

	return ret;
}

ParsedPage JavascriptApi::parsePage(Page *parentPage, const QString &source, int first, int limit) const
{
	Q_UNUSED(limit);

	ParsedPage ret;

	Site *site = parentPage->site();
	const QJSValue &api = m_source.property("apis").property(m_key);
	QJSValue parseFunction = api.property("search").property("parse");
	const QJSValue &results = parseFunction.call(QList<QJSValue>() << source);

	// Script errors and exceptions
	if (results.isError())
	{
		ret.error = QString("Uncaught exception at line %1: %2").arg(results.property("lineNumber").toInt()).arg(results.toString());
		return ret;
	}

	if (results.hasProperty("error"))
	{ ret.error = results.property("error").toString(); }

	if (results.hasProperty("tags"))
	{ ret.tags = makeTags(results.property("tags"), site); }

	if (results.hasProperty("images"))
	{
		QJSValue images = results.property("images");
		QJSValueIterator it(images);
		while (it.hasNext())
		{
			it.next();

			QList<Tag> tags;

			QMap<QString, QString> d;
			QJSValueIterator it3(it.value());
			while (it3.hasNext())
			{
				it3.next();

				const QString &key = it3.name();
				const QJSValue &val = it3.value();

				if (it3.value().isUndefined())
				{
					log(QString("Undefined value returned by JS model: %1").arg(key), Logger::Debug);
					continue;
				}

				if (key == "tags_obj" || (key == "tags" && val.isArray()))
				{ tags = makeTags(val, site); }
				else
				{ d[key] = val.toString(); }
			}

			if (!d.isEmpty())
			{
				int id = d["id"].toInt();
				QSharedPointer<Image> img = parseImage(parentPage, d, id + first, tags, false);
				if (!img.isNull())
				{ ret.images.append(img); }
			}
		}
	}

	// Basic properties
	if (results.hasProperty("imageCount"))
	{ ret.imageCount = results.property("imageCount").toInt(); }
	if (results.hasProperty("pageCount"))
	{ ret.pageCount = results.property("pageCount").toInt(); }
	if (results.hasProperty("urlNextPage"))
	{ ret.urlNextPage = results.property("urlNextPage").toString(); }
	if (results.hasProperty("urlPrevPage"))
	{ ret.urlPrevPage = results.property("urlPrevPage").toString(); }
	if (results.hasProperty("wiki"))
	{ ret.wiki = results.property("wiki").toString(); }

	return ret;
}

bool JavascriptApi::canLoadTags() const
{
	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue urlFunction = api.property("tags").property("url");
	return !urlFunction.isUndefined();
}

PageUrl JavascriptApi::tagsUrl(int page, int limit, Site *site) const
{
	PageUrl ret;

	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue urlFunction = api.property("tags").property("url");
	if (urlFunction.isUndefined())
	{
		ret.error = "This API does not support tag loading";
		return ret;
	}

	QJSValue query = m_source.engine()->newObject();
	query.setProperty("page", page);

	QJSValue opts = m_source.engine()->newObject();
	opts.setProperty("limit", limit);
	QJSValue auth = m_source.engine()->newObject();
	MixedSettings *settings = site->settings();
	settings->beginGroup("auth");
	for (const QString &key : settings->childKeys())
	{
		QString value = settings->value(key).toString();
		if (key == "pseudo" && !auth.hasProperty("login"))
		{ auth.setProperty("login", value); }
		if (key == "password" && !auth.hasProperty("password_hash"))
		{ auth.setProperty("password_hash", value); }
		auth.setProperty(key, value);
	}
	settings->endGroup();
	opts.setProperty("auth", auth);

	QJSValue result = urlFunction.call(QList<QJSValue>() << query << opts);
	fillUrlObject(result, site, ret);

	return ret;
}

ParsedTags JavascriptApi::parseTags(const QString &source, Site *site) const
{
	ParsedTags ret;

	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue parseFunction = api.property("tags").property("parse");
	QJSValue results = parseFunction.call(QList<QJSValue>() << source);

	// Script errors and exceptions
	if (results.isError())
	{
		ret.error = QString("Uncaught exception at line %1: %2").arg(results.property("lineNumber").toInt()).arg(results.toString());
		return ret;
	}

	if (results.hasProperty("error"))
	{ ret.error = results.property("error").toString(); }
	if (results.hasProperty("tags"))
	{ ret.tags = makeTags(results.property("tags"), site); }

	return ret;
}

bool JavascriptApi::canLoadDetails() const
{
	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue urlFunction = api.property("details").property("url");
	return !urlFunction.isUndefined();
}

PageUrl JavascriptApi::detailsUrl(qulonglong id, const QString &md5, Site *site) const
{
	PageUrl ret;

	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue urlFunction = api.property("details").property("url");
	if (urlFunction.isUndefined())
	{
		ret.error = "This API does not support details loading";
		return ret;
	}

	QJSValue result = urlFunction.call(QList<QJSValue>() << QString::number(id) << md5);
	fillUrlObject(result, site, ret);

	return ret;
}

ParsedDetails JavascriptApi::parseDetails(const QString &source, Site *site) const
{
	ParsedDetails ret;

	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue parseFunction = api.property("details").property("parse");
	QJSValue results = parseFunction.call(QList<QJSValue>() << source);

	// Script errors and exceptions
	if (results.isError())
	{
		ret.error = QString("Uncaught exception at line %1: %2").arg(results.property("lineNumber").toInt()).arg(results.toString());
		return ret;
	}

	if (results.hasProperty("error") && results.property("error").isString())
	{ ret.error = results.property("error").toString(); }
	if (results.hasProperty("tags"))
	{ ret.tags = makeTags(results.property("tags"), site); }
	if (results.hasProperty("imageUrl") && results.property("imageUrl").isString())
	{ ret.imageUrl = results.property("imageUrl").toString(); }
	if (results.hasProperty("createdAt") && results.property("createdAt").isString())
	{ ret.createdAt = qDateTimeFromString(results.property("createdAt").toString()); }

	if (results.hasProperty("pools"))
	{
		QJSValue images = results.property("pools");
		QJSValueIterator it(images);
		while (it.hasNext())
		{
			it.next();

			QJSValue pool = it.value();
			if (!pool.isObject())
				continue;

			int id = pool.hasProperty("id") ? pool.property("id").toInt() : 0;
			QString name = pool.property("name").toString();
			int next = pool.hasProperty("next") ? pool.property("next").toInt() : 0;
			int previous = pool.hasProperty("previous") ? pool.property("previous").toInt() : 0;

			ret.pools.append(Pool(id, name, 0, next, previous));
		}
	}

	return ret;
}

bool JavascriptApi::canLoadCheck() const
{
	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue urlFunction = api.property("check").property("url");
	return !urlFunction.isUndefined();
}

PageUrl JavascriptApi::checkUrl() const
{
	PageUrl ret;

	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue urlFunction = api.property("check").property("url");
	if (urlFunction.isUndefined())
	{
		ret.error = "This API does not support checking";
		return ret;
	}

	QJSValue result = urlFunction.call();
	fillUrlObject(result, Q_NULLPTR, ret);

	return ret;
}

ParsedCheck JavascriptApi::parseCheck(const QString &source) const
{
	ParsedCheck ret;

	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue parseFunction = api.property("check").property("parse");
	QJSValue result = parseFunction.call(QList<QJSValue>() << source);

	// Script errors and exceptions
	if (result.isError())
	{
		ret.error = QString("Uncaught exception at line %1: %2").arg(result.property("lineNumber").toInt()).arg(result.toString());
		return ret;
	}

	ret.ok = result.toBool();

	return ret;
}

QJSValue JavascriptApi::getJsConst(const QString &key, const QJSValue &def) const
{
	QJSValue api = m_source.property("apis").property(m_key);
	if (api.hasProperty(key))
	{ return api.property(key); }
	if (m_source.hasProperty(key))
	{ return m_source.property(key); }
	return def;
}

bool JavascriptApi::needAuth() const
{
	QStringList requiredAuths = jsToStringList(getJsConst("forcedLimit"));
	return !requiredAuths.isEmpty();
}

int JavascriptApi::forcedLimit() const
{ return getJsConst("forcedLimit", 0).toInt(); }
int JavascriptApi::maxLimit() const
{ return getJsConst("maxLimit", 0).toInt(); }

QStringList JavascriptApi::modifiers() const
{ return jsToStringList(getJsConst("modifiers")); }
QStringList JavascriptApi::forcedTokens() const
{ return jsToStringList(getJsConst("forcedTokens")); }
<commit_msg>Pass logged in status to JS model url creation<commit_after>#include "models/api/javascript-api.h"
#include <QJSEngine>
#include <QJSValueIterator>
#include "functions.h"
#include "logger.h"
#include "mixed-settings.h"
#include "models/page.h"
#include "models/pool.h"
#include "models/site.h"
#include "tags/tag-database.h"

QStringList jsToStringList(const QJSValue &val)
{
	QStringList ret;

	QJSValueIterator it(val);
	while (it.hasNext())
	{
		it.next();
		ret.append(it.value().toString());
	}

	return ret;
}

QString normalize(QString key)
{
	key = key.toLower();
	key[0] = key[0].toUpper();
	return key;
}

JavascriptApi::JavascriptApi(const QMap<QString, QString> &data, const QJSValue &source, const QString &key)
	: Api(normalize(key), data), m_source(source), m_key(key)
{}

void JavascriptApi::fillUrlObject(const QJSValue &result, Site *site, PageUrl &ret) const
{
	// Script errors and exceptions
	if (result.isError())
	{
		QString err = QString("Uncaught exception at line %1: %2").arg(result.property("lineNumber").toInt()).arg(result.toString());
		ret.error = err;
		log(err, Logger::Error);
		return;
	}

	// Parse result
	QString url;
	if (result.isObject())
	{
		if (result.hasProperty("error"))
		{
			ret.error = result.property("error").toString();
			return;
		}

		url = result.property("url").toString();
	}
	else
	{ url = result.toString(); }

	// Site-ize url
	if (site != Q_NULLPTR)
	{
		url = site->fixLoginUrl(url);
		url = site->fixUrl(url).toString();
	}

	ret.url = url;
}

PageUrl JavascriptApi::pageUrl(const QString &search, int page, int limit, int lastPage, int lastPageMinId, int lastPageMaxId, Site *site) const
{
	PageUrl ret;

	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue urlFunction = api.property("search").property("url");
	if (urlFunction.isUndefined())
	{
		ret.error = "This API does not support search";
		return ret;
	}

	QJSValue query = m_source.engine()->newObject();
	query.setProperty("search", search);
	query.setProperty("page", page);

	QJSValue opts = m_source.engine()->newObject();
	opts.setProperty("limit", limit);
	QJSValue auth = m_source.engine()->newObject();
	MixedSettings *settings = site->settings();
	settings->beginGroup("auth");
	for (const QString &key : settings->childKeys())
	{
		QString value = settings->value(key).toString();
		if (key == "pseudo" && !auth.hasProperty("login"))
		{ auth.setProperty("login", value); }
		if (key == "password" && !auth.hasProperty("password_hash"))
		{ auth.setProperty("password_hash", value); }
		auth.setProperty(key, value);
	}
	settings->endGroup();
	opts.setProperty("auth", auth);

	QJSValue previous = QJSValue(QJSValue::UndefinedValue);
	if (lastPage > 0)
	{
		previous = m_source.engine()->newObject();
		previous.setProperty("page", lastPage);
		previous.setProperty("minId", lastPageMinId);
		previous.setProperty("maxId", lastPageMaxId);
	}

	QJSValue result = urlFunction.call(QList<QJSValue>() << query << opts << previous);
	fillUrlObject(result, site, ret);

	return ret;
}

QList<Tag> JavascriptApi::makeTags(const QJSValue &tags, Site *site) const
{
	QList<Tag> ret;
	QMap<int, TagType> tagTypes = site->tagDatabase()->tagTypes();

	QJSValueIterator it(tags);
	while (it.hasNext())
	{
		it.next();

		QJSValue tag = it.value();
		if (tag.isString())
		{
			ret.append(Tag(tag.toString()));
			continue;
		}
		else if (!tag.isObject())
		{ continue; }

		int id = tag.hasProperty("id") ? tag.property("id").toInt() : 0;
		QString text = tag.property("name").toString();
		int count = tag.hasProperty("count") ? tag.property("count").toInt() : 0;

		QString type;
		int typeId;
		if (tag.hasProperty("type"))
		{
			if (tag.property("type").isNumber())
			{ typeId = tag.property("type").toInt(); }
			else
			{ type = tag.property("type").toString(); }
		}
		if (tag.hasProperty("typeId"))
		{ typeId = tag.property("typeId").toInt(); }

		TagType tagType = !type.isEmpty() ? TagType(type) : (tagTypes.contains(typeId) ? tagTypes[typeId] : TagType("unknown"));
		ret.append(Tag(id, text, tagType, count));
	}

	return ret;
}

ParsedPage JavascriptApi::parsePage(Page *parentPage, const QString &source, int first, int limit) const
{
	Q_UNUSED(limit);

	ParsedPage ret;

	Site *site = parentPage->site();
	const QJSValue &api = m_source.property("apis").property(m_key);
	QJSValue parseFunction = api.property("search").property("parse");
	const QJSValue &results = parseFunction.call(QList<QJSValue>() << source);

	// Script errors and exceptions
	if (results.isError())
	{
		ret.error = QString("Uncaught exception at line %1: %2").arg(results.property("lineNumber").toInt()).arg(results.toString());
		return ret;
	}

	if (results.hasProperty("error"))
	{ ret.error = results.property("error").toString(); }

	if (results.hasProperty("tags"))
	{ ret.tags = makeTags(results.property("tags"), site); }

	if (results.hasProperty("images"))
	{
		QJSValue images = results.property("images");
		QJSValueIterator it(images);
		while (it.hasNext())
		{
			it.next();

			QList<Tag> tags;

			QMap<QString, QString> d;
			QJSValueIterator it3(it.value());
			while (it3.hasNext())
			{
				it3.next();

				const QString &key = it3.name();
				const QJSValue &val = it3.value();

				if (it3.value().isUndefined())
				{
					log(QString("Undefined value returned by JS model: %1").arg(key), Logger::Debug);
					continue;
				}

				if (key == "tags_obj" || (key == "tags" && val.isArray()))
				{ tags = makeTags(val, site); }
				else
				{ d[key] = val.toString(); }
			}

			if (!d.isEmpty())
			{
				int id = d["id"].toInt();
				QSharedPointer<Image> img = parseImage(parentPage, d, id + first, tags, false);
				if (!img.isNull())
				{ ret.images.append(img); }
			}
		}
	}

	// Basic properties
	if (results.hasProperty("imageCount"))
	{ ret.imageCount = results.property("imageCount").toInt(); }
	if (results.hasProperty("pageCount"))
	{ ret.pageCount = results.property("pageCount").toInt(); }
	if (results.hasProperty("urlNextPage"))
	{ ret.urlNextPage = results.property("urlNextPage").toString(); }
	if (results.hasProperty("urlPrevPage"))
	{ ret.urlPrevPage = results.property("urlPrevPage").toString(); }
	if (results.hasProperty("wiki"))
	{ ret.wiki = results.property("wiki").toString(); }

	return ret;
}

bool JavascriptApi::canLoadTags() const
{
	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue urlFunction = api.property("tags").property("url");
	return !urlFunction.isUndefined();
}

PageUrl JavascriptApi::tagsUrl(int page, int limit, Site *site) const
{
	PageUrl ret;

	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue urlFunction = api.property("tags").property("url");
	if (urlFunction.isUndefined())
	{
		ret.error = "This API does not support tag loading";
		return ret;
	}

	QJSValue query = m_source.engine()->newObject();
	query.setProperty("page", page);

	QJSValue opts = m_source.engine()->newObject();
	opts.setProperty("limit", limit);
	opts.setProperty("loggedIn", site->isLoggedIn(false));
	QJSValue auth = m_source.engine()->newObject();
	MixedSettings *settings = site->settings();
	settings->beginGroup("auth");
	for (const QString &key : settings->childKeys())
	{
		QString value = settings->value(key).toString();
		if (key == "pseudo" && !auth.hasProperty("login"))
		{ auth.setProperty("login", value); }
		if (key == "password" && !auth.hasProperty("password_hash"))
		{ auth.setProperty("password_hash", value); }
		auth.setProperty(key, value);
	}
	settings->endGroup();
	opts.setProperty("auth", auth);

	QJSValue result = urlFunction.call(QList<QJSValue>() << query << opts);
	fillUrlObject(result, site, ret);

	return ret;
}

ParsedTags JavascriptApi::parseTags(const QString &source, Site *site) const
{
	ParsedTags ret;

	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue parseFunction = api.property("tags").property("parse");
	QJSValue results = parseFunction.call(QList<QJSValue>() << source);

	// Script errors and exceptions
	if (results.isError())
	{
		ret.error = QString("Uncaught exception at line %1: %2").arg(results.property("lineNumber").toInt()).arg(results.toString());
		return ret;
	}

	if (results.hasProperty("error"))
	{ ret.error = results.property("error").toString(); }
	if (results.hasProperty("tags"))
	{ ret.tags = makeTags(results.property("tags"), site); }

	return ret;
}

bool JavascriptApi::canLoadDetails() const
{
	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue urlFunction = api.property("details").property("url");
	return !urlFunction.isUndefined();
}

PageUrl JavascriptApi::detailsUrl(qulonglong id, const QString &md5, Site *site) const
{
	PageUrl ret;

	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue urlFunction = api.property("details").property("url");
	if (urlFunction.isUndefined())
	{
		ret.error = "This API does not support details loading";
		return ret;
	}

	QJSValue result = urlFunction.call(QList<QJSValue>() << QString::number(id) << md5);
	fillUrlObject(result, site, ret);

	return ret;
}

ParsedDetails JavascriptApi::parseDetails(const QString &source, Site *site) const
{
	ParsedDetails ret;

	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue parseFunction = api.property("details").property("parse");
	QJSValue results = parseFunction.call(QList<QJSValue>() << source);

	// Script errors and exceptions
	if (results.isError())
	{
		ret.error = QString("Uncaught exception at line %1: %2").arg(results.property("lineNumber").toInt()).arg(results.toString());
		return ret;
	}

	if (results.hasProperty("error") && results.property("error").isString())
	{ ret.error = results.property("error").toString(); }
	if (results.hasProperty("tags"))
	{ ret.tags = makeTags(results.property("tags"), site); }
	if (results.hasProperty("imageUrl") && results.property("imageUrl").isString())
	{ ret.imageUrl = results.property("imageUrl").toString(); }
	if (results.hasProperty("createdAt") && results.property("createdAt").isString())
	{ ret.createdAt = qDateTimeFromString(results.property("createdAt").toString()); }

	if (results.hasProperty("pools"))
	{
		QJSValue images = results.property("pools");
		QJSValueIterator it(images);
		while (it.hasNext())
		{
			it.next();

			QJSValue pool = it.value();
			if (!pool.isObject())
				continue;

			int id = pool.hasProperty("id") ? pool.property("id").toInt() : 0;
			QString name = pool.property("name").toString();
			int next = pool.hasProperty("next") ? pool.property("next").toInt() : 0;
			int previous = pool.hasProperty("previous") ? pool.property("previous").toInt() : 0;

			ret.pools.append(Pool(id, name, 0, next, previous));
		}
	}

	return ret;
}

bool JavascriptApi::canLoadCheck() const
{
	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue urlFunction = api.property("check").property("url");
	return !urlFunction.isUndefined();
}

PageUrl JavascriptApi::checkUrl() const
{
	PageUrl ret;

	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue urlFunction = api.property("check").property("url");
	if (urlFunction.isUndefined())
	{
		ret.error = "This API does not support checking";
		return ret;
	}

	QJSValue result = urlFunction.call();
	fillUrlObject(result, Q_NULLPTR, ret);

	return ret;
}

ParsedCheck JavascriptApi::parseCheck(const QString &source) const
{
	ParsedCheck ret;

	QJSValue api = m_source.property("apis").property(m_key);
	QJSValue parseFunction = api.property("check").property("parse");
	QJSValue result = parseFunction.call(QList<QJSValue>() << source);

	// Script errors and exceptions
	if (result.isError())
	{
		ret.error = QString("Uncaught exception at line %1: %2").arg(result.property("lineNumber").toInt()).arg(result.toString());
		return ret;
	}

	ret.ok = result.toBool();

	return ret;
}

QJSValue JavascriptApi::getJsConst(const QString &key, const QJSValue &def) const
{
	QJSValue api = m_source.property("apis").property(m_key);
	if (api.hasProperty(key))
	{ return api.property(key); }
	if (m_source.hasProperty(key))
	{ return m_source.property(key); }
	return def;
}

bool JavascriptApi::needAuth() const
{
	QStringList requiredAuths = jsToStringList(getJsConst("forcedLimit"));
	return !requiredAuths.isEmpty();
}

int JavascriptApi::forcedLimit() const
{ return getJsConst("forcedLimit", 0).toInt(); }
int JavascriptApi::maxLimit() const
{ return getJsConst("maxLimit", 0).toInt(); }

QStringList JavascriptApi::modifiers() const
{ return jsToStringList(getJsConst("modifiers")); }
QStringList JavascriptApi::forcedTokens() const
{ return jsToStringList(getJsConst("forcedTokens")); }
<|endoftext|>


<commit_before>/*****************************************************************************
 * volume.cpp
 *****************************************************************************
 * Copyright (C) 2003 the VideoLAN team
 * $Id$
 *
 * Authors: Cyril Deguet     <asmax@via.ecp.fr>
 *          Olivier Teulière <ipkiss@via.ecp.fr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <vlc_common.h>
#include <vlc_aout.h>
#include "volume.hpp"

Volume::Volume( intf_thread_t *pIntf ): VarPercent( pIntf )
{
    // Initial value
    audio_volume_t val;

    aout_VolumeGet( getIntf()->p_sys->p_playlist, &val );
    VarPercent::set( val * 2.0 / AOUT_VOLUME_MAX );
}

void Volume::set( float percentage )
{
    // Avoid looping forever...
    if( (int)(get() * AOUT_VOLUME_MAX) !=
        (int)(percentage * AOUT_VOLUME_MAX) )
    {
        VarPercent::set( percentage );

        aout_VolumeSet( getIntf()->p_sys->p_playlist(),
                        (int)(get() * AOUT_VOLUME_MAX / 2.0) );
    }
}

string Volume::getAsStringPercent() const
{
    int value = (int)(100. * VarPercent::get());
    // 0 <= value <= 100, so we need 4 chars
    char *str = new char[4];
    snprintf( str, 4, "%d", value );
    string ret = str;
    delete[] str;

    return ret;
}

<commit_msg>skins: missing include<commit_after>/*****************************************************************************
 * volume.cpp
 *****************************************************************************
 * Copyright (C) 2003 the VideoLAN team
 * $Id$
 *
 * Authors: Cyril Deguet     <asmax@via.ecp.fr>
 *          Olivier Teulière <ipkiss@via.ecp.fr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <vlc_common.h>
#include <vlc_aout.h>
#include <vlc_playlist.h>
#include "volume.hpp"

Volume::Volume( intf_thread_t *pIntf ): VarPercent( pIntf )
{
    // Initial value
    audio_volume_t val;

    aout_VolumeGet( getIntf()->p_sys->p_playlist, &val );
    VarPercent::set( val * 2.0 / AOUT_VOLUME_MAX );
}

void Volume::set( float percentage )
{
    // Avoid looping forever...
    if( (int)(get() * AOUT_VOLUME_MAX) !=
        (int)(percentage * AOUT_VOLUME_MAX) )
    {
        VarPercent::set( percentage );

        aout_VolumeSet( getIntf()->p_sys->p_playlist(),
                        (int)(get() * AOUT_VOLUME_MAX / 2.0) );
    }
}

string Volume::getAsStringPercent() const
{
    int value = (int)(100. * VarPercent::get());
    // 0 <= value <= 100, so we need 4 chars
    char *str = new char[4];
    snprintf( str, 4, "%d", value );
    string ret = str;
    delete[] str;

    return ret;
}

<|endoftext|>