mirror of
https://github.com/rricharz/Tek4010.git
synced 2026-01-13 15:27:31 +00:00
194 lines
5.9 KiB
C
194 lines
5.9 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.
|
|
*
|
|
*
|
|
*/
|
|
|
|
#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;
|
|
|
|
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)
|
|
{
|
|
int width = WINDOW_WIDTH; // we do not use actual window size here
|
|
int height = WINDOW_HEIGHT; // because surfaces does not change size
|
|
|
|
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, width, height);
|
|
temporary_surface = cairo_surface_create_similar(cairo_get_target(cr),
|
|
CAIRO_CONTENT_COLOR_ALPHA, width, height);
|
|
}
|
|
|
|
cairo_t *permanent_cr = cairo_create(permanent_surface);
|
|
cairo_t *temporary_cr = cairo_create(temporary_surface);
|
|
tek4010_draw(permanent_cr, temporary_cr, width, height, 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;
|
|
|
|
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);
|
|
|
|
|
|
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_default_size(GTK_WINDOW(window), WINDOW_WIDTH, WINDOW_HEIGHT);
|
|
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);
|
|
}
|
|
|
|
tek4010_init(argc, argv);
|
|
|
|
gtk_widget_show_all(window);
|
|
|
|
gtk_main();
|
|
|
|
return 0;
|
|
}
|