diff --git a/captcha.admin.inc b/captcha.admin.inc
index 2a956c4..6878d8e 100644
--- a/captcha.admin.inc
+++ b/captcha.admin.inc
@@ -64,10 +64,10 @@ function captcha_admin_settings() {
   );
   $form['captcha_form_protection']['captcha_form_id_overview']['captcha_captcha_points'] = array();
   $captcha_type_options = _captcha_available_challenge_types();
-  $result = db_select('captcha_points', 'cp')->fields('cp')->orderBy('form_id')->execute();
-  foreach ($result as $captcha_point) {
-    $form['captcha_form_protection']['captcha_form_id_overview']['captcha_captcha_points'][$captcha_point->form_id] = array();
-    $form['captcha_form_protection']['captcha_form_id_overview']['captcha_captcha_points'][$captcha_point->form_id]['form_id'] = array(
+  $captcha_points = captcha_get_captcha_points();
+  foreach ($captcha_points as $captcha_point) {
+    $elem = array();
+    $elem['form_id'] = array(
       '#markup' => $captcha_point->form_id,
     );
     // Select widget for CAPTCHA type.
@@ -80,17 +80,24 @@ function captcha_admin_settings() {
     else {
       $captcha_type = 'none';
     }
-    $form['captcha_form_protection']['captcha_form_id_overview']['captcha_captcha_points'][$captcha_point->form_id]['captcha_type'] = array(
+    $elem['captcha_type'] = array(
       '#type' => 'select',
       '#default_value' => $captcha_type,
       '#options' => $captcha_type_options,
     );
-    // Additional operations.
-    $form['captcha_form_protection']['captcha_form_id_overview']['captcha_captcha_points'][$captcha_point->form_id]['operations'] = array(
-      '#markup' => implode(", ", array(
-        l(t('delete'), "admin/config/people/captcha/captcha/captcha_point/{$captcha_point->form_id}/delete"),
-      )),
-    );
+    $ops = array();
+    if (module_exists('ctools') && $captcha_point->export_type & EXPORT_IN_CODE) {
+      if ($captcha_point->export_type & EXPORT_IN_DATABASE) {
+        $ops[] = l(t('revert'), "admin/config/people/captcha/captcha/captcha_point/{$captcha_point->form_id}/delete");
+      }
+      // TODO Disable exported points.
+    }
+    else {
+      $ops[] = l(t('delete'), "admin/config/people/captcha/captcha/captcha_point/{$captcha_point->form_id}/delete");
+    }
+    $elem['operations'] = array('#markup' => implode(", ", $ops));
+
+    $form['captcha_form_protection']['captcha_form_id_overview']['captcha_captcha_points'][$captcha_point->form_id] = $elem;
   }
 
   // Form items for new form_id.
@@ -281,7 +288,26 @@ function captcha_admin_settings_submit($form, &$form_state) {
 
   // Process CAPTCHA points.
   if (isset($form_state['values']['captcha_form_id_overview']['captcha_captcha_points'])) {
+    // Load existing data.
+    $captcha_points = captcha_get_captcha_points();
     foreach ($form_state['values']['captcha_form_id_overview']['captcha_captcha_points'] as $captcha_point_form_id => $data) {
+      // If this is an in-code captcha point and its settings are unchanged,
+      // don't save to the database.
+      if (module_exists('ctools') && isset($captcha_points[$captcha_point_form_id])) {
+        // Parse module and captcha_type from submitted values.
+        if (is_string($data['captcha_type']) && substr_count($data['captcha_type'], '/') == 1) {
+          list($module, $captcha_type) = explode('/', $data['captcha_type']);
+        }
+        else {
+          $module = '';
+          $captcha_type = $data['captcha_type'];
+        }
+
+        $point = $captcha_points[$captcha_point_form_id];
+        if ($point->export_type & EXPORT_IN_CODE && !($point->export_type & EXPORT_IN_DATABASE) && $point->module == $module && $point->captcha_type == $captcha_type) {
+          continue;
+        }
+      }
       captcha_set_form_id_setting($captcha_point_form_id, $data['captcha_type']);
     }
   }
diff --git a/captcha.inc b/captcha.inc
index 9412bc7..934d72f 100644
--- a/captcha.inc
+++ b/captcha.inc
@@ -83,8 +83,16 @@ function captcha_set_form_id_setting($form_id, $captcha_type) {
  */
 function captcha_get_form_id_setting($form_id, $symbolic = FALSE) {
   // Fetch setting from database.
-  $result = db_query("SELECT module, captcha_type FROM {captcha_points} WHERE form_id = :form_id", array(':form_id' => $form_id));
-  $captcha_point = $result->fetchObject();
+  if (module_exists('ctools')) {
+    ctools_include('export');
+    $object = ctools_export_load_object('captcha_points', 'names', array($form_id));
+    $captcha_point = array_pop($object);
+  }
+  else {
+    $result = db_query("SELECT module, captcha_type FROM {captcha_points} WHERE form_id = :form_id",
+      array(':form_id' =>  $form_id));
+    $captcha_point = $result->fetchObject();
+  }
 
   // If no setting is available in database for the given form,
   // but 'captcha_default_challenge_on_nonlisted_forms' is enabled, pick the default type anyway.
@@ -116,6 +124,26 @@ function captcha_get_form_id_setting($form_id, $symbolic = FALSE) {
 }
 
 /**
+ * Helper function to load all captcha points.
+ *
+ * @return array of all captcha_points
+ */
+function captcha_get_captcha_points() {
+  if (module_exists('ctools')) {
+    ctools_include('export');
+    $captcha_points = ctools_export_load_object('captcha_points', 'all');
+  }
+  else {
+    $captcha_points = array();
+    $result = db_select('captcha_points', 'cp')->fields('cp')->orderBy('form_id')->execute();
+    foreach ($result as $captcha_point) {
+      $captcha_points[] = $captcha_point;
+    }
+  }
+  return $captcha_points;
+}
+
+/**
  * Helper function for generating a new CAPTCHA session.
  *
  * @param string $form_id
diff --git a/captcha.install b/captcha.install
index 58d0847..dc37f83 100644
--- a/captcha.install
+++ b/captcha.install
@@ -12,6 +12,18 @@ function captcha_schema() {
   // Table for positions and types of the challenges.
   $schema['captcha_points'] = array(
     'description' => 'This table describes which challenges should be added to which forms.',
+    'export' => array(
+      'key' => 'form_id',
+      'identifier' => 'captcha',
+      'default hook' => 'captcha_default_points',  // Function hook name.
+      'status' => 'mark_status',
+      'api' => array(
+        'owner' => 'captcha',
+        'api' => 'captcha',  // Base name for api include files.
+        'minimum_version' => 1,
+        'current_version' => 1,
+      ),
+    ),
     'fields' => array(
       'form_id' => array(
         'description' => 'The form_id of the form to add a CAPTCHA to.',
@@ -134,25 +146,6 @@ function captcha_requirements($phase) {
  */
 function captcha_install() {
   $t = get_t();
-  // Insert some default CAPTCHA points.
-  $form_ids = array(
-    'contact_site_form', 'contact_personal_form',
-    'user_register_form', 'user_pass', 'user_login', 'user_login_block',
-    'forum_node_form',
-  );
-  // Add form_ids of all currently known node types too.
-  foreach (node_type_get_names() as $type => $name) {
-    $form_ids[] = 'comment_node_' . $type . '_form';
-  }
-  foreach ($form_ids as $form_id) {
-    db_insert('captcha_points')
-      ->fields(array(
-        'form_id' => $form_id,
-        'module' => NULL,
-        'captcha_type' => NULL,
-      ))
-      ->execute();
-  }
 
   // Be friendly to your users: what to do after install?
   drupal_set_message($t('You can now <a href="!captcha_admin">configure the CAPTCHA module</a> for your site.',
diff --git a/captcha.module b/captcha.module
index 1323393..16844ec 100644
--- a/captcha.module
+++ b/captcha.module
@@ -304,6 +304,54 @@ function captcha_element_process($element, &$form_state, $complete_form) {
 }
 
 /**
+ * Implementation of hook_captcha_default_points_alter().
+ *
+ * Provide some default captchas only if defaults are not already
+ * provided by other modules.
+ */
+function captcha_captcha_default_points_alter(&$items) {
+  $modules = array(
+    'comment' => array(
+    ),
+    'contact' => array(
+      'contact_site_form',
+      'contact_personal_form'
+    ),
+    'forum' => array(
+      'forum_node_form',
+    ),
+    'user' => array(
+      'user_register_form',
+      'user_pass',
+      'user_login',
+      'user_login_block',
+    ),
+  );
+  // Add comment form_ids of all currently known node types.
+  foreach (node_type_get_names() as $type => $name) {
+    $modules['comment'][] = 'comment_node_' . $type . '_form';
+  }
+
+  foreach ($modules as $module => $form_ids) {
+    // Only give defaults if the module exists.
+    if (module_exists($module)) {
+      foreach ($form_ids as $form_id) {
+        // Ensure a default has not been provided already.
+        if (!isset($items[$form_id])) {
+          $captcha = new stdClass;
+          $captcha->disabled = FALSE;
+          $captcha->api_version = 1;
+          $captcha->form_id = $form_id;
+          $captcha->module = '';
+          $captcha->captcha_type = 'default';
+          $items[$form_id] = $captcha;
+        }
+      }
+    }
+  }
+}
+
+/**
  * Theme function for a CAPTCHA element.
  *
  * Render it in a fieldset if a description of the CAPTCHA
