<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include "fat32.hpp"
#include "console.hpp"

#include "stl/types.hpp"
#include "stl/unique_ptr.hpp"
#include "stl/algorithms.hpp"
#include "stl/pair.hpp"

namespace {

//FAT 32 Boot Sector
struct fat_bs_t {
    uint8_t jump[3];
    char oem_name[8];
    uint16_t bytes_per_sector;
    uint8_t sectors_per_cluster;
    uint16_t reserved_sectors;
    uint8_t number_of_fat;
    uint16_t root_directories_entries;
    uint16_t total_sectors;
    uint8_t media_descriptor;
    uint16_t sectors_per_fat;
    uint16_t sectors_per_track;
    uint16_t heads;
    uint32_t hidden_sectors;
    uint32_t total_sectors_long;
    uint32_t sectors_per_fat_long;
    uint16_t drive_description;
    uint16_t version;
    uint32_t root_directory_cluster_start;
    uint16_t fs_information_sector;
    uint16_t boot_sectors_copy_sector;
    uint8_t filler[12];
    uint8_t physical_drive_number;
    uint8_t reserved;
    uint8_t extended_boot_signature;
    uint32_t volume_id;
    char volume_label[11];
    char file_system_type[8];
    uint8_t boot_code[420];
    uint16_t signature;
}__attribute__ ((packed));

struct fat_is_t {
    uint32_t signature_start;
    uint8_t reserved[480];
    uint32_t signature_middle;
    uint32_t free_clusters;
    uint32_t allocated_clusters;
    uint8_t reserved_2[12];
    uint32_t signature_end;
}__attribute__ ((packed));

static_assert(sizeof(fat_bs_t) == 512, "FAT Boot Sector is exactly one disk sector");

struct cluster_entry {
    char name[11];
    uint8_t attrib;
    uint8_t reserved;
    uint8_t creation_time_seconds;
    uint16_t creation_time;
    uint16_t creation_date;
    uint16_t accessed_date;
    uint16_t cluster_high;
    uint16_t modification_time;
    uint16_t modification_date;
    uint16_t cluster_low;
    uint32_t file_size;
} __attribute__ ((packed));

static_assert(sizeof(cluster_entry) == 32, "A cluster entry is 32 bytes");

uint64_t cached_disk = -1;
uint64_t cached_partition = -1;
uint64_t partition_start;

fat_bs_t* fat_bs = nullptr;
fat_is_t* fat_is = nullptr;

void cache_bs(fat32::dd disk, const disks::partition_descriptor& partition){
    std::unique_ptr<fat_bs_t> fat_bs_tmp(new fat_bs_t());

    if(read_sectors(disk, partition.start, 1, fat_bs_tmp.get())){
        fat_bs = fat_bs_tmp.release();

        //TODO fat_bs->signature should be 0xAA55
        //TODO fat_bs->file_system_type should be FAT32
    } else {
        fat_bs = nullptr;
    }
}

void cache_is(fat32::dd disk, const disks::partition_descriptor& partition){
    auto fs_information_sector = partition.start + static_cast<uint64_t>(fat_bs->fs_information_sector);

    std::unique_ptr<fat_is_t> fat_is_tmp(new fat_is_t());

    if(read_sectors(disk, fs_information_sector, 1, fat_is_tmp.get())){
        fat_is = fat_is_tmp.release();

        //TODO fat_is->signature_start should be 0x52 0x52 0x61 0x41
        //TODO fat_is->signature_middle should be 0x72 0x72 0x41 0x61
        //TODO fat_is->signature_end should be 0x00 0x00 0x55 0xAA
    } else {
        fat_is = nullptr;
    }
}

uint64_t cluster_lba(uint64_t cluster){
    uint64_t fat_begin = partition_start + fat_bs->reserved_sectors;
    uint64_t cluster_begin = fat_begin + (fat_bs->number_of_fat * fat_bs->sectors_per_fat_long);

    return cluster_begin + (cluster - 2 ) * fat_bs->sectors_per_cluster;
}

uint32_t read_fat_value(fat32::dd disk, uint32_t cluster){
    uint64_t fat_begin = partition_start + fat_bs->reserved_sectors;
    uint32_t cluster_size = 512 * fat_bs->sectors_per_cluster;

    uint64_t fat_sector = fat_begin + (cluster * 4) / cluster_size;

    std::unique_heap_array<uint32_t> fat_table(cluster_size / sizeof(uint32_t));
    if(read_sectors(disk, fat_sector, fat_bs->sectors_per_cluster, fat_table.get())){
        uint64_t entry_offset = ((cluster * 4) % cluster_size) / 4;
        return fat_table[entry_offset] & 0x0FFFFFFF;
    } else {
        return 0;
    }
}

uint32_t next_cluster(fat32::dd disk, uint32_t cluster){
    auto fat_value = read_fat_value(disk, cluster);
    if(fat_value >= 0x0FFFFFF8){
        return 0;
    }

    return fat_value;
}

inline bool entry_used(const cluster_entry& entry){
    return static_cast<unsigned char>(entry.name[0]) != 0xE5;
}

inline bool end_of_directory(const cluster_entry& entry){
    return entry.name[0] == 0x0;
}

inline bool is_long_name(const cluster_entry& entry){
    return entry.attrib == 0x0F;
}

std::vector<disks::file> files(const std::unique_heap_array<cluster_entry>& cluster){
    std::vector<disks::file> files;

    bool end_reached = false;

    for(auto& entry : cluster){
        if(end_of_directory(entry)){
            end_reached = true;
            break;
        }

        if(entry_used(entry)){
            disks::file file;

            if(is_long_name(entry)){
                //It is a long file name
                //TODO Add suppport for long file name
                file.file_name = "LONG";
            } else {
                //It is a normal file name
                //Copy the name until the first space

                for(size_t s = 0; s < 11; ++s){
                    if(entry.name[s] == ' '){
                        break;
                    }

                    file.file_name += entry.name[s];
                }
            }

            file.hidden = entry.attrib & 0x1;
            file.system = entry.attrib & 0x2;
            file.directory = entry.attrib & 0x10;
            file.size = entry.file_size;

            files.push_back(file);
        }
    }

    //TODO If end_reached not true, we should read the next cluster

    return std::move(files);
}

std::vector<disks::file> files(fat32::dd disk, uint64_t cluster_addr){
    std::unique_heap_array<cluster_entry> cluster(16 * fat_bs->sectors_per_cluster);

    if(read_sectors(disk, cluster_lba(cluster_addr), fat_bs->sectors_per_cluster, cluster.get())){
        return files(cluster);
    } else {
        return {};
    }
}

size_t filename_length(char* filename){
    for(size_t s = 0; s < 11; ++s){
        if(filename[s] == ' '){
            return s;
        }
    }

    return 11;
}

bool filename_equals(char* name, const std::string& path){
    auto length = filename_length(name);

    if(path.size() != length){
        return false;
    }

    for(size_t i = 0; i < length; ++i){
        if(path[i] != name[i]){
            return false;
        }
    }

    return true;
}

bool cache_disk_partition(fat32::dd disk, const disks::partition_descriptor& partition){
    if(cached_disk != disk.uuid || cached_partition != partition.uuid){
        partition_start = partition.start;

        cache_bs(disk, partition);
        cache_is(disk, partition);

        cached_disk = disk.uuid;
        cached_partition = partition.uuid;
    }

    //Something may go wrong when reading the two base vectors
    return fat_bs && fat_is;
}

std::pair<bool, std::unique_heap_array<cluster_entry>> find_cluster(fat32::dd disk, const std::vector<std::string>& path){
    auto cluster_addr = cluster_lba(fat_bs->root_directory_cluster_start);

    std::unique_heap_array<cluster_entry> current_cluster(16 * fat_bs->sectors_per_cluster);

    if(read_sectors(disk, cluster_addr, fat_bs->sectors_per_cluster, current_cluster.get())){
        for(auto& p : path){
            bool found = false;
            bool end_reached = false;

            for(auto& entry : current_cluster){
                if(end_of_directory(entry)){
                    end_reached = true;
                    break;
                }

                if(entry_used(entry) && !is_long_name(entry) && entry.attrib & 0x10){
                    //entry.name is not a real c_string, cannot be compared
                    //directly
                    if(filename_equals(entry.name, p)){
                        std::unique_heap_array<cluster_entry> cluster(16 * fat_bs->sectors_per_cluster);

                        if(read_sectors(disk, cluster_lba(entry.cluster_low + (entry.cluster_high << 16)),
                                fat_bs->sectors_per_cluster, cluster.get())){
                            current_cluster = std::move(cluster);
                            found = true;

                            break;
                        } else {
                            return std::make_pair(false, std::unique_heap_array<cluster_entry>());
                        }
                    }
                }
            }

            if(!found){
                //TODO If not end_reached, read the next cluster

                return std::make_pair(false, std::unique_heap_array<cluster_entry>());
            }
        }

        return std::make_pair(true, std::move(current_cluster));
    }

    return std::make_pair(false, std::unique_heap_array<cluster_entry>());
}

} //end of anonymous namespace

uint64_t fat32::free_size(dd disk, const disks::partition_descriptor& partition){
    if(!cache_disk_partition(disk, partition)){
        return 0;
    }

    return fat_is->free_clusters * fat_bs->sectors_per_cluster * 512;
}

std::vector<disks::file> fat32::ls(dd disk, const disks::partition_descriptor& partition, const std::vector<std::string>& path){
    if(!cache_disk_partition(disk, partition)){
        return {};
    }

    auto cluster = find_cluster(disk, path);

    if(cluster.first){
        return files(cluster.second);
    } else {
        return {};
    }
}

std::string fat32::read_file(dd disk, const disks::partition_descriptor& partition, const std::vector<std::string>& path, const std::string& file){
    if(!cache_disk_partition(disk, partition)){
        return {};
    }

    auto result = find_cluster(disk, path);

    if(result.first){
        auto& directory_cluster = result.second;

        bool found = false;
        bool end_reached = false;

        for(auto& entry : directory_cluster){
            if(end_of_directory(entry)){
                end_reached = true;
                break;
            }

            if(entry_used(entry) && !is_long_name(entry) && !(entry.attrib & 0x10)){
                if(filename_equals(entry.name, file)){
                    std::string content(entry.file_size + 1);

                    auto cluster = entry.cluster_low + (entry.cluster_high << 16);

                    size_t read = 0;

                    while(read < entry.file_size){
                        size_t cluster_size = 512 * fat_bs->sectors_per_cluster;
                        std::unique_heap_array<char> sector(cluster_size);

                        if(read_sectors(disk, cluster_lba(cluster), fat_bs->sectors_per_cluster, sector.get())){
                            for(size_t i = 0; i < cluster_size && read < entry.file_size; ++i,++read){
                                content += sector[i];
                            }
                        } else {
                            break;
                        }

                        //If the file is not read completely, get the next
                        //cluster
                        if(read < entry.file_size){
                            auto next = next_cluster(disk, cluster);

                            //It may be possible that either the file size or
                            //the FAT entry is wrong
                            if(!next){
                                break;
                            }

                            //The block is corrupted
                            if(next == 0x0FFFFFF7){
                                break;
                            }

                            cluster = next;
                        }
                    }

                    return std::move(content);
                }
            }
        }

        if(!found && end_reached){
            //TODO Read the next cluster to find the file
        }
    }

    return {};
}
<commit_msg>Refactor<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include "fat32.hpp"
#include "console.hpp"

#include "stl/types.hpp"
#include "stl/unique_ptr.hpp"
#include "stl/algorithms.hpp"
#include "stl/pair.hpp"

namespace {

//FAT 32 Boot Sector
struct fat_bs_t {
    uint8_t jump[3];
    char oem_name[8];
    uint16_t bytes_per_sector;
    uint8_t sectors_per_cluster;
    uint16_t reserved_sectors;
    uint8_t number_of_fat;
    uint16_t root_directories_entries;
    uint16_t total_sectors;
    uint8_t media_descriptor;
    uint16_t sectors_per_fat;
    uint16_t sectors_per_track;
    uint16_t heads;
    uint32_t hidden_sectors;
    uint32_t total_sectors_long;
    uint32_t sectors_per_fat_long;
    uint16_t drive_description;
    uint16_t version;
    uint32_t root_directory_cluster_start;
    uint16_t fs_information_sector;
    uint16_t boot_sectors_copy_sector;
    uint8_t filler[12];
    uint8_t physical_drive_number;
    uint8_t reserved;
    uint8_t extended_boot_signature;
    uint32_t volume_id;
    char volume_label[11];
    char file_system_type[8];
    uint8_t boot_code[420];
    uint16_t signature;
}__attribute__ ((packed));

struct fat_is_t {
    uint32_t signature_start;
    uint8_t reserved[480];
    uint32_t signature_middle;
    uint32_t free_clusters;
    uint32_t allocated_clusters;
    uint8_t reserved_2[12];
    uint32_t signature_end;
}__attribute__ ((packed));

static_assert(sizeof(fat_bs_t) == 512, "FAT Boot Sector is exactly one disk sector");

struct cluster_entry {
    char name[11];
    uint8_t attrib;
    uint8_t reserved;
    uint8_t creation_time_seconds;
    uint16_t creation_time;
    uint16_t creation_date;
    uint16_t accessed_date;
    uint16_t cluster_high;
    uint16_t modification_time;
    uint16_t modification_date;
    uint16_t cluster_low;
    uint32_t file_size;
} __attribute__ ((packed));

static_assert(sizeof(cluster_entry) == 32, "A cluster entry is 32 bytes");

uint64_t cached_disk = -1;
uint64_t cached_partition = -1;
uint64_t partition_start;

fat_bs_t* fat_bs = nullptr;
fat_is_t* fat_is = nullptr;

void cache_bs(fat32::dd disk, const disks::partition_descriptor& partition){
    std::unique_ptr<fat_bs_t> fat_bs_tmp(new fat_bs_t());

    if(read_sectors(disk, partition.start, 1, fat_bs_tmp.get())){
        fat_bs = fat_bs_tmp.release();

        //TODO fat_bs->signature should be 0xAA55
        //TODO fat_bs->file_system_type should be FAT32
    } else {
        fat_bs = nullptr;
    }
}

void cache_is(fat32::dd disk, const disks::partition_descriptor& partition){
    auto fs_information_sector = partition.start + static_cast<uint64_t>(fat_bs->fs_information_sector);

    std::unique_ptr<fat_is_t> fat_is_tmp(new fat_is_t());

    if(read_sectors(disk, fs_information_sector, 1, fat_is_tmp.get())){
        fat_is = fat_is_tmp.release();

        //TODO fat_is->signature_start should be 0x52 0x52 0x61 0x41
        //TODO fat_is->signature_middle should be 0x72 0x72 0x41 0x61
        //TODO fat_is->signature_end should be 0x00 0x00 0x55 0xAA
    } else {
        fat_is = nullptr;
    }
}

uint64_t cluster_lba(uint64_t cluster){
    uint64_t fat_begin = partition_start + fat_bs->reserved_sectors;
    uint64_t cluster_begin = fat_begin + (fat_bs->number_of_fat * fat_bs->sectors_per_fat_long);

    return cluster_begin + (cluster - 2 ) * fat_bs->sectors_per_cluster;
}

uint32_t read_fat_value(fat32::dd disk, uint32_t cluster){
    uint64_t fat_begin = partition_start + fat_bs->reserved_sectors;
    uint32_t cluster_size = 512 * fat_bs->sectors_per_cluster;

    uint64_t fat_sector = fat_begin + (cluster * 4) / cluster_size;

    std::unique_heap_array<uint32_t> fat_table(cluster_size / sizeof(uint32_t));
    if(read_sectors(disk, fat_sector, fat_bs->sectors_per_cluster, fat_table.get())){
        uint64_t entry_offset = ((cluster * 4) % cluster_size) / 4;
        return fat_table[entry_offset] & 0x0FFFFFFF;
    } else {
        return 0;
    }
}

uint32_t next_cluster(fat32::dd disk, uint32_t cluster){
    auto fat_value = read_fat_value(disk, cluster);
    if(fat_value >= 0x0FFFFFF8){
        return 0;
    }

    return fat_value;
}

inline bool entry_used(const cluster_entry& entry){
    return static_cast<unsigned char>(entry.name[0]) != 0xE5;
}

inline bool end_of_directory(const cluster_entry& entry){
    return entry.name[0] == 0x0;
}

inline bool is_long_name(const cluster_entry& entry){
    return entry.attrib == 0x0F;
}

size_t filename_length(char* filename){
    for(size_t s = 0; s < 11; ++s){
        if(filename[s] == ' '){
            return s;
        }
    }

    return 11;
}

bool filename_equals(char* name, const std::string& path){
    auto length = filename_length(name);

    if(path.size() != length){
        return false;
    }

    for(size_t i = 0; i < length; ++i){
        if(path[i] != name[i]){
            return false;
        }
    }

    return true;
}

bool cache_disk_partition(fat32::dd disk, const disks::partition_descriptor& partition){
    if(cached_disk != disk.uuid || cached_partition != partition.uuid){
        partition_start = partition.start;

        cache_bs(disk, partition);
        cache_is(disk, partition);

        cached_disk = disk.uuid;
        cached_partition = partition.uuid;
    }

    //Something may go wrong when reading the two base vectors
    return fat_bs && fat_is;
}

std::pair<bool, uint32_t> find_cluster_number(fat32::dd disk, const std::vector<std::string>& path){
    if(path.empty()){
        return std::make_pair(true, (uint32_t) fat_bs->root_directory_cluster_start);
    }

    auto cluster_addr = cluster_lba(fat_bs->root_directory_cluster_start);

    std::unique_heap_array<cluster_entry> current_cluster(16 * fat_bs->sectors_per_cluster);

    if(read_sectors(disk, cluster_addr, fat_bs->sectors_per_cluster, current_cluster.get())){
        for(size_t i = 0; i < path.size(); ++i){
            auto& p = path[i];

            bool found = false;
            bool end_reached = false;

            for(auto& entry : current_cluster){
                if(end_of_directory(entry)){
                    end_reached = true;
                    break;
                }

                if(entry_used(entry) && !is_long_name(entry) && entry.attrib & 0x10){
                    //entry.name is not a real c_string, cannot be compared
                    //directly
                    if(filename_equals(entry.name, p)){
                        auto cluster_number = entry.cluster_low + (entry.cluster_high << 16);

                        //If it is the last part of the path, just return the
                        //number
                        if(i == path.size() - 1){
                            return std::make_pair(true, cluster_number);
                        }

                        //Otherwise, continue deeper in the search

                        std::unique_heap_array<cluster_entry> cluster(16 * fat_bs->sectors_per_cluster);

                        if(read_sectors(disk, cluster_lba(cluster_number), fat_bs->sectors_per_cluster, cluster.get())){
                            current_cluster = std::move(cluster);
                            found = true;

                            break;
                        } else {
                            return std::make_pair(false, 0);
                        }
                    }
                }
            }

            if(!found){
                //TODO If not end_reached, read the next cluster

                return std::make_pair(false, 0);
            }
        }
    }

    return std::make_pair(false, 0);
}

std::pair<bool, std::unique_heap_array<cluster_entry>> find_cluster(fat32::dd disk, const std::vector<std::string>& path){
    auto cluster_number = find_cluster_number(disk, path);

    if(cluster_number.first){
        std::unique_heap_array<cluster_entry> cluster(16 * fat_bs->sectors_per_cluster);

        if(read_sectors(disk, cluster_lba(cluster_number.second), fat_bs->sectors_per_cluster, cluster.get())){
            return std::make_pair(true, std::move(cluster));
        } else {
            return std::make_pair(false, std::unique_heap_array<cluster_entry>());
        }
    }

    return std::make_pair(false, std::unique_heap_array<cluster_entry>());
}

std::vector<disks::file> files(const std::unique_heap_array<cluster_entry>& cluster){
    std::vector<disks::file> files;

    bool end_reached = false;

    for(auto& entry : cluster){
        if(end_of_directory(entry)){
            end_reached = true;
            break;
        }

        if(entry_used(entry)){
            disks::file file;

            if(is_long_name(entry)){
                //It is a long file name
                //TODO Add suppport for long file name
                file.file_name = "LONG";
            } else {
                //It is a normal file name
                //Copy the name until the first space

                for(size_t s = 0; s < 11; ++s){
                    if(entry.name[s] == ' '){
                        break;
                    }

                    file.file_name += entry.name[s];
                }
            }

            file.hidden = entry.attrib & 0x1;
            file.system = entry.attrib & 0x2;
            file.directory = entry.attrib & 0x10;
            file.size = entry.file_size;

            files.push_back(file);
        }
    }

    //TODO If end_reached not true, we should read the next cluster

    return std::move(files);
}

std::vector<disks::file> files(fat32::dd disk, uint64_t cluster_addr){
    std::unique_heap_array<cluster_entry> cluster(16 * fat_bs->sectors_per_cluster);

    if(read_sectors(disk, cluster_lba(cluster_addr), fat_bs->sectors_per_cluster, cluster.get())){
        return files(cluster);
    } else {
        return {};
    }
}

} //end of anonymous namespace

uint64_t fat32::free_size(dd disk, const disks::partition_descriptor& partition){
    if(!cache_disk_partition(disk, partition)){
        return 0;
    }

    return fat_is->free_clusters * fat_bs->sectors_per_cluster * 512;
}

std::vector<disks::file> fat32::ls(dd disk, const disks::partition_descriptor& partition, const std::vector<std::string>& path){
    if(!cache_disk_partition(disk, partition)){
        return {};
    }

    auto cluster = find_cluster(disk, path);

    if(cluster.first){
        return files(cluster.second);
    } else {
        return {};
    }
}

std::string fat32::read_file(dd disk, const disks::partition_descriptor& partition, const std::vector<std::string>& path, const std::string& file){
    if(!cache_disk_partition(disk, partition)){
        return {};
    }

    auto result = find_cluster(disk, path);

    if(result.first){
        auto& directory_cluster = result.second;

        bool found = false;
        bool end_reached = false;

        for(auto& entry : directory_cluster){
            if(end_of_directory(entry)){
                end_reached = true;
                break;
            }

            if(entry_used(entry) && !is_long_name(entry) && !(entry.attrib & 0x10)){
                if(filename_equals(entry.name, file)){
                    std::string content(entry.file_size + 1);

                    auto cluster = entry.cluster_low + (entry.cluster_high << 16);

                    size_t read = 0;

                    while(read < entry.file_size){
                        size_t cluster_size = 512 * fat_bs->sectors_per_cluster;
                        std::unique_heap_array<char> sector(cluster_size);

                        if(read_sectors(disk, cluster_lba(cluster), fat_bs->sectors_per_cluster, sector.get())){
                            for(size_t i = 0; i < cluster_size && read < entry.file_size; ++i,++read){
                                content += sector[i];
                            }
                        } else {
                            break;
                        }

                        //If the file is not read completely, get the next
                        //cluster
                        if(read < entry.file_size){
                            auto next = next_cluster(disk, cluster);

                            //It may be possible that either the file size or
                            //the FAT entry is wrong
                            if(!next){
                                break;
                            }

                            //The block is corrupted
                            if(next == 0x0FFFFFF7){
                                break;
                            }

                            cluster = next;
                        }
                    }

                    return std::move(content);
                }
            }
        }

        if(!found && end_reached){
            //TODO Read the next cluster to find the file
        }
    }

    return {};
}
<|endoftext|>


<commit_before>#include "vlsim.h"
#include "verilated.h"
#include <XsimTop.h>
#include <ConnectalProjectConfig.h>

#ifdef BSV_POSITIVE_RESET
  #define BSV_RESET_VALUE 1
  #define BSV_RESET_EDGE 0 //posedge
#else
  #define BSV_RESET_VALUE 0
  #define BSV_RESET_EDGE 1 //negedge
#endif

#if VM_TRACE
# include <verilated_vcd_c.h>   // Trace file format header
#endif

vluint64_t main_time = 0;
int main(int argc, char **argv, char **env)
{
  fprintf(stderr, "vlsim::main\n");
  Verilated::commandArgs(argc, argv);
  vlsim* top = new vlsim;

  fprintf(stderr, "vlsim calling dpi_init\n");
  dpi_init();

#if VM_TRACE                    // If verilator was invoked with --trace
  Verilated::traceEverOn(true);       // Verilator must compute traced signals
  VL_PRINTF("Enabling waves...\n");
  VerilatedVcdC* tfp = new VerilatedVcdC;
  top->trace (tfp, 4);       // Trace 4 levels of hierarchy
  tfp->open ("vlt_dump.vcd"); // Open the dump file
#endif

  fprintf(stderr, "starting simulation\n");
  top->CLK = 0;
  top->RST_N = BSV_RESET_VALUE;
  while (!Verilated::gotFinish()) {
    if (main_time >= 10) {
      if ((top->CLK == BSV_RESET_EDGE) && (top->RST_N == BSV_RESET_VALUE)) {
	fprintf(stderr, "time=%d leaving reset new value %d\n", main_time, !BSV_RESET_VALUE);
	top->RST_N = !BSV_RESET_VALUE;
      }
    }

    if ((main_time % 2) == 1) {	// Toggle clock
      top->CLK = 1;
    }
    if ((main_time % 2) == 0) {
      top->CLK = 0;
    }
    top->eval();

#if VM_TRACE
    if (tfp) tfp->dump (main_time); // Create waveform trace for this timestamp
#endif

    main_time++;
  }
  top->final();

#if VM_TRACE
  if (tfp) tfp->close();
#endif

  delete top;
  exit(0);
}
<commit_msg>call vl_finish when done (e.g., software disconnected from simulator)<commit_after>#include "vlsim.h"
#include "verilated.h"
#include <XsimTop.h>
#include <ConnectalProjectConfig.h>

#ifdef BSV_POSITIVE_RESET
  #define BSV_RESET_VALUE 1
  #define BSV_RESET_EDGE 0 //posedge
#else
  #define BSV_RESET_VALUE 0
  #define BSV_RESET_EDGE 1 //negedge
#endif

#if VM_TRACE
# include <verilated_vcd_c.h>   // Trace file format header
#endif

vluint64_t main_time = 0;
int main(int argc, char **argv, char **env)
{
  fprintf(stderr, "vlsim::main\n");
  Verilated::commandArgs(argc, argv);
  vlsim* top = new vlsim;

  fprintf(stderr, "vlsim calling dpi_init\n");
  dpi_init();

#if VM_TRACE                    // If verilator was invoked with --trace
  Verilated::traceEverOn(true);       // Verilator must compute traced signals
  VL_PRINTF("Enabling waves...\n");
  VerilatedVcdC* tfp = new VerilatedVcdC;
  top->trace (tfp, 4);       // Trace 4 levels of hierarchy
  tfp->open ("vlt_dump.vcd"); // Open the dump file
#endif

  fprintf(stderr, "starting simulation\n");
  top->CLK = 0;
  top->RST_N = BSV_RESET_VALUE;
  while (!Verilated::gotFinish()) {
    if (main_time >= 10) {
      if ((top->CLK == BSV_RESET_EDGE) && (top->RST_N == BSV_RESET_VALUE)) {
	fprintf(stderr, "time=%ld leaving reset new value %d\n", (long)main_time, !BSV_RESET_VALUE);
	top->RST_N = !BSV_RESET_VALUE;
      }
    }

    if (dpi_finish())
      vl_finish(__FILE__, __LINE__, "vlsim");

    if ((main_time % 2) == 1) {	// Toggle clock
      top->CLK = 1;
    }
    if ((main_time % 2) == 0) {
      top->CLK = 0;
    }
    top->eval();

#if VM_TRACE
    if (tfp) tfp->dump (main_time); // Create waveform trace for this timestamp
#endif

    main_time++;
  }
  top->final();

#if VM_TRACE
  if (tfp) tfp->close();
#endif

  delete top;
  exit(0);
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

/** this file contains the uno service registrations for all services in the svxcore lib */

#include "sal/types.h"
#include "osl/diagnose.h"
#include "cppuhelper/factory.hxx"

#include <coreservices.hxx>

using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::registry;

extern "C"
{

SAL_DLLPUBLIC_EXPORT void * SAL_CALL svxcore_component_getFactory (
    const sal_Char * pImplName, void * pServiceManager, void *  )
{
    void * pRet = 0;
    if( pServiceManager  )
    {
        Reference< XSingleServiceFactory > xFactory;

        if( ::svx::ExtrusionDepthController_getImplementationName().equalsAscii( pImplName ) )
        {
            xFactory = ::cppu::createSingleFactory(
                reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
                ::svx::ExtrusionDepthController_getImplementationName(),
                ::svx::ExtrusionDepthController_createInstance,
                ::svx::ExtrusionDepthController_getSupportedServiceNames() );
        }
        else if( ::svx::ExtrusionDirectionControl_getImplementationName().equalsAscii( pImplName ) )
        {
            xFactory = ::cppu::createSingleFactory(
                reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
                ::svx::ExtrusionDirectionControl_getImplementationName(),
                ::svx::ExtrusionDirectionControl_createInstance,
                ::svx::ExtrusionDirectionControl_getSupportedServiceNames() );
        }
        else if( ::svx::ExtrusionLightingControl_getImplementationName().equalsAscii( pImplName ) )
        {
            xFactory = ::cppu::createSingleFactory(
                reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
                ::svx::ExtrusionLightingControl_getImplementationName(),
                ::svx::ExtrusionLightingControl_createInstance,
                ::svx::ExtrusionLightingControl_getSupportedServiceNames() );
        }
        else if( ::svx::ExtrusionSurfaceControl_getImplementationName().equalsAscii( pImplName ) )
        {
            xFactory = ::cppu::createSingleFactory(
                reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
                ::svx::ExtrusionSurfaceControl_getImplementationName(),
                ::svx::ExtrusionSurfaceControl_createInstance,
                ::svx::ExtrusionSurfaceControl_getSupportedServiceNames() );
        }
        else if( ::svx::FontworkAlignmentControl_getImplementationName().equalsAscii( pImplName ) )
        {
            xFactory = ::cppu::createSingleFactory(
                reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
                ::svx::FontworkAlignmentControl_getImplementationName(),
                ::svx::FontworkAlignmentControl_createInstance,
                ::svx::FontworkAlignmentControl_getSupportedServiceNames() );
        }
        else if( ::svx::FontworkCharacterSpacingControl_getImplementationName().equalsAscii( pImplName ) )
        {
            xFactory = ::cppu::createSingleFactory(
                reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
                ::svx::FontworkCharacterSpacingControl_getImplementationName(),
                ::svx::FontworkCharacterSpacingControl_createInstance,
                ::svx::FontworkCharacterSpacingControl_getSupportedServiceNames() );
        }       if( xFactory.is())
        {
            xFactory->acquire();
            pRet = xFactory.get();
        }
    }

    return pRet;
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Reduce to static_cast any reinterpret_cast from void pointers<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

/** this file contains the uno service registrations for all services in the svxcore lib */

#include "sal/types.h"
#include "osl/diagnose.h"
#include "cppuhelper/factory.hxx"

#include <coreservices.hxx>

using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::registry;

extern "C"
{

SAL_DLLPUBLIC_EXPORT void * SAL_CALL svxcore_component_getFactory (
    const sal_Char * pImplName, void * pServiceManager, void *  )
{
    void * pRet = 0;
    if( pServiceManager  )
    {
        Reference< XSingleServiceFactory > xFactory;

        if( ::svx::ExtrusionDepthController_getImplementationName().equalsAscii( pImplName ) )
        {
            xFactory = ::cppu::createSingleFactory(
                static_cast< XMultiServiceFactory * >( pServiceManager ),
                ::svx::ExtrusionDepthController_getImplementationName(),
                ::svx::ExtrusionDepthController_createInstance,
                ::svx::ExtrusionDepthController_getSupportedServiceNames() );
        }
        else if( ::svx::ExtrusionDirectionControl_getImplementationName().equalsAscii( pImplName ) )
        {
            xFactory = ::cppu::createSingleFactory(
                static_cast< XMultiServiceFactory * >( pServiceManager ),
                ::svx::ExtrusionDirectionControl_getImplementationName(),
                ::svx::ExtrusionDirectionControl_createInstance,
                ::svx::ExtrusionDirectionControl_getSupportedServiceNames() );
        }
        else if( ::svx::ExtrusionLightingControl_getImplementationName().equalsAscii( pImplName ) )
        {
            xFactory = ::cppu::createSingleFactory(
                static_cast< XMultiServiceFactory * >( pServiceManager ),
                ::svx::ExtrusionLightingControl_getImplementationName(),
                ::svx::ExtrusionLightingControl_createInstance,
                ::svx::ExtrusionLightingControl_getSupportedServiceNames() );
        }
        else if( ::svx::ExtrusionSurfaceControl_getImplementationName().equalsAscii( pImplName ) )
        {
            xFactory = ::cppu::createSingleFactory(
                static_cast< XMultiServiceFactory * >( pServiceManager ),
                ::svx::ExtrusionSurfaceControl_getImplementationName(),
                ::svx::ExtrusionSurfaceControl_createInstance,
                ::svx::ExtrusionSurfaceControl_getSupportedServiceNames() );
        }
        else if( ::svx::FontworkAlignmentControl_getImplementationName().equalsAscii( pImplName ) )
        {
            xFactory = ::cppu::createSingleFactory(
                static_cast< XMultiServiceFactory * >( pServiceManager ),
                ::svx::FontworkAlignmentControl_getImplementationName(),
                ::svx::FontworkAlignmentControl_createInstance,
                ::svx::FontworkAlignmentControl_getSupportedServiceNames() );
        }
        else if( ::svx::FontworkCharacterSpacingControl_getImplementationName().equalsAscii( pImplName ) )
        {
            xFactory = ::cppu::createSingleFactory(
                static_cast< XMultiServiceFactory * >( pServiceManager ),
                ::svx::FontworkCharacterSpacingControl_getImplementationName(),
                ::svx::FontworkCharacterSpacingControl_createInstance,
                ::svx::FontworkCharacterSpacingControl_getSupportedServiceNames() );
        }       if( xFactory.is())
        {
            xFactory->acquire();
            pRet = xFactory.get();
        }
    }

    return pRet;
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: borderconn.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2004-08-02 17:42:37 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRUNTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SVX_BORDERCONN_HXX
#include "borderconn.hxx"
#endif

#ifndef SVX_FRMSEL_HXX
#include "frmsel.hxx"
#endif

#define ITEMID_LINE     0
#define ITEMID_BOX      0
#define ITEMID_BOXINFO  0
#define ITEMID_MARGIN   SID_ATTR_ALIGN_MARGIN
#define ITEMID_SHADOW   SID_ATTR_BORDER_SHADOW

#ifndef _SVX_BOLNITEM_HXX
#include "bolnitem.hxx"
#endif
#ifndef _SVX_BOXITEM_HXX
#include "boxitem.hxx"
#endif
#ifndef _SVX_ALGITEM_HXX
#include "algitem.hxx"
#endif
#ifndef _SVX_SHADITEM_HXX
#include "shaditem.hxx"
#endif

namespace svx {

/* ============================================================================
SvxLineItem connection
----------------------
Connects an SvxLineItem (that contains the style of one line of a cell border)
with one frame border from a svx::FrameSelector control. If this connection is
used, no additional code is needed in the Reset() and FillItemSet() functions
of the tab page.
============================================================================ */

// 1st: item wrappers ---------------------------------------------------------

class LineItemWrapper : public sfx::SingleItemWrapper< SvxLineItem, const SvxBorderLine* >
{
public:
    inline explicit     LineItemWrapper( USHORT nSlot ) : SingleItemWrapperType( nSlot ) {}

    virtual const SvxBorderLine* GetItemValue( const SvxLineItem& rItem ) const
                            { return rItem.GetLine(); }
    virtual void        SetItemValue( SvxLineItem& rItem, const SvxBorderLine* pLine ) const
                            { rItem.SetLine( pLine ); }
};

// 2nd: control wrappers ------------------------------------------------------

class FrameSelectorWrapper : public sfx::SingleControlWrapper< FrameSelector, const SvxBorderLine* >
{
public:
    inline explicit     FrameSelectorWrapper( FrameSelector& rFrameSel, FrameBorderType eBorder ) :
                            SingleControlWrapperType( rFrameSel ), meBorder( eBorder ) {}

    virtual bool        IsControlDontKnow() const;
    virtual void        SetControlDontKnow( bool bSet );

    virtual const SvxBorderLine* GetControlValue() const;
    virtual void        SetControlValue( const SvxBorderLine* pLine );

private:
    FrameBorderType       meBorder;         /// The line this wrapper works with.
};

bool FrameSelectorWrapper::IsControlDontKnow() const
{
    return GetControl().GetBorderState( meBorder ) == FRAMESTATE_DONTCARE;
}

void FrameSelectorWrapper::SetControlDontKnow( bool bSet )
{
    if( bSet )
        GetControl().SetBorderDontCare( meBorder );
}

const SvxBorderLine* FrameSelectorWrapper::GetControlValue() const
{
    return GetControl().GetBorderStyle( meBorder );
}

void FrameSelectorWrapper::SetControlValue( const SvxBorderLine* pLine )
{
    GetControl().ShowBorder( meBorder, pLine );
}

// 3rd: connection ------------------------------------------------------------

typedef sfx::ItemControlConnection< LineItemWrapper, FrameSelectorWrapper > FrameLineConnection;

/* ============================================================================
SvxMarginItem connection
------------------------
Connects an SvxMarginItem (that contains the inner margin of all cell borders)
with the numerical edit controls of the SvxBorderTabPage. If this connection is
used, no additional code is needed in the Reset() and FillItemSet() functions
of the tab page.
============================================================================ */

// 1st: item wrappers ---------------------------------------------------------

typedef sfx::IdentItemWrapper< SvxMarginItem > MarginItemWrapper;

// 2nd: control wrappers ------------------------------------------------------

class MarginControlsWrapper : public sfx::MultiControlWrapper< SvxMarginItem >
{
public:
    explicit            MarginControlsWrapper(
                            MetricField& rMfLeft, MetricField& rMfRight,
                            MetricField& rMfTop, MetricField& rMfBottom );

    virtual SvxMarginItem GetControlValue() const;
    virtual void        SetControlValue( SvxMarginItem aItem );

private:
    sfx::Int16MetricFieldWrapper maLeftWrp;
    sfx::Int16MetricFieldWrapper maRightWrp;
    sfx::Int16MetricFieldWrapper maTopWrp;
    sfx::Int16MetricFieldWrapper maBottomWrp;
};

MarginControlsWrapper::MarginControlsWrapper(
        MetricField& rMfLeft, MetricField& rMfRight, MetricField& rMfTop, MetricField& rMfBottom ) :
    maLeftWrp( rMfLeft, FUNIT_TWIP ),
    maRightWrp( rMfRight, FUNIT_TWIP ),
    maTopWrp( rMfTop, FUNIT_TWIP ),
    maBottomWrp( rMfBottom, FUNIT_TWIP )
{
    RegisterControlWrapper( maLeftWrp );
    RegisterControlWrapper( maRightWrp );
    RegisterControlWrapper( maTopWrp );
    RegisterControlWrapper( maBottomWrp );
}

SvxMarginItem MarginControlsWrapper::GetControlValue() const
{
    SvxMarginItem aItem( GetDefaultValue() );
    if( !maLeftWrp.IsControlDontKnow() )
        aItem.SetLeftMargin( maLeftWrp.GetControlValue() );
    if( !maRightWrp.IsControlDontKnow() )
        aItem.SetRightMargin( maRightWrp.GetControlValue() );
    if( !maTopWrp.IsControlDontKnow() )
        aItem.SetTopMargin( maTopWrp.GetControlValue() );
    if( !maBottomWrp.IsControlDontKnow() )
        aItem.SetBottomMargin( maBottomWrp.GetControlValue() );
    return aItem;
}

void MarginControlsWrapper::SetControlValue( SvxMarginItem aItem )
{
    maLeftWrp.SetControlValue( aItem.GetLeftMargin() );
    maRightWrp.SetControlValue( aItem.GetRightMargin() );
    maTopWrp.SetControlValue( aItem.GetTopMargin() );
    maBottomWrp.SetControlValue( aItem.GetBottomMargin() );
}

// 3rd: connection ------------------------------------------------------------

class MarginConnection : public sfx::ItemControlConnection< MarginItemWrapper, MarginControlsWrapper >
{
public:
    explicit            MarginConnection( const SfxItemSet& rItemSet,
                            MetricField& rMfLeft, MetricField& rMfRight,
                            MetricField& rMfTop, MetricField& rMfBottom,
                            sfx::ItemConnFlags nFlags = sfx::ITEMCONN_DEFAULT );
};

MarginConnection::MarginConnection( const SfxItemSet& rItemSet,
        MetricField& rMfLeft, MetricField& rMfRight, MetricField& rMfTop, MetricField& rMfBottom,
        sfx::ItemConnFlags nFlags ) :
    ItemControlConnectionType( ITEMID_MARGIN, new MarginControlsWrapper( rMfLeft, rMfRight, rMfTop, rMfBottom ), nFlags )
{
    mxCtrlWrp->SetDefaultValue( maItemWrp.GetDefaultItem( rItemSet ) );
}

/* ============================================================================
SvxShadowItem connection
------------------------
Connects an SvxShadowItem (that contains shadow position, size, and color) with
the controls of the SvxBorderTabPage. If this connection is used, no additional
code is needed in the Reset() and FillItemSet() functions of the tab page.
============================================================================ */

// 1st: item wrappers ---------------------------------------------------------

typedef sfx::IdentItemWrapper< SvxShadowItem > ShadowItemWrapper;

// 2nd: control wrappers ------------------------------------------------------

typedef sfx::ValueSetWrapper< SvxShadowLocation > ShadowPosWrapper;
static const ShadowPosWrapper::MapEntryType s_pShadowPosMap[] =
{
    { 1,                        SVX_SHADOW_NONE         },
    { 2,                        SVX_SHADOW_BOTTOMRIGHT  },
    { 3,                        SVX_SHADOW_TOPRIGHT     },
    { 4,                        SVX_SHADOW_BOTTOMLEFT   },
    { 5,                        SVX_SHADOW_TOPLEFT      },
    { VALUESET_ITEM_NOTFOUND,   SVX_SHADOW_NONE         }
};

class ShadowControlsWrapper : public sfx::MultiControlWrapper< SvxShadowItem >
{
public:
    explicit            ShadowControlsWrapper( ValueSet& rVsPos, MetricField& rMfSize, ColorListBox& rLbColor );

    virtual SvxShadowItem GetControlValue() const;
    virtual void        SetControlValue( SvxShadowItem aItem );

private:
    ShadowPosWrapper                maPosWrp;
    sfx::UShortMetricFieldWrapper   maSizeWrp;
    sfx::ColorListBoxWrapper        maColorWrp;
};

ShadowControlsWrapper::ShadowControlsWrapper(
        ValueSet& rVsPos, MetricField& rMfSize, ColorListBox& rLbColor ) :
    maPosWrp( rVsPos, s_pShadowPosMap ),
    maSizeWrp( rMfSize, FUNIT_TWIP ),
    maColorWrp( rLbColor )
{
    RegisterControlWrapper( maPosWrp );
    RegisterControlWrapper( maSizeWrp );
    RegisterControlWrapper( maColorWrp );
}

SvxShadowItem ShadowControlsWrapper::GetControlValue() const
{
    SvxShadowItem aItem( GetDefaultValue() );
    if( !maPosWrp.IsControlDontKnow() )
        aItem.SetLocation( maPosWrp.GetControlValue() );
    if( !maSizeWrp.IsControlDontKnow() )
        aItem.SetWidth( maSizeWrp.GetControlValue() );
    if( !maColorWrp.IsControlDontKnow() )
        aItem.SetColor( maColorWrp.GetControlValue() );
    return aItem;
}

void ShadowControlsWrapper::SetControlValue( SvxShadowItem aItem )
{
    maPosWrp.SetControlValue( aItem.GetLocation() );
    maSizeWrp.SetControlValue( aItem.GetWidth() );
    maColorWrp.SetControlValue( aItem.GetColor() );
}

// 3rd: connection ------------------------------------------------------------

class ShadowConnection : public sfx::ItemControlConnection< ShadowItemWrapper, ShadowControlsWrapper >
{
public:
    explicit            ShadowConnection( const SfxItemSet& rItemSet,
                                ValueSet& rVsPos, MetricField& rMfSize, ColorListBox& rLbColor,
                                sfx::ItemConnFlags nFlags = sfx::ITEMCONN_DEFAULT );
};

ShadowConnection::ShadowConnection( const SfxItemSet& rItemSet,
        ValueSet& rVsPos, MetricField& rMfSize, ColorListBox& rLbColor, sfx::ItemConnFlags nFlags ) :
    ItemControlConnectionType( ITEMID_SHADOW, new ShadowControlsWrapper( rVsPos, rMfSize, rLbColor ), nFlags )
{
    mxCtrlWrp->SetDefaultValue( maItemWrp.GetDefaultItem( rItemSet ) );
}

// ============================================================================
// ============================================================================

sfx::ItemConnectionBase* CreateFrameLineConnection( USHORT nSlot,
        FrameSelector& rFrameSel, FrameBorderType eBorder, sfx::ItemConnFlags nFlags )
{
    return new FrameLineConnection( nSlot, new FrameSelectorWrapper( rFrameSel, eBorder ), nFlags );
}

sfx::ItemConnectionBase* CreateFrameBoxConnection( USHORT nBoxSlot, USHORT nBoxInfoSlot,
        FrameSelector& rFrameSel, FrameBorderType eBorder, sfx::ItemConnFlags nFlags )
{
    DBG_ERRORFILE( "svx::CreateFrameBoxConnection - not implemented" );
    return 0;
}

sfx::ItemConnectionBase* CreateMarginConnection( const SfxItemSet& rItemSet,
        MetricField& rMfLeft, MetricField& rMfRight,
        MetricField& rMfTop, MetricField& rMfBottom,
        sfx::ItemConnFlags nFlags )
{
    return new MarginConnection( rItemSet, rMfLeft, rMfRight, rMfTop, rMfBottom, nFlags );
}

sfx::ItemConnectionBase* CreateShadowConnection( const SfxItemSet& rItemSet,
        ValueSet& rVsPos, MetricField& rMfSize, ColorListBox& rLbColor,
        sfx::ItemConnFlags nFlags )
{
    return new ShadowConnection( rItemSet, rVsPos, rMfSize, rLbColor, nFlags );
}

// ============================================================================

} // namespace svx

<commit_msg>INTEGRATION: CWS ooo19126 (1.2.756); FILE MERGED 2005/09/05 14:19:05 rt 1.2.756.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: borderconn.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 20:38:16 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SVX_BORDERCONN_HXX
#include "borderconn.hxx"
#endif

#ifndef SVX_FRMSEL_HXX
#include "frmsel.hxx"
#endif

#define ITEMID_LINE     0
#define ITEMID_BOX      0
#define ITEMID_BOXINFO  0
#define ITEMID_MARGIN   SID_ATTR_ALIGN_MARGIN
#define ITEMID_SHADOW   SID_ATTR_BORDER_SHADOW

#ifndef _SVX_BOLNITEM_HXX
#include "bolnitem.hxx"
#endif
#ifndef _SVX_BOXITEM_HXX
#include "boxitem.hxx"
#endif
#ifndef _SVX_ALGITEM_HXX
#include "algitem.hxx"
#endif
#ifndef _SVX_SHADITEM_HXX
#include "shaditem.hxx"
#endif

namespace svx {

/* ============================================================================
SvxLineItem connection
----------------------
Connects an SvxLineItem (that contains the style of one line of a cell border)
with one frame border from a svx::FrameSelector control. If this connection is
used, no additional code is needed in the Reset() and FillItemSet() functions
of the tab page.
============================================================================ */

// 1st: item wrappers ---------------------------------------------------------

class LineItemWrapper : public sfx::SingleItemWrapper< SvxLineItem, const SvxBorderLine* >
{
public:
    inline explicit     LineItemWrapper( USHORT nSlot ) : SingleItemWrapperType( nSlot ) {}

    virtual const SvxBorderLine* GetItemValue( const SvxLineItem& rItem ) const
                            { return rItem.GetLine(); }
    virtual void        SetItemValue( SvxLineItem& rItem, const SvxBorderLine* pLine ) const
                            { rItem.SetLine( pLine ); }
};

// 2nd: control wrappers ------------------------------------------------------

class FrameSelectorWrapper : public sfx::SingleControlWrapper< FrameSelector, const SvxBorderLine* >
{
public:
    inline explicit     FrameSelectorWrapper( FrameSelector& rFrameSel, FrameBorderType eBorder ) :
                            SingleControlWrapperType( rFrameSel ), meBorder( eBorder ) {}

    virtual bool        IsControlDontKnow() const;
    virtual void        SetControlDontKnow( bool bSet );

    virtual const SvxBorderLine* GetControlValue() const;
    virtual void        SetControlValue( const SvxBorderLine* pLine );

private:
    FrameBorderType       meBorder;         /// The line this wrapper works with.
};

bool FrameSelectorWrapper::IsControlDontKnow() const
{
    return GetControl().GetBorderState( meBorder ) == FRAMESTATE_DONTCARE;
}

void FrameSelectorWrapper::SetControlDontKnow( bool bSet )
{
    if( bSet )
        GetControl().SetBorderDontCare( meBorder );
}

const SvxBorderLine* FrameSelectorWrapper::GetControlValue() const
{
    return GetControl().GetBorderStyle( meBorder );
}

void FrameSelectorWrapper::SetControlValue( const SvxBorderLine* pLine )
{
    GetControl().ShowBorder( meBorder, pLine );
}

// 3rd: connection ------------------------------------------------------------

typedef sfx::ItemControlConnection< LineItemWrapper, FrameSelectorWrapper > FrameLineConnection;

/* ============================================================================
SvxMarginItem connection
------------------------
Connects an SvxMarginItem (that contains the inner margin of all cell borders)
with the numerical edit controls of the SvxBorderTabPage. If this connection is
used, no additional code is needed in the Reset() and FillItemSet() functions
of the tab page.
============================================================================ */

// 1st: item wrappers ---------------------------------------------------------

typedef sfx::IdentItemWrapper< SvxMarginItem > MarginItemWrapper;

// 2nd: control wrappers ------------------------------------------------------

class MarginControlsWrapper : public sfx::MultiControlWrapper< SvxMarginItem >
{
public:
    explicit            MarginControlsWrapper(
                            MetricField& rMfLeft, MetricField& rMfRight,
                            MetricField& rMfTop, MetricField& rMfBottom );

    virtual SvxMarginItem GetControlValue() const;
    virtual void        SetControlValue( SvxMarginItem aItem );

private:
    sfx::Int16MetricFieldWrapper maLeftWrp;
    sfx::Int16MetricFieldWrapper maRightWrp;
    sfx::Int16MetricFieldWrapper maTopWrp;
    sfx::Int16MetricFieldWrapper maBottomWrp;
};

MarginControlsWrapper::MarginControlsWrapper(
        MetricField& rMfLeft, MetricField& rMfRight, MetricField& rMfTop, MetricField& rMfBottom ) :
    maLeftWrp( rMfLeft, FUNIT_TWIP ),
    maRightWrp( rMfRight, FUNIT_TWIP ),
    maTopWrp( rMfTop, FUNIT_TWIP ),
    maBottomWrp( rMfBottom, FUNIT_TWIP )
{
    RegisterControlWrapper( maLeftWrp );
    RegisterControlWrapper( maRightWrp );
    RegisterControlWrapper( maTopWrp );
    RegisterControlWrapper( maBottomWrp );
}

SvxMarginItem MarginControlsWrapper::GetControlValue() const
{
    SvxMarginItem aItem( GetDefaultValue() );
    if( !maLeftWrp.IsControlDontKnow() )
        aItem.SetLeftMargin( maLeftWrp.GetControlValue() );
    if( !maRightWrp.IsControlDontKnow() )
        aItem.SetRightMargin( maRightWrp.GetControlValue() );
    if( !maTopWrp.IsControlDontKnow() )
        aItem.SetTopMargin( maTopWrp.GetControlValue() );
    if( !maBottomWrp.IsControlDontKnow() )
        aItem.SetBottomMargin( maBottomWrp.GetControlValue() );
    return aItem;
}

void MarginControlsWrapper::SetControlValue( SvxMarginItem aItem )
{
    maLeftWrp.SetControlValue( aItem.GetLeftMargin() );
    maRightWrp.SetControlValue( aItem.GetRightMargin() );
    maTopWrp.SetControlValue( aItem.GetTopMargin() );
    maBottomWrp.SetControlValue( aItem.GetBottomMargin() );
}

// 3rd: connection ------------------------------------------------------------

class MarginConnection : public sfx::ItemControlConnection< MarginItemWrapper, MarginControlsWrapper >
{
public:
    explicit            MarginConnection( const SfxItemSet& rItemSet,
                            MetricField& rMfLeft, MetricField& rMfRight,
                            MetricField& rMfTop, MetricField& rMfBottom,
                            sfx::ItemConnFlags nFlags = sfx::ITEMCONN_DEFAULT );
};

MarginConnection::MarginConnection( const SfxItemSet& rItemSet,
        MetricField& rMfLeft, MetricField& rMfRight, MetricField& rMfTop, MetricField& rMfBottom,
        sfx::ItemConnFlags nFlags ) :
    ItemControlConnectionType( ITEMID_MARGIN, new MarginControlsWrapper( rMfLeft, rMfRight, rMfTop, rMfBottom ), nFlags )
{
    mxCtrlWrp->SetDefaultValue( maItemWrp.GetDefaultItem( rItemSet ) );
}

/* ============================================================================
SvxShadowItem connection
------------------------
Connects an SvxShadowItem (that contains shadow position, size, and color) with
the controls of the SvxBorderTabPage. If this connection is used, no additional
code is needed in the Reset() and FillItemSet() functions of the tab page.
============================================================================ */

// 1st: item wrappers ---------------------------------------------------------

typedef sfx::IdentItemWrapper< SvxShadowItem > ShadowItemWrapper;

// 2nd: control wrappers ------------------------------------------------------

typedef sfx::ValueSetWrapper< SvxShadowLocation > ShadowPosWrapper;
static const ShadowPosWrapper::MapEntryType s_pShadowPosMap[] =
{
    { 1,                        SVX_SHADOW_NONE         },
    { 2,                        SVX_SHADOW_BOTTOMRIGHT  },
    { 3,                        SVX_SHADOW_TOPRIGHT     },
    { 4,                        SVX_SHADOW_BOTTOMLEFT   },
    { 5,                        SVX_SHADOW_TOPLEFT      },
    { VALUESET_ITEM_NOTFOUND,   SVX_SHADOW_NONE         }
};

class ShadowControlsWrapper : public sfx::MultiControlWrapper< SvxShadowItem >
{
public:
    explicit            ShadowControlsWrapper( ValueSet& rVsPos, MetricField& rMfSize, ColorListBox& rLbColor );

    virtual SvxShadowItem GetControlValue() const;
    virtual void        SetControlValue( SvxShadowItem aItem );

private:
    ShadowPosWrapper                maPosWrp;
    sfx::UShortMetricFieldWrapper   maSizeWrp;
    sfx::ColorListBoxWrapper        maColorWrp;
};

ShadowControlsWrapper::ShadowControlsWrapper(
        ValueSet& rVsPos, MetricField& rMfSize, ColorListBox& rLbColor ) :
    maPosWrp( rVsPos, s_pShadowPosMap ),
    maSizeWrp( rMfSize, FUNIT_TWIP ),
    maColorWrp( rLbColor )
{
    RegisterControlWrapper( maPosWrp );
    RegisterControlWrapper( maSizeWrp );
    RegisterControlWrapper( maColorWrp );
}

SvxShadowItem ShadowControlsWrapper::GetControlValue() const
{
    SvxShadowItem aItem( GetDefaultValue() );
    if( !maPosWrp.IsControlDontKnow() )
        aItem.SetLocation( maPosWrp.GetControlValue() );
    if( !maSizeWrp.IsControlDontKnow() )
        aItem.SetWidth( maSizeWrp.GetControlValue() );
    if( !maColorWrp.IsControlDontKnow() )
        aItem.SetColor( maColorWrp.GetControlValue() );
    return aItem;
}

void ShadowControlsWrapper::SetControlValue( SvxShadowItem aItem )
{
    maPosWrp.SetControlValue( aItem.GetLocation() );
    maSizeWrp.SetControlValue( aItem.GetWidth() );
    maColorWrp.SetControlValue( aItem.GetColor() );
}

// 3rd: connection ------------------------------------------------------------

class ShadowConnection : public sfx::ItemControlConnection< ShadowItemWrapper, ShadowControlsWrapper >
{
public:
    explicit            ShadowConnection( const SfxItemSet& rItemSet,
                                ValueSet& rVsPos, MetricField& rMfSize, ColorListBox& rLbColor,
                                sfx::ItemConnFlags nFlags = sfx::ITEMCONN_DEFAULT );
};

ShadowConnection::ShadowConnection( const SfxItemSet& rItemSet,
        ValueSet& rVsPos, MetricField& rMfSize, ColorListBox& rLbColor, sfx::ItemConnFlags nFlags ) :
    ItemControlConnectionType( ITEMID_SHADOW, new ShadowControlsWrapper( rVsPos, rMfSize, rLbColor ), nFlags )
{
    mxCtrlWrp->SetDefaultValue( maItemWrp.GetDefaultItem( rItemSet ) );
}

// ============================================================================
// ============================================================================

sfx::ItemConnectionBase* CreateFrameLineConnection( USHORT nSlot,
        FrameSelector& rFrameSel, FrameBorderType eBorder, sfx::ItemConnFlags nFlags )
{
    return new FrameLineConnection( nSlot, new FrameSelectorWrapper( rFrameSel, eBorder ), nFlags );
}

sfx::ItemConnectionBase* CreateFrameBoxConnection( USHORT nBoxSlot, USHORT nBoxInfoSlot,
        FrameSelector& rFrameSel, FrameBorderType eBorder, sfx::ItemConnFlags nFlags )
{
    DBG_ERRORFILE( "svx::CreateFrameBoxConnection - not implemented" );
    return 0;
}

sfx::ItemConnectionBase* CreateMarginConnection( const SfxItemSet& rItemSet,
        MetricField& rMfLeft, MetricField& rMfRight,
        MetricField& rMfTop, MetricField& rMfBottom,
        sfx::ItemConnFlags nFlags )
{
    return new MarginConnection( rItemSet, rMfLeft, rMfRight, rMfTop, rMfBottom, nFlags );
}

sfx::ItemConnectionBase* CreateShadowConnection( const SfxItemSet& rItemSet,
        ValueSet& rVsPos, MetricField& rMfSize, ColorListBox& rLbColor,
        sfx::ItemConnFlags nFlags )
{
    return new ShadowConnection( rItemSet, rVsPos, rMfSize, rLbColor, nFlags );
}

// ============================================================================

} // namespace svx

<|endoftext|>


<commit_before><commit_msg>Update D3DDEVICEDESC structure.<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2012-2015 Dano Pernis
// See LICENSE for details

#include <gtk/gtk.h>
#include <glib.h>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <cassert>
#include "CPU.h"

namespace hcc {

struct ROM : public IROM {
    unsigned short *data;
    static const unsigned int size = 0x8000;
    ROM() {
        data = new unsigned short[size];
    }
    virtual ~ROM() {
        delete[] data;
    }

    bool load(const char *filename) {
        std::ifstream input(filename);
        std::string line;
        unsigned int counter = 0;
        while (input.good() && counter < size) {
            getline(input, line);
            if (line.size() == 0)
                continue;
            if (line.size() != 16)
                return false;

            unsigned int instruction = 0;
            for (unsigned int i = 0; i<16; ++i) {
                instruction <<= 1;
                switch (line[i]) {
                case '0':
                    break;
                case '1':
                    instruction |= 1;
                    break;
                default:
                    return false;
                }
            }
            data[counter++] = instruction;
        }
        // clear the rest
        while (counter < size) {
            data[counter++] = 0;
        }

        return true;
    }
    virtual unsigned short get(unsigned int address) const {
        if (address < size) {
            return data[address];
        } else {
            std::cerr << "requested memory at " << address << '\n';
            throw std::runtime_error("Memory::get");
        }
    }
};

} // end namespace

struct GUIEmulatorRAM : public hcc::IRAM {
    static const unsigned int CHANNELS = 3;
    static const unsigned int SCREEN_WIDTH = 512;
    static const unsigned int SCREEN_HEIGHT = 256;
    static const unsigned int size = 0x6001;

    unsigned short *data;
    unsigned char *vram;
    GdkPixbuf *pixbuf;
    GtkWidget *screen;

    void putpixel(unsigned short x, unsigned short y, bool black) {
        unsigned int offset = CHANNELS*(SCREEN_WIDTH*y + x);
        for (unsigned int channel = 0; channel<CHANNELS; ++channel) {
            vram[offset++] = black ? 0x00 : 0xff;
        }
    }
public:
    GUIEmulatorRAM() {
        data = new unsigned short[size];
        vram = new unsigned char[CHANNELS*SCREEN_WIDTH*SCREEN_HEIGHT];
        pixbuf = gdk_pixbuf_new_from_data(vram, GDK_COLORSPACE_RGB, FALSE, 8, SCREEN_WIDTH, SCREEN_HEIGHT, CHANNELS*SCREEN_WIDTH, NULL, NULL);
        screen = gtk_image_new_from_pixbuf(pixbuf);
    }
    virtual ~GUIEmulatorRAM() {
        delete[] data;
        delete[] vram;
    }
    void keyboard(unsigned short value) {
        data[0x6000] = value;
    }
    GtkWidget* getScreenWidget() {
        return screen;
    }
    virtual void set(unsigned int address, unsigned short value) {
        if (address >= size) {
            throw std::runtime_error("RAM::set");
        }

        data[address] = value;

        // check if we are writing to video RAM
        if (0x4000 <= address && address <0x6000) {
            address -= 0x4000;

            unsigned short y = address / 32;
            unsigned short x = 16*(address % 32);
            for (int bit = 0; bit<16; ++bit) {
                putpixel(x + bit, y, value & 1);
                value = value >> 1;
            }
            gdk_threads_enter();
            gtk_widget_queue_draw(screen);
            gdk_threads_leave();
        }
    }
    virtual unsigned short get(unsigned int address) const {
        if (address >= size) {
            throw std::runtime_error("RAM::get");
        }

        return data[address];
    }
};
hcc::ROM rom;
GUIEmulatorRAM *ram;
hcc::CPU cpu;

bool running = false;

GtkWidget *window;
GtkToolItem *button_load, *button_run, *button_pause;

void load_clicked(GtkButton *button, gpointer user_data)
{
    bool loaded = false;

    GtkWidget *dialog = gtk_file_chooser_dialog_new("Load ROM",
        GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL,
        GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
        loaded = rom.load(filename);
        g_free(filename);
    }
    gtk_widget_destroy(dialog);

    if (!loaded) {
        GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(window),
            GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
            "Error loading program");
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
    } else {
        cpu.reset();
        gtk_widget_set_sensitive(GTK_WIDGET(button_run), TRUE);
    }
}

gpointer run_thread(gpointer user_data)
{
    int steps = 0;
    while (running) {
        cpu.step(&rom, ram);
        if (steps>100) {
            g_usleep(10);
            steps = 0;
        }
        ++steps;
    }
    return NULL;
}
void run_clicked()
{
    assert(!running);

    running = true;
    gtk_widget_set_sensitive(GTK_WIDGET(button_run), FALSE);
    gtk_widget_set_visible(GTK_WIDGET(button_run), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(button_pause), TRUE);
    gtk_widget_set_visible(GTK_WIDGET(button_pause), TRUE);

    g_thread_create(run_thread, NULL, FALSE, NULL);
}
void pause_clicked()
{
    assert(running);

    running = false;
    gtk_widget_set_sensitive(GTK_WIDGET(button_pause), FALSE);
    gtk_widget_set_visible(GTK_WIDGET(button_pause), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(button_run), TRUE);
    gtk_widget_set_visible(GTK_WIDGET(button_run), TRUE);
}

// Translate special keys. See Figure 5.6 in TECS book.
unsigned short translate(guint keyval)
{
    switch (keyval) {
    case GDK_KEY_Return:    return 128;
    case GDK_KEY_BackSpace: return 129;
    case GDK_KEY_Left:      return 130;
    case GDK_KEY_Up:        return 131;
    case GDK_KEY_Right:     return 132;
    case GDK_KEY_Down:      return 133;
    case GDK_KEY_Home:      return 134;
    case GDK_KEY_End:       return 135;
    case GDK_KEY_Page_Up:   return 136;
    case GDK_KEY_Page_Down: return 137;
    case GDK_KEY_Insert:    return 138;
    case GDK_KEY_Delete:    return 139;
    case GDK_KEY_Escape:    return 140;
    case GDK_KEY_F1:        return 141;
    case GDK_KEY_F2:        return 142;
    case GDK_KEY_F3:        return 143;
    case GDK_KEY_F4:        return 144;
    case GDK_KEY_F5:        return 145;
    case GDK_KEY_F6:        return 146;
    case GDK_KEY_F7:        return 147;
    case GDK_KEY_F8:        return 148;
    case GDK_KEY_F9:        return 149;
    case GDK_KEY_F10:       return 150;
    case GDK_KEY_F11:       return 151;
    case GDK_KEY_F12:       return 152;
    }
    return keyval;
}

gboolean keyboard_callback(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
    if (event->type == GDK_KEY_RELEASE) {
        ram->keyboard(0);
    } else {
        ram->keyboard(translate(event->keyval));
    }
    return TRUE;
}

GtkToolItem *create_button(const gchar *stock_id, const gchar *text, GCallback callback)
{
    GtkToolItem *button = gtk_tool_button_new_from_stock(stock_id);
    gtk_tool_button_set_label(GTK_TOOL_BUTTON(button), text);
    gtk_tool_item_set_tooltip_text(button, text);
    g_signal_connect(button, "clicked", callback, NULL);
    return button;
}

int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);
    ram = new GUIEmulatorRAM();

    /* toolbar buttons */
    button_load    = create_button(GTK_STOCK_OPEN,        "Load...", G_CALLBACK(load_clicked));
    button_run     = create_button(GTK_STOCK_MEDIA_PLAY,  "Run",     G_CALLBACK(run_clicked));
    button_pause   = create_button(GTK_STOCK_MEDIA_PAUSE, "Pause",   G_CALLBACK(pause_clicked));

    GtkToolItem *separator1 = gtk_separator_tool_item_new();

    gtk_widget_set_sensitive(GTK_WIDGET(button_run), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(button_pause), FALSE);

    /* toolbar itself */
    GtkWidget *toolbar = gtk_toolbar_new();
    gtk_widget_set_hexpand(toolbar, TRUE);
    gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), button_load,  -1);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), separator1,   -1);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), button_run,   -1);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), button_pause, -1);

    /* keyboard */
    GtkWidget *keyboard = gtk_toggle_button_new_with_label("Grab keyboard focus");
    gtk_widget_add_events(keyboard, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
    g_signal_connect(keyboard, "key-press-event",   G_CALLBACK(keyboard_callback), NULL);
    g_signal_connect(keyboard, "key-release-event", G_CALLBACK(keyboard_callback), NULL);

    /* main layout */
    GtkWidget *grid = gtk_grid_new();
    gtk_grid_attach(GTK_GRID(grid), toolbar, 0, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), ram->getScreenWidget(), 0, 1, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), keyboard, 0, 2, 1, 1);

    /* main window */
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "HACK emulator");
    gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
    gtk_window_set_focus(GTK_WINDOW(window), NULL);
    g_signal_connect(window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
    gtk_container_add(GTK_CONTAINER(window), grid);
    gtk_widget_show_all(window);
    gtk_widget_set_visible(GTK_WIDGET(button_pause), FALSE);

    gtk_main();
    return 0;
}
<commit_msg>Fixed gtk3 stock deprecation<commit_after>// Copyright (c) 2012-2015 Dano Pernis
// See LICENSE for details

#include <gtk/gtk.h>
#include <glib.h>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <cassert>
#include "CPU.h"

namespace hcc {

struct ROM : public IROM {
    unsigned short *data;
    static const unsigned int size = 0x8000;
    ROM() {
        data = new unsigned short[size];
    }
    virtual ~ROM() {
        delete[] data;
    }

    bool load(const char *filename) {
        std::ifstream input(filename);
        std::string line;
        unsigned int counter = 0;
        while (input.good() && counter < size) {
            getline(input, line);
            if (line.size() == 0)
                continue;
            if (line.size() != 16)
                return false;

            unsigned int instruction = 0;
            for (unsigned int i = 0; i<16; ++i) {
                instruction <<= 1;
                switch (line[i]) {
                case '0':
                    break;
                case '1':
                    instruction |= 1;
                    break;
                default:
                    return false;
                }
            }
            data[counter++] = instruction;
        }
        // clear the rest
        while (counter < size) {
            data[counter++] = 0;
        }

        return true;
    }
    virtual unsigned short get(unsigned int address) const {
        if (address < size) {
            return data[address];
        } else {
            std::cerr << "requested memory at " << address << '\n';
            throw std::runtime_error("Memory::get");
        }
    }
};

} // end namespace

struct GUIEmulatorRAM : public hcc::IRAM {
    static const unsigned int CHANNELS = 3;
    static const unsigned int SCREEN_WIDTH = 512;
    static const unsigned int SCREEN_HEIGHT = 256;
    static const unsigned int size = 0x6001;

    unsigned short *data;
    unsigned char *vram;
    GdkPixbuf *pixbuf;
    GtkWidget *screen;

    void putpixel(unsigned short x, unsigned short y, bool black) {
        unsigned int offset = CHANNELS*(SCREEN_WIDTH*y + x);
        for (unsigned int channel = 0; channel<CHANNELS; ++channel) {
            vram[offset++] = black ? 0x00 : 0xff;
        }
    }
public:
    GUIEmulatorRAM() {
        data = new unsigned short[size];
        vram = new unsigned char[CHANNELS*SCREEN_WIDTH*SCREEN_HEIGHT];
        pixbuf = gdk_pixbuf_new_from_data(vram, GDK_COLORSPACE_RGB, FALSE, 8, SCREEN_WIDTH, SCREEN_HEIGHT, CHANNELS*SCREEN_WIDTH, NULL, NULL);
        screen = gtk_image_new_from_pixbuf(pixbuf);
    }
    virtual ~GUIEmulatorRAM() {
        delete[] data;
        delete[] vram;
    }
    void keyboard(unsigned short value) {
        data[0x6000] = value;
    }
    GtkWidget* getScreenWidget() {
        return screen;
    }
    virtual void set(unsigned int address, unsigned short value) {
        if (address >= size) {
            throw std::runtime_error("RAM::set");
        }

        data[address] = value;

        // check if we are writing to video RAM
        if (0x4000 <= address && address <0x6000) {
            address -= 0x4000;

            unsigned short y = address / 32;
            unsigned short x = 16*(address % 32);
            for (int bit = 0; bit<16; ++bit) {
                putpixel(x + bit, y, value & 1);
                value = value >> 1;
            }
            gdk_threads_enter();
            gtk_widget_queue_draw(screen);
            gdk_threads_leave();
        }
    }
    virtual unsigned short get(unsigned int address) const {
        if (address >= size) {
            throw std::runtime_error("RAM::get");
        }

        return data[address];
    }
};
hcc::ROM rom;
GUIEmulatorRAM *ram;
hcc::CPU cpu;

bool running = false;

GtkWidget *window;
GtkToolItem *button_load, *button_run, *button_pause;

void load_clicked(GtkButton *button, gpointer user_data)
{
    bool loaded = false;

    GtkWidget *dialog = gtk_file_chooser_dialog_new(
        "Load ROM", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN,
        "gtk-cancel", GTK_RESPONSE_CANCEL,
        "gtk-open", GTK_RESPONSE_ACCEPT,
        NULL);
    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
        loaded = rom.load(filename);
        g_free(filename);
    }
    gtk_widget_destroy(dialog);

    if (!loaded) {
        GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(window),
            GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
            "Error loading program");
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
    } else {
        cpu.reset();
        gtk_widget_set_sensitive(GTK_WIDGET(button_run), TRUE);
    }
}

gpointer run_thread(gpointer user_data)
{
    int steps = 0;
    while (running) {
        cpu.step(&rom, ram);
        if (steps>100) {
            g_usleep(10);
            steps = 0;
        }
        ++steps;
    }
    return NULL;
}
void run_clicked()
{
    assert(!running);

    running = true;
    gtk_widget_set_sensitive(GTK_WIDGET(button_run), FALSE);
    gtk_widget_set_visible(GTK_WIDGET(button_run), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(button_pause), TRUE);
    gtk_widget_set_visible(GTK_WIDGET(button_pause), TRUE);

    g_thread_create(run_thread, NULL, FALSE, NULL);
}
void pause_clicked()
{
    assert(running);

    running = false;
    gtk_widget_set_sensitive(GTK_WIDGET(button_pause), FALSE);
    gtk_widget_set_visible(GTK_WIDGET(button_pause), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(button_run), TRUE);
    gtk_widget_set_visible(GTK_WIDGET(button_run), TRUE);
}

// Translate special keys. See Figure 5.6 in TECS book.
unsigned short translate(guint keyval)
{
    switch (keyval) {
    case GDK_KEY_Return:    return 128;
    case GDK_KEY_BackSpace: return 129;
    case GDK_KEY_Left:      return 130;
    case GDK_KEY_Up:        return 131;
    case GDK_KEY_Right:     return 132;
    case GDK_KEY_Down:      return 133;
    case GDK_KEY_Home:      return 134;
    case GDK_KEY_End:       return 135;
    case GDK_KEY_Page_Up:   return 136;
    case GDK_KEY_Page_Down: return 137;
    case GDK_KEY_Insert:    return 138;
    case GDK_KEY_Delete:    return 139;
    case GDK_KEY_Escape:    return 140;
    case GDK_KEY_F1:        return 141;
    case GDK_KEY_F2:        return 142;
    case GDK_KEY_F3:        return 143;
    case GDK_KEY_F4:        return 144;
    case GDK_KEY_F5:        return 145;
    case GDK_KEY_F6:        return 146;
    case GDK_KEY_F7:        return 147;
    case GDK_KEY_F8:        return 148;
    case GDK_KEY_F9:        return 149;
    case GDK_KEY_F10:       return 150;
    case GDK_KEY_F11:       return 151;
    case GDK_KEY_F12:       return 152;
    }
    return keyval;
}

gboolean keyboard_callback(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
    if (event->type == GDK_KEY_RELEASE) {
        ram->keyboard(0);
    } else {
        ram->keyboard(translate(event->keyval));
    }
    return TRUE;
}

GtkToolItem *create_button(const gchar *stock_id, const gchar *text, GCallback callback)
{
    GtkToolItem *button = gtk_tool_button_new(NULL, text);
    gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(button), stock_id);
    gtk_tool_item_set_tooltip_text(button, text);
    g_signal_connect(button, "clicked", callback, NULL);
    return button;
}

int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);
    ram = new GUIEmulatorRAM();

    /* toolbar buttons */
    button_load    = create_button("document-open",        "Load...", G_CALLBACK(load_clicked));
    button_run     = create_button("media-playback-start", "Run",     G_CALLBACK(run_clicked));
    button_pause   = create_button("media-playback-pause", "Pause",   G_CALLBACK(pause_clicked));

    GtkToolItem *separator1 = gtk_separator_tool_item_new();

    gtk_widget_set_sensitive(GTK_WIDGET(button_run), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(button_pause), FALSE);

    /* toolbar itself */
    GtkWidget *toolbar = gtk_toolbar_new();
    gtk_widget_set_hexpand(toolbar, TRUE);
    gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), button_load,  -1);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), separator1,   -1);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), button_run,   -1);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), button_pause, -1);

    /* keyboard */
    GtkWidget *keyboard = gtk_toggle_button_new_with_label("Grab keyboard focus");
    gtk_widget_add_events(keyboard, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
    g_signal_connect(keyboard, "key-press-event",   G_CALLBACK(keyboard_callback), NULL);
    g_signal_connect(keyboard, "key-release-event", G_CALLBACK(keyboard_callback), NULL);

    /* main layout */
    GtkWidget *grid = gtk_grid_new();
    gtk_grid_attach(GTK_GRID(grid), toolbar, 0, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), ram->getScreenWidget(), 0, 1, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), keyboard, 0, 2, 1, 1);

    /* main window */
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "HACK emulator");
    gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
    gtk_window_set_focus(GTK_WINDOW(window), NULL);
    g_signal_connect(window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
    gtk_container_add(GTK_CONTAINER(window), grid);
    gtk_widget_show_all(window);
    gtk_widget_set_visible(GTK_WIDGET(button_pause), FALSE);

    gtk_main();
    return 0;
}
<|endoftext|>


<commit_before><commit_msg>increase bfsdepth<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: findcoll.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 20:46:06 $
 *
 *  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_sw.hxx"

#ifndef _SWCRSR_HXX
#include <swcrsr.hxx>
#endif
#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _PAMTYP_HXX
#include <pamtyp.hxx>
#endif
#ifndef _SWUNDO_HXX
#include <swundo.hxx>
#endif
#ifndef _UNDOBJ_HXX
#include <undobj.hxx>
#endif
#ifndef _COMCORE_HRC
#include <comcore.hrc>
#endif
#ifndef _TOOLS_RESID_HXX
#include <tools/resid.hxx>
#endif

//------------------ Methoden der CrsrShell ---------------------------

// Parameter fuer das Suchen vom FormatCollections
struct SwFindParaFmtColl : public SwFindParas
{
    const SwTxtFmtColl *pFmtColl, *pReplColl;
    SwCursor& rCursor;
    SwFindParaFmtColl( const SwTxtFmtColl& rFmtColl,
                        const SwTxtFmtColl* pRpColl, SwCursor& rCrsr )
        : pFmtColl( &rFmtColl ), pReplColl( pRpColl ), rCursor( rCrsr )
    {}
    virtual int Find( SwPaM* , SwMoveFn , const SwPaM*, FASTBOOL bInReadOnly );
    virtual int IsReplaceMode() const;
};

int SwFindParaFmtColl::Find( SwPaM* pCrsr, SwMoveFn fnMove, const SwPaM* pRegion,
                            FASTBOOL bInReadOnly )
{
    int nRet = FIND_FOUND;
    if( bInReadOnly && pReplColl )
        bInReadOnly = FALSE;

    if( !pCrsr->Find( *pFmtColl, fnMove, pRegion, bInReadOnly ) )
        nRet = FIND_NOT_FOUND;
    else if( pReplColl )
    {
        pCrsr->GetDoc()->SetTxtFmtColl( *pCrsr, (SwTxtFmtColl*)pReplColl );
        nRet = FIND_NO_RING;
    }
    return nRet;
}

int SwFindParaFmtColl::IsReplaceMode() const
{
    return 0 != pReplColl;
}

// Suchen nach Format-Collections

ULONG SwCursor::Find( const SwTxtFmtColl& rFmtColl,
                    SwDocPositions nStart, SwDocPositions nEnde, BOOL& bCancel,
                    FindRanges eFndRngs, const SwTxtFmtColl* pReplFmtColl )
{
    // OLE-Benachrichtigung abschalten !!
    SwDoc* pDoc = GetDoc();
    Link aLnk( pDoc->GetOle2Link() );
    pDoc->SetOle2Link( Link() );

    BOOL bSttUndo = pDoc->DoesUndo() && pReplFmtColl;
    if( bSttUndo )
    {
        SwRewriter aRewriter;
        aRewriter.AddRule(UNDO_ARG1, rFmtColl.GetName());
        aRewriter.AddRule(UNDO_ARG2, SW_RES(STR_YIELDS));
        aRewriter.AddRule(UNDO_ARG3, pReplFmtColl->GetName());

        pDoc->StartUndo( UIUNDO_REPLACE_STYLE, &aRewriter );
    }

    SwFindParaFmtColl aSwFindParaFmtColl( rFmtColl, pReplFmtColl, *this );

    ULONG nRet = FindAll( aSwFindParaFmtColl, nStart, nEnde, eFndRngs, bCancel );
    pDoc->SetOle2Link( aLnk );

    if( nRet && pReplFmtColl )
        pDoc->SetModified();

    if( bSttUndo )
        pDoc->EndUndo( UIUNDO_REPLACE_STYLE, NULL );
    return nRet;
}

<commit_msg>INTEGRATION: CWS swwarnings (1.8.222); FILE MERGED 2007/04/03 12:59:24 tl 1.8.222.2: #i69287# warning-free code 2007/02/22 15:06:23 tl 1.8.222.1: #i69287# warning-free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: findcoll.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2007-09-27 08:29:33 $
 *
 *  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_sw.hxx"

#ifndef _SWCRSR_HXX
#include <swcrsr.hxx>
#endif
#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _PAMTYP_HXX
#include <pamtyp.hxx>
#endif
#ifndef _SWUNDO_HXX
#include <swundo.hxx>
#endif
#ifndef _UNDOBJ_HXX
#include <undobj.hxx>
#endif
#ifndef _COMCORE_HRC
#include <comcore.hrc>
#endif
#ifndef _TOOLS_RESID_HXX
#include <tools/resid.hxx>
#endif

//------------------ Methoden der CrsrShell ---------------------------

// Parameter fuer das Suchen vom FormatCollections
struct SwFindParaFmtColl : public SwFindParas
{
    const SwTxtFmtColl *pFmtColl, *pReplColl;
    SwCursor& rCursor;
    SwFindParaFmtColl( const SwTxtFmtColl& rFmtColl,
                        const SwTxtFmtColl* pRpColl, SwCursor& rCrsr )
        : pFmtColl( &rFmtColl ), pReplColl( pRpColl ), rCursor( rCrsr )
    {}
    virtual int Find( SwPaM* , SwMoveFn , const SwPaM*, BOOL bInReadOnly );
    virtual int IsReplaceMode() const;
};

int SwFindParaFmtColl::Find( SwPaM* pCrsr, SwMoveFn fnMove, const SwPaM* pRegion,
                            BOOL bInReadOnly )
{
    int nRet = FIND_FOUND;
    if( bInReadOnly && pReplColl )
        bInReadOnly = FALSE;

    if( !pCrsr->Find( *pFmtColl, fnMove, pRegion, bInReadOnly ) )
        nRet = FIND_NOT_FOUND;
    else if( pReplColl )
    {
        pCrsr->GetDoc()->SetTxtFmtColl( *pCrsr, (SwTxtFmtColl*)pReplColl );
        nRet = FIND_NO_RING;
    }
    return nRet;
}

int SwFindParaFmtColl::IsReplaceMode() const
{
    return 0 != pReplColl;
}

// Suchen nach Format-Collections

ULONG SwCursor::Find( const SwTxtFmtColl& rFmtColl,
                    SwDocPositions nStart, SwDocPositions nEnde, BOOL& bCancel,
                    FindRanges eFndRngs, const SwTxtFmtColl* pReplFmtColl )
{
    // OLE-Benachrichtigung abschalten !!
    SwDoc* pDoc = GetDoc();
    Link aLnk( pDoc->GetOle2Link() );
    pDoc->SetOle2Link( Link() );

    BOOL bSttUndo = pDoc->DoesUndo() && pReplFmtColl;
    if( bSttUndo )
    {
        SwRewriter aRewriter;
        aRewriter.AddRule(UNDO_ARG1, rFmtColl.GetName());
        aRewriter.AddRule(UNDO_ARG2, SW_RES(STR_YIELDS));
        aRewriter.AddRule(UNDO_ARG3, pReplFmtColl->GetName());

        pDoc->StartUndo( UNDO_UI_REPLACE_STYLE, &aRewriter );
    }

    SwFindParaFmtColl aSwFindParaFmtColl( rFmtColl, pReplFmtColl, *this );

    ULONG nRet = FindAll( aSwFindParaFmtColl, nStart, nEnde, eFndRngs, bCancel );
    pDoc->SetOle2Link( aLnk );

    if( nRet && pReplFmtColl )
        pDoc->SetModified();

    if( bSttUndo )
        pDoc->EndUndo( UNDO_UI_REPLACE_STYLE, NULL );
    return nRet;
}

<|endoftext|>