PageRenderTime 60ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/src/plugins/mscommon/mscommon_gui_handlers.c

https://gitlab.com/libreems-suite/megatunix
C | 1914 lines | 1404 code | 176 blank | 334 comment | 215 complexity | d3f823c38d9f61fbc7a4b9f08996a257 MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright (C) 2002-2012 by Dave J. Andruczyk <djandruczyk at yahoo dot com>
  3. *
  4. * Linux Megasquirt tuning software
  5. *
  6. *
  7. * This software comes under the GPL (GNU Public License)
  8. * You may freely copy,distribute etc. this as long as the source code
  9. * is made available for FREE.
  10. *
  11. * No warranty is made or implied. You use this program at your own risk.
  12. */
  13. /*!
  14. \file src/plugins/mscommon/mscommon_gui_handlers.c
  15. \ingroup MSCommonPlugin,Plugins
  16. \brief MS Common Gui handling functions
  17. \author David Andruczyk
  18. */
  19. #include <config.h>
  20. #include <combo_loader.h>
  21. #include <datamgmt.h>
  22. #include <defines.h>
  23. #include <enums.h>
  24. #include <firmware.h>
  25. #include <glade/glade.h>
  26. #include <mscommon_comms.h>
  27. #include <mscommon_gui_handlers.h>
  28. #include <mscommon_plugin.h>
  29. #include <req_fuel.h>
  30. #include <serialio.h>
  31. #include <stdlib.h>
  32. #include <user_outputs.h>
  33. extern gconstpointer *global_data;
  34. /*!
  35. \brief handles text entries common to the megasquirt family, and if the
  36. hander isn't found it calls per ecu handlers to deal with those specifics
  37. \param widget is the entry the user interacted with
  38. \param data is unused
  39. \returns TRUE on success, FALSE otherwise
  40. */
  41. G_MODULE_EXPORT gboolean common_entry_handler(GtkWidget *widget, gpointer data)
  42. {
  43. static Firmware_Details *firmware = NULL;
  44. static gboolean (*ecu_handler)(GtkWidget *, gpointer) = NULL;
  45. GdkColor black = {0,0,0,0};
  46. MSCommonStdHandler handler;
  47. gchar *text = NULL;
  48. gchar *tmpbuf = NULL;
  49. gfloat tmpf = -1;
  50. gfloat value = -1;
  51. gint table_num = -1;
  52. gint tmpi = -1;
  53. gint tmp = -1;
  54. gint page = -1;
  55. gint canID = 0;
  56. gint old = -1;
  57. gint offset = -1;
  58. gint dload_val = -1;
  59. gint dl_type = -1;
  60. gint precision = -1;
  61. gint spconfig_offset = -1;
  62. gint oddfire_bit_offset = -1;
  63. gint mtx_temp_units = 0;
  64. gboolean temp_dep = FALSE;
  65. gfloat real_value = 0.0;
  66. DataSize size = MTX_U08;
  67. gint raw_lower = 0;
  68. gint raw_upper = 0;
  69. GdkColor color;
  70. ENTER();
  71. if (!firmware)
  72. firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
  73. g_return_val_if_fail(firmware,FALSE);
  74. handler = (MSCommonStdHandler)(GINT)OBJ_GET(widget,"handler");
  75. dl_type = (GINT) OBJ_GET(widget,"dl_type");
  76. get_essentials(widget,&canID,&page,&offset,&size,&precision);
  77. text = gtk_editable_get_chars(GTK_EDITABLE(widget),0,-1);
  78. tmpi = (GINT)strtol(text,NULL,10);
  79. tmpf = (gfloat)g_ascii_strtod(g_strdelimit(text,",.",'.'),NULL);
  80. g_free(text);
  81. if ((tmpf != (gfloat)tmpi) && (precision == 0))
  82. {
  83. /* Pause signals while we change the value
  84. printf("resetting\n");*/
  85. g_signal_handlers_block_by_func (widget,*(void **)(&std_entry_handler_f), data);
  86. g_signal_handlers_block_by_func (widget,*(void **)(&entry_changed_handler_f), data);
  87. tmpbuf = g_strdup_printf("%i",tmpi);
  88. gtk_entry_set_text(GTK_ENTRY(widget),tmpbuf);
  89. g_free(tmpbuf);
  90. g_signal_handlers_unblock_by_func (widget,*(void **)(&entry_changed_handler_f), data);
  91. g_signal_handlers_unblock_by_func (widget,*(void **)(&std_entry_handler_f), data);
  92. }
  93. switch (handler)
  94. {
  95. case GENERIC:
  96. if (OBJ_GET(widget,"temp_dep"))
  97. value = temp_to_ecu_f(tmpf);
  98. else
  99. value = tmpf;
  100. dload_val = convert_before_download_f(widget,value);
  101. /* What we are doing is doing the forward/reverse
  102. * conversion which will give us an exact value
  103. * if the user inputs something in between, thus
  104. * we can reset the display to a sane value...
  105. */
  106. old = ms_get_ecu_data(canID,page,offset,size);
  107. ms_set_ecu_data(canID,page,offset,size,dload_val);
  108. real_value = convert_after_upload_f(widget);
  109. ms_set_ecu_data(canID,page,offset,size,old);
  110. g_signal_handlers_block_by_func (widget,*(void **)(& std_entry_handler_f), data);
  111. g_signal_handlers_block_by_func (widget,*(void **)(& entry_changed_handler_f), data);
  112. if (OBJ_GET(widget,"temp_dep"))
  113. value = temp_to_host_f(real_value);
  114. else
  115. value = real_value;
  116. tmpbuf = g_strdup_printf("%1$.*2$f",value,precision);
  117. gtk_entry_set_text(GTK_ENTRY(widget),tmpbuf);
  118. g_free(tmpbuf);
  119. g_signal_handlers_unblock_by_func (widget,*(void **)(& entry_changed_handler_f), data);
  120. g_signal_handlers_unblock_by_func (widget,*(void **)(& std_entry_handler_f), data);
  121. break;
  122. default:
  123. /* We need to fall to ECU SPECIFIC entry handler for
  124. anything specific there */
  125. if (!ecu_handler)
  126. {
  127. if (get_symbol_f("ecu_entry_handler",(void **)&ecu_handler))
  128. {
  129. EXIT();
  130. return ecu_handler(widget,data);
  131. }
  132. else
  133. MTXDBG(CRITICAL,_("Default case, but there is NO ecu_entry_handler available, unhandled case for widget %s, BUG!\n"),glade_get_widget_name(widget));
  134. }
  135. else
  136. {
  137. EXIT();
  138. return ecu_handler(widget,data);
  139. }
  140. break;
  141. }
  142. if (dl_type == IMMEDIATE)
  143. {
  144. /* If data has NOT changed, don't bother updating
  145. * and wasting time.
  146. */
  147. if (dload_val != ms_get_ecu_data(canID,page,offset,size))
  148. ms_send_to_ecu(canID, page, offset, size, dload_val, TRUE);
  149. }
  150. gtk_widget_modify_text(widget,GTK_STATE_NORMAL,&black);
  151. OBJ_SET(widget,"not_sent",NULL);
  152. EXIT();
  153. return TRUE;
  154. }
  155. /*!
  156. \brief handles common radio/check buttons, if the handler isn't found it
  157. calls the ECU firmware specific handler to deal with it
  158. \param widget is the button the user interacted with
  159. \param data is unused
  160. */
  161. G_MODULE_EXPORT gboolean common_bitmask_button_handler(GtkWidget *widget, gpointer data)
  162. {
  163. static Firmware_Details *firmware = NULL;
  164. static GHashTable **interdep_vars = NULL;
  165. static GHashTable *sources_hash = NULL;
  166. static gboolean (*ecu_handler)(GtkWidget *, gpointer) = NULL;
  167. gint bitshift = -1;
  168. gint bitval = -1;
  169. gint bitmask = -1;
  170. gint dload_val = -1;
  171. gint canID = 0;
  172. gint page = -1;
  173. gint tmp = 0;
  174. gint tmp32 = 0;
  175. gint offset = -1;
  176. DataSize size = MTX_U08;
  177. gint dl_type = -1;
  178. gint handler = 0;
  179. gint table_num = -1;
  180. gchar * set_labels = NULL;
  181. Deferred_Data *d_data = NULL;
  182. ENTER();
  183. if (!firmware)
  184. firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
  185. g_return_val_if_fail(firmware,FALSE);
  186. if (!(firmware->capabilities & JIMSTIM))
  187. {
  188. if (!interdep_vars)
  189. interdep_vars = (GHashTable **)DATA_GET(global_data,"interdep_vars");
  190. g_return_val_if_fail(interdep_vars,FALSE);
  191. }
  192. if (gtk_toggle_button_get_inconsistent(GTK_TOGGLE_BUTTON(widget)))
  193. gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(widget),FALSE);
  194. get_essential_bits(widget,&canID,&page,&offset,&bitval,&bitmask,&bitshift);
  195. size = (DataSize)(GINT)OBJ_GET(widget,"size");
  196. dl_type = (GINT)OBJ_GET(widget,"dl_type");
  197. handler = (GINT)OBJ_GET(widget,"handler");
  198. /* If it's a check button then it's state is dependant on the button's state*/
  199. if (!GTK_IS_RADIO_BUTTON(widget))
  200. bitval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
  201. switch ((MSCommonStdHandler)handler)
  202. {
  203. case MULTI_EXPRESSION:
  204. /*printf("MULTI_EXPRESSION CHANGE\n");*/
  205. if (!sources_hash)
  206. sources_hash = (GHashTable *)DATA_GET(global_data,"sources_hash");
  207. if ((OBJ_GET(widget,"source_key")) && (OBJ_GET(widget,"source_value")))
  208. {
  209. /* printf("key %s value %s\n",(gchar *)OBJ_GET(widget,"source_key"),(gchar *)OBJ_GET(widget,"source_value"));*/
  210. g_hash_table_replace(sources_hash,(gpointer)g_strdup((gchar *)OBJ_GET(widget,"source_key")),(gpointer)g_strdup((gchar *)OBJ_GET(widget,"source_value")));
  211. g_timeout_add(2000,update_multi_expression_wrapper,NULL);
  212. }
  213. /* FAll Through */
  214. case GENERIC:
  215. tmp = ms_get_ecu_data(canID,page,offset,size);
  216. tmp = tmp & ~bitmask; /*clears bits */
  217. tmp = tmp | (bitval << bitshift);
  218. dload_val = tmp;
  219. if (dload_val == ms_get_ecu_data(canID,page,offset,size))
  220. {
  221. EXIT();
  222. return FALSE;
  223. }
  224. break;
  225. case ALT_SIMUL:
  226. /* Alternate or simultaneous */
  227. if (firmware->capabilities & MS1_E)
  228. {
  229. table_num = (GINT)strtol((gchar *)OBJ_GET(widget,"table_num"),NULL,10);
  230. tmp = ms_get_ecu_data(canID,page,offset,size);
  231. tmp = tmp & ~bitmask;/* clears bits */
  232. tmp = tmp | (bitval << bitshift);
  233. dload_val = tmp;
  234. /*printf("ALT_SIMUL, MSnS-E, table num %i, dload_val %i, curr ecu val %i\n",table_num,dload_val, ms_get_ecu_data(canID,page,offset,size));*/
  235. if (dload_val == ms_get_ecu_data(canID,page,offset,size))
  236. {
  237. EXIT();
  238. return FALSE;
  239. }
  240. firmware->rf_params[table_num]->last_alternate = firmware->rf_params[table_num]->alternate;
  241. firmware->rf_params[table_num]->alternate = bitval;
  242. /*printf("last alt %i, cur alt %i\n",firmware->rf_params[table_num]->last_alternate,firmware->rf_params[table_num]->alternate);*/
  243. d_data = g_new0(Deferred_Data, 1);
  244. d_data->canID = canID;
  245. d_data->page = page;
  246. d_data->offset = offset;
  247. d_data->value = dload_val;
  248. d_data->size = MTX_U08;
  249. g_hash_table_replace(interdep_vars[table_num],
  250. GINT_TO_POINTER(offset),
  251. d_data);
  252. check_req_fuel_limits(table_num);
  253. }
  254. else
  255. {
  256. table_num = (GINT)strtol((gchar *)OBJ_GET(widget,"table_num"),NULL,10);
  257. dload_val = bitval;
  258. if (dload_val == ms_get_ecu_data(canID,page,offset,size))
  259. {
  260. EXIT();
  261. return FALSE;
  262. }
  263. firmware->rf_params[table_num]->last_alternate = firmware->rf_params[table_num]->alternate;
  264. firmware->rf_params[table_num]->alternate = bitval;
  265. d_data = g_new0(Deferred_Data, 1);
  266. d_data->canID = canID;
  267. d_data->page = page;
  268. d_data->offset = offset;
  269. d_data->value = dload_val;
  270. d_data->size = MTX_U08;
  271. g_hash_table_replace(interdep_vars[table_num],
  272. GINT_TO_POINTER(offset),
  273. d_data);
  274. check_req_fuel_limits(table_num);
  275. }
  276. break;
  277. default:
  278. if (!ecu_handler)
  279. {
  280. if (get_symbol_f("ecu_bitmask_button_handler",(void **)&ecu_handler))
  281. {
  282. EXIT();
  283. return ecu_handler(widget,data);
  284. }
  285. else
  286. MTXDBG(CRITICAL,_("Default case, but there is NO ecu_bitmask_button_handler available, unhandled case for widget %s, BUG!\n"),glade_get_widget_name(widget));
  287. }
  288. else
  289. {
  290. EXIT();
  291. return ecu_handler(widget,data);
  292. }
  293. MTXDBG(CRITICAL,_("Bitmask button at page: %i, offset %i, NOT handled\n\tERROR!!, contact author\n"),page,offset);
  294. EXIT();
  295. return FALSE;
  296. break;
  297. }
  298. /* Sets the label of another control based on this widget's state... */
  299. set_labels = (gchar *)OBJ_GET(widget,"set_widgets_label");
  300. if ((set_labels) && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
  301. set_widget_labels_f(set_labels);
  302. /* Swaps the label of another control based on widget state... */
  303. if (OBJ_GET(widget,"swap_labels"))
  304. swap_labels_f(widget,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
  305. /* MUST use dispatcher, as the update functions run outside of the
  306. * normal GTK+ context, so if we were to call it direct we'd get a
  307. * deadlock due to gtk_threads_enter/leave() calls, so we use the
  308. * dispatch queue to let it run in the correct "state"....
  309. */
  310. if (OBJ_GET(widget,"table_2_update"))
  311. g_timeout_add(2000,force_update_table_wrapper,OBJ_GET(widget,"table_2_update"));
  312. if (OBJ_GET(widget,"algorithm"))
  313. handle_algorithm(widget);
  314. /* Update controls that are dependant on a controls state...
  315. * In this case, MAP sensor related ctrls */
  316. if (OBJ_GET(widget,"group_2_update"))
  317. {
  318. g_timeout_add(2000,force_view_recompute_wrapper,NULL);
  319. g_timeout_add(2000,trigger_group_update_wrapper,OBJ_GET(widget,"group_2_update"));
  320. }
  321. if (dl_type == IMMEDIATE)
  322. {
  323. dload_val = convert_before_download_f(widget,dload_val);
  324. ms_send_to_ecu(canID, page, offset, size, dload_val, TRUE);
  325. }
  326. EXIT();
  327. return TRUE;
  328. }
  329. /*!
  330. \brief handles common toggle buttons and calls an ECU specific handler if the
  331. case statemnt here doesn't catch it
  332. \param widget is the toggle button the user flipped
  333. \param data is unused
  334. \returns TRUE on success, FALSE otherwise
  335. */
  336. G_MODULE_EXPORT gboolean common_toggle_button_handler(GtkWidget *widget, gpointer data)
  337. {
  338. static gboolean (*ecu_handler)(GtkWidget *widget, gpointer) = NULL;
  339. gint handler = -1;
  340. ENTER();
  341. handler = (GINT)OBJ_GET(widget,"handler");
  342. switch (handler)
  343. {
  344. default:
  345. if (!ecu_handler)
  346. {
  347. if (get_symbol_f("ecu_toggle_button_handler",(void **)&ecu_handler))
  348. {
  349. EXIT();
  350. return ecu_handler(widget,data);
  351. }
  352. else
  353. {
  354. MTXDBG(CRITICAL,_("Default case, ecu handler NOT found in plugins, BUG!\n"));
  355. EXIT();
  356. return TRUE;
  357. }
  358. }
  359. else
  360. {
  361. EXIT();
  362. return ecu_handler(widget,data);
  363. }
  364. break;
  365. }
  366. }
  367. /*!
  368. \brief handles common sliders/ranges and calls an ECU specific handler if the
  369. case statemnt here doesn't catch it
  370. \param widget is the toggle button the user flipped
  371. \param data is unused
  372. \returns TRUE on success, FALSE otherwise
  373. */
  374. G_MODULE_EXPORT gboolean common_slider_handler(GtkWidget *widget, gpointer data)
  375. {
  376. gint page = 0;
  377. gint offset = 0;
  378. DataSize size = MTX_U08;
  379. gint canID = 0;
  380. gint dl_type = -1;
  381. gfloat value = 0.0;
  382. gint dload_val = 0;
  383. ENTER();
  384. dl_type = (GINT) OBJ_GET(widget,"dl_type");
  385. get_essentials(widget,&canID,&page,&offset,&size,NULL);
  386. value = gtk_range_get_value(GTK_RANGE(widget));
  387. dload_val = convert_before_download_f(widget,value);
  388. if (dl_type == IMMEDIATE)
  389. {
  390. /* If data has NOT changed, don't bother updating
  391. * and wasting time.
  392. */
  393. if (dload_val != ms_get_ecu_data(canID,page,offset,size))
  394. ms_send_to_ecu(canID, page, offset, size, dload_val, TRUE);
  395. }
  396. EXIT();
  397. return FALSE; /* Let other handlers run! */
  398. }
  399. /*!
  400. \brief handles common buttons and calls an ECU specific handler if the
  401. case statemnt here doesn't catch it
  402. \param widget is the toggle button the user flipped
  403. \param data is unused
  404. \returns TRUE on success, FALSE otherwise
  405. */
  406. G_MODULE_EXPORT gboolean common_std_button_handler(GtkWidget *widget, gpointer data)
  407. {
  408. static gboolean (*ecu_handler)(GtkWidget *widget, gpointer) = NULL;
  409. gint handler = -1;
  410. gint tmpi = 0;
  411. gint tmp2 = 0;
  412. gint page = 0;
  413. gint offset = 0;
  414. gint canID = 0;
  415. gint raw_lower = 0;
  416. gint raw_upper = 0;
  417. DataSize size = MTX_U08;
  418. gfloat tmpf = 0.0;
  419. gchar * tmpbuf = NULL;
  420. gchar * dest = NULL;
  421. ENTER();
  422. handler = (MSCommonStdHandler)(GINT)OBJ_GET(widget,"handler");
  423. switch ((MSCommonStdHandler)handler)
  424. {
  425. case INCREMENT_VALUE:
  426. case DECREMENT_VALUE:
  427. dest = (gchar *)OBJ_GET(widget,"partner_widget");
  428. tmp2 = (GINT)OBJ_GET(widget,"amount");
  429. if (OBJ_GET(dest,"raw_lower"))
  430. raw_lower = (GINT)strtol((gchar *)OBJ_GET(dest,"raw_lower"),NULL,10);
  431. else
  432. raw_lower = get_extreme_from_size_f(size,LOWER);
  433. if (OBJ_GET(dest,"raw_upper"))
  434. raw_upper = (GINT)strtol((gchar *)OBJ_GET(dest,"raw_upper"),NULL,10);
  435. else
  436. raw_upper = get_extreme_from_size_f(size,UPPER);
  437. canID = (GINT)OBJ_GET(dest,"canID");
  438. page = (GINT)OBJ_GET(dest,"page");
  439. size = (DataSize)(GINT)OBJ_GET(dest,"size");
  440. offset = (GINT)OBJ_GET(dest,"offset");
  441. tmpi = ms_get_ecu_data(canID,page,offset,size);
  442. if (handler == INCREMENT_VALUE)
  443. tmpi = tmpi+tmp2 > raw_upper? raw_upper:tmpi+tmp2;
  444. else
  445. tmpi = tmpi-tmp2 < raw_lower? raw_lower:tmpi-tmp2;
  446. ms_send_to_ecu(canID, page, offset, size, tmpi, TRUE);
  447. break;
  448. case REQFUEL_RESCALE_TABLE:
  449. reqfuel_rescale_table(widget);
  450. break;
  451. case REQ_FUEL_POPUP:
  452. reqd_fuel_popup(widget);
  453. reqd_fuel_change(widget);
  454. break;
  455. default:
  456. if (!ecu_handler)
  457. {
  458. if (get_symbol_f("ecu_std_button_handler",(void **)&ecu_handler))
  459. {
  460. EXIT();
  461. return ecu_handler(widget,data);
  462. }
  463. else
  464. {
  465. MTXDBG(CRITICAL,_("Default case, ecu handler NOT found in plugins, BUG!\n"));
  466. EXIT();
  467. return TRUE;
  468. }
  469. }
  470. else
  471. {
  472. EXIT();
  473. return ecu_handler(widget,data);
  474. }
  475. break;
  476. }
  477. EXIT();
  478. return TRUE;
  479. }
  480. /*!
  481. \brief handles common combo buttons and calls an ECU specific handler if the
  482. case statemnt here doesn't catch it
  483. \param widget is the toggle button the user flipped
  484. \param data is unused
  485. \returns TRUE on success, FALSE otherwise
  486. */
  487. G_MODULE_EXPORT gboolean common_combo_handler(GtkWidget *widget, gpointer data)
  488. {
  489. static Firmware_Details *firmware = NULL;
  490. static GHashTable **interdep_vars = NULL;
  491. static GHashTable *sources_hash = NULL;
  492. static gboolean (*ecu_handler)(GtkWidget *, gpointer) = NULL;
  493. GtkTreeIter iter;
  494. GtkTreeModel *model = NULL;
  495. gboolean state = FALSE;
  496. MSCommonStdHandler handler;
  497. gint total = 0;
  498. gchar * set_labels = NULL;
  499. gchar * tmpbuf = NULL;
  500. gchar * lower = NULL;
  501. gchar * upper = NULL;
  502. gint precision = 0;
  503. gchar ** vector = NULL;
  504. guint i = 0;
  505. gint tmpi = 0;
  506. gint canID = 0;
  507. gint page = 0;
  508. gint offset = 0;
  509. gint bitval = 0;
  510. gint bitmask = 0;
  511. gint bitshift = 0;
  512. gint table_num = 0;
  513. gchar * range = NULL;
  514. DataSize size = MTX_U08;
  515. guint8 tmp = 0;
  516. gint dload_val = 0;
  517. gint dl_type = 0;
  518. gfloat tmpf = 0.0;
  519. gfloat tmpf2 = 0.0;
  520. Deferred_Data *d_data = NULL;
  521. GtkWidget *tmpwidget = NULL;
  522. void *eval = NULL;
  523. ENTER();
  524. if (!firmware)
  525. firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
  526. g_return_val_if_fail(firmware,FALSE);
  527. if (!(firmware->capabilities & JIMSTIM))
  528. {
  529. if (!interdep_vars)
  530. interdep_vars = (GHashTable **)DATA_GET(global_data,"interdep_vars");
  531. g_return_val_if_fail(interdep_vars,FALSE);
  532. }
  533. get_essential_bits(widget, &canID, &page, &offset, &bitval, &bitmask, &bitshift);
  534. dl_type = (GINT) OBJ_GET(widget,"dl_type");
  535. handler = (MSCommonStdHandler)(GINT) OBJ_GET(widget,"handler");
  536. size = (DataSize)(GINT)OBJ_GET(widget,"size");
  537. set_labels = (gchar *)OBJ_GET(widget,"set_widgets_label");
  538. state = gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget),&iter);
  539. model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
  540. if (!state)
  541. {
  542. /* Not selected by combo popdown button, thus is being edited.
  543. * Do a model scan to see if we actually hit the jackpot or
  544. * not, and get the iter for it...
  545. */
  546. if (!search_model(model,widget,&iter))
  547. {
  548. EXIT();
  549. return FALSE;
  550. }
  551. }
  552. gtk_tree_model_get(model,&iter,BITVAL_COL,&bitval,-1);
  553. switch ((MSCommonStdHandler)handler)
  554. {
  555. case MULTI_EXPRESSION:
  556. if (!sources_hash)
  557. sources_hash = (GHashTable *)DATA_GET(global_data,"sources_hash");
  558. /*printf("combo MULTI EXPRESSION\n");*/
  559. if ((OBJ_GET(widget,"source_key")) && (OBJ_GET(widget,"source_values")))
  560. {
  561. tmpbuf = (gchar *)OBJ_GET(widget,"source_values");
  562. vector = g_strsplit(tmpbuf,",",-1);
  563. if ((guint)gtk_combo_box_get_active(GTK_COMBO_BOX(widget)) >= g_strv_length(vector))
  564. {
  565. printf("combo size doesn't match source_values for multi_expression\n");
  566. EXIT();
  567. return FALSE;
  568. }
  569. /*printf("key %s value %s\n",(gchar *)OBJ_GET(widget,"source_key"),vector[gtk_combo_box_get_active(GTK_COMBO_BOX(widget))]);*/
  570. g_hash_table_replace(sources_hash,g_strdup((gchar *)OBJ_GET(widget,"source_key")),g_strdup(vector[gtk_combo_box_get_active(GTK_COMBO_BOX(widget))]));
  571. g_timeout_add(2000,update_multi_expression_wrapper,NULL);
  572. }
  573. /* Fall through to generic */
  574. case GENERIC:
  575. tmp = ms_get_ecu_data(canID,page,offset,size);
  576. tmp = tmp & ~bitmask; /*clears bits */
  577. tmp = tmp | (bitval << bitshift);
  578. dload_val = tmp;
  579. if (dload_val == ms_get_ecu_data(canID,page,offset,size))
  580. {
  581. EXIT();
  582. return FALSE;
  583. }
  584. break;
  585. case ALT_SIMUL:
  586. /* Alternate or simultaneous */
  587. if (firmware->capabilities & MS1_E)
  588. {
  589. if (!OBJ_GET(widget,"table_num"))
  590. {
  591. printf(" common_combo_handler, ALT_SIMUL case, table_num is undefined, BUG!, widget %s\n",glade_get_widget_name(widget));
  592. break;
  593. }
  594. table_num = (GINT)strtol((gchar *)OBJ_GET(widget,"table_num"),NULL,10);
  595. tmp = ms_get_ecu_data(canID,page,offset,size);
  596. tmp = tmp & ~bitmask;/* clears bits */
  597. tmp = tmp | (bitval << bitshift);
  598. dload_val = tmp;
  599. /*printf("ALT_SIMUL, MSnS-E, table num %i, dload_val %i, curr ecu val %i\n",table_num,dload_val, ms_get_ecu_data(canID,page,offset,size));*/
  600. if (dload_val == ms_get_ecu_data(canID,page,offset,size))
  601. {
  602. EXIT();
  603. return FALSE;
  604. }
  605. firmware->rf_params[table_num]->last_alternate = firmware->rf_params[table_num]->alternate;
  606. firmware->rf_params[table_num]->alternate = bitval;
  607. /*printf("last alt %i, cur alt %i\n",firmware->rf_params[table_num]->last_alternate,firmware->rf_params[table_num]->alternate);*/
  608. d_data = g_new0(Deferred_Data, 1);
  609. d_data->canID = canID;
  610. d_data->page = page;
  611. d_data->offset = offset;
  612. d_data->value = dload_val;
  613. d_data->size = MTX_U08;
  614. g_hash_table_replace(interdep_vars[table_num],
  615. GINT_TO_POINTER(offset),
  616. d_data);
  617. check_req_fuel_limits(table_num);
  618. }
  619. else
  620. {
  621. table_num = (GINT)strtol((gchar *)OBJ_GET(widget,"table_num"),NULL,10);
  622. dload_val = bitval;
  623. if (dload_val == ms_get_ecu_data(canID,page,offset,size))
  624. {
  625. EXIT();
  626. return FALSE;
  627. }
  628. firmware->rf_params[table_num]->last_alternate = firmware->rf_params[table_num]->alternate;
  629. firmware->rf_params[table_num]->alternate = bitval;
  630. d_data = g_new0(Deferred_Data, 1);
  631. d_data->canID = canID;
  632. d_data->page = page;
  633. d_data->offset = offset;
  634. d_data->value = dload_val;
  635. d_data->size = MTX_U08;
  636. g_hash_table_replace(interdep_vars[table_num],
  637. GINT_TO_POINTER(offset),
  638. d_data);
  639. check_req_fuel_limits(table_num);
  640. }
  641. break;
  642. default:
  643. if (!ecu_handler)
  644. {
  645. if (get_symbol_f("ecu_combo_handler",(void **)&ecu_handler))
  646. {
  647. EXIT();
  648. return ecu_handler(widget,data);
  649. }
  650. else
  651. {
  652. MTXDBG(CRITICAL,_("Default case, ecu handler NOT found in plugins, BUG!\n"));
  653. EXIT();
  654. return TRUE;
  655. }
  656. }
  657. else
  658. {
  659. EXIT();
  660. return ecu_handler(widget,data);
  661. }
  662. break;
  663. }
  664. if (OBJ_GET(widget,"algorithms"))
  665. combo_handle_algorithms(widget);
  666. if (OBJ_GET(widget,"swap_labels"))
  667. swap_labels_f(widget,bitval);
  668. if (OBJ_GET(widget,"table_2_update"))
  669. g_timeout_add(2000,force_update_table_wrapper,OBJ_GET(widget,"table_2_update"));
  670. if (set_labels)
  671. {
  672. total = get_choice_count_f(model);
  673. tmpi = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
  674. vector = g_strsplit(set_labels,",",-1);
  675. if ((g_strv_length(vector)%(total+1)) != 0)
  676. {
  677. MTXDBG(CRITICAL,_("Problem with set_widget_labels, counts don't match up\n"));
  678. goto combo_download;
  679. }
  680. for (guint i=0;i<(g_strv_length(vector)/(total+1));i++)
  681. {
  682. tmpbuf = g_strconcat(vector[i*(total+1)],",",vector[(i*(total+1))+1+tmpi],NULL);
  683. set_widget_labels_f(tmpbuf);
  684. g_free(tmpbuf);
  685. }
  686. g_strfreev(vector);
  687. }
  688. combo_download:
  689. if (dl_type == IMMEDIATE)
  690. {
  691. dload_val = convert_before_download_f(widget,dload_val);
  692. ms_send_to_ecu(canID, page, offset, size, dload_val, TRUE);
  693. }
  694. EXIT();
  695. return TRUE;
  696. }
  697. /*
  698. * \brief wrapper for force_update_table()
  699. */
  700. G_MODULE_EXPORT gboolean force_update_table_wrapper(gpointer data)
  701. {
  702. ENTER();
  703. g_idle_add(force_update_table,data);
  704. EXIT();
  705. return FALSE;
  706. }
  707. /*!
  708. \brief force_update_table() updates a subset of widgets (specifically ONLY
  709. the Z axis widgets) of a table on screen.
  710. \param data is the string representation of the table number
  711. */
  712. G_MODULE_EXPORT gboolean force_update_table(gpointer data)
  713. {
  714. gint offset = -1;
  715. gint page = -1;
  716. gint table_num = -1;
  717. gint base = 0;
  718. gint length = 0;
  719. Firmware_Details *firmware = NULL;
  720. GList ***ecu_widgets = NULL;
  721. ENTER();
  722. ecu_widgets = (GList ***)DATA_GET(global_data,"ecu_widgets");
  723. firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
  724. if (DATA_GET(global_data,"leaving"))
  725. {
  726. EXIT();
  727. return FALSE;
  728. }
  729. if (page > firmware->total_pages)
  730. {
  731. EXIT();
  732. return FALSE;
  733. }
  734. table_num = (GINT)strtol((gchar *)data,NULL,10);
  735. if ((table_num < 0) || (table_num > (firmware->total_tables-1)))
  736. {
  737. EXIT();
  738. return FALSE;
  739. }
  740. base = firmware->table_params[table_num]->z_base;
  741. length = firmware->table_params[table_num]->x_bincount *
  742. firmware->table_params[table_num]->y_bincount;
  743. page = firmware->table_params[table_num]->z_page;
  744. for (offset=base;offset<base+length;offset++)
  745. {
  746. if ((DATA_GET(global_data,"leaving")) || (!firmware))
  747. {
  748. EXIT();
  749. return FALSE;
  750. }
  751. if (ecu_widgets[page][offset] != NULL)
  752. g_list_foreach(ecu_widgets[page][offset],update_widget,NULL);
  753. }
  754. DATA_SET(global_data,"forced_update",GINT_TO_POINTER(TRUE));
  755. EXIT();
  756. return FALSE;
  757. }
  758. /*!
  759. * \brief wrapper for trigger_group_update,data()
  760. */
  761. G_MODULE_EXPORT gboolean trigger_group_update_wrapper(gpointer data)
  762. {
  763. ENTER();
  764. g_idle_add(trigger_group_update,data);
  765. EXIT();
  766. return FALSE;
  767. }
  768. /*!
  769. \brief trigger_group_update() updates a subset of widgets (any widgets in
  770. the group name passed. This runs as a timeout delayed asynchronously from
  771. when the ctrl is modified, to prevent a deadlock.
  772. \param data is the string name of list of controls
  773. \returns FALSE to cancel the timeout
  774. */
  775. G_MODULE_EXPORT gboolean trigger_group_update(gpointer data)
  776. {
  777. ENTER();
  778. if (DATA_GET(global_data,"leaving"))
  779. {
  780. EXIT();
  781. return FALSE;
  782. }
  783. g_list_foreach(get_list_f((gchar *)data),update_widget,NULL);
  784. EXIT();
  785. return FALSE;/* Make it cancel and not run again till called */
  786. }
  787. /*!
  788. \brief wrapper for update_multi_expression
  789. \returns FALSE to cancel the timeout
  790. */
  791. G_MODULE_EXPORT gboolean update_multi_expression_wrapper(gpointer data)
  792. {
  793. ENTER();
  794. g_idle_add(update_multi_expression,data);
  795. EXIT();
  796. return FALSE;
  797. }
  798. /*!
  799. \brief updates anywidgets in the "multi_expression" group
  800. \returns FALSE to cancel the timeout
  801. */
  802. G_MODULE_EXPORT gboolean update_multi_expression(gpointer data)
  803. {
  804. ENTER();
  805. g_list_foreach(get_list_f("multi_expression"),update_widget,NULL);
  806. EXIT();
  807. return FALSE;
  808. }
  809. /*!
  810. \brief update_ecu_controls_pf() is called after a read of the block of
  811. data from the ECU. It takes care of updating evey control that relates to
  812. an ECU variable on screen
  813. */
  814. G_MODULE_EXPORT void update_ecu_controls_pf(void)
  815. {
  816. gint canID = 0;
  817. gint page = 0;
  818. gint offset = 0;
  819. DataSize size = MTX_U08;
  820. gfloat tmpf = 0.0;
  821. gint reqfuel = 0;
  822. gint i = 0;
  823. guint mask = 0;
  824. guint shift = 0;
  825. guint tmpi = 0;
  826. guint8 addon = 0;
  827. gint mult = 0;
  828. Firmware_Details *firmware = NULL;
  829. GList ***ecu_widgets = NULL;
  830. ENTER();
  831. ecu_widgets = (GList ***)DATA_GET(global_data,"ecu_widgets");
  832. firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
  833. g_return_if_fail(firmware);
  834. canID = firmware->canID;
  835. if (DATA_GET(global_data,"leaving"))
  836. {
  837. EXIT();
  838. return;
  839. }
  840. set_title_f(g_strdup(_("Updating Controls...")));
  841. DATA_SET(global_data,"paused_handlers",GINT_TO_POINTER(TRUE));
  842. /* DualTable Fuel Calculations
  843. * DT code no longer uses the "alternate" firing mode as each table
  844. * is pretty much independant from the other, so the calcs are a
  845. * little simpler...
  846. *
  847. * / num_inj_1 \
  848. * req_fuel_per_squirt * (-------------------------)
  849. * \ divider /
  850. * req_fuel_total = --------------------------------------------------
  851. * 10
  852. *
  853. * where divider = num_cyls/num_squirts;
  854. *
  855. *
  856. * B&G, MSnS, MSnEDIS req Fuel calc *
  857. * req-fuel
  858. * / num_inj \
  859. * req_fuel_per_squirt * (-------------------------)
  860. * \ divider*(alternate+1) /
  861. * req_fuel_total = ------------------------------------------
  862. * 10
  863. *
  864. * where divider = num_cyls/num_squirts;
  865. *
  866. * The req_fuel_per_squirt is the part stored in the MS ECU as
  867. * the req_fuel variable. Take note when doing conversions.
  868. * On screen the value is divided by ten from what is
  869. * in the MS.
  870. *
  871. */
  872. /* All Tables */
  873. if (firmware->capabilities & MS2)
  874. {
  875. addon = 0;
  876. mult = 100;
  877. }
  878. else
  879. {
  880. addon = 1;
  881. mult = 1;
  882. }
  883. for (i=0;i<firmware->total_tables;i++)
  884. {
  885. recalc_table_limits_f(0,i);
  886. if (firmware->table_params[i]->reqfuel_offset < 0)
  887. continue;
  888. tmpi = ms_get_ecu_data(canID,firmware->table_params[i]->num_cyl_page,firmware->table_params[i]->num_cyl_offset,size);
  889. mask = firmware->table_params[i]->num_cyl_mask;
  890. shift = get_bitshift_f(firmware->table_params[i]->num_cyl_mask);
  891. firmware->rf_params[i]->num_cyls = ((tmpi & mask) >> shift)+addon;
  892. firmware->rf_params[i]->last_num_cyls = ((tmpi & mask) >> shift)+addon;
  893. /*printf("num_cyls for table %i in the firmware is %i\n",i,firmware->rf_params[i]->num_cyls);*/
  894. tmpi = ms_get_ecu_data(canID,firmware->table_params[i]->num_inj_page,firmware->table_params[i]->num_inj_offset,size);
  895. mask = firmware->table_params[i]->num_cyl_mask;
  896. shift = get_bitshift_f(firmware->table_params[i]->num_cyl_mask);
  897. firmware->rf_params[i]->num_inj = ((tmpi & mask) >> shift)+addon;
  898. firmware->rf_params[i]->last_num_inj = ((tmpi & mask) >> shift)+addon;
  899. /*printf("num_inj for table %i in the firmware is %i\n",i,firmware->rf_params[i]->num_inj);*/
  900. firmware->rf_params[i]->divider = ms_get_ecu_data(canID,firmware->table_params[i]->divider_page,firmware->table_params[i]->divider_offset,size);
  901. if (firmware->rf_params[i]->divider == 0)
  902. firmware->rf_params[i]->divider = 1;
  903. firmware->rf_params[i]->last_divider = firmware->rf_params[i]->divider;
  904. if (!(firmware->capabilities & MS1_DT))
  905. {
  906. firmware->rf_params[i]->alternate = ms_get_ecu_data(canID,firmware->table_params[i]->alternate_page,firmware->table_params[i]->alternate_offset,size);
  907. firmware->rf_params[i]->last_alternate = firmware->rf_params[i]->alternate;
  908. /*printf("alternate for table %i in the firmware is %i\n",i,firmware->rf_params[i]->alternate);*/
  909. }
  910. reqfuel = ms_get_ecu_data(canID,firmware->table_params[i]->reqfuel_page,firmware->table_params[i]->reqfuel_offset,firmware->table_params[i]->reqfuel_size);
  911. /*
  912. printf("reqfuel for table %i in the firmware is %i\n",i,reqfuel);
  913. printf("reqfuel_page %i, reqfuel_offset %i\n",firmware->table_params[i]->reqfuel_page,firmware->table_params[i]->reqfuel_offset);
  914. printf("num_inj %i, divider %i\n",firmware->rf_params[i]->num_inj,firmware->rf_params[i]->divider);
  915. printf("num_cyls %i, alternate %i\n",firmware->rf_params[i]->num_cyls,firmware->rf_params[i]->alternate);
  916. printf("req_fuel_per_1_squirt is %i\n",reqfuel);
  917. */
  918. /* Calcs vary based on firmware.
  919. * DT uses num_inj/divider
  920. * MSnS-E uses the SAME in DT mode only
  921. * MSnS-E uses B&G form in single table mode
  922. */
  923. if (firmware->capabilities & MS1_DT)
  924. {
  925. /*
  926. * printf("DT\n");
  927. */
  928. tmpf = (float)(firmware->rf_params[i]->num_inj)/(float)(firmware->rf_params[i]->divider);
  929. }
  930. else if (firmware->capabilities & MS1_E)
  931. {
  932. shift = get_bitshift_f(firmware->table_params[i]->dtmode_mask);
  933. if ((ms_get_ecu_data(canID,firmware->table_params[i]->dtmode_page,firmware->table_params[i]->dtmode_offset,size) & firmware->table_params[i]->dtmode_mask) >> shift)
  934. {
  935. /*
  936. * printf("MSnS-E DT\n");
  937. */
  938. tmpf = (float)(firmware->rf_params[i]->num_inj)/(float)(firmware->rf_params[i]->divider);
  939. }
  940. else
  941. {
  942. /*
  943. * printf("MSnS-E non-DT\n");
  944. */
  945. tmpf = (float)(firmware->rf_params[i]->num_inj)/((float)(firmware->rf_params[i]->divider)*((float)(firmware->rf_params[i]->alternate)+1.0));
  946. }
  947. }
  948. else
  949. {
  950. /*
  951. * printf("B&G\n");
  952. */
  953. tmpf = (float)(firmware->rf_params[i]->num_inj)/((float)(firmware->rf_params[i]->divider)*((float)(firmware->rf_params[i]->alternate)+1.0));
  954. }
  955. /* ReqFuel Total */
  956. /*
  957. * printf("intermediate tmpf is %f\n",tmpf);
  958. */
  959. tmpf *= (float)reqfuel;
  960. tmpf /= (10.0*mult);
  961. firmware->rf_params[i]->req_fuel_total = tmpf;
  962. firmware->rf_params[i]->last_req_fuel_total = tmpf;
  963. /*printf("req_fuel_total for table number %i is %f\n",i,tmpf);*/
  964. /* Injections per cycle */
  965. firmware->rf_params[i]->num_squirts = (float)(firmware->rf_params[i]->num_cyls)/(float)(firmware->rf_params[i]->divider);
  966. /*printf("num_squirts for table number %i is %i\n",i,firmware->rf_params[i]->num_squirts);*/
  967. if (firmware->rf_params[i]->num_squirts < 1 )
  968. firmware->rf_params[i]->num_squirts = 1;
  969. firmware->rf_params[i]->last_num_squirts = firmware->rf_params[i]->num_squirts;
  970. set_reqfuel_color_f(BLACK,i);
  971. }
  972. DATA_SET(global_data,"paused_handlers",GINT_TO_POINTER(FALSE));
  973. thread_update_widget_f("info_label",MTX_LABEL,g_strdup_printf(_("<b>Ready...</b>")));
  974. update_current_notebook_page_f();
  975. set_title_f(g_strdup(_("Ready...")));
  976. EXIT();
  977. return;
  978. }
  979. /*!
  980. \brief handles spinbuttons common to the megasquirt family, and if the
  981. hander isn't found it calls per ecu handlers to deal with those specifics
  982. \param widget is the entry the user interacted with
  983. \param data is unused
  984. \returns TRUE on success, FALSE otherwise
  985. */
  986. G_MODULE_EXPORT gboolean common_spin_button_handler(GtkWidget *widget, gpointer data)
  987. {
  988. /* Gets the value from the spinbutton then modifues the
  989. * necessary deta in the the app and calls any handlers
  990. * if necessary. works well, one generic function with a
  991. * select/case branch to handle the choices..
  992. */
  993. static Firmware_Details *firmware = NULL;
  994. static GHashTable **interdep_vars = NULL;
  995. static gboolean (*ecu_handler)(GtkWidget *, gpointer) = NULL;
  996. gint dl_type = -1;
  997. gint offset = -1;
  998. gint dload_val = -1;
  999. gint canID = 0;
  1000. gint page = -1;
  1001. DataSize size = MTX_U08;
  1002. gint bitmask = -1;
  1003. gint bitshift = -1;
  1004. gint spconfig_offset = 0;
  1005. gint oddfire_bit_offset = 0;
  1006. gint tmpi = 0;
  1007. gint tmp = 0;
  1008. gint handler = -1;
  1009. gint divider_offset = 0;
  1010. gint table_num = -1;
  1011. gint mtx_temp_units = 0;
  1012. gint source = 0;
  1013. gboolean temp_dep = FALSE;
  1014. gfloat value = 0.0;
  1015. GtkWidget * tmpwidget = NULL;
  1016. Deferred_Data *d_data = NULL;
  1017. GdkColor black = {0,0,0,0};
  1018. ENTER();
  1019. if (!firmware)
  1020. firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
  1021. g_return_val_if_fail(firmware,FALSE);
  1022. if (!(firmware->capabilities & JIMSTIM))
  1023. {
  1024. if (!interdep_vars)
  1025. interdep_vars = (GHashTable **)DATA_GET(global_data,"interdep_vars");
  1026. g_return_val_if_fail(interdep_vars,FALSE);
  1027. }
  1028. handler = (MSCommonStdHandler)(GINT)OBJ_GET(widget,"handler");
  1029. dl_type = (GINT) OBJ_GET(widget,"dl_type");
  1030. size = (DataSize)(GINT) OBJ_GET(widget,"size");
  1031. get_essential_bits(widget,&canID,&page,&offset,NULL,&bitmask,&bitshift);
  1032. value = (float)gtk_spin_button_get_value((GtkSpinButton *)widget);
  1033. tmpi = (int)(value+.001);
  1034. switch ((MSCommonStdHandler)handler)
  1035. {
  1036. case REQ_FUEL_1:
  1037. case REQ_FUEL_2:
  1038. table_num = (GINT)strtol((gchar *)OBJ_GET(widget,"table_num"),NULL,10);
  1039. firmware->rf_params[table_num]->last_req_fuel_total = firmware->rf_params[table_num]->req_fuel_total;
  1040. firmware->rf_params[table_num]->req_fuel_total = value;
  1041. check_req_fuel_limits(table_num);
  1042. break;
  1043. case LOCKED_REQ_FUEL:
  1044. table_num = (GINT)strtol((gchar *)OBJ_GET(widget,"table_num"),NULL,10);
  1045. gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget),firmware->rf_params[table_num]->req_fuel_total);
  1046. break;
  1047. case NUM_SQUIRTS_1:
  1048. case NUM_SQUIRTS_2:
  1049. /* This actually affects another variable */
  1050. table_num = (GINT)strtol((gchar *)OBJ_GET(widget,"table_num"),NULL,10);
  1051. divider_offset = firmware->table_params[table_num]->divider_offset;
  1052. firmware->rf_params[table_num]->last_num_squirts = firmware->rf_params[table_num]->num_squirts;
  1053. firmware->rf_params[table_num]->last_divider = ms_get_ecu_data(canID,page,divider_offset,size);
  1054. firmware->rf_params[table_num]->num_squirts = tmpi;
  1055. if (firmware->rf_params[table_num]->num_cyls % firmware->rf_params[table_num]->num_squirts)
  1056. set_reqfuel_color_f(RED,table_num);
  1057. else
  1058. {
  1059. dload_val = (GINT)(((float)firmware->rf_params[table_num]->num_cyls/(float)firmware->rf_params[table_num]->num_squirts)+0.001);
  1060. firmware->rf_params[table_num]->divider = dload_val;
  1061. d_data = g_new0(Deferred_Data, 1);
  1062. d_data->canID = canID;
  1063. d_data->page = page;
  1064. d_data->offset = divider_offset;
  1065. d_data->value = dload_val;
  1066. d_data->size = MTX_U08;
  1067. g_hash_table_replace(interdep_vars[table_num],
  1068. GINT_TO_POINTER(divider_offset),
  1069. d_data);
  1070. set_reqfuel_color_f(BLACK,table_num);
  1071. check_req_fuel_limits(table_num);
  1072. }
  1073. break;
  1074. case NUM_CYLINDERS_1:
  1075. case NUM_CYLINDERS_2:
  1076. /* Updates a shared bitfield */
  1077. table_num = (GINT)strtol((gchar *)OBJ_GET(widget,"table_num"),NULL,10);
  1078. divider_offset = firmware->table_params[table_num]->divider_offset;
  1079. firmware->rf_params[table_num]->last_divider = ms_get_ecu_data(canID,page,divider_offset,size);
  1080. firmware->rf_params[table_num]->last_num_cyls = firmware->rf_params[table_num]->num_cyls;
  1081. firmware->rf_params[table_num]->num_cyls = tmpi;
  1082. if (firmware->rf_params[table_num]->num_cyls % firmware->rf_params[table_num]->num_squirts)
  1083. set_reqfuel_color_f(RED,table_num);
  1084. else
  1085. {
  1086. tmp = ms_get_ecu_data(canID,page,offset,size);
  1087. tmp = tmp & ~bitmask; /*clears bits */
  1088. if (firmware->capabilities & MS2)
  1089. tmp = tmp | ((tmpi) << bitshift);
  1090. else
  1091. tmp = tmp | ((tmpi-1) << bitshift);
  1092. dload_val = tmp;
  1093. d_data = g_new0(Deferred_Data, 1);
  1094. d_data->canID = canID;
  1095. d_data->page = page;
  1096. d_data->offset = offset;
  1097. d_data->value = dload_val;
  1098. d_data->size = MTX_U08;
  1099. g_hash_table_replace(interdep_vars[table_num],
  1100. GINT_TO_POINTER(offset),
  1101. d_data);
  1102. dload_val = (GINT)(((float)firmware->rf_params[table_num]->num_cyls/(float)firmware->rf_params[table_num]->num_squirts)+0.001);
  1103. firmware->rf_params[table_num]->divider = dload_val;
  1104. d_data = g_new0(Deferred_Data, 1);
  1105. d_data->canID = canID;
  1106. d_data->page = page;
  1107. d_data->offset = divider_offset;
  1108. d_data->value = dload_val;
  1109. d_data->size = MTX_U08;
  1110. g_hash_table_replace(interdep_vars[table_num],
  1111. GINT_TO_POINTER(divider_offset),
  1112. d_data);
  1113. set_reqfuel_color_f(BLACK,table_num);
  1114. check_req_fuel_limits(table_num);
  1115. }
  1116. break;
  1117. case NUM_INJECTORS_1:
  1118. case NUM_INJECTORS_2:
  1119. /* Updates a shared bitfield */
  1120. table_num = (GINT)strtol((gchar *)OBJ_GET(widget,"table_num"),NULL,10);
  1121. firmware->rf_params[table_num]->last_num_inj = firmware->rf_params[table_num]->num_inj;
  1122. firmware->rf_params[table_num]->num_inj = tmpi;
  1123. tmp = ms_get_ecu_data(canID,page,offset,size);
  1124. tmp = tmp & ~bitmask; /*clears bits */
  1125. if (firmware->capabilities & MS2)
  1126. tmp = tmp | ((tmpi) << bitshift);
  1127. else
  1128. tmp = tmp | ((tmpi-1) << bitshift);
  1129. dload_val = tmp;
  1130. d_data = g_new0(Deferred_Data, 1);
  1131. d_data->canID = canID;
  1132. d_data->page = page;
  1133. d_data->offset = offset;
  1134. d_data->value = dload_val;
  1135. d_data->size = MTX_U08;
  1136. g_hash_table_replace(interdep_vars[table_num],
  1137. GINT_TO_POINTER(offset),
  1138. d_data);
  1139. check_req_fuel_limits(table_num);
  1140. break;
  1141. case GENERIC: /* Handles almost ALL other variables */
  1142. if ((GBOOLEAN)OBJ_GET(widget,"temp_dep"))
  1143. value = temp_to_ecu_f(value);
  1144. dload_val = convert_before_download_f(widget,value);
  1145. break;
  1146. default:
  1147. if (!ecu_handler)
  1148. {
  1149. if (get_symbol_f("ecu_spin_button_handler",(void **)&ecu_handler))
  1150. {
  1151. EXIT();
  1152. return ecu_handler(widget,data);
  1153. }
  1154. else
  1155. {
  1156. MTXDBG(CRITICAL,_("Default case, ecu handler NOT found in plugins, BUG!\n"));
  1157. EXIT();
  1158. return TRUE;
  1159. }
  1160. }
  1161. else
  1162. {
  1163. EXIT();
  1164. return ecu_handler(widget,data);
  1165. }
  1166. break;
  1167. }
  1168. if (dl_type == IMMEDIATE)
  1169. {
  1170. /* If data has NOT changed, don't bother updating
  1171. * and wasting time.
  1172. */
  1173. if (dload_val != ms_get_ecu_data(canID,page,offset,size))
  1174. ms_send_to_ecu(canID, page, offset, size, dload_val, TRUE);
  1175. }
  1176. gtk_widget_modify_text(widget,GTK_STATE_NORMAL,&black);
  1177. EXIT();
  1178. return TRUE;
  1179. }
  1180. /*!
  1181. \brief Checks the widget's type and updates it or callsthe appropriate
  1182. update function forit
  1183. \param object is a pointer to the object to update
  1184. \param user_data is used to detect a recursive loop and break out
  1185. */
  1186. G_MODULE_EXPORT void update_widget(gpointer object, gpointer user_data)
  1187. {
  1188. static void (*insert_text_handler)(GtkEntry *, const gchar *, gint, gint *, gpointer);
  1189. GtkWidget *widget = (GtkWidget *)object;
  1190. gint last = -G_MAXINT;
  1191. gint tmpi = 0;
  1192. gdouble value = 0.0;
  1193. ENTER();
  1194. if (!insert_text_handler)
  1195. get_symbol_f("insert_text_handler",(void **)&insert_text_handler);
  1196. g_return_if_fail(insert_text_handler);
  1197. g_return_if_fail(widget);
  1198. g_return_if_fail(GTK_IS_WIDGET(widget));
  1199. if (DATA_GET(global_data,"leaving"))
  1200. {
  1201. EXIT();
  1202. return;
  1203. }
  1204. /* If passed widget and user data are identical, break out as
  1205. * we already updated the widget.
  1206. */
  1207. if ((GTK_IS_WIDGET(user_data)) && (widget == user_data))
  1208. {
  1209. EXIT();
  1210. return;
  1211. }
  1212. /* update widget whether spin,radio or checkbutton
  1213. * (checkbutton encompases radio)
  1214. */
  1215. value = convert_after_upload_f(widget);
  1216. tmpi = value*1000;
  1217. last = (GINT)OBJ_GET(widget,"last_value");
  1218. /*printf("Old %i, new %i\n",last, tmpi);*/
  1219. if ((tmpi == last) && (!DATA_GET(global_data,"force_update")) && (!OBJ_GET(widget,"temp_dep")))
  1220. {
  1221. /*printf("new and old match, exiting early....\n");*/
  1222. EXIT();
  1223. return;
  1224. }
  1225. else
  1226. {
  1227. /*printf("Values changed, updating..\n");*/
  1228. OBJ_SET(widget,"last_value",GINT_TO_POINTER(tmpi));
  1229. }
  1230. if (GTK_IS_ENTRY(widget) || GTK_IS_SPIN_BUTTON(widget))
  1231. {
  1232. g_signal_handlers_block_by_func(widget,*(void **)(&insert_text_handler),NULL);
  1233. update_entry(widget);
  1234. g_signal_handlers_unblock_by_func(widget,*(void **)(&insert_text_handler),NULL);
  1235. }
  1236. else if (GTK_IS_COMBO_BOX(widget))
  1237. update_combo(widget);
  1238. else if (GTK_IS_CHECK_BUTTON(widget))
  1239. update_checkbutton(widget);
  1240. else if (GTK_IS_RANGE(widget))
  1241. update_range(widget,value);
  1242. else if (GTK_IS_SCROLLED_WINDOW(widget))
  1243. {
  1244. /* This will looks really weird, but is used in the
  1245. * special case of a treeview widget which is always
  1246. * packed into a scrolled window. Since the treeview
  1247. * depends on ECU variables, we call a handler here
  1248. * passing in a pointer to the treeview(the scrolled
  1249. * window's child widget)
  1250. */
  1251. update_model_from_view(gtk_bin_get_child(GTK_BIN(widget)));
  1252. }
  1253. /* IF control has groups linked to it's state, adjust */
  1254. }
  1255. /*!
  1256. \brief updates a gtk range
  1257. \param widget is the pointer to the range
  1258. */
  1259. void update_range(GtkWidget *widget, gfloat value)
  1260. {
  1261. gint dl_type = 0;
  1262. GtkAdjustment *adj = NULL;
  1263. gdouble upper = 0.0;
  1264. gdouble lower = 0.0;
  1265. ENTER();
  1266. dl_type = (GINT)OBJ_GET(widget,"dl_type");
  1267. adj = gtk_range_get_adjustment(GTK_RANGE(widget));
  1268. upper = gtk_adjustment_get_upper(adj);
  1269. lower = gtk_adjustment_get_lower(adj);
  1270. g_signal_handlers_block_by_func(widget,(gpointer)common_slider_handler,(gpointer) NULL);
  1271. if (value > upper)
  1272. gtk_range_set_value(GTK_RANGE(widget),upper);
  1273. else if (value < lower)
  1274. gtk_range_set_value(GTK_RANGE(widget),lower);
  1275. else
  1276. gtk_range_set_value(GTK_RANGE(widget),value);
  1277. g_signal_handlers_unblock_by_func(G_OBJECT(widget),
  1278. (gpointer)common_slider_handler, NULL);
  1279. }
  1280. /*!
  1281. \brief updates a checkbutton
  1282. \param widget is the pointer to the button
  1283. */
  1284. void update_checkbutton(GtkWidget *widget)
  1285. {
  1286. gboolean cur_state = FALSE;
  1287. gint tmpi = 0;
  1288. gboolean new_state = FALSE;
  1289. gint bitmask = 0;
  1290. gint bitshift = 0;
  1291. gint bitval = 0;
  1292. gdouble value = 0.0;
  1293. gchar * set_labels = NULL;
  1294. ENTER();
  1295. get_essential_bits(widget, NULL, NULL, NULL, &bitval, &bitmask, &bitshift);
  1296. if (gtk_toggle_button_get_inconsistent(GTK_TOGGLE_BUTTON(widget)))
  1297. gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(widget),FALSE);
  1298. /* Swaps the label of another control based on widget state... */
  1299. /* If value masked by bitmask, shifted right by bitshift = bitval
  1300. * then set button state to on...
  1301. */
  1302. cur_state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
  1303. value = convert_after_upload_f(widget);
  1304. tmpi = (GINT)value;
  1305. /* Avoid unnecessary widget setting and signal propogation
  1306. * First if. If current bit is SET but button is NOT, set it
  1307. * Second if, If currrent bit is NOT set but button IS then
  1308. * un-set it.
  1309. */
  1310. if (((tmpi & bitmask) >> bitshift) == bitval)
  1311. new_state = TRUE;
  1312. else if (((tmpi & bitmask) >> bitshift) != bitval)
  1313. new_state = FALSE;
  1314. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),new_state);
  1315. set_labels = (gchar *)OBJ_GET(widget,"set_widgets_label");
  1316. if ((set_labels) && (new_state))
  1317. set_widget_labels_f(set_labels);
  1318. if (OBJ_GET(widget,"swap_labels"))
  1319. swap_labels_f(widget,new_state);
  1320. if (new_state)
  1321. handle_algorithm(widget);
  1322. if ((new_state) && (OBJ_GET(widget,"group_2_update")))
  1323. handle_group_2_update(widget);
  1324. if (OBJ_GET(widget,"toggle_groups"))
  1325. combo_toggle_groups_linked_f(widget,new_state);
  1326. }
  1327. /*!
  1328. \brief updates a text entry
  1329. \param widget is the pointer to the button
  1330. */
  1331. void update_entry(GtkWidget *widget)
  1332. {
  1333. static void (*update_handler)(GtkWidget *) = NULL;
  1334. static Firmware_Details *firmware = NULL;
  1335. gboolean changed = FALSE;
  1336. gboolean use_color = FALSE;
  1337. DataSize size = MTX_U08;
  1338. gint handler = -1;
  1339. gchar * widget_text = NULL;
  1340. gchar * tmpbuf = NULL;
  1341. gdouble value = 0.0;
  1342. gint raw_lower = 0;
  1343. gint raw_upper = 0;
  1344. gint precision = 0;
  1345. GdkColor black = {0,0,0,0};
  1346. ENTER();
  1347. if (!firmware)
  1348. firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
  1349. g_return_if_fail(firmware);
  1350. value = convert_after_upload_f(widget);
  1351. handler = (GINT)OBJ_GET(widget,"handler");
  1352. precision = (GINT)OBJ_GET(widget,"precision");
  1353. /* Fringe case for module specific handlers */
  1354. if (OBJ_GET(widget,"modspecific"))
  1355. {
  1356. if (!update_handler)
  1357. {
  1358. if (get_symbol_f("ecu_update_entry",(void **)&update_handler))
  1359. update_handler(widget);
  1360. else
  1361. MTXDBG(CRITICAL,_("Default case, but there is NO ecu_update_entry function available, unhandled case for widget %s, BUG!\n"),glade_get_widget_name(widget));
  1362. }
  1363. else
  1364. update_handler(widget);
  1365. }
  1366. if ((GBOOLEAN)OBJ_GET(widget,"temp_dep"))
  1367. value = temp_to_host_f(value);
  1368. if (GTK_IS_SPIN_BUTTON(widget))
  1369. {
  1370. gfloat spin_value = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget));
  1371. if (value != spin_value)
  1372. gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget),value);
  1373. }
  1374. else
  1375. {
  1376. widget_text = (gchar *)gtk_entry_get_text(GTK_ENTRY(widget));
  1377. tmpbuf = g_strdup_printf("%1$.*2$f",value,precision);
  1378. /* If different, update it */
  1379. /*printf("widget text %s, new text %s\n",widget_text,tmpbuf);*/
  1380. if (g_ascii_strcasecmp(widget_text,tmpbuf) != 0)
  1381. {
  1382. /*printf("updating entry %p!\n",widget);*/
  1383. gtk_entry_set_text(GTK_ENTRY(widget),tmpbuf);
  1384. changed = TRUE;
  1385. }
  1386. /*
  1387. else
  1388. printf("not updating widget %p\n",widget);*/
  1389. g_free(tmpbuf);
  1390. }
  1391. if (OBJ_GET(widget,"use_color"))
  1392. {
  1393. gint table_num = -1;
  1394. if (OBJ_GET(widget,"table_num"))
  1395. table_num = (GINT)strtol((gchar *)OBJ_GET(widget,"table_num"),NULL,10);
  1396. if (table_num >= 0)
  1397. update_entry_color_f(widget,table_num,TRUE,FALSE);
  1398. else
  1399. update_entry_color_f(widget,0,FALSE,((changed) || (value == 0)));
  1400. }
  1401. if (OBJ_GET(widget,"not_sent"))
  1402. gtk_widget_modify_text(widget,GTK_STATE_NORMAL,&black);
  1403. }
  1404. /*!
  1405. \brief updates a combo box
  1406. \param widget is the pointer to the button
  1407. */
  1408. void update_combo(GtkWidget *widget)
  1409. {
  1410. static Firmware_Details *firmware = NULL;
  1411. static gboolean (*ecu_update_combo)(GtkWidget *) = NULL;
  1412. gint tmpi = -1;
  1413. gint canID = 0;
  1414. gint page = 0;
  1415. gint offset = 0;
  1416. gint bitval = 0;
  1417. gint bitmask = 0;
  1418. gint bitshift = 0;
  1419. gint t_bitval = 0;
  1420. gdouble value = 0;
  1421. GtkTreeModel *model = NULL;
  1422. GtkTreeIter iter;
  1423. gint valid = 0;
  1424. gint i = 0;
  1425. gchar * tmpbuf = NULL;
  1426. GdkColor red = {0,65535,0,0};
  1427. GdkColor white = {0,65535,65535,65535};
  1428. gint dl_type = 0;
  1429. ENTER();
  1430. if (!firmware)
  1431. firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
  1432. g_return_if_fail(firmware);
  1433. if (!ecu_update_combo)
  1434. get_symbol_f("ecu_update_combo",(void **)&ecu_update_combo);
  1435. g_return_if_fail(ecu_update_combo);
  1436. dl_type = (GINT)OBJ_GET(widget,"dl_type");
  1437. ecu_update_combo(widget);
  1438. /* if (dl_type == DEFERRED)
  1439. {
  1440. EXIT();
  1441. return;
  1442. }
  1443. */
  1444. get_essential_bits(widget,&canID, &page, &offset, &bitval, &bitmask, &bitshift);
  1445. /*printf("Combo at page %i, offset %i, bitmask %i, bitshift %i, value %i\n",page,offset,bitmask,bitshift,(GINT)value);*/
  1446. value = convert_after_upload_f(widget);
  1447. tmpi = ((GINT)value & bitmask) >> bitshift;
  1448. model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
  1449. if (!GTK_IS_TREE_MODEL(model))
  1450. printf(_("ERROR no model for Combo at page %i, offset %i, bitmask %i, bitshift %i, value %i\n"),page,offset,bitmask,bitshift,(GINT)value);
  1451. valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model),&iter);
  1452. i = 0;
  1453. while (valid)
  1454. {
  1455. gtk_tree_model_get(GTK_TREE_MODEL(model),&iter,BITVAL_COL,&t_bitval,-1);
  1456. if (tmpi == t_bitval)
  1457. {
  1458. gtk_combo_box_set_active_iter(GTK_COMBO_BOX(widget),&iter);
  1459. gtk_widget_modify_base(gtk_bin_get_child(GTK_BIN(widget)),GTK_STATE_NORMAL,&white);
  1460. if (OBJ_GET(widget,"algorithms"))
  1461. combo_handle_algorithms(widget);
  1462. if (OBJ_GET(widget,"group_2_update"))
  1463. combo_handle_group_2_update(widget);
  1464. goto combo_toggle;
  1465. }
  1466. valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(model), &iter);
  1467. i++;
  1468. }
  1469. /*printf("COULD NOT FIND MATCH for data for combo %p, data %i!!\n",widget,tmpi);*/
  1470. gtk_widget_modify_base(gtk_bin_get_child(GTK_BIN(widget)),GTK_STATE_NORMAL,&red);
  1471. EXIT();
  1472. return;
  1473. combo_toggle:
  1474. if (OBJ_GET(widget,"toggle_labels"))
  1475. combo_toggle_labels_linked_f(widget,i);
  1476. if (OBJ_GET(widget,"toggle_groups"))
  1477. combo_toggle_groups_linked_f(widget,i);
  1478. if (OBJ_GET(widget,"swap_labels"))
  1479. swap_labels_f(widget,tmpi);
  1480. if (OBJ_GET(widget,"set_widgets_label"))
  1481. combo_set_labels_f(widget,model);
  1482. }
  1483. /*!
  1484. \brief handles the case where a combobox enables or disables multiple
  1485. groups of controls based on which value is chosen
  1486. \param widget is the pointer to the button
  1487. */
  1488. void combo_handle_group_2_update(GtkWidget *widget)
  1489. {
  1490. static GHashTable *sources_hash = NULL;
  1491. gchar *tmpbuf = NULL;
  1492. gchar **vector = NULL;
  1493. gchar * source_key = NULL;
  1494. gchar * source_values = NULL;
  1495. ENTER();
  1496. if (!sources_hash)
  1497. sources_hash = (GHashTable *)DATA_GET(global_data,"sources_hash");
  1498. source_key = (gchar *)OBJ_GET(widget,"source_key");
  1499. source_values = (gchar *)OBJ_GET(widget,"source_values");
  1500. g_return_if_fail(sources_has

Large files files are truncated, but you can click here to view the full file