diff options
Diffstat (limited to 'ldmicro/ldmicro.cpp')
-rw-r--r-- | ldmicro/ldmicro.cpp | 1374 |
1 files changed, 1374 insertions, 0 deletions
diff --git a/ldmicro/ldmicro.cpp b/ldmicro/ldmicro.cpp new file mode 100644 index 0000000..e878eae --- /dev/null +++ b/ldmicro/ldmicro.cpp @@ -0,0 +1,1374 @@ +//----------------------------------------------------------------------------- +// Copyright 2007 Jonathan Westhues +// +// This file is part of LDmicro. +// +// LDmicro 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 3 of the License, or +// (at your option) any later version. +// +// LDmicro 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 LDmicro. If not, see <http://www.gnu.org/licenses/>. +//------ +// +// A ladder logic compiler for 8 bit micros: user draws a ladder diagram, +// with an appropriately constrained `schematic editor,' and then we can +// simulated it under Windows or generate PIC/AVR code that performs the +// requested operations. This files contains the program entry point, plus +// most of the UI logic relating to the main window. +// Jonathan Westhues, Oct 2004 +//----------------------------------------------------------------------------- +#include "linuxUI.h" + +#include <stdio.h> +#include <stdlib.h> +#include "ldmicro.h" +#include "freezeLD.h" +#include "mcutable.h" + + +HINSTANCE Instance; +HWID MainWindow; +HWID DrawWindow; +HCRDC Hdc; + +// parameters used to capture the mouse when implementing our totally non- +// general splitter control +//static HHOOK MouseHookHandle; +static int MouseY; + +// For the open/save dialog boxes +#define LDMICRO_PATTERN "LDmicro Ladder Logic Programs (*.ld)\0*.ld\0" \ + "All files\0*\0\0" +char CurrentSaveFile[MAX_PATH]; +static BOOL ProgramChangedNotSaved = FALSE; + +#define HEX_PATTERN "Intel Hex Files (*.hex)\0*.hex\0All files\0*\0\0" +#define C_PATTERN "C Source Files (*.c)\0*.c\0All Files\0*\0\0" +#define INTERPRETED_PATTERN \ + "Interpretable Byte Code Files (*.int)\0*.int\0All Files\0*\0\0" +char CurrentCompileFile[MAX_PATH]; + +#define TXT_PATTERN "Text Files (*.txt)\0*.txt\0All files\0*\0\0" + +// Everything relating to the PLC's program, I/O configuration, processor +// choice, and so on--basically everything that would be saved in the +// project file. +PlcProgram Prog; + +//----------------------------------------------------------------------------- +// Get a filename with a common dialog box and then save the program to that +// file and then set our default filename to that. +//----------------------------------------------------------------------------- +// static BOOL SaveAsDialog(void) +// { +// OPENFILENAME ofn; + +// memset(&ofn, 0, sizeof(ofn)); +// ofn.lStructSize = sizeof(ofn); +// ofn.hInstance = Instance; +// ofn.lpstrFilter = LDMICRO_PATTERN; +// ofn.lpstrDefExt = "ld"; +// ofn.lpstrFile = CurrentSaveFile; +// ofn.nMaxFile = sizeof(CurrentSaveFile); +// ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + +// if(!GetSaveFileName(&ofn)) +// return FALSE; + +// if(!SaveProjectToFile(CurrentSaveFile)) { +// Error(_("Couldn't write to '%s'."), CurrentSaveFile); +// return FALSE; +// } else { +// ProgramChangedNotSaved = FALSE; +// return TRUE; +// } +// } + +//----------------------------------------------------------------------------- +// Get a filename with a common dialog box and then export the program as +// an ASCII art drawing. +//----------------------------------------------------------------------------- +// static void ExportDialog(void) +// { +// char exportFile[MAX_PATH]; +// OPENFILENAME ofn; + +// exportFile[0] = '\0'; + +// memset(&ofn, 0, sizeof(ofn)); +// ofn.lStructSize = sizeof(ofn); +// ofn.hInstance = Instance; +// ofn.lpstrFilter = TXT_PATTERN; +// ofn.lpstrFile = exportFile; +// ofn.lpstrTitle = _("Export As Text"); +// ofn.nMaxFile = sizeof(exportFile); +// ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + +// if(!GetSaveFileName(&ofn)) +// return; + +// ExportDrawingAsText(exportFile); +// } + +//----------------------------------------------------------------------------- +// If we already have a filename, save the program to that. Otherwise same +// as Save As. Returns TRUE if it worked, else returns FALSE. +//----------------------------------------------------------------------------- +// static BOOL SaveProgram(void) +// { +// if(strlen(CurrentSaveFile)) { +// if(!SaveProjectToFile(CurrentSaveFile)) { +// Error(_("Couldn't write to '%s'."), CurrentSaveFile); +// return FALSE; +// } else { +// ProgramChangedNotSaved = FALSE; +// return TRUE; +// } +// } else { +// return SaveAsDialog(); +// } +// } + +//----------------------------------------------------------------------------- +// Compile the program to a hex file for the target micro. Get the output +// file name if necessary, then call the micro-specific compile routines. +//----------------------------------------------------------------------------- +static void CompileProgram(BOOL compileAs) +{ + if(compileAs || strlen(CurrentCompileFile)==0) { + OPENFILENAME ofn; + + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.parentWindow = NULL; + ofn.lpstrTitle = _("Compile To"); + if(Prog.mcu && Prog.mcu->whichIsa == ISA_ANSIC) { + ofn.lpstrFilter = C_PATTERN; + ofn.lpstrDefExt = "c"; + } else if(Prog.mcu && Prog.mcu->whichIsa == ISA_INTERPRETED) { + ofn.lpstrFilter = INTERPRETED_PATTERN; + ofn.lpstrDefExt = "int"; + } else { + ofn.lpstrFilter = HEX_PATTERN; + ofn.lpstrDefExt = "hex"; + } + ofn.lpstrFile = CurrentCompileFile; + ofn.nMaxFile = sizeof(CurrentCompileFile); + ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + + if(!GetSaveFileName(&ofn)) + return; + + // hex output filename is stored in the .ld file + ProgramChangedNotSaved = TRUE; + } + + if(!GenerateIntermediateCode()) return; + + if(Prog.mcu == NULL) { + Error(_("Must choose a target microcontroller before compiling.")); + return; + } + + if(UartFunctionUsed() && Prog.mcu->uartNeeds.rxPin == 0) { + Error(_("UART function used but not supported for this micro.")); + return; + } + + if(PwmFunctionUsed() && Prog.mcu->pwmNeedsPin == 0) { + Error(_("PWM function used but not supported for this micro.")); + return; + } + + switch(Prog.mcu->whichIsa) { + case ISA_AVR: CompileAvr(CurrentCompileFile); break; + case ISA_PIC16: CompilePic16(CurrentCompileFile); break; + case ISA_ANSIC: CompileAnsiC(CurrentCompileFile); break; + case ISA_INTERPRETED: CompileInterpreted(CurrentCompileFile); break; + case ISA_ARDUINO: CompileArduino(CurrentCompileFile); break; + + default: oops(); + } + IntDumpListing("t.pl"); +} + +//----------------------------------------------------------------------------- +// If the program has been modified then give the user the option to save it +// or to cancel the operation they are performing. Return TRUE if they want +// to cancel. +//----------------------------------------------------------------------------- +// BOOL CheckSaveUserCancels(void) +// { +// if(!ProgramChangedNotSaved) { +// // no problem +// return FALSE; +// } + +// int r = MessageBox(MainWindow, +// _("The program has changed since it was last saved.\r\n\r\n" +// "Do you want to save the changes?"), "LDmicro", +// MB_YESNOCANCEL | MB_ICONWARNING); +// switch(r) { +// case IDYES: +// if(SaveProgram()) +// return FALSE; +// else +// return TRUE; + +// case IDNO: +// return FALSE; + +// case IDCANCEL: +// return TRUE; + +// default: +// oops(); +// } +// } + +//----------------------------------------------------------------------------- +// Load a new program from a file. If it succeeds then set our default filename +// to that, else we end up with an empty file then. +//----------------------------------------------------------------------------- +// static void OpenDialog(void) +// { +// OPENFILENAME ofn; + +// char tempSaveFile[MAX_PATH] = ""; + +// memset(&ofn, 0, sizeof(ofn)); +// ofn.lStructSize = sizeof(ofn); +// ofn.hInstance = Instance; +// ofn.lpstrFilter = LDMICRO_PATTERN; +// ofn.lpstrDefExt = "ld"; +// ofn.lpstrFile = tempSaveFile; +// ofn.nMaxFile = sizeof(tempSaveFile); +// ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + +// if(!GetOpenFileName(&ofn)) +// return; + +// if(!LoadProjectFromFile(tempSaveFile)) { +// Error(_("Couldn't open '%s'."), tempSaveFile); +// CurrentSaveFile[0] = '\0'; +// } else { +// ProgramChangedNotSaved = FALSE; +// strcpy(CurrentSaveFile, tempSaveFile); +// UndoFlush(); +// } + +// GenerateIoListDontLoseSelection(); +// RefreshScrollbars(); +// UpdateMainWindowTitleBar(); +// } + +//----------------------------------------------------------------------------- +// Housekeeping required when the program changes: mark the program as +// changed so that we ask if user wants to save before exiting, and update +// the I/O list. +//----------------------------------------------------------------------------- +// void ProgramChanged(void) +// { +// ProgramChangedNotSaved = TRUE; +// GenerateIoListDontLoseSelection(); +// RefreshScrollbars(); +// } +// #define CHANGING_PROGRAM(x) { \ +// UndoRemember(); \ +// x; \ +// ProgramChanged(); \ +// } + +//----------------------------------------------------------------------------- +// Hook that we install when the user starts dragging the `splitter,' in case +// they drag it out of the narrow area of the drawn splitter bar. Resize +// the listview in response to mouse move, and unhook ourselves when they +// release the mouse button. +//----------------------------------------------------------------------------- +// static LRESULT CALLBACK MouseHook(int code, WPARAM wParam, LPARAM lParam) +// { +// switch(code) { +// case HC_ACTION: { +// MSLLHOOKSTRUCT *mhs = (MSLLHOOKSTRUCT *)lParam; + +// switch(wParam) { +// case WM_MOUSEMOVE: { +// int dy = MouseY - mhs->pt.y; + +// IoListHeight += dy; +// if(IoListHeight < 50) IoListHeight = 50; +// MouseY = mhs->pt.y; +// MainWindowResized(); + +// break; +// } + +// case WM_LBUTTONUP: +// UnhookWindowsHookEx(MouseHookHandle); +// break; +// } +// break; +// } +// } +// return CallNextHookEx(MouseHookHandle, code, wParam, lParam); +// } + +//----------------------------------------------------------------------------- +// Handle a selection from the menu bar of the main window. +//----------------------------------------------------------------------------- +// static void ProcessMenu(int code) +// { +// if(code >= MNU_PROCESSOR_0 && code < MNU_PROCESSOR_0+NUM_SUPPORTED_MCUS) { +// strcpy(CurrentCompileFile, ""); +// Prog.mcu = &SupportedMcus[code - MNU_PROCESSOR_0]; +// RefreshControlsToSettings(); +// return; +// } +// if(code == MNU_PROCESSOR_0+NUM_SUPPORTED_MCUS) { +// Prog.mcu = NULL; +// strcpy(CurrentCompileFile, ""); +// RefreshControlsToSettings(); +// return; +// } + +// switch(code) { +// case MNU_NEW: +// if(CheckSaveUserCancels()) break; +// NewProgram(); +// strcpy(CurrentSaveFile, ""); +// strcpy(CurrentCompileFile, ""); +// GenerateIoListDontLoseSelection(); +// RefreshScrollbars(); +// UpdateMainWindowTitleBar(); +// break; + +// case MNU_OPEN: +// if(CheckSaveUserCancels()) break; +// OpenDialog(); +// break; + +// case MNU_SAVE: +// SaveProgram(); +// UpdateMainWindowTitleBar(); +// break; + +// case MNU_SAVE_AS: +// SaveAsDialog(); +// UpdateMainWindowTitleBar(); +// break; + +// case MNU_EXPORT: +// ExportDialog(); +// break; + +// case MNU_EXIT: +// if(CheckSaveUserCancels()) break; +// PostQuitMessage(0); +// break; + +// case MNU_INSERT_COMMENT: +// CHANGING_PROGRAM(AddComment(_("--add comment here--"))); +// break; + +// case MNU_INSERT_CONTACTS: +// CHANGING_PROGRAM(AddContact()); +// break; + +// case MNU_INSERT_COIL: +// CHANGING_PROGRAM(AddCoil()); +// break; + +// case MNU_INSERT_TON: +// CHANGING_PROGRAM(AddTimer(ELEM_TON)); +// break; + +// case MNU_INSERT_TOF: +// CHANGING_PROGRAM(AddTimer(ELEM_TOF)); +// break; + +// case MNU_INSERT_RTO: +// CHANGING_PROGRAM(AddTimer(ELEM_RTO)); +// break; + +// case MNU_INSERT_CTU: +// CHANGING_PROGRAM(AddCounter(ELEM_CTU)); +// break; + +// case MNU_INSERT_CTD: +// CHANGING_PROGRAM(AddCounter(ELEM_CTD)); +// break; + +// case MNU_INSERT_CTC: +// CHANGING_PROGRAM(AddCounter(ELEM_CTC)); +// break; + +// case MNU_INSERT_RES: +// CHANGING_PROGRAM(AddReset()); +// break; + +// case MNU_INSERT_OPEN: +// CHANGING_PROGRAM(AddEmpty(ELEM_OPEN)); +// break; + +// case MNU_INSERT_SHORT: +// CHANGING_PROGRAM(AddEmpty(ELEM_SHORT)); +// break; + +// case MNU_INSERT_MASTER_RLY: +// CHANGING_PROGRAM(AddMasterRelay()); +// break; + +// case MNU_INSERT_SHIFT_REG: +// CHANGING_PROGRAM(AddShiftRegister()); +// break; + +// case MNU_INSERT_LUT: +// CHANGING_PROGRAM(AddLookUpTable()); +// break; + +// case MNU_INSERT_PWL: +// CHANGING_PROGRAM(AddPiecewiseLinear()); +// break; + +// case MNU_INSERT_FMTD_STR: +// CHANGING_PROGRAM(AddFormattedString()); +// break; + +// case MNU_INSERT_OSR: +// CHANGING_PROGRAM(AddEmpty(ELEM_ONE_SHOT_RISING)); +// break; + +// case MNU_INSERT_OSF: +// CHANGING_PROGRAM(AddEmpty(ELEM_ONE_SHOT_FALLING)); +// break; + +// case MNU_INSERT_MOV: +// CHANGING_PROGRAM(AddMove()); +// break; + +// case MNU_INSERT_SET_PWM: +// CHANGING_PROGRAM(AddSetPwm()); +// break; + +// case MNU_INSERT_READ_ADC: +// CHANGING_PROGRAM(AddReadAdc()); +// break; + +// case MNU_INSERT_UART_SEND: +// CHANGING_PROGRAM(AddUart(ELEM_UART_SEND)); +// break; + +// case MNU_INSERT_UART_RECV: +// CHANGING_PROGRAM(AddUart(ELEM_UART_RECV)); +// break; + +// case MNU_INSERT_PERSIST: +// CHANGING_PROGRAM(AddPersist()); +// break; + +// { +// int elem; +// case MNU_INSERT_ADD: elem = ELEM_ADD; goto math; +// case MNU_INSERT_SUB: elem = ELEM_SUB; goto math; +// case MNU_INSERT_MUL: elem = ELEM_MUL; goto math; +// case MNU_INSERT_DIV: elem = ELEM_DIV; goto math; +// math: +// CHANGING_PROGRAM(AddMath(elem)); +// break; +// } + +// { +// int elem; +// case MNU_INSERT_EQU: elem = ELEM_EQU; goto cmp; +// case MNU_INSERT_NEQ: elem = ELEM_NEQ; goto cmp; +// case MNU_INSERT_GRT: elem = ELEM_GRT; goto cmp; +// case MNU_INSERT_GEQ: elem = ELEM_GEQ; goto cmp; +// case MNU_INSERT_LES: elem = ELEM_LES; goto cmp; +// case MNU_INSERT_LEQ: elem = ELEM_LEQ; goto cmp; +// cmp: +// CHANGING_PROGRAM(AddCmp(elem)); +// break; +// } + +// case MNU_MAKE_NORMAL: +// CHANGING_PROGRAM(MakeNormalSelected()); +// break; + +// case MNU_NEGATE: +// CHANGING_PROGRAM(NegateSelected()); +// break; + +// case MNU_MAKE_SET_ONLY: +// CHANGING_PROGRAM(MakeSetOnlySelected()); +// break; + +// case MNU_MAKE_RESET_ONLY: +// CHANGING_PROGRAM(MakeResetOnlySelected()); +// break; + +// case MNU_UNDO: +// UndoUndo(); +// break; + +// case MNU_REDO: +// UndoRedo(); +// break; + +// case MNU_INSERT_RUNG_BEFORE: +// CHANGING_PROGRAM(InsertRung(FALSE)); +// break; + +// case MNU_INSERT_RUNG_AFTER: +// CHANGING_PROGRAM(InsertRung(TRUE)); +// break; + +// case MNU_DELETE_RUNG: +// CHANGING_PROGRAM(DeleteSelectedRung()); +// break; + +// case MNU_PUSH_RUNG_UP: +// CHANGING_PROGRAM(PushRungUp()); +// break; + +// case MNU_PUSH_RUNG_DOWN: +// CHANGING_PROGRAM(PushRungDown()); +// break; + +// case MNU_DELETE_ELEMENT: +// CHANGING_PROGRAM(DeleteSelectedFromProgram()); +// break; + +// case MNU_MCU_SETTINGS: +// CHANGING_PROGRAM(ShowConfDialog()); +// break; + +// case MNU_SIMULATION_MODE: +// ToggleSimulationMode(); +// break; + +// case MNU_START_SIMULATION: +// StartSimulation(); +// break; + +// case MNU_STOP_SIMULATION: +// StopSimulation(); +// break; + +// case MNU_SINGLE_CYCLE: +// SimulateOneCycle(TRUE); +// break; + +// case MNU_COMPILE: +// CompileProgram(FALSE); +// break; + +// case MNU_COMPILE_AS: +// CompileProgram(TRUE); +// break; + +// case MNU_MANUAL: +// ShowHelpDialog(FALSE); +// break; + +// case MNU_ABOUT: +// ShowHelpDialog(TRUE); +// break; +// } +// } + +//----------------------------------------------------------------------------- +// WndProc for MainWindow. +//----------------------------------------------------------------------------- +LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + // switch (msg) { + // case WM_ERASEBKGND: + // break; + + // case WM_SETFOCUS: + + // case WM_PAINT: { + // } + + // case WM_KEYDOWN: { + // } + + // case WM_LBUTTONDBLCLK: { + // } + + // case WM_LBUTTONDOWN: { + // } + // case WM_MOUSEMOVE: { + // } + // case WM_MOUSEWHEEL: { + // } + + // case WM_SIZE: + + // case WM_NOTIFY: { + // NMHDR *h = (NMHDR *)lParam; + // if(h->hwndFrom == IoList) { + // IoListProc(h); + // } + // return 0; + // } + // case WM_VSCROLL: + + // case WM_HSCROLL: + + // case WM_COMMAND: + // ProcessMenu(LOWORD(wParam)); + // InvalidateRect(MainWindow, NULL, FALSE); + // break; + + // case WM_CLOSE: + // case WM_DESTROY: + + // default: + // return DefWindowProc(hwnd, msg, wParam, lParam); + // } + + return 1; +} + +void LD_WM_Close_call(GtkWidget *widget, GdkEvent *event, gpointer user_data)//(HWND window) +{ + /* Handles: + * WM_CLOSE + */ + + FreezeWindowPos(MainWindow); + FreezeDWORD(IoListHeight); + + gtk_main_quit(); +} + +gboolean LD_WM_KeyDown_call(GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + /* Handles: + * WM_KEYDOWN + */ + + switch(event->key.state) + { + case GDK_SHIFT_MASK: + g_print("SHIFT+"); + break; + case GDK_CONTROL_MASK: + g_print("CONTROL+"); + break; + } + + g_print("%c\n", (char)gdk_keyval_to_unicode(event->key.keyval)); + + // if(wParam == 'M') { + // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) { + // ToggleSimulationMode(); + // break; + // } + // } else if(wParam == VK_TAB) { + // SetFocus(IoList); + // BlinkCursor(0, 0, 0, 0); + // break; + // } else if(wParam == VK_F1) { + // ShowHelpDialog(FALSE); + // break; + // } + + // if(InSimulationMode) { + // switch(wParam) { + // case ' ': + // SimulateOneCycle(TRUE); + // break; + + // case 'R': + // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) + // StartSimulation(); + // break; + + // case 'H': + // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) + // StopSimulation(); + // break; + + // case VK_DOWN: + // if(ScrollYOffset < ScrollYOffsetMax) + // ScrollYOffset++; + // RefreshScrollbars(); + // InvalidateRect(MainWindow, NULL, FALSE); + // break; + + // case VK_UP: + // if(ScrollYOffset > 0) + // ScrollYOffset--; + // RefreshScrollbars(); + // InvalidateRect(MainWindow, NULL, FALSE); + // break; + + // case VK_LEFT: + // ScrollXOffset -= FONT_WIDTH; + // if(ScrollXOffset < 0) ScrollXOffset = 0; + // RefreshScrollbars(); + // InvalidateRect(MainWindow, NULL, FALSE); + // break; + + // case VK_RIGHT: + // ScrollXOffset += FONT_WIDTH; + // if(ScrollXOffset >= ScrollXOffsetMax) + // ScrollXOffset = ScrollXOffsetMax; + // RefreshScrollbars(); + // InvalidateRect(MainWindow, NULL, FALSE); + // break; + + // case VK_RETURN: + // case VK_ESCAPE: + // ToggleSimulationMode(); + // break; + // } + // break; + // } + + + // switch(wParam) { + // case VK_F5: + // CompileProgram(FALSE); + // break; + + // case VK_UP: + // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { + // CHANGING_PROGRAM(PushRungUp()); + // } else { + // MoveCursorKeyboard(wParam); + // } + // break; + + // case VK_DOWN: + // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { + // CHANGING_PROGRAM(PushRungDown()); + // } else { + // MoveCursorKeyboard(wParam); + // } + // break; + + // case VK_RIGHT: + // case VK_LEFT: + // MoveCursorKeyboard(wParam); + // break; + + // case VK_RETURN: + // CHANGING_PROGRAM(EditSelectedElement()); + // break; + + // case VK_DELETE: + // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { + // CHANGING_PROGRAM(DeleteSelectedRung()); + // } else { + // CHANGING_PROGRAM(DeleteSelectedFromProgram()); + // } + // break; + + // case VK_OEM_1: + // CHANGING_PROGRAM(AddComment(_("--add comment here--"))); + // break; + + // case 'C': + // CHANGING_PROGRAM(AddContact()); + // break; + + // // TODO: rather country-specific here + // case VK_OEM_2: + // CHANGING_PROGRAM(AddEmpty(ELEM_ONE_SHOT_RISING)); + // break; + + // case VK_OEM_5: + // CHANGING_PROGRAM(AddEmpty(ELEM_ONE_SHOT_FALLING)); + // break; + + // case 'L': + // CHANGING_PROGRAM(AddCoil()); + // break; + + // case 'R': + // CHANGING_PROGRAM(MakeResetOnlySelected()); + // break; + + // case 'E': + // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) { + // ExportDialog(); + // } else { + // CHANGING_PROGRAM(AddReset()); + // } + // break; + + // case 'S': + // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) { + // SaveProgram(); + // UpdateMainWindowTitleBar(); + // } else { + // CHANGING_PROGRAM(MakeSetOnlySelected()); + // } + // break; + + // case 'N': + // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) { + // if(CheckSaveUserCancels()) break; + // if(!ProgramChangedNotSaved) { + // int r = MessageBox(MainWindow, + // _("Start new program?"), + // "LDmicro", MB_YESNO | MB_DEFBUTTON2 | + // MB_ICONQUESTION); + // if(r == IDNO) break; + // } + // NewProgram(); + // strcpy(CurrentSaveFile, ""); + // strcpy(CurrentCompileFile, ""); + // GenerateIoListDontLoseSelection(); + // RefreshScrollbars(); + // UpdateMainWindowTitleBar(); + // } else { + // CHANGING_PROGRAM(NegateSelected()); + // } + // break; + + // case 'A': + // CHANGING_PROGRAM(MakeNormalSelected()); + // break; + + // case 'T': + // CHANGING_PROGRAM(AddTimer(ELEM_RTO)); + // break; + + // case 'O': + // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) { + // if(CheckSaveUserCancels()) break; + // OpenDialog(); + // } else { + // CHANGING_PROGRAM(AddTimer(ELEM_TON)); + // } + // break; + + // case 'F': + // CHANGING_PROGRAM(AddTimer(ELEM_TOF)); + // break; + + // case 'U': + // CHANGING_PROGRAM(AddCounter(ELEM_CTU)); + // break; + + // case 'I': + // CHANGING_PROGRAM(AddCounter(ELEM_CTD)); + // break; + + // case 'J': + // CHANGING_PROGRAM(AddCounter(ELEM_CTC)); + // break; + + // case 'M': + // CHANGING_PROGRAM(AddMove()); + // break; + + // case 'P': + // CHANGING_PROGRAM(AddReadAdc()); + // break; + + // case VK_OEM_PLUS: + // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { + // CHANGING_PROGRAM(AddMath(ELEM_ADD)); + // } else { + // CHANGING_PROGRAM(AddCmp(ELEM_EQU)); + // } + // break; + + // case VK_OEM_MINUS: + // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { + // } else { + // CHANGING_PROGRAM(AddMath(ELEM_SUB)); + // } + // break; + + // case '8': + // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { + // CHANGING_PROGRAM(AddMath(ELEM_MUL)); + // } + // break; + + // case 'D': + // CHANGING_PROGRAM(AddMath(ELEM_DIV)); + // break; + + // case VK_OEM_PERIOD: + // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { + // CHANGING_PROGRAM(AddCmp(ELEM_GRT)); + // } else { + // CHANGING_PROGRAM(AddCmp(ELEM_GEQ)); + // } + // break; + + // case VK_OEM_COMMA: + // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { + // CHANGING_PROGRAM(AddCmp(ELEM_LES)); + // } else { + // CHANGING_PROGRAM(AddCmp(ELEM_LEQ)); + // } + // break; + + // case 'V': + // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { + // CHANGING_PROGRAM(InsertRung(TRUE)); + // } + // break; + + // case '6': + // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { + // CHANGING_PROGRAM(InsertRung(FALSE)); + // } + // break; + + // case 'Z': + // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) { + // UndoUndo(); + // } + // break; + + // case 'Y': + // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) { + // UndoRedo(); + // } + // break; + + // default: + // break; + // } + // if(wParam != VK_SHIFT && wParam != VK_CONTROL) { + // InvalidateRect(MainWindow, NULL, FALSE); + // } + // break; + return FALSE; +} + +gboolean LD_GTK_mouse_click_hook(GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + /* Handles: + * WM_LBUTTONDBLCLK, WM_LBUTTONDOWN + */ + + g_print("x = %f\n", event->button.x_root); + g_print("y = %f\n", event->button.y_root); + switch(event->button.type) + { + case GDK_BUTTON_PRESS:// To Do: run only for left click + // int x = LOWORD(lParam); + // int y = HIWORD(lParam); + // if((y > (IoListTop - 9)) && (y < (IoListTop + 3))) { + // POINT pt; + // pt.x = x; pt.y = y; + // ClientToScreen(MainWindow, &pt); + // MouseY = pt.y; + // MouseHookHandle = SetWindowsHookEx(WH_MOUSE_LL, + // (HOOKPROC)MouseHook, Instance, 0); + // } + // if(!InSimulationMode) MoveCursorMouseClick(x, y); + + // SetFocus(MainWindow); + // InvalidateRect(MainWindow, NULL, FALSE); + break; + case GDK_2BUTTON_PRESS: + // int x = LOWORD(lParam); + // int y = HIWORD(lParam); + // if(InSimulationMode) { + // EditElementMouseDoubleclick(x, y); + // } else { + // CHANGING_PROGRAM(EditElementMouseDoubleclick(x, y)); + // } + // InvalidateRect(MainWindow, NULL, FALSE); + break; + + } + return FALSE; +} + +gboolean LD_GTK_mouse_scroll_hook(GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + /* Handles: + * WM_VSCROLL, WM_HSCROLL, WM_MOUSEWHEEL + */ + + switch(event->scroll.direction) + { + case GDK_SCROLL_UP: + case GDK_SCROLL_DOWN: + // VscrollProc(wParam); + break; + case GDK_SCROLL_LEFT: + case GDK_SCROLL_RIGHT: + // HscrollProc(wParam); + break; + case GDK_SCROLL_SMOOTH: + // if((GET_WHEEL_DELTA_WPARAM(wParam)) > 0) { + // VscrollProc(SB_LINEUP); + // } else { + // VscrollProc(SB_LINEDOWN); + // } + // gdk_event_get_scroll_deltas (const GdkEvent *event, gdouble *delta_x, gdouble *delta_y); + break; + + } + return FALSE; +} + +gboolean LD_WM_MouseMove_call(GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + /* Handles: + * WM_MOUSEMOVE + */ + + // g_print("x = %f\n", event->button.x_root); + // g_print("y = %f\n", event->button.y_root); + + // int x = LOWORD(lParam); + // int y = HIWORD(lParam); + + // if((y > (IoListTop - 9)) && (y < (IoListTop + 3))) { + // SetCursor(LoadCursor(NULL, IDC_SIZENS)); + // } else { + // SetCursor(LoadCursor(NULL, IDC_ARROW)); + // } + + // break; + return FALSE; +} + +gboolean LD_WM_Paint_call(HWID widget, HCRDC cr, gpointer data) +{ + /* Handles: + * WM_PAINT + */ + + g_print("draw called\n"); + + // guint width, height; + // GdkRGBA color; + // GtkStyleContext *context; + + // context = gtk_widget_get_style_context (widget); + + // width = gtk_widget_get_allocated_width (widget); + // height = gtk_widget_get_allocated_height (widget); + + // gtk_render_background (context, cr, 0, 0, width, height); + + // cairo_arc (cr, + // width / 2.0, height / 2.0, + // MIN (width, height) / 3.0, + // 0, 2 * G_PI); + + // gtk_style_context_get_color (context, + // gtk_style_context_get_state (context), + // &color); + // gdk_cairo_set_source_rgba (cr, &color); + + // cairo_fill (cr); + // static double Cairo_R = 0.0, Cairo_G = 0.0, Cairo_B = 0.0; + // cairo_set_source_rgb(cr, Cairo_R, Cairo_G, Cairo_G); + // Cairo_R = (Cairo_R+0.2 > 0.4) ? 0 : Cairo_R+0.2; + // Cairo_G = (Cairo_G+0.4 > 1.0) ? 0.4 : Cairo_G+0.4; + // Cairo_B = (Cairo_B+0.1 > 0.5) ? 0 : Cairo_B+0.1; + + // cairo_select_font_face(cr, "Purisa", + // CAIRO_FONT_SLANT_NORMAL, + // CAIRO_FONT_WEIGHT_BOLD); + + // cairo_set_font_size(cr, 20); + + // cairo_move_to(cr, 20, height / 2.0); + // cairo_show_text(cr, "-----------THIS IS A TEST DRAW----------"); + + // cairo_fill (cr); + + + // PAINTSTRUCT ps; + Hdc = cr;//BeginPaint(hwnd, &ps); + + /// This draws the schematic. + PaintWindow(); + + // cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); + // cairo_set_line_width(cr, 1); + + // cairo_rectangle(cr, 20, 20, 120, 80); + // cairo_rectangle(cr, 180, 20, 80, 80); + // cairo_stroke_preserve(cr); + // cairo_fill(cr); + + RECT r; + // Fill around the scroll bars + // if(NeedHoriz) { + ScrollHeight = 10; + r.top = IoListTop - ScrollHeight - 2; + r.bottom = IoListTop - 2; + r.right = 5; + FillRect(Hdc, &r, (HBRUSH)GetStockObject(LTGRAY_BRUSH)); + // } + GetClientRect(DrawWindow, &r); + ScrollWidth = 10; + r.left = r.right - ScrollWidth - 2; + FillRect(Hdc, &r, (HBRUSH)GetStockObject(LTGRAY_BRUSH)); + // Draw the splitter thing to grab to resize the I/O listview. + GetClientRect(DrawWindow, &r); + r.top = IoListTop - 2; + r.bottom = IoListTop; + FillRect(Hdc, &r, (HBRUSH)GetStockObject(LTGRAY_BRUSH)); + r.top = IoListTop - 2; + r.bottom = IoListTop - 1; + FillRect(Hdc, &r, (HBRUSH)GetStockObject(WHITE_BRUSH)); + r.top = IoListTop; + r.bottom = IoListTop + 1; + FillRect(Hdc, &r, (HBRUSH)GetStockObject(DKGRAY_BRUSH)); + // EndPaint(hwnd, &ps); + + return FALSE; +} + +gboolean LD_WM_Destroy_call(GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + /* Handles: + * WM_DESTROY + */ + + // if(CheckSaveUserCancels()) break; + + // PostQuitMessage(0); + // return 1; + + return FALSE; +} + +gboolean LD_WM_Size_call(GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + /* Handles: + * WM_SIZE + */ + + // MainWindowResized(); + // break; + + return FALSE; +} + +gboolean LD_WM_SetFocus_call(GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + /* Handles: + * WM_SETFOCUS + */ + + // InvalidateRect(MainWindow, NULL, FALSE); + // break; + + return FALSE; +} + +//----------------------------------------------------------------------------- +// Entry point into the program. +//----------------------------------------------------------------------------- +int main(int argc, char** argv) +{ + /// Check if we're running in non-interactive mode; in that case we should + /// load the file, compile, and exit. + + if(argc >= 2 && !(argc < 4) ) { + RunningInBatchMode = TRUE; + + char *err = + "Bad command line arguments: run 'ldmicro /c src.ld dest.hex'"; + + // if (argc < 4) + // { + // Error(err); + // exit(-1); + // } + + char *source = (char*)malloc(strlen(argv[2]) + strlen(argv[3]) + 2); + sprintf(source, "%s %s", argv[2], argv[3]); + + while(isspace(*source)) { + source++; + } + if(*source == '\0') + { + Error(err); + free(source); + exit(-1); + } + + char *dest = source; + while(!isspace(*dest) && *dest) { + dest++; + } + if(*dest == '\0') + { + Error(err); + free(source); + exit(-1); + } + *dest = '\0'; dest++; + while(isspace(*dest)) { + dest++; + } + + if(*dest == '\0') + { + Error(err); + free(source); + exit(-1); + } + + if(!LoadProjectFromFile(source)) { + Error("Couldn't open '%s', running non-interactively.\n", source); + free(source); + exit(-1); + } + strcpy(CurrentCompileFile, dest); + GenerateIoList(-1); + CompileProgram(FALSE); + exit(0); + } + + gtk_init(&argc, &argv); + Instance = NULL; + /* TEST + MainWindow=gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(MainWindow), "LDMicro"); + g_signal_connect (MainWindow, "delete_event", G_CALLBACK (LDMicro_close), NULL); + gtk_window_set_default_size (GTK_WINDOW (MainWindow), 600, 400); + gtk_window_resize (GTK_WINDOW (MainWindow), 600, 400); + + ThawWindowPos(MainWindow); + ThawDWORD(IoListHeight); + + + // Title bar + UpdateMainWindowTitleBar(); + + // Splitting the window + MakeMainWindowControls(); + + // Calling the Simulation functions + + // StartSimulation(); // test + // SetMenusEnabled(true, true, false, + // true, false, false, false, + // true, true, true); // test + // ToggleSimulationMode(); //test + // GenerateIoListDontLoseSelection(); + StopSimulation(); //Test + */ + + MainHeap = HeapCreate(0, 1024*64, 0); + + // MakeDialogBoxClass(); + // MakeComponentListClass(); + // MakeSmplDialogClass(); + // MakeNamingListClass(); + HMENU top = MakeMainWindowMenus(); + + /// Make main window + MainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(MainWindow), "LDmicro"); + gtk_window_set_default_size (GTK_WINDOW(MainWindow), 800, 600); + gtk_window_resize (GTK_WINDOW(MainWindow), 800, 600); + gtk_window_move(GTK_WINDOW(MainWindow), 10, 10); + gtk_widget_override_background_color(GTK_WIDGET(MainWindow), + GTK_STATE_FLAG_NORMAL, ((HBRUSH)GetStockObject(GRAY_BRUSH))->getThis()); + gtk_window_set_default_icon(LoadImage(Instance, LDMICRO_ICON, + IMAGE_ICON, 32, 32, 0)); + gtk_window_set_icon(GTK_WINDOW(MainWindow), LoadImage(Instance, LDMICRO_ICON, + IMAGE_ICON, 32, 32, 0)); + /// Make main window - end + + InitForDrawing(); + + ThawWindowPos(MainWindow); + IoListHeight = 100; + ThawDWORD(IoListHeight); + + MakeMainWindowControls(); /// takes care of MakeMainWindowMenus() + MainWindowResized(); + + /// Keyboard and mouse hooks equivalent to MainWndProc + g_signal_connect (MainWindow, "delete_event", G_CALLBACK (LD_WM_Close_call), NULL); + g_signal_connect (MainWindow, "key_press_event", G_CALLBACK (LD_WM_KeyDown_call), NULL); + g_signal_connect (MainWindow, "button_press_event", G_CALLBACK (LD_GTK_mouse_click_hook), NULL); + g_signal_connect (MainWindow, "scroll_event", G_CALLBACK (LD_GTK_mouse_scroll_hook), NULL); + g_signal_connect (MainWindow, "motion_notify_event", G_CALLBACK (LD_WM_MouseMove_call), NULL); + g_signal_connect (DrawWindow, "draw", G_CALLBACK (LD_WM_Paint_call), NULL); + g_signal_connect (MainWindow, "destroy_event", G_CALLBACK (LD_WM_Destroy_call), NULL); + g_signal_connect (MainWindow, "configure_event", G_CALLBACK (LD_WM_Size_call), NULL); + g_signal_connect (MainWindow, "focus_in_event", G_CALLBACK (LD_WM_SetFocus_call), NULL); + /// Keyboard and mouse hooks equivalent to MainWndProc - end + + NewProgram(); + strcpy(CurrentSaveFile, ""); + + // We are running interactively, or we would already have exited. We + // can therefore show the window now, and otherwise set up the GUI. + + // Displaying the window + gtk_widget_show_all(MainWindow); + // SetTimer(MainWindow, TIMER_BLINK_CURSOR, 800, BlinkCursor); + + if(argc >= 2) { + // g_print("load prog: %s\n", argv[1]); + char line[MAX_PATH]; + if(*argv[1] == '"') { + strcpy(line, argv[1]+1); + } else { + strcpy(line, argv[1]); + } + if(strchr(line, '"')) *strchr(line, '"') = '\0'; + + realpath(line, CurrentSaveFile); + // g_print("resolved path: %s\n", CurrentSaveFile); + if(!LoadProjectFromFile(CurrentSaveFile)) { + NewProgram(); + Error(_("Couldn't open '%s'."), CurrentSaveFile); + CurrentSaveFile[0] = '\0'; + } + UndoFlush(); + } + + GenerateIoListDontLoseSelection(); //~ + // RefreshScrollbars(); + UpdateMainWindowTitleBar(); //~ + + // MSG msg; + // DWORD ret; + // while(ret = GetMessage(&msg, NULL, 0, 0)) { + // if(msg.hwnd == IoList && msg.message == WM_KEYDOWN) { + // if(msg.wParam == VK_TAB) { + // SetFocus(MainWindow); + // continue; + // } + // } + // if(msg.message == WM_KEYDOWN && msg.wParam != VK_UP && + // msg.wParam != VK_DOWN && msg.wParam != VK_RETURN && msg.wParam + // != VK_SHIFT) + // { + // if(msg.hwnd == IoList) { + // msg.hwnd = MainWindow; + // SetFocus(MainWindow); + // } + // } + // TranslateMessage(&msg); + // DispatchMessage(&msg); + // } + + gtk_main(); + return EXIT_SUCCESS; +}
\ No newline at end of file |