summaryrefslogtreecommitdiff
path: root/ldmicro/iolist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ldmicro/iolist.cpp')
-rw-r--r--ldmicro/iolist.cpp920
1 files changed, 471 insertions, 449 deletions
diff --git a/ldmicro/iolist.cpp b/ldmicro/iolist.cpp
index e2fc032..f20b2f7 100644
--- a/ldmicro/iolist.cpp
+++ b/ldmicro/iolist.cpp
@@ -43,20 +43,20 @@ static struct {
static int IoSeenPreviouslyCount;
// // stuff for the dialog box that lets you choose pin assignments
-// static BOOL DialogDone;
-// static BOOL DialogCancel;
+static BOOL DialogDone;
+static BOOL DialogCancel;
-// static HWND IoDialog;
+static HWID IoDialog;
-// static HWND PinList;
-// static HWND OkButton;
-// static HWND CancelButton;
+static HWID PinList;
+static HWID OkButton;
+static HWID CancelButton;
// // stuff for the popup that lets you set the simulated value of an analog in
-// static HWND AnalogSliderMain;
-// static HWND AnalogSliderTrackbar;
-// static BOOL AnalogSliderDone;
-// static BOOL AnalogSliderCancel;
+static HWID AnalogSliderMain;
+static HWID AnalogSliderTrackbar;
+static BOOL AnalogSliderDone;
+static BOOL AnalogSliderCancel;
//-----------------------------------------------------------------------------
@@ -394,159 +394,200 @@ void SaveIoListToFile(FILE *f)
// Dialog proc for the popup that lets you set the value of an analog input for
// simulation.
//-----------------------------------------------------------------------------
-// static LRESULT CALLBACK AnalogSliderDialogProc(HWND hwnd, UINT msg,
-// WPARAM wParam, LPARAM lParam)
-// {
-// switch (msg) {
-// case WM_CLOSE:
-// case WM_DESTROY:
-// AnalogSliderDone = TRUE;
-// AnalogSliderCancel = TRUE;
-// return 1;
-
-// default:
-// return DefWindowProc(hwnd, msg, wParam, lParam);
-// }
-// }
+static gboolean AnalogSliderDialogKeyboardProc(GtkWidget* widget, GdkEventKey* event, gpointer name)
+{
+ SWORD v = (SWORD)gtk_range_get_value(GTK_RANGE(AnalogSliderTrackbar));
+ SetAdcShadow((char*)name, v);
+ if (AnalogSliderDone == TRUE || AnalogSliderCancel == TRUE)
+ {
+ DestroyWindow (AnalogSliderMain);
+ return FALSE;
+ }
+
+ if (event->keyval == GDK_KEY_Return){
+ DestroyWindow (AnalogSliderMain);
+ AnalogSliderDone = TRUE;
+ }
+ else if (event->keyval == GDK_KEY_Escape){
+ DestroyWindow (AnalogSliderMain);
+ AnalogSliderDone = TRUE;
+ AnalogSliderCancel = TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean AnalogSliderDialogMouseProc(GtkWidget *widget, GdkEventButton *event, gpointer name)
+{
+ SWORD v = (SWORD)gtk_range_get_value(GTK_RANGE(AnalogSliderTrackbar));
+ SetAdcShadow((char*)name, v);
+ if (event->button == 1 && event->type == GDK_BUTTON_RELEASE){
+ DestroyWindow (AnalogSliderMain);
+ AnalogSliderDone = TRUE;
+ }
+
+ return FALSE;
+}
+
+void AnalogSliderUpdateProc (GtkRange *range, GtkScrollType step, gpointer name)
+{
+ SWORD v = (SWORD)gtk_range_get_value(GTK_RANGE(AnalogSliderTrackbar));
+ SetAdcShadow((char*)name, v);
+}
//-----------------------------------------------------------------------------
// A little toolbar-style window that pops up to allow the user to set the
// simulated value of an ADC pin.
//-----------------------------------------------------------------------------
-// void ShowAnalogSliderPopup(char *name)
-// {
-// WNDCLASSEX wc;
-// memset(&wc, 0, sizeof(wc));
-// wc.cbSize = sizeof(wc);
-
-// wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_OWNDC |
-// CS_DBLCLKS;
-// wc.lpfnWndProc = (WNDPROC)AnalogSliderDialogProc;
-// wc.hInstance = Instance;
-// wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
-// wc.lpszClassName = "LDmicroAnalogSlider";
-// wc.lpszMenuName = NULL;
-// wc.hCursor = LoadCursor(NULL, IDC_ARROW);
-
-// RegisterClassEx(&wc);
+void ShowAnalogSliderPopup(char *name)
+{
+ SWORD currentVal = GetAdcShadow(name);
-// POINT pt;
-// GetCursorPos(&pt);
+ SWORD maxVal;
+ if(Prog.mcu) {
+ maxVal = Prog.mcu->adcMax;
+ } else {
+ maxVal = 1023;
+ }
+ if(maxVal == 0) {
+ Error(_("No ADC or ADC not supported for selected micro."));
+ return;
+ }
-// SWORD currentVal = GetAdcShadow(name);
+ int left = GLOBAL_mouse_last_clicked_x - 10;
+ // try to put the slider directly under the cursor (though later we might
+ // realize that that would put the popup off the screen)
+ int top = GLOBAL_mouse_last_clicked_y - (15 + (73*currentVal)/maxVal);
-// SWORD maxVal;
-// if(Prog.mcu) {
-// maxVal = Prog.mcu->adcMax;
-// } else {
-// maxVal = 1023;
-// }
-// if(maxVal == 0) {
-// Error(_("No ADC or ADC not supported for selected micro."));
-// return;
-// }
+ int x, y;
+ gdk_window_get_origin (gtk_widget_get_window (view), &x, &y);
-// int left = pt.x - 10;
-// // try to put the slider directly under the cursor (though later we might
-// // realize that that would put the popup off the screen)
-// int top = pt.y - (15 + (73*currentVal)/maxVal);
+ if(top < 0) top = y + 10;
+ if(left < 0) left = x + 20;
+
+ if (GTK_IS_WINDOW(AnalogSliderMain))
+ return;
+
+ AnalogSliderMain = gtk_window_new(GTK_WINDOW_POPUP);
+ gtk_window_set_title(GTK_WINDOW(AnalogSliderMain), _("I/O Pin"));
+ gtk_window_resize (GTK_WINDOW(AnalogSliderMain), 30, 100);
+ gtk_window_move(GTK_WINDOW(AnalogSliderMain), left, top);
-// RECT r;
-// SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
+ AnalogSliderTrackbar = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL,
+ 0,
+ maxVal,
+ 1);
-// if(top + 110 >= r.bottom) {
-// top = r.bottom - 110;
-// }
-// if(top < 0) top = 0;
+ gtk_range_set_value (GTK_RANGE(AnalogSliderTrackbar), currentVal);
-// AnalogSliderMain = CreateWindowClient(0, "LDmicroAnalogSlider", "I/O Pin",
-// WS_VISIBLE | WS_POPUP | WS_DLGFRAME,
-// left, top, 30, 100, NULL, NULL, Instance, NULL);
-
-// AnalogSliderTrackbar = CreateWindowEx(0, TRACKBAR_CLASS, "", WS_CHILD |
-// TBS_AUTOTICKS | TBS_VERT | TBS_TOOLTIPS | WS_CLIPSIBLINGS | WS_VISIBLE,
-// 0, 0, 30, 100, AnalogSliderMain, NULL, Instance, NULL);
-// SendMessage(AnalogSliderTrackbar, TBM_SETRANGE, FALSE,
-// MAKELONG(0, maxVal));
-// SendMessage(AnalogSliderTrackbar, TBM_SETTICFREQ, (maxVal + 1)/8, 0);
-// SendMessage(AnalogSliderTrackbar, TBM_SETPOS, TRUE, currentVal);
-
-// EnableWindow(MainWindow, FALSE);
-// ShowWindow(AnalogSliderMain, TRUE);
-// SetFocus(AnalogSliderTrackbar);
-
-// DWORD ret;
-// MSG msg;
-// AnalogSliderDone = FALSE;
-// AnalogSliderCancel = FALSE;
-
-// SWORD orig = GetAdcShadow(name);
-
-// while(!AnalogSliderDone && (ret = GetMessage(&msg, NULL, 0, 0))) {
-// SWORD v = (SWORD)SendMessage(AnalogSliderTrackbar, TBM_GETPOS, 0, 0);
-
-// if(msg.message == WM_KEYDOWN) {
-// if(msg.wParam == VK_RETURN) {
-// AnalogSliderDone = TRUE;
-// break;
-// } else if(msg.wParam == VK_ESCAPE) {
-// AnalogSliderDone = TRUE;
-// AnalogSliderCancel = TRUE;
-// break;
-// }
-// } else if(msg.message == WM_LBUTTONUP) {
-// if(v != orig) {
-// AnalogSliderDone = TRUE;
-// }
-// }
-// SetAdcShadow(name, v);
-
-// TranslateMessage(&msg);
-// DispatchMessage(&msg);
-// }
-
-// if(!AnalogSliderCancel) {
-// SWORD v = (SWORD)SendMessage(AnalogSliderTrackbar, TBM_GETPOS, 0, 0);
-// SetAdcShadow(name, v);
-// }
-
-// EnableWindow(MainWindow, TRUE);
-// DestroyWindow(AnalogSliderMain);
-// ListView_RedrawItems(IoList, 0, Prog.io.count - 1);
-// }
+ gtk_container_add(GTK_CONTAINER(AnalogSliderMain), AnalogSliderTrackbar);
+
+ // SetFocus(AnalogSliderTrackbar);
+ gtk_window_set_focus_visible (GTK_WINDOW(AnalogSliderMain), TRUE);
+ gtk_window_set_keep_above (GTK_WINDOW(AnalogSliderMain), TRUE);
+ gtk_window_set_focus (GTK_WINDOW(AnalogSliderMain), AnalogSliderTrackbar);
+
+ g_signal_connect (GTK_RANGE(AnalogSliderTrackbar), "key-press-event",
+ G_CALLBACK(AnalogSliderDialogKeyboardProc), (PVOID)name);
+ g_signal_connect (GTK_RANGE(AnalogSliderTrackbar), "button-release-event",
+ G_CALLBACK (AnalogSliderDialogMouseProc), (PVOID)name);
+ g_signal_connect (GTK_RANGE(AnalogSliderTrackbar), "value-changed",
+ G_CALLBACK (AnalogSliderUpdateProc), (PVOID)name);
+
+ gtk_widget_show_all(AnalogSliderMain);
+
+ AnalogSliderDone = FALSE;
+ AnalogSliderCancel = FALSE;
+
+ // ListView_RedrawItems(IoList, 0, Prog.io.count - 1);
+}
//-----------------------------------------------------------------------------
// Window proc for the contacts dialog box
//-----------------------------------------------------------------------------
-// static LRESULT CALLBACK IoDialogProc(HWND hwnd, UINT msg, WPARAM wParam,
-// LPARAM lParam)
-// {
-// switch (msg) {
-// case WM_COMMAND: {
-// HWND h = (HWND)lParam;
-// if(h == OkButton && wParam == BN_CLICKED) {
-// DialogDone = TRUE;
-// } else if(h == CancelButton && wParam == BN_CLICKED) {
-// DialogDone = TRUE;
-// DialogCancel = TRUE;
-// } else if(h == PinList && HIWORD(wParam) == LBN_DBLCLK) {
-// DialogDone = TRUE;
-// }
-// break;
-// }
-
-// case WM_CLOSE:
-// case WM_DESTROY:
-// DialogDone = TRUE;
-// DialogCancel = TRUE;
-// return 1;
-
-// default:
-// return DefWindowProc(hwnd, msg, wParam, lParam);
-// }
-
-// return 1;
-// }
+static void IoDialogProc(BOOL DialogDone, int item)
+{
+ if(DialogDone)
+ {
+ char pin[16];
+ ITLIST iter;
+
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(PinList));
+ gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
+
+ if(gtk_tree_selection_get_selected (selection, NULL, &iter))
+ {
+ GValue valproc = G_VALUE_INIT;
+
+ gtk_tree_model_get_value (gtk_tree_view_get_model (GTK_TREE_VIEW(PinList)),
+ &iter, 0, &valproc);
+ gchar* str = (char*)g_value_get_string(&valproc);
+ strcpy(pin, str);
+ g_free(str);
+ }
+ else
+ strcpy(pin, _("(no pin)"));
+
+ if(strcmp(pin, _("(no pin)"))==0)
+ {
+ int i;
+ for(i = 0; i < IoSeenPreviouslyCount; i++) {
+ if(strcmp(IoSeenPreviously[i].name,
+ Prog.io.assignment[item].name)==0)
+ {
+ IoSeenPreviously[i].pin = NO_PIN_ASSIGNED;
+ }
+ }
+ Prog.io.assignment[item].pin = NO_PIN_ASSIGNED;
+ }
+ else
+ {
+ Prog.io.assignment[item].pin = atoi(pin);
+ // Only one name can be bound to each pin; make sure that there's
+ // not another entry for this pin in the IoSeenPreviously list,
+ // that might get used if the user creates a new pin with that
+ // name.
+ int i;
+ for(i = 0; i < IoSeenPreviouslyCount; i++) {
+ if(IoSeenPreviously[i].pin == atoi(pin)) {
+ IoSeenPreviously[i].pin = NO_PIN_ASSIGNED;
+ }
+ }
+ }
+ RefreshControlsToSettings();
+ }
+
+ DestroyWindow(IoDialog);
+}
+
+void IoDialogRowActivateProc(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
+{
+ IoDialogProc(TRUE, GPOINTER_TO_INT(user_data));
+}
+
+void IoDialogCancelProc(HWID widget, gpointer data)
+{
+ IoDialogProc(FALSE, GPOINTER_TO_INT(data));
+}
+
+void IoDialogOkProc(HWID widget, gpointer data)
+{
+ IoDialogProc(TRUE, GPOINTER_TO_INT(data));
+}
+
+static gboolean IoDialogKeyPressProc(HWID widget, GdkEventKey* event, gpointer data)
+{
+ if (event -> keyval == GDK_KEY_Return)
+ {
+ IoDialogProc(TRUE, GPOINTER_TO_INT(data));
+ }
+ else if (event -> keyval == GDK_KEY_Escape)
+ {
+ IoDialogProc(FALSE, GPOINTER_TO_INT(data));
+ }
+
+ return FALSE;
+}
//-----------------------------------------------------------------------------
// Create our window class; nothing exciting.
@@ -573,193 +614,165 @@ void SaveIoListToFile(FILE *f)
// return RegisterClassEx(&wc);
// }
-// static void MakeControls(void)
-// {
-// HWND textLabel = CreateWindowEx(0, WC_STATIC, _("Assign:"),
-// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
-// 6, 1, 80, 17, IoDialog, NULL, Instance, NULL);
-// NiceFont(textLabel);
-
-// PinList = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTBOX, "",
-// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | WS_VSCROLL |
-// LBS_NOTIFY, 6, 18, 95, 320, IoDialog, NULL, Instance, NULL);
-// FixedFont(PinList);
-
-// OkButton = CreateWindowEx(0, WC_BUTTON, _("OK"),
-// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON,
-// 6, 325, 95, 23, IoDialog, NULL, Instance, NULL);
-// NiceFont(OkButton);
-
-// CancelButton = CreateWindowEx(0, WC_BUTTON, _("Cancel"),
-// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE,
-// 6, 356, 95, 23, IoDialog, NULL, Instance, NULL);
-// NiceFont(CancelButton);
-// }
+static void MakeControls(HWID Dialog)
+{
+ HLIST IoPinList = (GtkTreeModel*)gtk_list_store_new (1, G_TYPE_STRING);
+
+ PinList = gtk_tree_view_new_with_model (GTK_TREE_MODEL(IoPinList));
+ HTVC column = gtk_tree_view_column_new_with_attributes(_("Assign:"),
+ gtk_cell_renderer_text_new(),
+ "text", 0,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(PinList), column);
+ FixedFont(PinList);
+
+ OkButton = gtk_button_new_with_label (_("OK"));
+ NiceFont(OkButton);
+
+ CancelButton = gtk_button_new_with_label (_("Cancel"));
+ NiceFont(CancelButton);
+
+ /// Add list to scrolled window to enable scrolling
+ HWID PinScroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (PinScroll),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_ALWAYS);
+ gtk_widget_set_hexpand(GTK_WIDGET(PinScroll), TRUE);
+ gtk_widget_set_vexpand(GTK_WIDGET(PinScroll), TRUE);
+
+ gtk_container_add (GTK_CONTAINER(PinScroll), PinList);
+
+ /// Pack all the widgets into main window
+ HWID PinBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+ gtk_box_pack_start(GTK_BOX(PinBox), PinScroll, FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(PinBox), OkButton, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(PinBox), CancelButton, FALSE, FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(Dialog), PinBox);
+}
-// void ShowIoDialog(int item)
-// {
-// if(!Prog.mcu) {
-// MessageBox(MainWindow,
-// _("No microcontroller has been selected. You must select a "
-// "microcontroller before you can assign I/O pins.\r\n\r\n"
-// "Select a microcontroller under the Settings menu and try "
-// "again."), _("I/O Pin Assignment"), MB_OK | MB_ICONWARNING);
-// return;
-// }
-
-// if(Prog.mcu->whichIsa == ISA_ANSIC) {
-// Error(_("Can't specify I/O assignment for ANSI C target; compile and "
-// "see comments in generated source code."));
-// return;
-// }
-
-// if(Prog.mcu->whichIsa == ISA_INTERPRETED) {
-// Error(_("Can't specify I/O assignment for interpretable target; see "
-// "comments in reference implementation of interpreter."));
-// return;
-// }
-
-// if(Prog.io.assignment[item].name[0] != 'X' &&
-// Prog.io.assignment[item].name[0] != 'Y' &&
-// Prog.io.assignment[item].name[0] != 'A')
-// {
-// Error(_("Can only assign pin number to input/output pins (Xname or "
-// "Yname or Aname)."));
-// return;
-// }
-
-// if(Prog.io.assignment[item].name[0] == 'A' && Prog.mcu->adcCount == 0) {
-// Error(_("No ADC or ADC not supported for this micro."));
-// return;
-// }
-
-// if(strcmp(Prog.io.assignment[item].name+1, "new")==0) {
-// Error(_("Rename I/O from default name ('%s') before assigning "
-// "MCU pin."), Prog.io.assignment[item].name);
-// return;
-// }
-
-// MakeWindowClass();
-
-// // We need the TOOLWINDOW style, or else the window will be forced to
-// // a minimum width greater than our current width. And without the
-// // APPWINDOW style, it becomes impossible to get the window back (by
-// // Alt+Tab or taskbar).
-// IoDialog = CreateWindowClient(WS_EX_TOOLWINDOW | WS_EX_APPWINDOW,
-// "LDmicroIo", _("I/O Pin"),
-// WS_OVERLAPPED | WS_SYSMENU,
-// 100, 100, 107, 387, NULL, NULL, Instance, NULL);
-
-// MakeControls();
-
-// SendMessage(PinList, LB_ADDSTRING, 0, (LPARAM)_("(no pin)"));
-// int i;
-// for(i = 0; i < Prog.mcu->pinCount; i++) {
-// int j;
-// for(j = 0; j < Prog.io.count; j++) {
-// if(j == item) continue;
-// if(Prog.io.assignment[j].pin == Prog.mcu->pinInfo[i].pin) {
-// goto cant_use_this_io;
-// }
-// }
-
-// if(UartFunctionUsed() && Prog.mcu &&
-// ((Prog.mcu->pinInfo[i].pin == Prog.mcu->uartNeeds.rxPin) ||
-// (Prog.mcu->pinInfo[i].pin == Prog.mcu->uartNeeds.txPin)))
-// {
-// goto cant_use_this_io;
-// }
-
-// if(PwmFunctionUsed() &&
-// Prog.mcu->pinInfo[i].pin == Prog.mcu->pwmNeedsPin)
-// {
-// goto cant_use_this_io;
-// }
-
-// if(Prog.io.assignment[item].name[0] == 'A') {
-// for(j = 0; j < Prog.mcu->adcCount; j++) {
-// if(Prog.mcu->adcInfo[j].pin == Prog.mcu->pinInfo[i].pin) {
-// // okay; we know how to connect it up to the ADC
-// break;
-// }
-// }
-// if(j == Prog.mcu->adcCount) {
-// goto cant_use_this_io;
-// }
-// }
-
-// char buf[40];
-// if(Prog.mcu->pinCount <= 21) {
-// sprintf(buf, "%3d %c%c%d", Prog.mcu->pinInfo[i].pin,
-// Prog.mcu->portPrefix, Prog.mcu->pinInfo[i].port,
-// Prog.mcu->pinInfo[i].bit);
-// } else {
-// sprintf(buf, "%3d %c%c%d", Prog.mcu->pinInfo[i].pin,
-// Prog.mcu->portPrefix, Prog.mcu->pinInfo[i].port,
-// Prog.mcu->pinInfo[i].bit);
-// }
-// SendMessage(PinList, LB_ADDSTRING, 0, (LPARAM)buf);
-// cant_use_this_io:;
-// }
-
-// EnableWindow(MainWindow, FALSE);
-// ShowWindow(IoDialog, TRUE);
-// SetFocus(PinList);
-
-// MSG msg;
-// DWORD ret;
-// DialogDone = FALSE;
-// DialogCancel = FALSE;
-// while((ret = GetMessage(&msg, NULL, 0, 0)) && !DialogDone) {
-// if(msg.message == WM_KEYDOWN) {
-// if(msg.wParam == VK_RETURN) {
-// DialogDone = TRUE;
-// break;
-// } else if(msg.wParam == VK_ESCAPE) {
-// DialogDone = TRUE;
-// DialogCancel = TRUE;
-// break;
-// }
-// }
-
-// if(IsDialogMessage(IoDialog, &msg)) continue;
-// TranslateMessage(&msg);
-// DispatchMessage(&msg);
-// }
-
-// if(!DialogCancel) {
-// int sel = SendMessage(PinList, LB_GETCURSEL, 0, 0);
-// char pin[16];
-// SendMessage(PinList, LB_GETTEXT, (WPARAM)sel, (LPARAM)pin);
-// if(strcmp(pin, _("(no pin)"))==0) {
-// int i;
-// for(i = 0; i < IoSeenPreviouslyCount; i++) {
-// if(strcmp(IoSeenPreviously[i].name,
-// Prog.io.assignment[item].name)==0)
-// {
-// IoSeenPreviously[i].pin = NO_PIN_ASSIGNED;
-// }
-// }
-// Prog.io.assignment[item].pin = NO_PIN_ASSIGNED;
-// } else {
-// Prog.io.assignment[item].pin = atoi(pin);
-// // Only one name can be bound to each pin; make sure that there's
-// // not another entry for this pin in the IoSeenPreviously list,
-// // that might get used if the user creates a new pin with that
-// // name.
-// int i;
-// for(i = 0; i < IoSeenPreviouslyCount; i++) {
-// if(IoSeenPreviously[i].pin == atoi(pin)) {
-// IoSeenPreviously[i].pin = NO_PIN_ASSIGNED;
-// }
-// }
-// }
-// }
-
-// EnableWindow(MainWindow, TRUE);
-// DestroyWindow(IoDialog);
-// return;
-// }
+void ShowIoDialog(int item)
+{
+ if(!Prog.mcu) {
+ MessageBox(MainWindow,
+ _("No microcontroller has been selected. You must select a "
+ "microcontroller before you can assign I/O pins.\r\n\r\n"
+ "Select a microcontroller under the Settings menu and try "
+ "again."), _("I/O Pin Assignment"), MB_OK | MB_ICONWARNING);
+ return;
+ }
+
+ if(Prog.mcu->whichIsa == ISA_ANSIC) {
+ Error(_("Can't specify I/O assignment for ANSI C target; compile and "
+ "see comments in generated source code."));
+ return;
+ }
+
+ if(Prog.mcu->whichIsa == ISA_INTERPRETED) {
+ Error(_("Can't specify I/O assignment for interpretable target; see "
+ "comments in reference implementation of interpreter."));
+ return;
+ }
+
+ if(Prog.io.assignment[item].name[0] != 'X' &&
+ Prog.io.assignment[item].name[0] != 'Y' &&
+ Prog.io.assignment[item].name[0] != 'A')
+ {
+ Error(_("Can only assign pin number to input/output pins (Xname or "
+ "Yname or Aname)."));
+ return;
+ }
+
+ if(Prog.io.assignment[item].name[0] == 'A' && Prog.mcu->adcCount == 0) {
+ Error(_("No ADC or ADC not supported for this micro."));
+ return;
+ }
+
+ if(strcmp(Prog.io.assignment[item].name+1, "new")==0) {
+ Error(_("Rename I/O from default name ('%s') before assigning "
+ "MCU pin."), Prog.io.assignment[item].name);
+ return;
+ }
+
+ // We need the TOOLWINDOW style, or else the window will be forced to
+ // a minimum width greater than our current width. And without the
+ // APPWINDOW style, it becomes impossible to get the window back (by
+ // Alt+Tab or taskbar).
+ IoDialog = CreateWindowClient(GTK_WINDOW_TOPLEVEL, GDK_WINDOW_TYPE_HINT_MENU, _("I/O Pin"),
+ 100, 100, 107, 387, NULL);
+
+ MakeControls(IoDialog);
+
+ ITLIST iter;
+ GValue val = G_VALUE_INIT;
+ g_value_init (&val, G_TYPE_STRING);
+
+ HLIST model = gtk_tree_view_get_model (GTK_TREE_VIEW(PinList));
+
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL(model), &iter);
+
+ gtk_list_store_append (GTK_LIST_STORE(model), &iter);
+
+ g_value_set_string(&val, _("(no pin)"));
+ gtk_list_store_set_value (GTK_LIST_STORE(model), &iter, 0, &val);
+
+ int i;
+ for(i = 0; i < Prog.mcu->pinCount; i++) {
+ int j;
+ for(j = 0; j < Prog.io.count; j++) {
+ if(j == item) continue;
+ if(Prog.io.assignment[j].pin == Prog.mcu->pinInfo[i].pin) {
+ goto cant_use_this_io;
+ }
+ }
+
+ if(UartFunctionUsed() && Prog.mcu &&
+ ((Prog.mcu->pinInfo[i].pin == Prog.mcu->uartNeeds.rxPin) ||
+ (Prog.mcu->pinInfo[i].pin == Prog.mcu->uartNeeds.txPin)))
+ {
+ goto cant_use_this_io;
+ }
+
+ if(PwmFunctionUsed() &&
+ Prog.mcu->pinInfo[i].pin == Prog.mcu->pwmNeedsPin)
+ {
+ goto cant_use_this_io;
+ }
+
+ if(Prog.io.assignment[item].name[0] == 'A') {
+ for(j = 0; j < Prog.mcu->adcCount; j++) {
+ if(Prog.mcu->adcInfo[j].pin == Prog.mcu->pinInfo[i].pin) {
+ // okay; we know how to connect it up to the ADC
+ break;
+ }
+ }
+ if(j == Prog.mcu->adcCount) {
+ goto cant_use_this_io;
+ }
+ }
+
+ char buf[40];
+ if(Prog.mcu->pinCount <= 21) {
+ sprintf(buf, "%3d %c%c%d", Prog.mcu->pinInfo[i].pin,
+ Prog.mcu->portPrefix, Prog.mcu->pinInfo[i].port,
+ Prog.mcu->pinInfo[i].bit);
+ } else {
+ sprintf(buf, "%3d %c%c%d", Prog.mcu->pinInfo[i].pin,
+ Prog.mcu->portPrefix, Prog.mcu->pinInfo[i].port,
+ Prog.mcu->pinInfo[i].bit);
+ }
+ gtk_list_store_append (GTK_LIST_STORE(model), &iter);
+ g_value_set_string(&val, buf);
+ gtk_list_store_set_value (GTK_LIST_STORE(model), &iter, 0, &val);
+cant_use_this_io:;
+ }
+
+ gtk_widget_show_all(IoDialog);
+
+ g_signal_connect (PinList, "row_activated", G_CALLBACK (IoDialogRowActivateProc), GINT_TO_POINTER(item));
+ g_signal_connect (IoDialog, "key_press_event", G_CALLBACK (IoDialogKeyPressProc), GINT_TO_POINTER(item));
+ g_signal_connect (CancelButton, "clicked", G_CALLBACK (IoDialogCancelProc), GINT_TO_POINTER(item));
+ g_signal_connect (OkButton, "clicked", G_CALLBACK (IoDialogOkProc), GINT_TO_POINTER(item));
+}
//-----------------------------------------------------------------------------
// Called in response to a notify for the listview. Handles click, text-edit
@@ -767,119 +780,128 @@ void SaveIoListToFile(FILE *f)
// where (LPSTR_TEXTCALLBACK); that way we don't have two parallel copies of
// the I/O list to keep in sync.
//-----------------------------------------------------------------------------
-// void IoListProc(NMHDR *h)
-// {
-// switch(h->code) {
-// case LVN_GETDISPINFO: {
-// NMLVDISPINFO *i = (NMLVDISPINFO *)h;
-// int item = i->item.iItem;
-// switch(i->item.iSubItem) {
-// case LV_IO_PIN:
-// // Don't confuse people by displaying bogus pin assignments
-// // for the C target.
-// if(Prog.mcu && (Prog.mcu->whichIsa == ISA_ANSIC ||
-// Prog.mcu->whichIsa == ISA_INTERPRETED) )
-// {
-// strcpy(i->item.pszText, "");
-// break;
-// }
-
-// PinNumberForIo(i->item.pszText,
-// &(Prog.io.assignment[item]));
-// break;
-
-// case LV_IO_TYPE: {
-// char *s = IoTypeToString(Prog.io.assignment[item].type);
-// strcpy(i->item.pszText, s);
-// break;
-// }
-// case LV_IO_NAME:
-// strcpy(i->item.pszText, Prog.io.assignment[item].name);
-// break;
-
-// case LV_IO_PORT: {
-// // Don't confuse people by displaying bogus pin assignments
-// // for the C target.
-// if(Prog.mcu && Prog.mcu->whichIsa == ISA_ANSIC) {
-// strcpy(i->item.pszText, "");
-// break;
-// }
-
-// int type = Prog.io.assignment[item].type;
-// if(type != IO_TYPE_DIG_INPUT && type != IO_TYPE_DIG_OUTPUT
-// && type != IO_TYPE_READ_ADC)
-// {
-// strcpy(i->item.pszText, "");
-// break;
-// }
-
-// int pin = Prog.io.assignment[item].pin;
-// if(pin == NO_PIN_ASSIGNED || !Prog.mcu) {
-// strcpy(i->item.pszText, "");
-// break;
-// }
-
-// if(UartFunctionUsed() && Prog.mcu) {
-// if((Prog.mcu->uartNeeds.rxPin == pin) ||
-// (Prog.mcu->uartNeeds.txPin == pin))
-// {
-// strcpy(i->item.pszText, _("<UART needs!>"));
-// break;
-// }
-// }
-
-// if(PwmFunctionUsed() && Prog.mcu) {
-// if(Prog.mcu->pwmNeedsPin == pin) {
-// strcpy(i->item.pszText, _("<PWM needs!>"));
-// break;
-// }
-// }
-
-// int j;
-// for(j = 0; j < Prog.mcu->pinCount; j++) {
-// if(Prog.mcu->pinInfo[j].pin == pin) {
-// sprintf(i->item.pszText, "%c%c%d",
-// Prog.mcu->portPrefix,
-// Prog.mcu->pinInfo[j].port,
-// Prog.mcu->pinInfo[j].bit);
-// break;
-// }
-// }
-// if(j == Prog.mcu->pinCount) {
-// sprintf(i->item.pszText, _("<not an I/O!>"));
-// }
-// break;
-// }
-
-// case LV_IO_STATE: {
-// if(InSimulationMode) {
-// char *name = Prog.io.assignment[item].name;
-// DescribeForIoList(name, i->item.pszText);
-// } else {
-// strcpy(i->item.pszText, "");
-// }
-// break;
-// }
-
-// }
-// break;
-// }
-// case LVN_ITEMACTIVATE: {
-// NMITEMACTIVATE *i = (NMITEMACTIVATE *)h;
-// if(InSimulationMode) {
-// char *name = Prog.io.assignment[i->iItem].name;
-// if(name[0] == 'X') {
-// SimulationToggleContact(name);
-// } else if(name[0] == 'A') {
-// ShowAnalogSliderPopup(name);
-// }
-// } else {
-// UndoRemember();
-// ShowIoDialog(i->iItem);
-// ProgramChanged();
-// InvalidateRect(MainWindow, NULL, FALSE);
-// }
-// break;
-// }
-// }
-// }
+void IoListProc(NMHDR *h)
+{
+ switch(h->code) {
+ case LVN_GETDISPINFO: {
+
+ int item = h->item.iItem;
+ /// Don't confuse people by displaying bogus pin assignments
+ /// for the C target.
+
+ char IO_value_holder[60];
+
+ GValue val = G_VALUE_INIT;
+ g_value_init (&val, G_TYPE_STRING);
+
+ /// case LV_IO_PIN:
+ if(Prog.mcu && (Prog.mcu->whichIsa == ISA_ANSIC ||
+ Prog.mcu->whichIsa == ISA_INTERPRETED) )
+ {
+ strcpy(IO_value_holder, "");
+
+ g_value_set_string(&val, (const char*)&IO_value_holder);
+ gtk_list_store_set_value (GTK_LIST_STORE(h->hlistFrom), h->hlistIter, LV_IO_PIN, &val);
+ }
+ else
+ {
+ PinNumberForIo(IO_value_holder, &(Prog.io.assignment[item]));
+ g_value_set_string(&val, (const char*)&IO_value_holder);
+ gtk_list_store_set_value (GTK_LIST_STORE(h->hlistFrom), h->hlistIter, LV_IO_PIN, &val);
+ }
+ /// case LV_IO_TYPE:
+ char *s = IoTypeToString(Prog.io.assignment[item].type);
+
+ g_value_set_string(&val, (const char*)s);
+ gtk_list_store_set_value (GTK_LIST_STORE(h->hlistFrom), h->hlistIter, LV_IO_TYPE, &val);
+
+ /// case LV_IO_NAME:
+ g_value_set_string(&val, (const char*)Prog.io.assignment[item].name);
+ gtk_list_store_set_value (GTK_LIST_STORE(h->hlistFrom), h->hlistIter, LV_IO_NAME, &val);
+
+ /// case LV_IO_PORT:
+ /// Don't confuse people by displaying bogus pin assignments
+ /// for the C target.
+ if(Prog.mcu && Prog.mcu->whichIsa == ISA_ANSIC) {
+ strcpy(IO_value_holder, "");
+ break;
+ }
+
+ int type = Prog.io.assignment[item].type;
+ if(type != IO_TYPE_DIG_INPUT && type != IO_TYPE_DIG_OUTPUT
+ && type != IO_TYPE_READ_ADC)
+ {
+ strcpy(IO_value_holder, "");
+ break;
+ }
+
+ int pin = Prog.io.assignment[item].pin;
+ if(pin == NO_PIN_ASSIGNED || !Prog.mcu) {
+ strcpy(IO_value_holder, "");
+ break;
+ }
+
+ if(UartFunctionUsed() && Prog.mcu) {
+ if((Prog.mcu->uartNeeds.rxPin == pin) ||
+ (Prog.mcu->uartNeeds.txPin == pin))
+ {
+ strcpy(IO_value_holder, _("<UART needs!>"));
+ break;
+ }
+ }
+
+ if(PwmFunctionUsed() && Prog.mcu) {
+ if(Prog.mcu->pwmNeedsPin == pin) {
+ strcpy(IO_value_holder, _("<PWM needs!>"));
+ break;
+ }
+ }
+
+ int j;
+ for(j = 0; j < Prog.mcu->pinCount; j++) {
+ if(Prog.mcu->pinInfo[j].pin == pin) {
+ sprintf(IO_value_holder, "%c%c%d",
+ Prog.mcu->portPrefix,
+ Prog.mcu->pinInfo[j].port,
+ Prog.mcu->pinInfo[j].bit);
+ break;
+ }
+ }
+ if(j == Prog.mcu->pinCount) {
+ sprintf(IO_value_holder, _("<not an I/O!>"));
+ }
+
+ g_value_set_string(&val, (const char*)IO_value_holder);
+ gtk_list_store_set_value (GTK_LIST_STORE(h->hlistFrom), h->hlistIter, LV_IO_PORT, &val);
+
+ /// case LV_IO_STATE:
+ if(InSimulationMode) {
+ char *name = Prog.io.assignment[item].name;
+ DescribeForIoList(name, IO_value_holder);
+ } else {
+ strcpy(IO_value_holder, "");
+ }
+
+ g_value_set_string(&val, (const char*)IO_value_holder);
+ gtk_list_store_set_value (GTK_LIST_STORE(h->hlistFrom), h->hlistIter, LV_IO_STATE, &val);
+
+ break;
+ }
+ case LVN_ITEMACTIVATE: {
+ if(InSimulationMode) {
+ char *name = Prog.io.assignment[h->item.iItem].name;
+ if(name[0] == 'X') {
+ SimulationToggleContact(name);
+ } else if(name[0] == 'A') {
+ ShowAnalogSliderPopup(name);
+ }
+ } else {
+ UndoRemember();
+ ShowIoDialog(h->item.iItem);
+ ProgramChanged();
+ InvalidateRect(MainWindow, NULL, FALSE);
+ }
+ break;
+ }
+ }
+}