1
0
mirror of https://github.com/rricharz/Tek4010.git synced 2026-01-13 15:27:31 +00:00
2019-04-03 13:50:41 +02:00

227 lines
7.0 KiB
C

/*
*
* main.c
* provides a simple framework for basic drawing with cairo and gtk+ 3.0
* define main window in tek4010.h
* and cairo drawing in tek4010.c
*
* The framework provides functions to
* a function to draw using cairo
* a function to initialize your code
* a function to exit your code
* a peridicaly called function
* a function called if the mouse is clicked
*
* Copyright 2016,2019 rricharz
*
* https://github.com/rricharz/Tek4010
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*
*/
#define GDK_DISABLE_DEPRECATION_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cairo.h>
#include <gtk/gtk.h>
#include "main.h"
#include "tek4010.h"
extern FILE *putKeys;
static int global_firstcall;
extern int argFull;
int windowWidth;
int windowHeight;
int globalClearPersistent;
static void do_drawing(cairo_t *, GtkWidget *);
static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr,
gpointer user_data)
{
do_drawing(cr, widget);
return FALSE;
}
static gboolean on_timer_event(GtkWidget *widget)
{
if (tek4010_on_timer_event())
gtk_widget_queue_draw(widget);
return TRUE;
}
static gboolean clicked(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
if (tek4010_clicked(event->button, event->x, event->y))
gtk_widget_queue_draw(widget);
return TRUE;
}
static void on_quit_event()
{
tek4010_quit();
gtk_main_quit();
exit(0);
}
static void do_drawing(cairo_t *cr, GtkWidget *widget)
{
static cairo_surface_t *permanent_surface, *temporary_surface;
if (global_firstcall) {
permanent_surface = cairo_surface_create_similar(cairo_get_target(cr),
CAIRO_CONTENT_COLOR_ALPHA, windowWidth, windowHeight);
temporary_surface = cairo_surface_create_similar(cairo_get_target(cr),
CAIRO_CONTENT_COLOR_ALPHA, windowWidth, windowHeight);
}
cairo_t *permanent_cr = cairo_create(permanent_surface);
cairo_t *temporary_cr = cairo_create(temporary_surface);
tek4010_draw(permanent_cr, temporary_cr, global_firstcall);
global_firstcall = FALSE;
cairo_set_source_surface(cr, permanent_surface, 0, 0);
cairo_paint(cr);
cairo_set_source_surface(cr, temporary_surface, 0, 0);
cairo_paint(cr);
cairo_destroy(permanent_cr);
cairo_destroy(temporary_cr);
}
static void on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
int ch;
// printf("key pressed, state =%04X, keyval=%04X\r\n", event->state, event->keyval);
if ((event->keyval == 0xFF50) || // "home" key
(event->keyval == 0xFF55) || // "page up" key
(event->keyval == 0xFF56)) // "page down" key
{
globalClearPersistent = 1;
gtk_widget_queue_draw(widget);
return;
}
// control keys
else if ((event->keyval >= 0xFF00) && (event->keyval <= 0xFF1F))
ch = event->keyval & 0x1F;
else if (event->state & GDK_CONTROL_MASK) {
if ((event->keyval == 0xFF51) || // "<ctrl>left arrow" key
(event->keyval == 0xFF52)) { // "<ctrl>up arrow" key
globalClearPersistent = 1;
gtk_widget_queue_draw(widget);
return;
}
else
ch = event->keyval & 0x1F;
}
else if (event->keyval == 0xFF52) ch = 16; // arrow up for history up
else if (event->keyval == 0xFF54) ch = 14; // arrow down for history down
// normal keys
else if ((event->keyval >= 0x0020) && (event->keyval <= 0x007F))
ch = event->keyval & 0x7F;
else return;
if (putKeys)
putc(ch,putKeys); // pipe key to child process, if stream open
}
int main (int argc, char *argv[])
{
GtkWidget *darea;
GtkWidget *window;
int askWindowWidth = A_WINDOW_WIDTH;
int askWindowHeight = A_WINDOW_HEIGHT;
tek4010_init(argc, argv);
if (argFull) {
askWindowWidth = 4096;
askWindowHeight = 3072;
}
gtk_init(&argc, &argv);
global_firstcall = TRUE;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
darea = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), darea);
gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
gtk_widget_add_events(window, GDK_KEY_PRESS_MASK);
g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(on_draw_event), NULL);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(on_quit_event), NULL);
g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(clicked), NULL);
g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(on_key_press), NULL);
GdkScreen *screen = gtk_window_get_screen(GTK_WINDOW(window));
int screenWidth = gdk_screen_get_width(screen);
int screenHeight = gdk_screen_get_height(screen);
printf("Screen dimensions: %d x %d\n", screenWidth, screenHeight);
if (argFull && (screenWidth<askWindowWidth+8) && (screenHeight<(askWindowHeight+72))) {
askWindowWidth = screenWidth - 8;
askWindowHeight = screenHeight - 72;
if (askWindowWidth > 4*askWindowHeight/3)
askWindowWidth = 4*askWindowHeight/3;
if (askWindowHeight > 3*askWindowWidth/4)
askWindowHeight = 3*askWindowWidth/4;
}
// DISPLAY DECORATED WINDOW
gtk_window_set_decorated(GTK_WINDOW(window), TRUE);
gtk_window_set_default_size(GTK_WINDOW(window),
askWindowWidth, askWindowHeight);
windowWidth = askWindowWidth;
windowHeight = askWindowHeight;
printf("Window dimensions: %d x %d\n", windowWidth, windowHeight);
if (TIME_INTERVAL > 0) {
// Add timer event
// Register the timer and set time in mS.
// The timer_event() function is called repeatedly until it returns FALSE.
g_timeout_add(TIME_INTERVAL, (GSourceFunc) on_timer_event, (gpointer) window);
}
gtk_window_set_title(GTK_WINDOW(window), WINDOW_NAME);
if (strlen(ICON_NAME) > 0) {
gtk_window_set_icon_from_file(GTK_WINDOW(window), ICON_NAME, NULL);
}
gtk_widget_show_all(window);
gtk_main();
return 0;
}